#!/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'; import { getBisayaLessonPedagogy } from './bisaya-course-phase2-pedagogy.js'; const LESSON_DIDACTICS = { 'Begrüßungen & Höflichkeit': { learningGoals: [ 'Einfache Begrüßungen verstehen und selbst verwenden.', 'Tageszeitbezogene Grüße und einfache Verabschiedungen unterscheiden.', 'Höfliche Reaktionen wie Danke und Bitte passend einsetzen.', 'Ein kurzes Begrüßungs-Mini-Gespräch laut üben.' ], corePatterns: [ { target: 'Kumusta ka?', gloss: 'Wie geht es dir?' }, { target: 'Maayong buntag.', gloss: 'Guten Morgen.' }, { target: 'Maayong adlaw.', gloss: 'Guten Tag.' }, { target: 'Maayong gabii.', gloss: 'Guten Abend.' }, { target: 'Maayong gabii, matulog na ta.', gloss: 'Guten Abend, wir legen uns schlafen.' }, { target: 'Katulog og maayo.', gloss: 'Schlaf gut.' }, { target: 'Kapoy na ka?', gloss: 'Bist du müde?' }, { target: 'Matulog na ta.', gloss: 'Lass uns schlafen gehen.' }, { target: 'Inom sa og tubig.', gloss: 'Trink Wasser.' }, { target: 'Patya ang suga.', gloss: 'Mach das Licht aus.' }, { target: 'Tabuni ang imong kaugalingon.', gloss: 'Deck dich zu.' }, { target: 'Ugma nasad.', gloss: 'Bis morgen wieder.' }, { target: 'Damgo og nindot.', gloss: 'Träum schön.' }, { target: 'Amping.', gloss: 'Pass auf dich auf.' }, { target: 'Babay.', gloss: 'Tschüss.' }, { target: 'Maayo ko.', gloss: 'Mir geht es gut.' }, { target: 'Salamat.', gloss: 'Danke.' }, { target: 'Palihug.', gloss: 'Bitte.' } ], grammarFocus: [ { title: 'Kurzantworten mit ko', text: 'Mit "ko" sprichst du über dich selbst: "Maayo ko."', example: 'Maayo ko. = Mir geht es gut.' }, { title: 'Maayong + Tageszeit', text: 'Mit "Maayong" kannst du Grüße für verschiedene Tageszeiten bilden.', example: 'Maayong buntag. / Maayong gabii.' }, { title: 'Abend und Schlafen', text: 'Im Familienalltag folgen auf einen Abendgruß oft direkte Schlafens- oder Fürsorgeformeln.', example: 'Maayong gabii. / Katulog og maayo.' }, { title: 'Sanfte Schlafensroutine', text: 'Kurze Fragen nach Müdigkeit und kleine Aufforderungen klingen im Familienalltag natürlicher als lange Sätze.', example: 'Kapoy na ka? Matulog na ta. Inom sa og tubig.' }, { title: 'Familiäre Abendformeln', text: 'Am Abend folgen oft sehr kurze Handlungsformeln wie Licht aus, zudecken oder ein Schlafwunsch.', example: 'Patya ang suga. Tabuni ang imong kaugalingon. Damgo og nindot.' } ], speakingPrompts: [ { title: 'Mini-Gespräch', prompt: 'Begrüße eine Person, frage nach dem Befinden und reagiere höflich.', cue: 'Kumusta ka? Maayo ko. Salamat.' }, { title: 'Verabschiedung', prompt: 'Verabschiede dich kurz und wünsche, dass die andere Person auf sich aufpasst.', cue: 'Babay. Amping.' }, { title: 'Abend und Schlaf', prompt: 'Wünsche einen guten Abend, eine gute Nacht und dass die Person gut schlafen soll.', cue: 'Maayong gabii. Katulog og maayo.' }, { title: 'Schlafensroutine', prompt: 'Frage, ob die Person müde ist, und leite dann sanft zum Schlafengehen über.', cue: 'Kapoy na ka? Matulog na ta. Inom sa og tubig.' }, { title: 'Vor dem Schlafen', prompt: 'Bitte darum, das Licht auszumachen, sich zuzudecken, und wünsche eine gute Nacht bis morgen.', cue: 'Patya ang suga. Tabuni ang imong kaugalingon. Ugma nasad. Damgo og nindot.' } ], practicalTasks: [{ title: 'Alltag', text: 'Sprich die Begrüßung dreimal laut und variiere die Antwort.' }] }, 'Familienwörter': { learningGoals: [ 'Die wichtigsten Familienbezeichnungen sicher erkennen.', 'Familienmitglieder und Großeltern mit respektvollen Wörtern ansprechen.', 'Kurze Sätze über die eigene Familie bilden.' ], corePatterns: [ { target: 'Si Nanay.', gloss: 'Das ist Mama.' }, { target: 'Si Tatay.', gloss: 'Das ist Papa.' }, { target: 'Si Kuya nako.', gloss: 'Das ist mein älterer Bruder.' }, { target: 'Si Ate nako.', gloss: 'Das ist meine ältere Schwester.' }, { target: 'Si Dodong nako.', gloss: 'Das ist mein jüngerer Bruder.' }, { target: 'Si Inday nako.', gloss: 'Das ist meine jüngere Schwester.' }, { target: 'Si Lola nako.', gloss: 'Das ist meine Großmutter.' }, { target: 'Si Lolo nako.', gloss: 'Das ist mein Großvater.' } ], grammarFocus: [ { title: 'Respekt in Familienanreden', text: 'Kuya und Ate richtest du an ältere Geschwister (oder respektvoll an andere). Dodong und Inday nutzt du für jüngere Brüder bzw. Schwestern; „Ading“ ist eine weiche Anrede an jüngere Geschwister.', example: 'Kuya, palihug. / Si Dodong nako.' }, { title: 'si als Personenmarker', text: 'Mit "si" markierst du im einfachen Satz eine konkrete Person.', example: 'Si Nanay. Si Tatay.' } ], speakingPrompts: [ { title: 'Meine Familie', prompt: 'Stelle vier Familienmitglieder mit kurzen Sätzen vor.', cue: 'Si Nanay. Si Tatay. Si Kuya nako. Si Dodong nako.' } ], practicalTasks: [{ title: 'Familienpraxis', text: 'Nenne laut die acht Kern-Familienwörter und bilde danach drei Mini-Sätze über deine Familie.' }] }, 'Überlebenssätze - Teil 1': { learningGoals: [ 'Zentrale Notfall- und Verständnisfragen schnell abrufen.', 'Höflich um Wiederholung, Hilfe und langsamere Sprache bitten.', 'Drei Überlebenssätze hintereinander sicher sprechen.' ], corePatterns: [ { target: 'Wala ko kasabot.', gloss: 'Ich verstehe nicht.' }, { target: 'Palihug ka mubalik?', gloss: 'Kannst du das bitte wiederholen?' }, { target: 'Asa ang CR?', gloss: 'Wo ist die Toilette?' }, { target: 'Hinay-hinay lang.', gloss: 'Bitte langsam.' }, { target: 'Tabangi ko, palihug.', gloss: 'Hilf mir bitte.' }, { target: 'Unsay pasabot ani?', gloss: 'Was bedeutet das?' } ], grammarFocus: [ { title: 'Bitte-Formeln mit palihug', text: '"Palihug" macht Bitten höflich und taucht in vielen Überlebenssätzen auf.', example: 'Palihug ka mubalik? / Tabangi ko, palihug.' }, { title: 'Kurze Verständnisfragen', text: 'Sehr kurze Fragen helfen dir im Alltag oft mehr als lange Sätze.', example: 'Unsay pasabot ani? Asa ang CR?' } ], speakingPrompts: [ { title: 'Wenn du etwas nicht verstehst', prompt: 'Sage, dass du etwas nicht verstehst, und bitte um Wiederholung.', cue: 'Wala ko kasabot. Palihug ka mubalik?' }, { title: 'Soforthilfe', prompt: 'Bitte um Hilfe und frage dann nach der Toilette oder nach der Bedeutung eines Wortes.', cue: 'Tabangi ko, palihug. Asa ang CR?' } ], practicalTasks: [{ title: 'Alltagsanker', text: 'Sprich alle sechs Überlebenssätze laut durch und ordne sie drei Alltagssituationen zu.' }] }, 'Familien-Gespräche': { learningGoals: [ 'Kurze Familiengespräche sicher verstehen.', 'Nach Familienmitgliedern fragen und einfache Antworten geben.', 'Ein Mini-Gespräch über Hunger und Zuhause nachsprechen.' ], corePatterns: [ { target: 'Kumusta ka, Nanay?', gloss: 'Wie geht es dir, Mama?' }, { target: 'Asa si Tatay?', gloss: 'Wo ist Papa?' }, { target: 'Naa siya sa balay.', gloss: 'Er ist zu Hause.' }, { target: 'Kumusta na ang Kuya?', gloss: 'Wie geht es dem älteren Bruder?' }, { target: 'Kumusta na ang Dodong?', gloss: 'Wie geht es dem jüngeren Bruder?' }, { target: 'Kumusta na ang Inday?', gloss: 'Wie geht es der jüngeren Schwester?' }, { target: 'Gutom na ko, Nanay.', gloss: 'Ich habe Hunger, Mama.' }, { target: 'Hapit na ang pagkaon.', gloss: 'Das Essen ist fast fertig.' } ], grammarFocus: [ { title: 'naa für Ort und Vorhandensein', text: '"Naa" hilft dir, über Orte und Vorhandensein zu sprechen.', example: 'Naa siya sa balay.' } ], speakingPrompts: [ { title: 'Familien-Mini-Dialog', prompt: 'Frage nach einem Familienmitglied und reagiere dann mit einer kurzen Antwort.', cue: 'Asa si Tatay? Naa siya sa balay.' } ], practicalTasks: [{ title: 'Gesprächspraxis', text: 'Spiele einen kurzen Familienaustausch mit Frage, Antwort und Fürsorge nach.' }] }, 'Gefühle & Zuneigung': { learningGoals: [ 'Wichtige Gefühle und Zuneigungsformeln sicher unterscheiden.', 'Freundliche Nähe und Vermissen sprachlich ausdrücken.', 'Zwischen positiven und negativen Gefühlen wechseln.' ], corePatterns: [ { target: 'Palangga taka.', gloss: 'Ich hab dich lieb.' }, { target: 'Ganahan ko nimo.', gloss: 'Ich mag dich.' }, { target: 'Gimingaw ko nimo.', gloss: 'Ich vermisse dich.' }, { target: 'Nalipay ko.', gloss: 'Ich bin glücklich.' }, { target: 'Nasubo ko.', gloss: 'Ich bin traurig.' }, { target: 'Nalipay ko nga nakita ka.', gloss: 'Ich freue mich, dich zu sehen.' } ], grammarFocus: [ { title: 'ko für eigene Gefühle', text: 'Viele Gefühlsaussagen bauen direkt auf dem Muster "Gefühl + ko" auf.', example: 'Nalipay ko. Nasubo ko.' } ], speakingPrompts: [ { title: 'Gefühl ausdrücken', prompt: 'Sage, dass du jemanden magst oder vermisst, und ergänze danach ein einfaches Gefühl.', cue: 'Ganahan ko nimo. Nalipay ko.' } ], practicalTasks: [{ title: 'Herzsprache', text: 'Lies drei Zuneigungsformeln laut und entscheide danach: liebhaben, mögen oder vermissen?' }] }, 'Überlebenssätze - Teil 2': { learningGoals: [ 'Weitere zentrale Alltagsfragen sicher sprechen.', 'Höflich Entschuldigung, Nachfrage und Hilfesprache verbinden.', 'Im Alltag Preise, Dinge und Sprache klar ansprechen.' ], corePatterns: [ { target: 'Tagpila ni?', gloss: 'Wie viel kostet das?' }, { target: 'Unsa ni?', gloss: 'Was ist das?' }, { target: 'Pasensya.', gloss: 'Entschuldigung.' }, { target: 'Dili ko mag-Bisaya.', gloss: 'Ich spreche kein Bisaya.' }, { target: 'Palihug isulat ni.', gloss: 'Bitte schreib das auf.' }, { target: 'Nawala ko.', gloss: 'Ich habe mich verlaufen.' } ], grammarFocus: [ { title: 'Kurze Markt- und Orientierungssprache', text: 'Kurze Fragewörter plus ein Nomen reichen oft, um im Alltag voranzukommen.', example: 'Tagpila ni? Unsa ni?' } ], speakingPrompts: [ { title: 'Auf dem Markt', prompt: 'Frage nach Preis und Bedeutung eines Gegenstands und bitte dann darum, etwas aufzuschreiben.', cue: 'Tagpila ni? Unsa ni? Palihug isulat ni.' } ], practicalTasks: [{ title: 'Unterwegs', text: 'Sprich drei Sätze für Einkauf, Nachfrage und Orientierung laut hintereinander.' }] }, 'Essen & Fürsorge': { learningGoals: [ 'Fürsorgliche Fragen rund ums Essen verstehen.', 'Einladungen zum Essen passend beantworten.', 'Kurze Essens-Dialoge laut üben.' ], corePatterns: [ { target: 'Nikaon na ka?', gloss: 'Hast du schon gegessen?' }, { target: 'Kaon ta.', gloss: 'Lass uns essen.' }, { target: 'Gusto ka mokaon?', gloss: 'Möchtest du essen?' }, { target: 'Gutom na ko.', gloss: 'Ich habe Hunger.' }, { target: 'Palihug, hatagi ko ug tubig.', gloss: 'Bitte gib mir Wasser.' }, { target: 'Salamat sa pagkaon.', gloss: 'Danke für das Essen.' }, { target: 'Busog na ko.', gloss: 'Ich bin satt.' }, { target: 'Lami kaayo.', gloss: 'Sehr lecker.' } ], grammarFocus: [ { title: 'na als Zustandsmarker', text: '"na" markiert oft etwas, das bereits eingetreten ist oder jetzt gilt.', example: 'Nikaon na ka?' }, { title: 'Bitten mit hatagi ko', text: 'Mit "hatagi ko" bittest du konkret darum, dass dir etwas gegeben wird.', example: 'Palihug, hatagi ko ug tubig.' } ], 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?' }, { title: 'Beim Essen reagieren', prompt: 'Sage, dass du Hunger hast, bitte um Wasser und reagiere danach auf das Essen.', cue: 'Gutom na ko. Palihug, hatagi ko ug tubig. Lami kaayo.' } ], practicalTasks: [{ title: 'Rollenspiel', text: 'Spiele ein kurzes Gespräch zwischen Gastgeber und Gast beim Essen.' }] }, 'Essen & Trinken': { learningGoals: [ 'Wichtige Essens- und Trinkwörter schnell erkennen.', 'Zwischen Grundnahrungsmitteln, Getränken und Beilagen unterscheiden.', 'Mit den neuen Wörtern kurze Einkaufs- oder Tischsätze bauen.' ], corePatterns: [ { target: 'Kan-on', gloss: 'gekochter Reis' }, { target: 'Tubig', gloss: 'Wasser' }, { target: 'Isda', gloss: 'Fisch' }, { target: 'Manok', gloss: 'Huhn' }, { target: 'Gulay', gloss: 'Gemüse' }, { target: 'Prutas', gloss: 'Obst' }, { target: 'Gatas', gloss: 'Milch' } ], grammarFocus: [ { title: 'Wortschatz statt ganzer Sätze', text: 'In dieser Lektion sammelst du bewusst Grundwörter, damit du später kurze Essenssätze daraus bauen kannst.', example: 'Kan-on. Tubig. Isda.' } ], speakingPrompts: [ { title: 'Auf dem Tisch', prompt: 'Nenne drei Dinge, die auf dem Tisch stehen oder die du essen und trinken möchtest.', cue: 'Kan-on, isda ug tubig.' } ], practicalTasks: [{ title: 'Küchenrunde', text: 'Zeige nacheinander auf sieben Lebensmittel oder stelle sie dir vor und sprich jedes Wort laut aus.' }] }, 'Haus & Familie': { learningGoals: [ 'Wichtige Wörter für Haus, Räume und Familie zuordnen und aussprechen.', 'Mit „Naa … sa …“ sagen, wo sich jemand oder etwas im Haus befindet.', 'Kurze Sätze über Zuhause und Familie verstehen und nachsprechen.' ], corePatterns: [ { target: 'Balay', gloss: 'Haus' }, { target: 'Kwarto', gloss: 'Zimmer' }, { target: 'Kusina', gloss: 'Küche' }, { target: 'Sala', gloss: 'Wohnzimmer' }, { target: 'Banyo', gloss: 'Badezimmer' }, { target: 'Pultahan', gloss: 'Tür' }, { target: 'Bintana', gloss: 'Fenster' }, { target: 'Atop', gloss: 'Dach' }, { target: 'Pamilya', gloss: 'Familie' }, { target: 'Among pamilya', gloss: 'unsere Familie' }, { target: 'Naa ko sa balay.', gloss: 'Ich bin zu Hause.' }, { target: 'Naa sila sa kusina.', gloss: 'Sie sind in der Küche.' }, { target: 'Asa ang kusina?', gloss: 'Wo ist die Küche?' }, { target: 'Ang among balay.', gloss: 'Unser Haus.' } ], grammarFocus: [ { title: 'Naa … sa … für Ort', text: '„Naa“ drückt aus, dass jemand oder etwas irgendwo ist; „sa“ verbindet mit dem Ort.', example: 'Naa ko sa balay. Naa sila sa kusina.' }, { title: 'among = unser (Plural inklusiv)', text: '„Among“ passt zu „wir/unsere“ im Sinne von Familie oder Gruppe.', example: 'Among pamilya. Ang among balay.' } ], speakingPrompts: [ { title: 'Räume benennen', prompt: 'Nenne Küche, Wohnzimmer und Badezimmer auf Bisaya.', cue: 'Kusina, sala, banyo.' }, { title: 'Wer ist wo?', prompt: 'Sage, dass du zu Hause bist, und frage, wo die Küche ist.', cue: 'Naa ko sa balay. Asa ang kusina?' } ], practicalTasks: [ { title: 'Rundgang', text: 'Geh in Gedanken durch dein Zuhause und benenne jeden Raum laut auf Bisaya.' } ] }, '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]; const pedagogy = getBisayaLessonPedagogy(lesson.lessonNumber); if (!didactics && !pedagogy) continue; const normalizedDidactics = didactics || {}; await lesson.update({ learningGoals: normalizedDidactics.learningGoals || [], corePatterns: normalizedDidactics.corePatterns || [], grammarFocus: normalizedDidactics.grammarFocus || [], speakingPrompts: normalizedDidactics.speakingPrompts || [], practicalTasks: normalizedDidactics.practicalTasks || [], didacticMode: pedagogy?.didacticMode || null, phaseLabel: pedagogy?.phaseLabel || null, blockNumber: pedagogy?.blockNumber ?? null, difficultyWeight: pedagogy?.difficultyWeight ?? null, newUnitTarget: pedagogy?.newUnitTarget ?? null, reviewWeight: pedagogy?.reviewWeight ?? null, isIntensiveReview: Boolean(pedagogy?.isIntensiveReview) }); 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); });