feat(t1-live): T1 Live frontend — Sprint 7b
Some checks are pending
CI / quality (push) Waiting to run
Some checks are pending
CI / quality (push) Waiting to run
- Add T1 state machine (8 states, presenting ⇄ interrupted) - Add useT1LiveSession (WS /t1/live, uplink gate by ref, no context msg) - Add T1PreparationPage, T1DialoguePage, T1SpeakingIndicator - Add EO_T1_LIVE card in TaskSelector gated via oral_t2_live - Extract shared t1Questionnaire.ts for batch/live DRY - Remove T1LiveQuestionnairePage + T1LiveContext (post patch 7a) - Simplified flow: card → preparation → dialogue - FTD-44 frozen (cross-feature audio hooks, Sprint 7.5) - FTD-45/46 frozen (Gemini relance quality + transcription) - Tests: 301/301 green
This commit is contained in:
parent
eb8987ddb3
commit
3016d909a6
14 changed files with 1385 additions and 68 deletions
|
|
@ -29,6 +29,35 @@ Chaque entrée suit ce format :
|
|||
|
||||
---
|
||||
|
||||
## [Unreleased] — 2026-06-30 — Sprint 7b — Frontend T1 Live (monologue + interruption non déterministe)
|
||||
|
||||
### Added
|
||||
|
||||
- Machine d'état T1 (`features/t1-live/state/t1-machine.ts`) — 8 états purs (`idle`, `preparing`, `connecting`, `presenting`, `interrupted`, `processing`, `ended`, `error`). Le cœur est la transition `interrupted ⇄ presenting` (interruption examinateur puis reprise candidat). +23 tests.
|
||||
- `useT1LiveSession` (`features/t1-live/hooks/useT1LiveSession.ts`) — orchestrateur du dialogue T1, calqué sur `useT2LiveSession` (discipline « Voie A »). WS `wss://${API_URL}/t1/live?token=<jwt>` (PAS de `&sujet=` — T1 n'est pas subject-based). Aucun VAD micro (T1 = monologue) ; l'uplink micro est coupé/rétabli pendant une interruption via un **ref** (`uplinkMutedRef`), jamais via `setState` (leçon Voie A). Réagit aux signaux applicatifs `{type:'interruption_start'}` / `{type:'interruption_end'}`. Timer dur 180 s. Close codes 1000/4001/4003/4005/4006.
|
||||
- `T1PreparationPage` + `T1DialoguePage` (`features/t1-live/pages/`) — parcours préparation → dialogue (3:00) ; écran terminal « Télécharger l'audio » + « Voir le rapport » (`/rapport/:id`). L'UI ne suppose JAMAIS qu'une relance suit (interruption non déterministe).
|
||||
- `T1SpeakingIndicator` (`features/t1-live/components/`) — indicateur de prise de parole (amplitude micro réelle en `presenting`, animation décorative en `interrupted`).
|
||||
- Carte `EO_T1_LIVE` dans `TaskSelector` (discriminateur `live?: 'T1' | 'T2'`, label « Tâche 1 — Live ») gatée Premium via `hasAccess(plan, 'oral_t2_live')` (TD-24 — pas de nouvelle permission, le gate couvre T1 et T2 Live) + prop `onT1LiveSelect`. `SimulationEOPage` câble `onT1LiveSelect → /simulation/eo/t1/live/preparation`.
|
||||
- `features/simulations/lib/t1Questionnaire.ts` — définition partagée du questionnaire T1 (FIELDS + schéma zod + `EMPTY_REPONSES`), réutilisée par le batch `QuestionnaireT1Page`.
|
||||
|
||||
### Changed
|
||||
|
||||
- `useT1LiveSession` aligné sur le **Patch 7a backend** : plus d'envoi du message `{type:'context'}`, plus d'option `reponses`, la session audio démarre directement sur `ws.onopen` (WS_OPENED → presenting).
|
||||
- Parcours T1 Live simplifié : carte `EO_T1_LIVE` → préparation → dialogue (plus d'étape questionnaire intermédiaire).
|
||||
- `t1-machine` : commentaire et test nettoyés (mapping close **4004** retiré → 4006), cohérent avec la suppression du contexte côté backend.
|
||||
|
||||
### Removed
|
||||
|
||||
- `T1LiveQuestionnairePage` et `T1LiveContext` (post-Patch 7a) — le backend n'exige plus de message `context` ni de réponses pré-remplies ; ces écrans/état deviennent sans objet.
|
||||
|
||||
### Notes
|
||||
|
||||
- **FTD-44 gelée** (§3bis TECH_DEBT) — les trois hooks audio génériques sont empruntés à `features/t2-live/hooks/` (violation FSD inter-features assumée et tracée, sites marqués `// TODO(FTD-44)`), réactivée au Sprint 7.5 (factorisation Sprint 7).
|
||||
- WebSocket / AudioContext non matérialisables en jsdom → validation manuelle ; la logique pure de transition est couverte par `t1-machine.test.ts`.
|
||||
- Bugs amont observés au test manuel, hors contrôle frontend : **FTD-45** (relances Gemini hors-sujet, extension TD-23) et **FTD-46** (transcription Gemini Live hasardeuse).
|
||||
|
||||
---
|
||||
|
||||
## [Unreleased] — 2026-06-29 — Sprint 6e — T2 Live « Voie A » (mix audio temps réel)
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@
|
|||
## Sprint 7 — T1 Live (interruption aléatoire)
|
||||
|
||||
- **7a (backend) ✅** : extension du proxy WebSocket Gemini Live (`gemini-3.1-flash-live-preview`, ws brut, pas de SDK) au mode T1 — system prompt « examinateur », décision d'interruption probabiliste, génération de la question de relance sur transcription partielle (DeepSeek). Réutilise l'infra T2 Live. Scoring EO 5 critères × /4. Phonologie live = 0 (TD-08, gelé). Contraintes héritées : pas de `speechConfig`. Livré : commits `868bd09` (code) + `3722e2a` (docs) ; dettes tracées TD-23/24/25 (cf. `TECH_DEBT-backend.md`).
|
||||
- **7b (frontend)** : UI T1 Live réutilisant ws-client + audio worklet + state machine T2 ; phase préparation ; gestion interruption / reprise du flux audio dans la state machine ; gating Premium.
|
||||
- **7b (frontend) ✅** : UI T1 Live — machine d'état T1 (8 états, `interrupted ⇄ presenting`), `useT1LiveSession` (WS `/t1/live`, sans message `context` post-Patch 7a, uplink coupé par ref pendant interruption), `T1PreparationPage` / `T1DialoguePage` / `T1SpeakingIndicator`, carte `EO_T1_LIVE` gatée Premium (`oral_t2_live`). Parcours simplifié carte → prépa → dialogue. `T1LiveQuestionnairePage` + `T1LiveContext` retirés. Réutilise les hooks audio T2 (FTD-44 gelée). **Bugs amont observés au test manuel** (hors contrôle frontend) : **FTD-45** (relances Gemini hors-sujet, extension TD-23) et **FTD-46** (transcription Gemini Live hasardeuse).
|
||||
|
||||
## Sprint 7.5 — Clean
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# TECH_DEBT.md — Expria Frontend
|
||||
|
||||
> **Document de référence — Version 1.28**
|
||||
> **Document de référence — Version 1.30**
|
||||
> Ce document recense les décisions techniques prises par pragmatisme qui devront être revisitées, les stubs temporaires, et les fonctionnalités reportées.
|
||||
> À mettre à jour après chaque session de développement.
|
||||
>
|
||||
|
|
@ -456,6 +456,49 @@ Frontend :
|
|||
|
||||
---
|
||||
|
||||
### FTD-44 — Hooks audio génériques empruntés à `features/t2-live/` (T1 Live)
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Gelé — réactivé au Sprint 7.5 (« factorisation Sprint 7 »)
|
||||
**Estimation de session :** 0,5 jour
|
||||
**Description :** Le flux T1 Live (Sprint 7b) importe directement les trois hooks audio génériques de `features/t2-live/hooks/` (`useAudioCapture`, `useAudioPlayback`, `useAudioRecording`) — une violation assumée de la frontière inter-features FSD (un feature ne devrait pas importer un sibling). Décision prise pour NE PAS toucher aux fichiers T2 (pipeline audio validé à l'oreille, intouchable jusqu'à factorisation). Sites d'import marqués `// TODO(FTD-44)` dans `features/t1-live/hooks/useT1LiveSession.ts`.
|
||||
|
||||
**À faire :** relocaliser les trois hooks (génériques par nature : aucune logique T2 spécifique) vers `shared/lib/audio/`, puis migrer les imports T2 ET T1 vers ce chemin partagé. Validation à l'oreille obligatoire après déplacement (T2 + T1).
|
||||
|
||||
**Condition de résolution :** Sprint 7.5 (factorisation Sprint 7), une fois les flux T1 et T2 Live stabilisés.
|
||||
|
||||
---
|
||||
|
||||
### FTD-45 — Relances Gemini T1 Live hors-sujet (extension TD-23)
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Gelé — dépend de l'amont (Gemini / backend TD-23), hors contrôle frontend
|
||||
**Estimation de session :** à évaluer (chantier backend/prompt)
|
||||
**Description :** En T1 Live, l'examinateur (Gemini) formule ses relances à partir de son contexte audio interne. Au test manuel, certaines relances partent **hors-sujet** (sans rapport avec ce que le candidat vient de dire). Extension de la dette backend **TD-23** : en VAD manuel, `inputTranscription` candidat n'est flushé qu'à `activityEnd`, donc le modèle relance sans transcription token-par-token fiable.
|
||||
|
||||
**Impact actuel :** dégrade le réalisme de l'entretien T1 ; non bloquant pour la livraison 7b (le flux fonctionne, l'évaluation finale reste correcte).
|
||||
|
||||
**À faire :** ré-évaluer côté backend/prompt (formulation de la consigne de relance, fenêtre de contexte) une fois la transcription incrémentale repensée (Sprint 7e / TD-23).
|
||||
|
||||
**Condition de résolution :** après traitement de TD-23 (transcription live) — non actionnable côté frontend seul.
|
||||
|
||||
---
|
||||
|
||||
### FTD-46 — Transcription Gemini Live hasardeuse (qualité audio→texte)
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Gelé — dépend de l'amont (qualité Gemini Live), hors contrôle frontend
|
||||
**Estimation de session :** à évaluer
|
||||
**Description :** La transcription produite par Gemini Live (`input/outputTranscription`) est de qualité **inégale** : mots manqués, segments approximatifs. Observé au test manuel T1 Live (et applicable au T2 Live). Affecte la fidélité du transcript utilisé pour l'évaluation et bloquera l'affichage live (Sprint 7e).
|
||||
|
||||
**Impact actuel :** qualité du transcript variable ; non bloquant pour 7b (l'évaluation 5 critères reste exploitable).
|
||||
|
||||
**À faire :** suivre l'évolution du modèle Gemini Live ; évaluer un post-traitement ou une source de transcription alternative si la qualité reste insuffisante au Sprint 7e.
|
||||
|
||||
**Condition de résolution :** amélioration amont (modèle) ou décision d'architecture transcription au Sprint 7e.
|
||||
|
||||
---
|
||||
|
||||
## 4. Tests à renforcer
|
||||
|
||||
> FTD-09 gelée au Sprint 5.5 (2026-04-26) — voir §3bis Backlog gelé.
|
||||
|
|
@ -555,3 +598,5 @@ Frontend :
|
|||
| 1.26 | 2026-04-26 | Sprint 5e (clean Sprint 5 Billing) — Ajout FTD-42 🟡 (modal prorata Standard→Premium avec montant exact — divergence PARCOURS_UTILISATEURS §3, actuellement Customer Portal natif sans preview in-app) et FTD-43 🟢 (race condition webhook post-redirect Stripe — `usePlan()` peut retourner ancien plan brièvement). **21 FTD actives — cap 15 dépassé de 6. Résorption FTD critique au Sprint 5.5 avant Sprint 6.** |
|
||||
| 1.27 | 2026-04-26 | Sprint 5.5 Clean — FTD-09, FTD-33, FTD-42 gelées. FTD-35 fermée (subsumée par FTD-41). FTD-14, FTD-38, FTD-39 résolues. **14 FTD actives** (cap 15 respecté). |
|
||||
| 1.28 | 2026-04-26 | Sprint 6c — FTD-09 et FTD-33 résolues (dégelées → fermées). **14 FTD actives** (inchangé — les gelées ne comptaient pas dans le cap). |
|
||||
| 1.29 | 2026-06-30 | Sprint 7b (T1 Live) — Ajout FTD-44 🟡 **gelée** (hooks audio génériques empruntés à `features/t2-live/`, réactivée au Sprint 7.5). **14 FTD actives** (inchangé — entrée gelée, ne compte pas dans le cap, même mécanique que FTD-06). |
|
||||
| 1.30 | 2026-06-30 | Sprint 7b (T1 Live, finalisation) — Ajout FTD-45 🟡 **gelée** (relances Gemini hors-sujet, extension TD-23) et FTD-46 🟡 **gelée** (transcription Gemini Live hasardeuse). Bugs amont observés au test manuel, hors contrôle frontend. **14 FTD actives** (inchangé — entrées gelées, ne comptent pas dans le cap). |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue