diff --git a/kanban.html b/kanban.html index 3e7042f..1a30fdd 100644 --- a/kanban.html +++ b/kanban.html @@ -458,9 +458,9 @@
1Migration v3
1Bugs ouverts
6À tester
-
23Planifié
+
22Planifié
8Bascule prod
-
56Fait récemment
+
57Fait récemment
@@ -584,7 +584,7 @@
-

Planifié

23
+

Planifié

22
@@ -755,24 +755,10 @@
XRV2 · subventionné

Meta Quest — borne VR

-

Pilote presse uniquement, quand le SDK sort de preview. Profil d'appel à projets, pas de ligne produit. ⚠️ Les Ray-Ban ne sont plus dans cette carte : elles passent en V1 le 12/08 (carte suivante).

+

Pilote presse uniquement, quand le SDK sort de preview. Profil d'appel à projets, pas de ligne produit. ⚠️ Les Ray-Ban ne sont plus dans cette carte : elles sont passées en V1 le 12/08, et leur volet stats est livré depuis le 13/08 (voir « Fait récemment »).

roadmap.md — section XR
-
-
visitapplunettesNouveau 12/08
-

Canal Vocal des stats — l'émission côté visiteur

-

Décidé le 12/08 : les Ray-Ban entrent en V1. Activation manuelle, instance par instance — au démarrage la seule instance concernée est MyInfoMate, celle de test, pour observer des stats vocales réelles avant de proposer quoi que ce soit. Aucune promesse externe ne dépend de cette date.

-

⚠️ L'écran est déjà fait, c'est l'émission qui manque — donc zéro ligne dans manager-app : statistics_screen.dart traite déjà AppType.Voice (libellé :189, part du vocal :205-210, KPI conditionnel :533-541, takeaway :480). Tout le travail est dans mymuseum-visitapp.

-

Trois trous mesurés le 12/08. (1) MyInfoMateLlmClient:40 envoie AppType.Mobile alors que son commentaire :9 annonce Voice. (2) StatisticsService est construit en dur avec appType: 'Mobile' (home_3.0.dart:715), son champ étant documenté // "Mobile" or "Tablet". (3) Le plus lourd : le flux lunettes n'émet aucun VisitEvent — tous les track() sont dans des écrans d'interface ; Services/Glasses/, wake_word_service et geo_beacon_trigger_service n'en appellent aucun. Une visite vocale ne produit aujourd'hui ni session, ni section vue, ni durée.

-

Périmètre tranché : session + contenu lu à voix haute. Une session Voice à l'activation, un sectionView quand le guide lit réellement une section (QR, beacon ou question). ⛔ Pas d'événement par question : elles sont déjà dans VisitorQuestion et remontent dans l'onglet Guide IA — les compter ici serait le même fait dans deux écrans. Ce périmètre fait marcher les KPI existants et l'export PDF sans retouche.

-

Le « fallback Voice → Mobile » n'existe pasguide-ia-screen-plan.md:226 l'affirmait et le commentaire d'AiController:356 le répétait : les deux étaient faux et se confirmaient mutuellement. Le code fait un FirstOrDefault sur le canal exact puis Forbid() (:357-361) : envoyer Voice au chat sans ApplicationInstance de ce type rendrait 403 à chaque question, extinction silencieuse des lunettes. ✅ Le chat reste donc en Mobile : les lunettes tournent dans l'app mobile, qui a déjà chargé son canal — un canal Voice la ferait jongler entre deux, piège déjà rencontré en K2 avec getConfigurations.

-

CORRECTION du 12/08, quelques heures après : les VisitEvent ne portent pas Voice non plus. Le vocal n'est pas un canal, c'est un attribut. La décision du miroir vocal (carte suivante) rend explicite qu'un visiteur passe des lunettes à l'écran dans une même session. Or StatisticsService génère un seul sessionId par lancement, et AppTypeDistribution compte une entrée par session en tranchant l'ambiguïté sur l'événement le plus ancien (StatsController:196-203) : commencer au doigt puis mettre les lunettes ⇒ session comptée Mobile, vocal invisible ; l'inverse ⇒ session comptée Voice, navigation tactile comprise. Le KPI dirait « sessions démarrées en vocal », pas « part du vocal ».

-

Retenu : marquer les événements consommés à la voix dans VisitEvent.Metadata — colonne JSON déjà existante, déjà exploitée par GetSummary pour six agrégats : aucune migration, le gel du lot B tient. KPI juste : « part des sessions ayant utilisé le vocal ». C'est la conception déjà appliquée ailleursVisitorQuestion n'a pas de canal vocal, il a IsVoice à côté de son AppType. AppType.Voice retrouve son sens d'origine : un déploiement lunettes autonome, cas pour lequel l'enum a été créé et qui n'est pas celui-ci. ⚠️ Conséquence : « zéro ligne dans manager-app » devient faux_voiceSessions lit appTypeDistribution['Voice'] (statistics_screen.dart:205-206) et devra lire un nouvel agrégat. ~3 h.

-

⚠️ Deux réserves qui survivent : la branche Meta-Rayban-Test n'est toujours pas mergée (question déjà ouverte avant K6, et plus pressante puisqu'on ne publie plus un POC mais une fonction V1), et ne pas vendre l'add-on avant la bascule TTS ElevenLabs → Gemini.

- v1-plan.md lot F — canal Vocal · v2/guide-ia-screen-plan.md -
-
@@ -854,9 +840,16 @@

Fait récemment

-

Cinquante-six chantiers clos entre le 5 et le 13 août 2026.

+

Cinquante-sept chantiers clos entre le 5 et le 13 août 2026. Le lot F est clos.

+
+ Le lot F est clos — canal vocal des stats, et L9 qui n'était pas un chantier + Le vocal est un attribut, pas un canal, comme tranché le 12/08. StatisticsService.track porte isVoice, qui pose "voice": true dans VisitEvent.Metadatacolonne existante, donc aucune migration et le gel du lot B tient. Le serveur expose « sessions ayant utilisé le vocal » et statistics_screen lit cet agrégat au lieu d'appTypeDistribution['Voice'], qui ne se serait jamais rempli. + ⚠️ Le sectionView vocal part après la synthèse, pas avant : un déclenchement dont le TTS échoue n'a rien fait entendre, le compter serait faux. ⛔ Aucun événement par question posée — elles sont déjà dans VisitorQuestion. ⚠️ Le test InMemory ne prouve rien ici, le provider évaluant le filtre côté client : un test Postgres a été ajouté à côté, il se saute sans démon Docker. + L9 était un malentendu de doc, pas du travail. La « cible Assistant / Persona » du Mode preview est exactement ce que le §5 du Guide IA a livré le 11/08. Les trois autres cibles (iframes mobile/web/kiosk, viewports, preview-token) sont hors V1. ⚠️ Mais l'aperçu polluait les stats du client : chaque essai de personnalité par le gestionnaire était journalisé comme une question de visiteur. Corrigé — et le drapeau d'hier, IsAutoTriggered, est renommé IsVisitorQuestion (défaut true) parce que son vrai sens couvrait déjà les deux cas. dotnet test 218. +
+
Une conversation, plusieurs surfaces — miroir vocal et conversationId Le chat écrit, le vocal et le proactif partagent désormais une seule conversation, portée par VisitAppContext.assistant. Les trois AssistantService séparés ont disparu ; le maxHistory: 6 du vocal s'aligne sur 10, deux surfaces qui partagent une conversation ne pouvant pas la tronquer différemment selon le point d'entrée. La concision vocale vient d'isVoice, qui change le prompt côté serveur. diff --git a/v1-plan.md b/v1-plan.md index 85cdf5b..6f7ab73 100644 --- a/v1-plan.md +++ b/v1-plan.md @@ -186,10 +186,24 @@ Ne change pas : la popup de traduction (un niveau justifié, langues verticales, ✅ **`conversationId` est enfin envoyé, et le champ manquait dans le client généré** — c'est ce qui expliquait que personne ne l'envoyait. Ajouté à la main dans `manager_api_new`. Il est renouvelé quand la conversation est vidée : sinon la visite entière d'un même visiteur n'en formerait qu'une. **2 tests serveur** fixent le lien entre deux tours et le repli — la branche `Guid.NewGuid()` n'était couverte par rien. +✅ **Canal vocal des stats livré le 2026-08-13, et L9 refermé.** `dotnet test` **218** (dont un test Postgres), APK `dev` ✅, `flutter build web` ✅. + +**Le vocal est un attribut, pas un canal** — la correction du 12/08 est appliquée telle quelle. `StatisticsService.track` porte `isVoice`, qui pose `"voice": true` dans `VisitEvent.Metadata` — **colonne existante, donc aucune migration et le gel du lot B tient**. `StatsSummaryDTO.VoiceSessions` compte les **sessions ayant utilisé le vocal**, et `statistics_screen` lit cet agrégat au lieu d'`appTypeDistribution['Voice']`, qui ne se serait jamais rempli. + +⚠️ **Le `sectionView` vocal est émis après la synthèse, pas avant** : un déclenchement dont le TTS échoue n'a rien fait entendre, le compter serait faux. ⛔ **Aucun événement par question posée**, conformément à l'arbitrage : elles sont déjà dans `VisitorQuestion` et remontent dans l'onglet Guide IA. + +⚠️ **Le test InMemory ne prouve rien ici** — le provider évalue le `Contains` côté client, donc une requête intraduisible passerait au vert. Un test Postgres a été ajouté à côté ; il se saute sans démon Docker, comme les 14 autres. + +⛔ **L9 : la convergence n'était pas un chantier, c'était un malentendu de doc.** La « cible Assistant / Persona » du Mode preview (`todo-features.md:599-603`) est **exactement** ce que le §5 du Guide IA a livré le 11/08 — `_sendPreview` interroge le vrai `/api/AI/chat`. Les trois autres cibles du Mode preview (mobile, web, kiosk en iframe, sélecteur de viewport, preview-token) sont une feature bien plus large, **hors V1**. Rien à coder.
⚠️ **Mais l'aperçu polluait les stats du client** : chaque essai de personnalité par le gestionnaire était journalisé comme une question de visiteur. Corrigé dans la même passe — voir le renommage ci-dessous. + +⚠️ **`IsAutoTriggered` renommé en `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 du gestionnaire. Renommé pendant qu'un seul commit en dépendait. Le défaut à `true` est délibéré : une app visiteur déjà publiée, qui n'envoie pas le champ, continue de journaliser — **un test le fixe**. + **Ce qui reste au lot F, et dans quel repo** — le backend ne bloque plus rien : -- ~~`manager-app`~~ ✅ **livré le 2026-08-13** : bouton du Customer Portal et diviseur `aiTokensPerQuestion`. `flutter analyze lib` **sans erreur**, `flutter build web` ✅. Détail ci-dessous. -- `mymuseum-visitapp` : déclenchement proactif (+ M3), miroir de la conversation vocale, émission des événements vocaux. C'est désormais **tout le reste du lot F**, et le plus gros. -- Non commencé, indépendant : l'aperçu de conversation (**L9**). +- ~~`manager-app`~~ ✅ **livré le 2026-08-13** : bouton du Customer Portal et diviseur `aiTokensPerQuestion`. +- ~~`mymuseum-visitapp`~~ ✅ **livré le 2026-08-13** : déclenchement proactif (+ M3), miroir de la conversation vocale, émission des événements vocaux. +- ~~L9, aperçu de conversation~~ ⛔ **sans objet** — livré par DB3 le 11/08, le reste du Mode preview est hors V1. + +🎉 **Le lot F est clos le 2026-08-13.** Ce qui reste avant la bascule : le **lot J** (RGPD), **K6** (publier les APK), **K9** (repasse visuelle de la borne, sacrifiable), le **lot H** (tests, dont D0 et §21 sur device), **D5**, et le **lot I** (infra + bascule). **Volet proactif + M3 du 2026-08-13 (`mymuseum-visitapp`) — ce que le code a corrigé de l'énoncé :**