From 3167f35d585e671b998637dfabad5590bd537cec Mon Sep 17 00:00:00 2001 From: laurentbarontini Date: Sat, 2 May 2026 20:09:23 +0200 Subject: [PATCH] Bug cards --- backend/app/services.py | 1 + frontend/src/App.jsx | 42 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/backend/app/services.py b/backend/app/services.py index 60e1c6e..27cf9bd 100644 --- a/backend/app/services.py +++ b/backend/app/services.py @@ -184,6 +184,7 @@ def build_lesson_reply(db: Session, student_id: int, user_message: str, lesson_c "Si un nombre n'est pas affiché ou autorisé dans ce contexte, tu n'en parles pas. " "Ne propose jamais 'un autre nombre' si le contexte ne donne pas cet autre nombre. " "Si l'élève veut continuer mais que la card courante est terminée, mets `advance_lesson_step` à true. " + "Si l'élève dit qu'il comprend, ou donne une réponse correcte attendue par le contexte, mets `advance_lesson_step` à true. " "Quand `advance_lesson_step` vaut true, ta réponse doit seulement dire: " "`Très bien, on passe à la suite.` Ne répète pas le nombre de la card terminée. " "N'utilise pas l'historique des séances précédentes pour choisir le thème de ta réponse. " diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 783c4dd..380b955 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -218,6 +218,7 @@ function TutorApp({ currentUser, onLogout }) { const [sessionCardStates, setSessionCardStates] = useState({}) const [sessionLogs, setSessionLogs] = useState([]) const [selectedSessionLog, setSelectedSessionLog] = useState(null) + const [sessionMessageStartIndex, setSessionMessageStartIndex] = useState(0) const [progressPanelOpen, setProgressPanelOpen] = useState(false) const [settingsPanelOpen, setSettingsPanelOpen] = useState(false) const mediaRecorderRef = useRef(null) @@ -430,6 +431,8 @@ function TutorApp({ currentUser, onLogout }) { if (!selectedStudentId) return try { setErrorMessage('') + setSessionMessageStartIndex(messages.length) + setSessionCardStates({}) const data = await apiFetch(`/session/start?student_id=${selectedStudentId}`, { method: 'POST' }) appendMessage('assistant', data.reply) setCurrentInstruction(data.reply) @@ -523,7 +526,8 @@ function TutorApp({ currentUser, onLogout }) { async function saveLessonSession() { if (!selectedStudentId || !studentProgram) return const currentCardState = getActiveCardState(40, false) - const conversation = messages.map((message) => ({ + const sessionMessages = messages.slice(sessionMessageStartIndex) + const conversation = sessionMessages.map((message) => ({ id: message.id, role: message.role, content: message.content, @@ -766,6 +770,39 @@ function TutorApp({ currentUser, onLogout }) { return `Très bien, on passe à ${title}. Regarde cette card.` } + function normalizeAnswer(text) { + return text + .toLowerCase() + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .replace(/[’']/g, ' ') + } + + function answerValidatesCurrentCard(text) { + const answer = normalizeAnswer(text) + const key = activeSection?.context_key || '' + if (/\b(oui|ok|d accord)\b/.test(answer) && /compr/.test(answer)) return true + if (key === 'Fiche1Card1') { + return /compr/.test(answer) || (answer.includes('345') && answer.includes('208')) + } + if (key === 'Fiche1Card2') { + return answer.includes('trois') && answer.includes('quarante') && answer.includes('mille') && answer.includes('huit') + } + if (key === 'Fiche1Card3') { + return answer.includes('milliers') && (answer.includes('unites') || answer.includes('simples')) + } + if (key === 'Fiche1Card4') { + return answer.includes('sept') && answer.includes('mille') && answer.includes('vingt') && answer.includes('cinq') + } + if (key === 'Fiche1Card5') { + return answer.includes('trente') && answer.includes('huit') && answer.includes('mille') && answer.includes('quatre') && answer.includes('dix') + } + if (key === 'Fiche1Card6') { + return answer.includes('cinq') && answer.includes('six') && answer.includes('mille') && answer.includes('douze') + } + return false + } + function getSectionKey(asset, section) { return section?.context_key || `${asset?.path || 'asset'}:${section?.index ?? 0}` } @@ -951,7 +988,8 @@ function TutorApp({ currentUser, onLogout }) { ...getLessonContextPayload(), }), }) - if (data.advance_lesson_step) { + const shouldAdvance = data.advance_lesson_step || answerValidatesCurrentCard(text) + if (shouldAdvance) { rememberActiveCard({ score: 100, validated: true }) const nextStep = getNextLessonStep() const transitionReply = nextStep