From e130d3792e53aadc16b43b61049ceb695d1b7623 Mon Sep 17 00:00:00 2001 From: Hermann_Kitio Date: Mon, 20 Apr 2026 23:05:01 +0300 Subject: [PATCH] feat(production): exposer SujetData dans Production + FTD-21 persistance session --- docs/TECH_DEBT.md | 21 +++++++++++++++++++ src/entities/production/types.ts | 20 ++++++++++++++++++ .../hooks/__tests__/useSimulation.test.tsx | 1 + 3 files changed, 42 insertions(+) diff --git a/docs/TECH_DEBT.md b/docs/TECH_DEBT.md index 0f8393c..76d8faf 100644 --- a/docs/TECH_DEBT.md +++ b/docs/TECH_DEBT.md @@ -268,6 +268,26 @@ Vient du pattern `c.json(result, result.status)` où `result` contient déjà `s --- +### FTD-21 — Persistance session simulation +**Priorité :** 🔴 Critique +**Statut :** Ouvert — session backend + frontend requise +**Estimation de session :** ~2 jours (1 jour backend + 1 jour frontend) +**Description :** Si l'utilisateur rafraîchit la page ou fait « retour » pendant une simulation, la production et le sujet sont perdus. L'utilisateur doit pouvoir reprendre exactement où il en était. + +**À faire (backend) :** +- Ajouter colonne `sujet_id` (FK → `sujets.id`) dans `productions` pour persister le sujet associé à chaque simulation +- Autosave du contenu de la textarea toutes les 30 s via `PATCH /simulations/:id/contenu` +- `GET /simulations/:id` retourne aussi le sujet associé (joint sur `sujet_id`) + +**À faire (frontend) :** +- `useSimulation` détecte si une simulation est en cours au chargement (via `localStorage` ou URL param) +- Reprend la `production` + `sujet` depuis `GET /simulations/:id` +- La textarea reprend le contenu sauvegardé + +**Condition de résolution :** session dédiée après G1-G5. + +--- + ## 4. Tests à renforcer ### FTD-09 — Tests de la state machine T2 Live non implémentés @@ -334,3 +354,4 @@ Vient du pattern `c.json(result, result.status)` où `result` contient déjà `s | 1.5 | 2026-04-19 | Ajout FTD-17 (clé ['plan'] dupliquée entre features — Sprint 3 étape 14) | | 1.6 | 2026-04-20 | Ajout FTD-18 (SimulationForm shadcn Button — Sprint 0.5 bis D2) ; ajout FTD-19 (token --shadow-focus manquant — Sprint 0.5 bis D2) | | 1.7 | 2026-04-20 | Ajout FTD-20 🔴 (GET /simulations/:id manquant backend — bloque RapportPage Sprint 3 étape 15) | +| 1.8 | 2026-04-20 | Ajout FTD-21 🔴 (persistance session simulation — prod + sujet perdus au refresh, session dédiée après G1-G5) | diff --git a/src/entities/production/types.ts b/src/entities/production/types.ts index 863c038..4321ad7 100644 --- a/src/entities/production/types.ts +++ b/src/entities/production/types.ts @@ -17,6 +17,25 @@ export type Tache = 'EE_T1' | 'EE_T2' | 'EE_T3' | 'EO_T1' | 'EO_T3' /** Mode de la simulation — examen uniquement accessible au plan Premium. */ export type Mode = 'entrainement' | 'examen' +/** + * Sujet d'examen (consigne + documents) associé à une production. + * + * Retourné par `POST /simulations` depuis la table `sujets` (filtrage actif + tâche). + * `null` lorsque la table ne contient aucun sujet actif pour la tâche, ou pour `EO_T2_LIVE` + * (interaction live sans sujet pré-défini). Voir TECH_DEBT FTD-21 pour la persistance + * via `GET /simulations/:id` (pas encore branchée). + */ +export interface SujetData { + id: string + consigne: string + role: string | null + contexte: string | null + doc1_titre: string | null + doc1_texte: string | null + doc2_titre: string | null + doc2_texte: string | null +} + /** * Réponse du backend pour `POST /simulations` (HTTP 201) et `GET /simulations/:id`. * Format confirmé par l'audit backend 2026-04-17 (cf. ARCHITECTURE.md §5). @@ -26,6 +45,7 @@ export interface Production { tache: Tache mode: Mode created_at: string + sujet: SujetData | null } /** Corps de la requête `POST /simulations`. */ diff --git a/src/features/simulations/hooks/__tests__/useSimulation.test.tsx b/src/features/simulations/hooks/__tests__/useSimulation.test.tsx index 293a176..a30bf43 100644 --- a/src/features/simulations/hooks/__tests__/useSimulation.test.tsx +++ b/src/features/simulations/hooks/__tests__/useSimulation.test.tsx @@ -31,6 +31,7 @@ const mockProduction: Production = { tache: 'EE_T1', mode: 'entrainement', created_at: '2026-04-19T00:00:00Z', + sujet: null, } const mockReport: Report = {