Sprint 6c — Frontend T2 Live UI + state machine + integration
feat(t2-live): state machine pure 9 states x 8 events (resolves FTD-09) feat(t2-live): useT2LiveSession WS orchestrator + audio hooks + close codes feat(t2-live): T2SujetsPage, T2PreparationPage (2min timer + notes + ideas), T2DialoguePage (3:30 dialogue + terminal screen with WAV download) feat(t2-live): T2LiveContext provider for sujet sharing between pages fix(TaskSelector): unlock EO_T2_LIVE card via hasAccess (resolves FTD-33) chore: Tache type + labels + config extended with EO_T2_LIVE test: 21 t2-machine tests — 259/259 green (+21)
This commit is contained in:
parent
7862f7c9f3
commit
1d95166611
17 changed files with 1229 additions and 33 deletions
|
|
@ -29,6 +29,34 @@ Chaque entrée suit ce format :
|
|||
|
||||
---
|
||||
|
||||
## [Unreleased] — 2026-04-26 — Sprint 6c — Frontend T2 Live UI
|
||||
|
||||
### Added
|
||||
|
||||
- `t2-machine.ts` — state machine pure T2 Live : 9 états (`idle` → `preparing` → `connecting` → `ready` → `speaking` ↔ `listening` → `processing` → `ended` / `error`), 8 events. 21 tests. Résout FTD-09.
|
||||
- `useT2LiveSession.ts` — hook orchestrateur : WebSocket + state machine + hooks audio (capture/playback/recording). Parse format Gemini natif (`serverContent.modelTurn`) + messages applicatifs backend (`warning`/`report`/`error`). Close codes 1000/4001/4003/4004. Timer dialogue 210 s. Ping 30 s keep-alive.
|
||||
- `T2LiveContext.tsx` — Provider léger pour partager le sujet sélectionné entre les pages T2.
|
||||
- `T2SujetsPage.tsx` — grille de sélection des sujets T2 (`GET /sujets?mode=EO&tache=2`).
|
||||
- `T2PreparationPage.tsx` — timer 2 min, consigne affichée, zone de notes locale, bouton « Suggestions d'idées » (DeepSeek, actif immédiatement), bouton « Je suis prêt », pré-warm micro via `getUserMedia`. Transition auto vers dialogue à 0:00.
|
||||
- `T2DialoguePage.tsx` — timer 3:30, indicateur d'état IA, waveform, bouton « Terminer ». Écran terminal (state `ended`) : bouton « Télécharger l'audio » (WAV mono 24 kHz) + bouton « Voir le rapport » (→ `/rapport/:id`).
|
||||
- 3 routes : `/simulation/eo/t2`, `/simulation/eo/t2/preparation`, `/simulation/eo/t2/dialogue` sous `T2LiveLayout`.
|
||||
|
||||
### Changed
|
||||
|
||||
- `TaskSelector.tsx` — carte EO T2 Live déverrouillée via `hasAccess(plan, 'oral_t2_live')` + prop `onT2LiveSelect`. Résout FTD-33.
|
||||
- `SimulationEOPage.tsx` — branche `onT2LiveSelect` vers `/simulation/eo/t2`.
|
||||
- `entities/production/` — `Tache` type, labels, `mapTacheToSujetParams`, config étendus avec `EO_T2_LIVE`.
|
||||
- `features/historique/` — `TACHE_NUMBER` étendu.
|
||||
|
||||
### Notes
|
||||
|
||||
- Tests frontend : 238 → 259 verts (+21 — tous sur t2-machine).
|
||||
- FTD-09 résolue (state machine testée).
|
||||
- FTD-33 résolue (carte déverrouillée via hasAccess).
|
||||
- `useT2LiveSession` non testé en unit (WebSocket non supporté jsdom) — validation manuelle prévue.
|
||||
|
||||
---
|
||||
|
||||
## [Unreleased] — 2026-04-26 — Sprint 6b — Frontend audio (T2 Live)
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# TECH_DEBT.md — Expria Frontend
|
||||
|
||||
> **Document de référence — Version 1.27**
|
||||
> **Document de référence — Version 1.28**
|
||||
> 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.
|
||||
>
|
||||
|
|
@ -421,29 +421,7 @@ Frontend :
|
|||
|
||||
---
|
||||
|
||||
### FTD-09 — Tests de la state machine T2 Live non implémentés
|
||||
|
||||
**Priorité :** 🟡 Important
|
||||
**Statut :** Gelé — Sprint 5.5 (2026-04-26)
|
||||
**Estimation de session :** 3h
|
||||
**Description :** La state machine T2 Live (`src/features/t2-live/state/t2-machine.ts`) n'existe pas encore. Quand elle sera créée, elle devra être testée de manière exhaustive (6+ tests couvrant les transitions d'états et les cas d'erreur).
|
||||
|
||||
**Motif de gel :** Gelé — le code n'existe pas encore, sera créé et testé au Sprint 6.
|
||||
|
||||
**Condition de résolution :** fin Sprint 6 (T2 Live).
|
||||
|
||||
---
|
||||
|
||||
### FTD-33 — Carte EO_T2_LIVE verrouillée en dur (pas via `hasAccess`)
|
||||
|
||||
**Priorité :** 🟢 Mineur
|
||||
**Statut :** Gelé — Sprint 5.5 (2026-04-26)
|
||||
**Estimation de session :** 0,5 jour
|
||||
**Description :** Dans `TaskSelector`, la carte EO_T2_LIVE a `tache: null` ce qui la rend inactive pour tous les plans, indépendamment de `hasAccess(plan, 'oral_t2_live')`. C'est volontaire tant que T2 Live n'est pas livré (Sprint 6) — un utilisateur Premium ne doit pas accéder à une feature non implémentée. À nettoyer dès que T2 Live est wired pour respecter strictement la Règle D.
|
||||
|
||||
**Motif de gel :** Gelé — condition de résolution = Sprint 6 T2 Live.
|
||||
|
||||
**Condition de résolution :** lancement de T2 Live (Sprint 6).
|
||||
> FTD-09 et FTD-33 résolues au Sprint 6c (2026-04-26) — voir §5 Historique.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -534,6 +512,8 @@ Frontend :
|
|||
| FTD-24 | Pas de polling automatique pour exercices / modèle `pending` | 2026-04-23 | Polling conditionnel dans `useRapport` via `refetchInterval: 3000` tant que `exercices_status === 'pending' \|\| modele_status === 'pending'`. Arrêt automatique dès que les deux sortent de pending (ready ou error). Timeout global 2 min → `hasTimedOut = true` + bouton « Réessayer » dans `JobStatusFallback` (primitive `@/shared/ui/Button`). `refetch()` réinitialise le flag et relance le polling. `staleTime: Infinity` conservé. 5 tests nouveaux dans `useRapport.test.tsx`. |
|
||||
| FTD-25 | Mise à jour ARCHITECTURE.md §3 (arborescence réelle) | 2026-04-25 | §3 réécrite : `app/` documenté avec entry points + layout (AppLayout, Sidebar, Topbar, BottomNav, MaintenancePage) ; ajout `entities/{patterns,presentation,transcription}` ; ajout `features/{historique,progression,design-system}` ; extension `simulations/` (pages EO, components/rapport/, lib/, state/) ; mise à jour `shared/`. `t2-live/` et `billing/` retirés (non implémentés — voir ROADMAP). Note explicative ajoutée sous `app/`. Bump doc v1.1. |
|
||||
| FTD-26 | Clarifier cohabitation `shared/ui/` vs `shared/components/ui/` | 2026-04-25 | Section dédiée ajoutée dans ARCHITECTURE.md §3 : tableau de distinction (PascalCase wrappers Expria vs kebab-case primitives shadcn) + règle d'évolution (toute nouvelle primitive Expria va dans `shared/ui/`, `shared/components/ui/` réservé à la CLI shadcn). Aucun fichier déplacé — documentation uniquement. |
|
||||
| FTD-09 | Tests de la state machine T2 Live non implémentés | 2026-04-26 | Sprint 6c — State machine pure créée (`src/features/t2-live/state/t2-machine.ts`, 9 états × 8 events) + 21 tests Vitest couvrant transitions nominales, END_REQUESTED depuis tout état actif, ERROR terminal, événements invalides ignorés. Dégelée et fermée. |
|
||||
| FTD-33 | Carte EO_T2_LIVE verrouillée en dur (pas via `hasAccess`) | 2026-04-26 | Sprint 6c — Carte EO_T2_LIVE déverrouillée via `hasAccess(plan, 'oral_t2_live')` + nouvelle prop `onT2LiveSelect` dans `TaskSelector`. Si plan donne accès, clic navigue vers `/simulation/eo/t2` (la production est créée par le backend en fin de session, pas au clic). Sinon, carte reste verrouillée avec lockLabel « Exclusivité Premium ». Dégelée et fermée. |
|
||||
| FTD-14 | Anti-FOUC thème : script inline manquant dans `<head>` | 2026-04-26 | Sprint 5.5 — Script `.light` déjà en place dans `index.html` (lignes 14-20), conforme DESIGN_SYSTEM v2.0. L'exemple `.dark` documenté dans la fiche FTD-14 datait de la DA Boréal v1.0 (obsolète). Aucune action code requise — FTD fermée comme déjà résolue. |
|
||||
| FTD-35 | `PresentationGenereeT1Page` : refresh sans simulation active | 2026-04-26 | Sprint 5.5 — Subsumée par FTD-41 : la résolution de FTD-41 (persistance T1 en BDD) élimine le problème de FTD-35 (localStorage instable). Aucune action propre. |
|
||||
| FTD-38 | `useAudioRecorder` : mise à jour de ref pendant le render | 2026-04-26 | Sprint 5.5 — Refactor `optionsRef.current = options` (assignation pendant render + eslint-disable) en `useEffect(() => { optionsRef.current = options })`. Sémantique préservée : effet sans deps run après chaque commit, donc avant le prochain render qui lit la ref. eslint-disable retiré. 195 lignes de tests `useAudioRecorder.test.ts` toujours vertes (219/219). |
|
||||
|
|
@ -574,3 +554,4 @@ Frontend :
|
|||
| 1.25 | 2026-04-25 | Sprint 4.5 — Ajout FTD-40 🟡 (conclusion `conseil_nclc` backend incohérente quand NCLC atteint > cible — patch frontend en place dans `ConseilNclcCallout`) et FTD-41 🔴 (persistance présentation EO T1 en BDD — résout FTD-35). **19 FTD actives — cap 15 dépassé de 4. Résorption obligatoire au Sprint 5.5 avant toute nouvelle FTD.** |
|
||||
| 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). |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue