diff --git a/backend/scripts/create-bisaya-course-content.js b/backend/scripts/create-bisaya-course-content.js index 6060cd4..165275b 100644 --- a/backend/scripts/create-bisaya-course-content.js +++ b/backend/scripts/create-bisaya-course-content.js @@ -36,6 +36,44 @@ function normalizeText(value) { .replace(/\s+/g, ' '); } +function countWords(value) { + return normalizeText(value).split(' ').filter(Boolean).length; +} + +function collectExerciseAuditWarnings(lessonTitle, exerciseData, exerciseNumber) { + const warnings = []; + const questionData = exerciseData?.questionData || {}; + const answerData = exerciseData?.answerData || {}; + if (questionData.type !== 'gap_fill') return warnings; + + const text = String(questionData.text || ''); + const answers = Array.isArray(answerData.answers) ? answerData.answers : []; + if (!text || !answers.length) return warnings; + + const hints = []; + const hintRegex = /\(([^)]+)\)/g; + let match = hintRegex.exec(text); + while (match) { + hints.push(normalizeText(match[1])); + match = hintRegex.exec(text); + } + + for (let i = 0; i < Math.min(answers.length, hints.length); i += 1) { + const answer = normalizeText(answers[i]); + const hint = hints[i]; + if (!answer || !hint) continue; + const answerWords = countWords(answer); + const hintWords = countWords(hint); + if (answerWords <= 2 && hintWords >= 4) { + warnings.push( + `[${lessonTitle} #${exerciseNumber}] Gap-Fill-Hinweis wirkt zu lang für eine Kurzantwort: "${answer}" <-> "${hint}"` + ); + } + } + + return warnings; +} + function normalizeCorePatternEntry(entry) { if (entry === null || entry === undefined || entry === '') { return null; @@ -2206,7 +2244,7 @@ const BISAYA_EXERCISES = { instruction: 'Fülle die Lücken mit den richtigen Bisaya-Wörtern.', questionData: { type: 'gap_fill', - text: '{gap} ka padulong? (Wohin gehst du?) | {gap} imong plano? (Was ist dein Plan?)', + text: '{gap} ka padulong? (wo/wohin) | {gap} imong plano? (was)', gaps: 2 }, answerData: { @@ -2221,7 +2259,7 @@ const BISAYA_EXERCISES = { instruction: 'Fülle die Lücken mit den richtigen Bisaya-Wörtern.', questionData: { type: 'gap_fill', - text: 'Moadto ko sa {gap}. (Ich gehe nach Hause.) | Moadto ko sa {gap}. (Ich gehe zum Markt.)', + text: 'Moadto ko sa {gap}. (Haus) | Moadto ko sa {gap}. (Markt)', gaps: 2 }, answerData: { @@ -4337,6 +4375,10 @@ async function createBisayaCourseContent() { // Erstelle Übungen let exerciseNumber = 1; for (const exerciseData of exercises) { + if (process.env.VOCAB_STRICT_AUDIT === '1') { + const warnings = collectExerciseAuditWarnings(lesson.title, exerciseData, exerciseNumber); + warnings.forEach((warning) => console.warn(` ⚠️ ${warning}`)); + } const exerciseTypeId = await resolveExerciseTypeId(exerciseData); await VocabGrammarExercise.create({ lessonId: lesson.id,