#!/usr/bin/env node /** * Spielt die überarbeiteten Bisaya-Kursinhalte ein und setzt den Lernfortschritt zurück. * * Verwendung: * node backend/scripts/apply-bisaya-course-refresh.js */ import { sequelize } from '../utils/sequelize.js'; import VocabCourseLesson from '../models/community/vocab_course_lesson.js'; import VocabGrammarExercise from '../models/community/vocab_grammar_exercise.js'; import VocabCourseProgress from '../models/community/vocab_course_progress.js'; import VocabGrammarExerciseProgress from '../models/community/vocab_grammar_exercise_progress.js'; import { Op } from 'sequelize'; const LESSON_DIDACTICS = { 'Begrüßungen & Höflichkeit': { learningGoals: [ 'Einfache Begrüßungen verstehen und selbst verwenden.', 'Höfliche Reaktionen wie Danke und Bitte passend einsetzen.', 'Ein kurzes Begrüßungs-Mini-Gespräch laut üben.' ], corePatterns: ['Kumusta ka?', 'Maayo ko.', 'Salamat.', 'Palihug.'], grammarFocus: [ { title: 'Kurzantworten mit ko', text: 'Mit "ko" sprichst du über dich selbst: "Maayo ko."', example: 'Maayo ko. = Mir geht es gut.' } ], speakingPrompts: [ { title: 'Mini-Gespräch', prompt: 'Begrüße eine Person, frage nach dem Befinden und reagiere höflich.', cue: 'Kumusta ka? Maayo ko. Salamat.' } ], practicalTasks: [{ title: 'Alltag', text: 'Sprich die Begrüßung dreimal laut und variiere die Antwort.' }] }, 'Familienwörter': { learningGoals: [ 'Die wichtigsten Familienbezeichnungen sicher erkennen.', 'Familienmitglieder mit respektvollen Wörtern ansprechen.', 'Kurze Sätze über die eigene Familie bilden.' ], corePatterns: ['Si Nanay', 'Si Tatay', 'Kuya nako', 'Ate nako'], grammarFocus: [ { title: 'Respekt in Familienanreden', text: 'Kuya und Ate werden nicht nur in der Familie, sondern auch respektvoll für ältere Personen benutzt.', example: 'Kuya, palihug.' } ], speakingPrompts: [ { title: 'Meine Familie', prompt: 'Stelle zwei Familienmitglieder mit einem kurzen Satz vor.', cue: 'Si Nanay. Si Kuya.' } ], practicalTasks: [{ title: 'Familienpraxis', text: 'Nenne laut fünf Familienwörter und bilde danach zwei Mini-Sätze.' }] }, 'Essen & Fürsorge': { learningGoals: [ 'Fürsorgliche Fragen rund ums Essen verstehen.', 'Einladungen zum Essen passend beantworten.', 'Kurze Essens-Dialoge laut üben.' ], corePatterns: ['Nikaon na ka?', 'Kaon ta.', 'Gusto ka mokaon?', 'Lami kaayo.'], grammarFocus: [ { title: 'na als Zustandsmarker', text: '"na" markiert oft etwas, das bereits eingetreten ist oder jetzt gilt.', example: 'Nikaon na ka?' } ], speakingPrompts: [ { title: 'Fürsorge-Dialog', prompt: 'Frage, ob jemand schon gegessen hat, und biete Essen oder Wasser an.', cue: 'Nikaon na ka? Gusto ka mokaon?' } ], practicalTasks: [{ title: 'Rollenspiel', text: 'Spiele ein kurzes Gespräch zwischen Gastgeber und Gast beim Essen.' }] }, 'Zeitformen - Grundlagen': { learningGoals: [ 'Ni- und Mo- als einfache Zeitmarker unterscheiden.', 'Kurze Sätze in Vergangenheit und Zukunft bilden.', 'Das Muster laut mit mehreren Verben wiederholen.' ], corePatterns: ['Ni-kaon ko.', 'Mo-kaon ko.', 'Ni-adto ko.', 'Mo-adto ko.'], grammarFocus: [ { title: 'Zeitpräfixe', text: 'Ni- verweist auf Vergangenes, Mo- auf Zukünftiges oder Bevorstehendes.', example: 'Ni-kaon ko. / Mo-kaon ko.' } ], speakingPrompts: [ { title: 'Vorher und nachher', prompt: 'Sage einen Satz über etwas, das du getan hast, und einen Satz über etwas, das du tun wirst.', cue: 'Ni-kaon ko. Mo-adto ko.' } ], practicalTasks: [{ title: 'Mustertraining', text: 'Nimm ein Verb und sprich es einmal mit Ni- und einmal mit Mo-.' }] }, 'Woche 1 - Wiederholung': { learningGoals: [ 'Die Kernmuster der ersten Woche ohne Hilfe wiederholen.', 'Zwischen Begrüßung, Familie und Fürsorge schneller wechseln.', 'Eine kurze Alltagssequenz frei sprechen.' ], corePatterns: ['Kumusta ka?', 'Palangga taka.', 'Nikaon na ka?', 'Wala ko kasabot.'], speakingPrompts: [ { title: 'Freie Wiederholung', prompt: 'Begrüße jemanden, drücke Zuneigung aus und frage fürsorglich nach dem Essen.', cue: 'Kumusta ka? Palangga taka. Nikaon na ka?' } ] }, 'Woche 1 - Vokabeltest': { learningGoals: [ 'Die wichtigsten Wörter der ersten Woche schnell abrufen.', 'Bedeutung und Gebrauch zentraler Wörter unterscheiden.', 'Von einzelnen Wörtern zu kurzen Sätzen übergehen.' ], corePatterns: ['Kumusta', 'Salamat', 'Lami', 'Mingaw ko nimo'] } }; async function resetBisayaProgress(courseIds) { if (courseIds.length === 0) return { lessonProgress: 0, exerciseProgress: 0 }; const lessonIds = await VocabCourseLesson.findAll({ where: { courseId: { [Op.in]: courseIds } }, attributes: ['id'] }); const numericLessonIds = lessonIds.map((row) => row.id); const exerciseIds = numericLessonIds.length > 0 ? await VocabGrammarExercise.findAll({ where: { lessonId: { [Op.in]: numericLessonIds } }, attributes: ['id'] }) : []; const deletedLessonProgress = await VocabCourseProgress.destroy({ where: { courseId: { [Op.in]: courseIds } } }); let deletedExerciseProgress = 0; if (exerciseIds.length > 0) { deletedExerciseProgress = await VocabGrammarExerciseProgress.destroy({ where: { exerciseId: { [Op.in]: exerciseIds.map((row) => row.id) } } }); } return { lessonProgress: deletedLessonProgress, exerciseProgress: deletedExerciseProgress }; } async function applyBisayaCourseRefresh() { await sequelize.authenticate(); const [bisayaLanguage] = await sequelize.query( `SELECT id FROM community.vocab_language WHERE name = 'Bisaya' LIMIT 1`, { type: sequelize.QueryTypes.SELECT } ); if (!bisayaLanguage) { console.error('❌ Bisaya-Sprache nicht gefunden.'); return; } const courses = await sequelize.query( `SELECT id, title FROM community.vocab_course WHERE language_id = :languageId ORDER BY id ASC`, { replacements: { languageId: bisayaLanguage.id }, type: sequelize.QueryTypes.SELECT } ); const courseIds = courses.map((course) => course.id); const resetStats = await resetBisayaProgress(courseIds); let updatedLessons = 0; for (const course of courses) { const lessons = await VocabCourseLesson.findAll({ where: { courseId: course.id } }); for (const lesson of lessons) { const didactics = LESSON_DIDACTICS[lesson.title]; if (!didactics) continue; await lesson.update({ learningGoals: didactics.learningGoals || [], corePatterns: didactics.corePatterns || [], grammarFocus: didactics.grammarFocus || [], speakingPrompts: didactics.speakingPrompts || [], practicalTasks: didactics.practicalTasks || [] }); updatedLessons++; } } console.log('✅ Bisaya-Kursupdate vorbereitet.'); console.log(` Kurse: ${courses.length}`); console.log(` Didaktisch aktualisierte Lektionen: ${updatedLessons}`); console.log(` Gelöschte Lektionsfortschritte: ${resetStats.lessonProgress}`); console.log(` Gelöschte Übungsfortschritte: ${resetStats.exerciseProgress}`); console.log(''); console.log('Nächste Schritte:'); console.log('1. create-bisaya-course-content.js ausführen, um die neuen Übungen einzuspielen'); console.log('2. optional update-week1-bisaya-exercises.js ausführen, falls Woche 1 separat gepflegt wird'); } applyBisayaCourseRefresh() .then(() => { sequelize.close(); process.exit(0); }) .catch((error) => { console.error('❌ Fehler:', error); sequelize.close(); process.exit(1); });