VoiceSessions : nombre de sessions ayant utilisé le vocal au moins une fois, lu
dans le JSON de Metadata. Volontairement hors d'AppTypeDistribution — le vocal
n'est pas une plateforme mais un mode d'interaction : un visiteur passe des
lunettes à l'écran dans une même session, or la distribution compte une entrée
par session tranchée sur l'événement le plus ancien. Le chiffre aurait dépendu de
l'ordre dans lequel le visiteur a touché ses appareils. Colonne Metadata déjà
existante : aucune migration, le gel du lot B tient.
Le test InMemory ne prouve rien ici — le provider évalue le filtre côté client,
donc une requête intraduisible passerait au vert. Un test Postgres l'accompagne.
IsAutoTriggered devient IsVisitorQuestion (défaut true). Le nom d'hier ne
couvrait qu'un des deux cas : le vrai sens n'est pas « déclenché
automatiquement » mais « ce tour n'est pas une question de visiteur », ce qui
vaut aussi pour l'aperçu de conversation, où c'est le gestionnaire qui teste sa
personnalité. Renommé pendant qu'un seul commit en dépendait. Le défaut à true
est délibéré : une app visiteur publiée qui n'envoie pas le champ continue de
journaliser, et un test le fixe.
dotnet test : 204 passés, 14 sautés, 0 échec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
eventsQuery.ToList() ramenait la fenetre entiere, toutes colonnes comprises,
pour n'en faire que des comptages. La retention est passee de 30 jours a 13
mois (StatsRetentionDays = 395) : la methode charge donc desormais treize
fois ce pour quoi elle avait ete ecrite, et ca grossit tout seul.
Ce qui part en SQL : sessions distinctes, sommes de duree par session,
duree moyenne par section, top sections, visites par jour, distributions
par session, top articles, total des scans QR.
Ce qui ne peut pas y aller : POI, agenda, quiz, jeux, menus et validite des
QR se regroupent sur du JSON dans Metadata. On ne remonte plus que les deux
colonnes utiles, et seulement pour le type d'evenement concerne (MetadataOf).
Deux effets de bord voulus :
- les stats avancees ne sont plus calculees puis effacees pour les plans qui
n'y ont pas droit -- les six requetes ne partent pas ;
- les titres de section ne sont resolus que pour les ids reellement affiches
(top 10 + quiz), plus pour tous les ids vus dans la fenetre.
Un changement de semantique, delibere : « la langue de la session » etait
prise sur le premier evenement rendu par la base, dans un ordre indefini.
C'est desormais le plus ancien horodatage. Meme chose pour AppType.
Le reste est preserve a l'identique, y compris les cas tordus : un scan QR
sans metadata compte dans le total sans etre ni valide ni invalide, une
metadata illisible compte la completion de quiz a zero.
11 tests ajoutes -- la branche « stats avancees » n'etait couverte par
AUCUN test : les cas existants ne seedent pas d'Instance, donc
hasAdvancedStats etait toujours faux et la moitie de la methode n'etait
jamais executee. dotnet test 186/186.
⚠️ Ces tests tournent sur le provider InMemory, qui evalue tout cote client :
ils tiennent la semantique, pas la traduction SQL. La verification sur un
vrai Postgres arrive avec les tests Testcontainers.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
75 fichiers, ~1 mois de travail depuis f222861 (17/07). Contenu :
Onboarding self-service — jamais exécuté de bout en bout
OnboardingController, StripeWebhookController, StripeService, ResendEmailService
+ IEmailService (10 templates), EmailTemplates/, TrialLifecycleService (Hangfire),
PasswordTokenHelper, SlugHelper, 5 DTOs. Essai 14 j, Stripe customer/Checkout/Tax,
mot de passe oublié + invitation user, plafond IA d'essai.
Schéma Postgres v3 — passe pendant que la base est vide
ContentEmbedding + index HNSW (vector_cosine_ops), IEmbeddingService +
GoogleEmbeddingService (gemini-embedding-001, 768 dims), Deployment/Dockerfile.postgres
(postgis 3.4.3 + pgvector 0.8.6, épinglé par digest — un tag mobile rejouerait le
warning de collation glibc). Colonnes Resource : StoragePath, FileName,
IncludeInAiKnowledge, AiIndexStatus + nouveaux ResourceType ajoutés EN FIN d'enum.
Guide IA
Champs Guide* sur Instance + InstanceDTO, AssistantService lit la configuration client
dans les 4 blocs de prompt (ton codé en dur retiré, règle hors-sujet ajoutée aux deux
variantes qui n'en avaient pas), IHttpClientFactory à la place des new HttpClient().
Table VisitorQuestion + ConversationId sur AiChatRequest.
Stats
Rétention unifiée à 13 mois (instances ET plans), VisitEventPurgeService.
Nettoyage
IsStepLocked / IsHiddenInitially / FactContent supprimés de GuidedStep — IsStepLocked
rendait une étape définitivement infranchissable même après réussite.
SectionMap allégé (-57 lignes).
Tests
SectionParcoursControllerTests, FakeConfiguration, FakeEmailService.
ContentEmbedding a cassé 116 tests sur 124 (EF InMemory ne connaît pas Vector) :
l'entité est exclue quand le provider n'est pas Npgsql. Conséquence assumée —
le vector store n'est couvert par aucun test. dotnet test 124/124.
10 migrations EF. Base locale à jour, dotnet build 0 erreur.
Rien n'est en prod : la bascule Mongo → Postgres est décrite dans DOCS/STATUS.md §1quinquies.
⚠️ appsettings.json contient les clés Stripe (test) et Resend (prod) en clair — à rotationner.