#!/usr/bin/env node /** * Script zum Aktualisieren der Woche-1-Lektionen in Bisaya-Kursen * * Verwendung: * node backend/scripts/update-week1-bisaya-exercises.js * * - Entfernt alte Platzhalter-Übungen * - Ersetzt durch korrekte Inhalte für "Woche 1 - Wiederholung" und "Woche 1 - Vokabeltest" */ 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 User from '../models/community/user.js'; function withTypeName(exerciseTypeName, exercise) { return { ...exercise, exerciseTypeName }; } const LESSON_TITLES = ['Woche 1 - Wiederholung', 'Woche 1 - Vokabeltest']; const BISAYA_EXERCISES = { 'Woche 1 - Wiederholung': [ { exerciseTypeId: 2, title: 'Wiederholung: Wie sagt man "Wie geht es dir?"?', instruction: 'Wähle die richtige Begrüßung aus.', questionData: { type: 'multiple_choice', question: 'Wie sagt man "Wie geht es dir?" auf Bisaya?', options: ['Kumusta ka?', 'Maayo', 'Salamat', 'Palihug'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Kumusta ka?" ist die Standard-Begrüßung auf Bisaya.' }, { exerciseTypeId: 2, title: 'Wiederholung: Wie sagt man "Mutter" auf Bisaya?', instruction: 'Wähle die richtige Übersetzung.', questionData: { type: 'multiple_choice', question: 'Wie sagt man "Mutter" auf Bisaya?', options: ['Nanay', 'Tatay', 'Kuya', 'Ate'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Nanay" bedeutet "Mutter" auf Bisaya.' }, { exerciseTypeId: 2, title: 'Wiederholung: Was bedeutet "Palangga taka"?', instruction: 'Wähle die richtige Bedeutung.', questionData: { type: 'multiple_choice', question: 'Was bedeutet "Palangga taka"?', options: ['Ich hab dich lieb', 'Danke', 'Guten Tag', 'Auf Wiedersehen'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Palangga taka" bedeutet "Ich hab dich lieb" - wärmer als "I love you" im Familienkontext.' }, { exerciseTypeId: 2, title: 'Wiederholung: Was fragt man mit "Nikaon ka?"?', instruction: 'Wähle die richtige Bedeutung.', questionData: { type: 'multiple_choice', question: 'Was bedeutet "Nikaon ka?"?', options: ['Hast du schon gegessen?', 'Wie geht es dir?', 'Danke', 'Bitte'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Nikaon ka?" bedeutet "Hast du schon gegessen?" - typisch fürsorglich auf den Philippinen.' }, { exerciseTypeId: 2, title: 'Wiederholung: Wie sagt man "Ich verstehe nicht"?', instruction: 'Wähle die richtige Übersetzung.', questionData: { type: 'multiple_choice', question: 'Wie sagt man "Ich verstehe nicht" auf Bisaya?', options: ['Wala ko kasabot', 'Salamat', 'Maayo', 'Palihug'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Wala ko kasabot" bedeutet "Ich verstehe nicht".' }, { exerciseTypeId: 3, title: 'Woche 1: Minisatz bauen', instruction: 'Schreibe eine kurze Sequenz aus Begrüßung und Fürsorge.', questionData: { type: 'sentence_building', question: 'Baue: "Wie geht es dir? Hast du schon gegessen?"', tokens: ['Kumusta', 'ka', 'Nikaon', 'na', 'ka'] }, answerData: { correct: ['Kumusta ka? Nikaon na ka?', 'Kumusta ka. Nikaon na ka?'] }, explanation: 'Hier kombinierst du zwei wichtige Muster aus Woche 1.' }, withTypeName('dialog_completion', { title: 'Woche 1: Dialog ergänzen', instruction: 'Ergänze die passende liebevolle Reaktion.', questionData: { type: 'dialog_completion', question: 'Welche Antwort passt?', dialog: ['A: Mingaw ko nimo.', 'B: ...'] }, answerData: { modelAnswer: 'Palangga taka.', correct: ['Palangga taka.'] }, explanation: 'Die Kombination klingt im Familienkontext warm und natürlich.' }) ], 'Woche 1 - Vokabeltest': [ { exerciseTypeId: 2, title: 'Vokabeltest: Kumusta', instruction: 'Was bedeutet "Kumusta"?', questionData: { type: 'multiple_choice', question: 'Was bedeutet "Kumusta"?', options: ['Wie geht es dir?', 'Danke', 'Bitte', 'Auf Wiedersehen'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Kumusta" kommt von spanisch "¿Cómo está?" - "Wie geht es dir?"' }, { exerciseTypeId: 2, title: 'Vokabeltest: Lola', instruction: 'Wähle die richtige Übersetzung.', questionData: { type: 'multiple_choice', question: 'Was bedeutet "Lola"?', options: ['Großmutter', 'Großvater', 'Mutter', 'Vater'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Lola" = Großmutter, "Lolo" = Großvater.' }, { exerciseTypeId: 2, title: 'Vokabeltest: Salamat', instruction: 'Wähle die richtige Bedeutung.', questionData: { type: 'multiple_choice', question: 'Was bedeutet "Salamat"?', options: ['Danke', 'Bitte', 'Entschuldigung', 'Gern geschehen'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Salamat" bedeutet "Danke".' }, { exerciseTypeId: 2, title: 'Vokabeltest: Lami', instruction: 'Was bedeutet "Lami"?', questionData: { type: 'multiple_choice', question: 'Was bedeutet "Lami"?', options: ['Lecker', 'Viel', 'Gut', 'Schnell'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Lami" bedeutet "lecker" oder "schmackhaft" - wichtig beim Essen!' }, { exerciseTypeId: 2, title: 'Vokabeltest: Mingaw ko nimo', instruction: 'Wähle die richtige Bedeutung.', questionData: { type: 'multiple_choice', question: 'Was bedeutet "Mingaw ko nimo"?', options: ['Ich vermisse dich', 'Ich freue mich', 'Ich mag dich', 'Ich liebe dich'] }, answerData: { type: 'multiple_choice', correctAnswer: 0 }, explanation: '"Mingaw ko nimo" bedeutet "Ich vermisse dich".' }, withTypeName('situational_response', { title: 'Woche 1: Situative Kurzantwort', instruction: 'Reagiere passend auf die Situation.', questionData: { type: 'situational_response', question: 'Jemand fragt: "Kumusta ka?" Antworte kurz und höflich.', keywords: ['maayo', 'salamat'] }, answerData: { modelAnswer: 'Maayo ko, salamat.', keywords: ['maayo', 'salamat'] }, explanation: 'Eine kurze höfliche Antwort reicht hier völlig aus.' }) ] }; async function resolveExerciseTypeId(exercise) { if (exercise.exerciseTypeId) { return exercise.exerciseTypeId; } const [type] = await sequelize.query( `SELECT id FROM community.vocab_grammar_exercise_type WHERE name = :name LIMIT 1`, { replacements: { name: exercise.exerciseTypeName }, type: sequelize.QueryTypes.SELECT } ); if (!type) { throw new Error(`Übungstyp "${exercise.exerciseTypeName}" nicht gefunden`); } return Number(type.id); } async function updateWeek1BisayaExercises() { await sequelize.authenticate(); console.log('Datenbankverbindung erfolgreich hergestellt.\n'); let systemUser; try { systemUser = await User.findOne({ where: { username: 'system' } }); if (!systemUser) systemUser = await User.findOne({ where: { username: 'admin' } }); if (!systemUser) throw new Error('System user not found'); } catch (e) { console.error('❌ System-Benutzer nicht gefunden.'); throw e; } 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 c.id, c.title, c.owner_user_id FROM community.vocab_course c WHERE c.language_id = :languageId`, { replacements: { languageId: bisayaLanguage.id }, type: sequelize.QueryTypes.SELECT } ); console.log(`Gefunden: ${courses.length} Bisaya-Kurs(e)\n`); let totalDeleted = 0; let totalAdded = 0; for (const course of courses) { console.log(`📚 Kurs: ${course.title} (ID: ${course.id})`); for (const lessonTitle of LESSON_TITLES) { const exercises = BISAYA_EXERCISES[lessonTitle]; if (!exercises || exercises.length === 0) continue; const lessons = await VocabCourseLesson.findAll({ where: { courseId: course.id, title: lessonTitle }, order: [['lessonNumber', 'ASC']] }); for (const lesson of lessons) { const deletedCount = await VocabGrammarExercise.destroy({ where: { lessonId: lesson.id } }); totalDeleted += deletedCount; console.log(` 🗑️ Lektion ${lesson.lessonNumber}: "${lesson.title}" - ${deletedCount} alte Übung(en) entfernt`); let exerciseNumber = 1; for (const ex of exercises) { const exerciseTypeId = await resolveExerciseTypeId(ex); await VocabGrammarExercise.create({ lessonId: lesson.id, exerciseTypeId, exerciseNumber: exerciseNumber++, title: ex.title, instruction: ex.instruction, questionData: JSON.stringify(ex.questionData), answerData: JSON.stringify(ex.answerData), explanation: ex.explanation, createdByUserId: course.owner_user_id || systemUser.id }); totalAdded++; } console.log(` ✅ Lektion ${lesson.lessonNumber}: "${lesson.title}" - ${exercises.length} neue Übung(en)`); } } console.log(''); } console.log(`\n🎉 Zusammenfassung:`); console.log(` ${totalDeleted} Platzhalter-Übungen entfernt`); console.log(` ${totalAdded} neue Übungen erstellt`); } updateWeek1BisayaExercises() .then(() => { sequelize.close(); process.exit(0); }) .catch((error) => { console.error('❌ Fehler:', error); sequelize.close(); process.exit(1); });