feat(production): types SimulationState + API autosave/updateSujet (FTD-21)
This commit is contained in:
parent
95711a7c44
commit
d395a04193
2 changed files with 88 additions and 2 deletions
|
|
@ -9,7 +9,13 @@
|
|||
*/
|
||||
|
||||
import { apiFetch } from '@/shared/lib/api-client'
|
||||
import type { CreateSimulationPayload, Production, SujetData, Tache } from './types'
|
||||
import type {
|
||||
CreateSimulationPayload,
|
||||
Production,
|
||||
SimulationState,
|
||||
SujetData,
|
||||
Tache,
|
||||
} from './types'
|
||||
|
||||
/** Crée une nouvelle simulation. Endpoint : `POST /simulations` (HTTP 201). */
|
||||
export function createSimulation(payload: CreateSimulationPayload): Promise<Production> {
|
||||
|
|
@ -21,6 +27,43 @@ export function getSimulation(id: string): Promise<Production> {
|
|||
return apiFetch<Production>(`/simulations/${id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* FTD-21 — récupère l'état complet d'une simulation (contenu + sujet + rapport).
|
||||
* Utilisé par `SimulationFlowProvider` pour restaurer une session depuis
|
||||
* `localStorage.expria_simulation_id` au mount.
|
||||
*
|
||||
* Si `rapport === null` → simulation en cours, restaurer `/simulation/ee`.
|
||||
* Sinon → simulation terminée, rediriger vers `/rapport/:id`.
|
||||
*/
|
||||
export function getSimulationState(id: string): Promise<SimulationState> {
|
||||
return apiFetch<SimulationState>(`/simulations/${id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* FTD-21 — autosave du contenu (debounce 30 s + beforeunload).
|
||||
* Endpoint : `PATCH /simulations/:id/contenu`.
|
||||
* Ne retourne rien : le client conserve déjà le texte localement.
|
||||
*/
|
||||
export async function autosaveContenu(id: string, contenu: string): Promise<void> {
|
||||
await apiFetch<{ ok: true }>(`/simulations/${id}/contenu`, {
|
||||
method: 'PATCH',
|
||||
body: { contenu },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* FTD-21 — persiste un changement de sujet côté backend.
|
||||
* Endpoint : `PATCH /simulations/:id/sujet`.
|
||||
* Appelé depuis `SimulationFlowProvider.changeSubject` quand l'utilisateur
|
||||
* choisit un autre sujet via `/sujets`.
|
||||
*/
|
||||
export async function updateSujet(id: string, sujetId: string): Promise<void> {
|
||||
await apiFetch<{ sujet: SujetData }>(`/simulations/${id}/sujet`, {
|
||||
method: 'PATCH',
|
||||
body: { sujet_id: sujetId },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Mappe une Tache vers les paramètres de la route `GET /sujets`.
|
||||
* Retourne `null` pour les tâches sans catalogue de sujets côté base
|
||||
|
|
|
|||
|
|
@ -37,8 +37,12 @@ export interface SujetData {
|
|||
}
|
||||
|
||||
/**
|
||||
* Réponse du backend pour `POST /simulations` (HTTP 201) et `GET /simulations/:id`.
|
||||
* Réponse du backend pour `POST /simulations` (HTTP 201).
|
||||
* Format confirmé par l'audit backend 2026-04-17 (cf. ARCHITECTURE.md §5).
|
||||
*
|
||||
* FTD-21 : `contenu` et `sujet_id` sont persistés côté backend pour permettre
|
||||
* la restauration de session. Ils ne sont pas retournés par `POST /simulations`
|
||||
* mais peuvent être hydratés via `getSimulationState(id)` pour le resume.
|
||||
*/
|
||||
export interface Production {
|
||||
id: string
|
||||
|
|
@ -46,6 +50,8 @@ export interface Production {
|
|||
mode: Mode
|
||||
created_at: string
|
||||
sujet: SujetData | null
|
||||
contenu?: string
|
||||
sujet_id?: string
|
||||
}
|
||||
|
||||
/** Corps de la requête `POST /simulations`. */
|
||||
|
|
@ -53,3 +59,40 @@ export interface CreateSimulationPayload {
|
|||
tache: Tache
|
||||
mode: Mode
|
||||
}
|
||||
|
||||
/**
|
||||
* Réponse du backend pour `GET /simulations/:id` (FTD-21).
|
||||
*
|
||||
* Contrairement au `Report` pur, cette réponse porte :
|
||||
* - le contenu textuel en cours (pour restaurer la textarea)
|
||||
* - le sujet joint (pour restaurer `SujetDisplay`)
|
||||
* - le rapport si disponible (sinon `null` → simulation en cours)
|
||||
*
|
||||
* Si `rapport === null`, le frontend restaure la session `/simulation/ee`.
|
||||
* Sinon, il redirige vers `/rapport/:id`.
|
||||
*/
|
||||
export interface SimulationState {
|
||||
simulation_id: string
|
||||
tache: Tache
|
||||
mode: Mode
|
||||
created_at: string
|
||||
contenu: string | null
|
||||
sujet: SujetData | null
|
||||
rapport: SimulationRapport | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Rapport tel que stocké par le backend (sans `simulation_id` — porté par SimulationState).
|
||||
* Miroir de `EERapport` côté backend ; ré-exposé ici pour éviter l'import circulaire
|
||||
* avec `entities/report/types.ts`.
|
||||
*/
|
||||
export interface SimulationRapport {
|
||||
score: number
|
||||
nclc: number
|
||||
feedback_court: string
|
||||
criteres: { nom: string; score: number; commentaire: string }[]
|
||||
erreurs: string[]
|
||||
modele: string
|
||||
idees: string[]
|
||||
exercices: string[]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue