feat(rapport/eo): support 5 critères × /4 — Phonologie (Sprint 4.8 frontend)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3ce91aaa7b
commit
04019f8348
11 changed files with 273 additions and 10 deletions
63
src/entities/report/__tests__/getMaxScorePerCritere.test.ts
Normal file
63
src/entities/report/__tests__/getMaxScorePerCritere.test.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { describe, it, expect } from 'vitest'
|
||||
import { getMaxScorePerCritere, critereCodeFromNom } from '../lib'
|
||||
import type { Critere } from '../types'
|
||||
|
||||
function critere(nom: string, score: number): Critere {
|
||||
return { nom, score, commentaire: '', exemple: '', suggestion: '', astuce: '' }
|
||||
}
|
||||
|
||||
describe('getMaxScorePerCritere — Sprint 4.8', () => {
|
||||
it('5 critères (EO Sprint 4.8) → maxScore = 4', () => {
|
||||
const rapport = {
|
||||
criteres: [
|
||||
critere('Adéquation à la tâche', 3),
|
||||
critere('Cohérence et cohésion', 3),
|
||||
critere('Étendue et maîtrise du lexique', 2),
|
||||
critere('Maîtrise morphosyntaxique', 3),
|
||||
critere('Phonologie', 3),
|
||||
],
|
||||
}
|
||||
expect(getMaxScorePerCritere(rapport)).toBe(4)
|
||||
})
|
||||
|
||||
it('4 critères (EE / EO legacy) → maxScore = 5', () => {
|
||||
const rapport = {
|
||||
criteres: [
|
||||
critere('Adéquation à la tâche et au registre', 4),
|
||||
critere('Cohérence et cohésion du discours', 3),
|
||||
critere('Compétence lexicale', 3),
|
||||
critere('Compétence grammaticale', 4),
|
||||
],
|
||||
}
|
||||
expect(getMaxScorePerCritere(rapport)).toBe(5)
|
||||
})
|
||||
|
||||
it('0 critère (cas limite) → maxScore = 5 (défaut sécurité)', () => {
|
||||
expect(getMaxScorePerCritere({ criteres: [] })).toBe(5)
|
||||
})
|
||||
|
||||
it('6+ critères (cas hypothétique) → maxScore = 5 (défaut sécurité)', () => {
|
||||
const rapport = {
|
||||
criteres: Array.from({ length: 6 }, (_, i) => critere(`c${i}`, 0)),
|
||||
}
|
||||
expect(getMaxScorePerCritere(rapport)).toBe(5)
|
||||
})
|
||||
})
|
||||
|
||||
describe('critereCodeFromNom — extension Sprint 4.8 EO', () => {
|
||||
it('mappe les libellés EO Sprint 4.8 vers les codes taxonomie', () => {
|
||||
expect(critereCodeFromNom('Adéquation à la tâche')).toBe('adequation_tache')
|
||||
expect(critereCodeFromNom('Cohérence et cohésion')).toBe('coherence_cohesion')
|
||||
expect(critereCodeFromNom('Étendue et maîtrise du lexique')).toBe('competence_lexicale')
|
||||
expect(critereCodeFromNom('Maîtrise morphosyntaxique')).toBe('competence_grammaticale')
|
||||
})
|
||||
|
||||
it("Phonologie n'a pas de code taxonomie → null", () => {
|
||||
expect(critereCodeFromNom('Phonologie')).toBeNull()
|
||||
})
|
||||
|
||||
it('libellés EE legacy toujours mappés (rétrocompat)', () => {
|
||||
expect(critereCodeFromNom('Adéquation à la tâche et au registre')).toBe('adequation_tache')
|
||||
expect(critereCodeFromNom('Compétence lexicale')).toBe('competence_lexicale')
|
||||
})
|
||||
})
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
import { hasAccess } from '@/entities/user/lib'
|
||||
import type { Plan } from '@/entities/user/lib'
|
||||
import type { BlurableSection, Critere, ErreurCode, CritereCode } from './types'
|
||||
import type { BlurableSection, Critere, ErreurCode, CritereCode, Report } from './types'
|
||||
|
||||
const SECTION_FEATURE: Record<BlurableSection, 'detailed_report' | 'tips'> = {
|
||||
criteres: 'detailed_report',
|
||||
|
|
@ -61,16 +61,40 @@ export function groupErreursByCritere(
|
|||
* pour rattacher `erreurs_codes` à la bonne carte critère côté UI.
|
||||
*/
|
||||
const CRITERE_NOM_TO_CODE: Record<string, CritereCode> = {
|
||||
// Libellés EE (CRITERE_LABELS backend)
|
||||
'Adéquation à la tâche et au registre': 'adequation_tache',
|
||||
'Cohérence et cohésion du discours': 'coherence_cohesion',
|
||||
'Compétence lexicale': 'competence_lexicale',
|
||||
'Compétence grammaticale': 'competence_grammaticale',
|
||||
// Libellés EO Sprint 4.8 (CRITERE_LABELS_EO backend) — mappés vers les
|
||||
// mêmes codes taxonomie pour rattacher les `erreurs_codes`. La 5e dimension
|
||||
// « Phonologie » n'a pas de CritereCode (aucune erreur taxonomie associée
|
||||
// côté backend) : `critereCodeFromNom('Phonologie')` retourne donc `null`.
|
||||
'Adéquation à la tâche': 'adequation_tache',
|
||||
'Cohérence et cohésion': 'coherence_cohesion',
|
||||
'Étendue et maîtrise du lexique': 'competence_lexicale',
|
||||
'Maîtrise morphosyntaxique': 'competence_grammaticale',
|
||||
}
|
||||
|
||||
export function critereCodeFromNom(nom: string): CritereCode | null {
|
||||
return CRITERE_NOM_TO_CODE[nom] ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* Sprint 4.8 — Détecte le score maximum par critère selon le format du rapport.
|
||||
*
|
||||
* - Rapports EO Sprint 4.8 : 5 critères × /4 (4 textuels DeepSeek + Phonologie Gemini).
|
||||
* - Rapports EE et EO legacy : 4 critères × /5.
|
||||
*
|
||||
* Détection sur la donnée elle-même (pas sur la tâche) pour rester rétrocompatible
|
||||
* avec les rapports EO en base d'avant Sprint 4.8.
|
||||
*
|
||||
* Défaut sécurité : tout autre nombre de critères → 5.
|
||||
*/
|
||||
export function getMaxScorePerCritere(rapport: Pick<Report, 'criteres'>): 4 | 5 {
|
||||
return rapport.criteres.length === 5 ? 4 : 5
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcule l'écart en points /20 entre le score obtenu et l'objectif NCLC cible.
|
||||
* Barème TCF Canada (cf. Prompt_maître.md §Barème) : NCLC 9 → 14/20, NCLC 10 → 16/20.
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export interface ErreurCode {
|
|||
|
||||
export interface Critere {
|
||||
nom: string
|
||||
score: number // 0-5
|
||||
score: number // 0-4 (EO Sprint 4.8 — 5 critères) | 0-5 (EE, EO legacy 4 critères)
|
||||
commentaire: string
|
||||
exemple: string
|
||||
suggestion: string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue