feat(corrections): Sprint 3.6a — nouveaux prompts + taxonomie erreurs + génération parallèle

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hermann_Kitio 2026-04-22 17:27:29 +03:00
parent df7ef2cc31
commit 63bc43ddcf
14 changed files with 2319 additions and 282 deletions

View file

@ -1,8 +1,14 @@
import { supabase } from '../lib/supabase.js'
import { canUserSimulate } from '../lib/access.js'
import type { EERapport } from '../lib/deepseek.js'
import type {
CorrectionRapport,
ProductionModele,
ExerciceItem,
} from '../lib/deepseek.js'
import type { AuthProfile } from '../middleware/auth.js'
export type JobStatus = 'pending' | 'ready' | 'error'
export type Tache = 'EE_T1' | 'EE_T2' | 'EE_T3' | 'EO_T1' | 'EO_T3' | 'EO_T2_LIVE'
export type Mode = 'entrainement' | 'examen'
@ -125,8 +131,8 @@ export async function create(
}
}
// EERapport et EORapport ont la même structure depuis l'étape A —
// on utilise EERapport comme représentation canonique du rapport parsé.
// Sprint 3.6a — structure enrichie (revelation, diagnostic, conseil_nclc,
// erreurs_codes) + statuts des jobs asynchrones (modele, exercices).
//
// FTD-21 : rapport peut être null (simulation en cours, pas encore corrigée).
// Le frontend distingue :
@ -139,7 +145,12 @@ export interface GetByIdResult {
created_at: string
contenu: string | null
sujet: SujetData | null
rapport: EERapport | null
rapport: CorrectionRapport | null
nclc_cible: 9 | 10 | null
exercices: ExerciceItem[] | null
exercices_status: JobStatus
modele: ProductionModele | null
modele_status: JobStatus
}
type ControllerError = {
@ -155,7 +166,9 @@ export async function getById(
): Promise<{ data: GetByIdResult } | ControllerError> {
const { data, error } = await supabase
.from('productions')
.select('id, user_id, tache, mode, contenu, sujet_id, rapport, created_at')
.select(
'id, user_id, tache, mode, contenu, sujet_id, rapport, created_at, nclc_cible, exercices, exercices_status, modele, modele_status',
)
.eq('id', id)
.single()
@ -188,7 +201,18 @@ export async function getById(
if (sujetRow) sujet = sujetRow as SujetData
}
const rapport = data.rapport ? (JSON.parse(data.rapport) as EERapport) : null
const rapport = data.rapport ? (JSON.parse(data.rapport) as CorrectionRapport) : null
// JSONB columns reviennent déjà parsées par supabase-js.
const exercices = Array.isArray(data.exercices) ? (data.exercices as ExerciceItem[]) : null
const modele =
data.modele && typeof data.modele === 'object' ? (data.modele as ProductionModele) : null
const exercicesStatus = (data.exercices_status as JobStatus | null) ?? 'pending'
const modeleStatus = (data.modele_status as JobStatus | null) ?? 'pending'
const nclcCibleRaw = data.nclc_cible
const nclcCible: 9 | 10 | null =
nclcCibleRaw === 9 || nclcCibleRaw === 10 ? nclcCibleRaw : null
return {
data: {
@ -199,6 +223,11 @@ export async function getById(
contenu: data.contenu ?? null,
sujet,
rapport,
nclc_cible: nclcCible,
exercices,
exercices_status: exercicesStatus,
modele,
modele_status: modeleStatus,
},
}
}