From 74b7297c97ea6d3f3d85f35d1950b289aa58af34 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Thu, 21 May 2026 13:47:42 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20F=C3=BCge=20Skript=20hinzu,=20um=20prob?= =?UTF-8?q?lematische=20Multiple-Choice-=C3=9Cbungen=20zu=20identifizieren?= =?UTF-8?q?=20und=20zu=20l=C3=B6schen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/scripts/repair-remove-sentence-mc.js | 74 ++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 backend/scripts/repair-remove-sentence-mc.js diff --git a/backend/scripts/repair-remove-sentence-mc.js b/backend/scripts/repair-remove-sentence-mc.js new file mode 100644 index 0000000..8828186 --- /dev/null +++ b/backend/scripts/repair-remove-sentence-mc.js @@ -0,0 +1,74 @@ +#!/usr/bin/env node +/** + * Findet Multiple-Choice-Übungen, bei denen die Frage ein einzelnes Wort ist + * aber die richtige Antwort ein kompletter Satz (mehrere Wörter) ist. + * + * Default: Dry-run und listet die gefundenen Übungen auf. + * Use --apply to actually delete them from the DB. + */ + +import { sequelize } from '../utils/sequelize.js'; +import VocabGrammarExercise from '../models/community/vocab_grammar_exercise.js'; + +const args = process.argv.slice(2); +const apply = args.includes('--apply'); + +async function run() { + try { + await sequelize.authenticate(); + console.log('✅ DB verbunden'); + + const list = await VocabGrammarExercise.findAll({ + where: { exerciseTypeId: 2 }, + order: [['lesson_id', 'ASC'], ['exercise_number', 'ASC']] + }); + + const candidates = []; + for (const ex of list) { + const q = ex.questionData || {}; + const a = ex.answerData || {}; + const questionText = String(q.question || q.text || '').trim(); + const correct = String(a.correctAnswer || a.correct || a.correctAnswerText || '').trim(); + if (!questionText || !correct) continue; + + const questionWords = questionText.split(/\s+/).filter(Boolean).length; + const correctWords = correct.split(/\s+/).filter(Boolean).length; + + // Heuristik: Frage ist Einzelwort, Antwort ist Satz (>1 Wort) + if (questionWords === 1 && correctWords > 1) { + candidates.push({ id: ex.id, lessonId: ex.lessonId, exerciseNumber: ex.exerciseNumber, title: ex.title, questionText, correct }); + } + } + + if (!candidates.length) { + console.log('Keine problematischen MC-Übungen gefunden.'); + return; + } + + console.log(`Gefundene problematische Übungen: ${candidates.length}`); + candidates.forEach((c, i) => { + console.log(`${i + 1}. ID:${c.id} lesson:${c.lessonId} #${c.exerciseNumber} title:"${c.title}" question:"${c.questionText}" -> correct:"${c.correct}"`); + }); + + if (!apply) { + console.log('\nDry-run beendet. Verwende --apply, um die gefundenen Übungen zu löschen.'); + return; + } + + console.log('\n--apply gesetzt: Lösche die gefundenen Übungen...'); + for (const c of candidates) { + const ex = await VocabGrammarExercise.findByPk(c.id); + if (ex) { + await ex.destroy(); + console.log(`Gelöscht: ID ${c.id}`); + } + } + console.log('Fertig.'); + } catch (err) { + console.error('Fehler:', err); + } finally { + await sequelize.close(); + } +} + +run();