Some checks failed
Deploy yourpart (blue-green) / deploy (push) Failing after 0s
- Updated the Bisaya course to include new evening greetings and sleep-related phrases in core patterns. - Added multiple exercises focusing on recognizing and using these phrases, improving practical language skills for learners. - Expanded lesson didactics to incorporate prompts for evening and sleep routines, enriching the overall learning experience.
224 lines
10 KiB
JavaScript
224 lines
10 KiB
JavaScript
#!/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: ['Kumusta ka?', 'Maayong buntag.', 'Maayong adlaw.', 'Maayong gabii.', 'Maayong gabii, matulog na ta.', 'Katulog og maayo.', 'Kapoy na ka?', 'Matulog na ta.', 'Inom sa og tubig.', 'Patya ang suga.', 'Tabuni ang imong kaugalingon.', 'Ugma nasad.', 'Damgo og nindot.', 'Amping.', 'Babay.', '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.' },
|
|
{ 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 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];
|
|
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);
|
|
});
|