#!/usr/bin/env node /** * Script zum Erstellen von Übungen für die "Gefühle & Zuneigung" Lektion * * Verwendung: * node backend/scripts/update-feelings-affection-exercises.js * * Erstellt Gesprächsübungen für die "Gefühle & Zuneigung" Lektion in allen Bisaya-Kursen. */ 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 VocabCourse from '../models/community/vocab_course.js'; import User from '../models/community/user.js'; import crypto from 'crypto'; import bcrypt from 'bcryptjs'; import { Op } from 'sequelize'; // Gefühle & Zuneigung auf Bisaya mit verschiedenen Muttersprachen const FEELINGS_AFFECTION = { // Deutsch -> Bisaya 'Deutsch': { conversations: [ { bisaya: 'Gihigugma ko ikaw.', native: 'Ich liebe dich.', explanation: '"Gihigugma" bedeutet "lieben", "ko" ist "ich", "ikaw" ist "dich"' }, { bisaya: 'Nahigugma ko nimo.', native: 'Ich liebe dich. (alternativ)', explanation: '"Nahigugma" ist eine andere Form von "lieben", "nimo" ist "dich" (informell)' }, { bisaya: 'Ganahan ko nimo.', native: 'Ich mag dich.', explanation: '"Ganahan" bedeutet "mögen/gefallen", "ko" ist "ich", "nimo" ist "dich"' }, { bisaya: 'Nalipay ko nga nakita ka.', native: 'Ich bin glücklich, dich zu sehen.', explanation: '"Nalipay" bedeutet "glücklich", "ko" ist "ich", "nga nakita ka" ist "dich zu sehen"' }, { bisaya: 'Gimingaw ko nimo.', native: 'Ich vermisse dich.', explanation: '"Gimingaw" bedeutet "vermissen", "ko" ist "ich", "nimo" ist "dich"' }, { bisaya: 'Nalipay ko.', native: 'Ich bin glücklich.', explanation: '"Nalipay" bedeutet "glücklich", "ko" ist "ich"' }, { bisaya: 'Nasubo ko.', native: 'Ich bin traurig.', explanation: '"Nasubo" bedeutet "traurig", "ko" ist "ich"' }, { bisaya: 'Nalipay ko nga naa ka dinhi.', native: 'Ich bin glücklich, dass du hier bist.', explanation: '"Nalipay" ist "glücklich", "nga naa ka dinhi" bedeutet "dass du hier bist"' } ] }, // Englisch -> Bisaya 'Englisch': { conversations: [ { bisaya: 'Gihigugma ko ikaw.', native: 'I love you.', explanation: '"Gihigugma" means "love", "ko" is "I", "ikaw" is "you"' }, { bisaya: 'Nahigugma ko nimo.', native: 'I love you. (alternative)', explanation: '"Nahigugma" is another form of "love", "nimo" is "you" (informal)' }, { bisaya: 'Ganahan ko nimo.', native: 'I like you.', explanation: '"Ganahan" means "like", "ko" is "I", "nimo" is "you"' }, { bisaya: 'Nalipay ko nga nakita ka.', native: 'I am happy to see you.', explanation: '"Nalipay" means "happy", "ko" is "I", "nga nakita ka" is "to see you"' }, { bisaya: 'Gimingaw ko nimo.', native: 'I miss you.', explanation: '"Gimingaw" means "miss", "ko" is "I", "nimo" is "you"' }, { bisaya: 'Nalipay ko.', native: 'I am happy.', explanation: '"Nalipay" means "happy", "ko" is "I"' }, { bisaya: 'Nasubo ko.', native: 'I am sad.', explanation: '"Nasubo" means "sad", "ko" is "I"' }, { bisaya: 'Nalipay ko nga naa ka dinhi.', native: 'I am happy that you are here.', explanation: '"Nalipay" is "happy", "nga naa ka dinhi" means "that you are here"' } ] }, // Spanisch -> Bisaya 'Spanisch': { conversations: [ { bisaya: 'Gihigugma ko ikaw.', native: 'Te amo.', explanation: '"Gihigugma" significa "amar", "ko" es "yo", "ikaw" es "tú"' }, { bisaya: 'Nahigugma ko nimo.', native: 'Te amo. (alternativa)', explanation: '"Nahigugma" es otra forma de "amar", "nimo" es "tú" (informal)' }, { bisaya: 'Ganahan ko nimo.', native: 'Me gustas.', explanation: '"Ganahan" significa "gustar", "ko" es "yo", "nimo" es "tú"' }, { bisaya: 'Nalipay ko nga nakita ka.', native: 'Estoy feliz de verte.', explanation: '"Nalipay" significa "feliz", "ko" es "yo", "nga nakita ka" es "verte"' }, { bisaya: 'Gimingaw ko nimo.', native: 'Te extraño.', explanation: '"Gimingaw" significa "extrañar", "ko" es "yo", "nimo" es "tú"' }, { bisaya: 'Nalipay ko.', native: 'Estoy feliz.', explanation: '"Nalipay" significa "feliz", "ko" es "yo"' }, { bisaya: 'Nasubo ko.', native: 'Estoy triste.', explanation: '"Nasubo" significa "triste", "ko" es "yo"' }, { bisaya: 'Nalipay ko nga naa ka dinhi.', native: 'Estoy feliz de que estés aquí.', explanation: '"Nalipay" es "feliz", "nga naa ka dinhi" significa "que estés aquí"' } ] }, // Französisch -> Bisaya 'Französisch': { conversations: [ { bisaya: 'Gihigugma ko ikaw.', native: 'Je t\'aime.', explanation: '"Gihigugma" signifie "aimer", "ko" est "je", "ikaw" est "tu"' }, { bisaya: 'Nahigugma ko nimo.', native: 'Je t\'aime. (alternative)', explanation: '"Nahigugma" est une autre forme de "aimer", "nimo" est "tu" (informel)' }, { bisaya: 'Ganahan ko nimo.', native: 'Je t\'aime bien.', explanation: '"Ganahan" signifie "aimer bien", "ko" est "je", "nimo" est "tu"' }, { bisaya: 'Nalipay ko nga nakita ka.', native: 'Je suis heureux de te voir.', explanation: '"Nalipay" signifie "heureux", "ko" est "je", "nga nakita ka" est "te voir"' }, { bisaya: 'Gimingaw ko nimo.', native: 'Tu me manques.', explanation: '"Gimingaw" signifie "manquer", "ko" est "je", "nimo" est "tu"' }, { bisaya: 'Nalipay ko.', native: 'Je suis heureux.', explanation: '"Nalipay" signifie "heureux", "ko" est "je"' }, { bisaya: 'Nasubo ko.', native: 'Je suis triste.', explanation: '"Nasubo" signifie "triste", "ko" est "je"' }, { bisaya: 'Nalipay ko nga naa ka dinhi.', native: 'Je suis heureux que tu sois ici.', explanation: '"Nalipay" est "heureux", "nga naa ka dinhi" signifie "que tu sois ici"' } ] }, // Italienisch -> Bisaya 'Italienisch': { conversations: [ { bisaya: 'Gihigugma ko ikaw.', native: 'Ti amo.', explanation: '"Gihigugma" significa "amare", "ko" è "io", "ikaw" è "tu"' }, { bisaya: 'Nahigugma ko nimo.', native: 'Ti amo. (alternativa)', explanation: '"Nahigugma" è un\'altra forma di "amare", "nimo" è "tu" (informale)' }, { bisaya: 'Ganahan ko nimo.', native: 'Mi piaci.', explanation: '"Ganahan" significa "piacere", "ko" è "io", "nimo" è "tu"' }, { bisaya: 'Nalipay ko nga nakita ka.', native: 'Sono felice di vederti.', explanation: '"Nalipay" significa "felice", "ko" è "io", "nga nakita ka" è "vederti"' }, { bisaya: 'Gimingaw ko nimo.', native: 'Mi manchi.', explanation: '"Gimingaw" significa "mancare", "ko" è "io", "nimo" è "tu"' }, { bisaya: 'Nalipay ko.', native: 'Sono felice.', explanation: '"Nalipay" significa "felice", "ko" è "io"' }, { bisaya: 'Nasubo ko.', native: 'Sono triste.', explanation: '"Nasubo" significa "triste", "ko" è "io"' }, { bisaya: 'Nalipay ko nga naa ka dinhi.', native: 'Sono felice che tu sia qui.', explanation: '"Nalipay" è "felice", "nga naa ka dinhi" significa "che tu sia qui"' } ] }, // Portugiesisch -> Bisaya 'Portugiesisch': { conversations: [ { bisaya: 'Gihigugma ko ikaw.', native: 'Eu te amo.', explanation: '"Gihigugma" significa "amar", "ko" é "eu", "ikaw" é "você"' }, { bisaya: 'Nahigugma ko nimo.', native: 'Eu te amo. (alternativa)', explanation: '"Nahigugma" é outra forma de "amar", "nimo" é "você" (informal)' }, { bisaya: 'Ganahan ko nimo.', native: 'Eu gosto de você.', explanation: '"Ganahan" significa "gostar", "ko" é "eu", "nimo" é "você"' }, { bisaya: 'Nalipay ko nga nakita ka.', native: 'Estou feliz em te ver.', explanation: '"Nalipay" significa "feliz", "ko" é "eu", "nga nakita ka" é "te ver"' }, { bisaya: 'Gimingaw ko nimo.', native: 'Eu sinto sua falta.', explanation: '"Gimingaw" significa "sentir falta", "ko" é "eu", "nimo" é "você"' }, { bisaya: 'Nalipay ko.', native: 'Estou feliz.', explanation: '"Nalipay" significa "feliz", "ko" é "eu"' }, { bisaya: 'Nasubo ko.', native: 'Estou triste.', explanation: '"Nasubo" significa "triste", "ko" é "eu"' }, { bisaya: 'Nalipay ko nga naa ka dinhi.', native: 'Estou feliz que você esteja aqui.', explanation: '"Nalipay" é "feliz", "nga naa ka dinhi" significa "que você esteja aqui"' } ] } }; async function findOrCreateSystemUser() { // Versuche zuerst einen System-Benutzer zu finden (z.B. mit username "system" oder "admin") let systemUser = await User.findOne({ where: { username: { [sequelize.Sequelize.Op.in]: ['system', 'admin', 'System', 'Admin'] } } }); if (!systemUser) { // Erstelle einen System-Benutzer const password = crypto.randomBytes(32).toString('hex'); const hashedPassword = await bcrypt.hash(password, 10); const hashedId = crypto.createHash('sha256').update(`system-${Date.now()}`).digest('hex'); systemUser = await User.create({ username: 'system', password: hashedPassword, hashedId: hashedId, email: 'system@your-part.de' }); console.log('✅ System-Benutzer erstellt:', systemUser.hashedId); } else { console.log('✅ System-Benutzer gefunden:', systemUser.hashedId); } return systemUser; } function createFeelingsAffectionExercises(nativeLanguageName) { const exercises = []; const conversations = FEELINGS_AFFECTION[nativeLanguageName]?.conversations || []; if (conversations.length === 0) { console.warn(`⚠️ Keine Gespräche für Muttersprache "${nativeLanguageName}" gefunden. Verwende Deutsch als Fallback.`); return createFeelingsAffectionExercises('Deutsch'); } let exerciseNum = 1; // Multiple Choice: Übersetze Bisaya-Satz in Muttersprache conversations.forEach((conv, idx) => { if (idx < 4) { // Erste 4 als Multiple Choice exercises.push({ exerciseTypeId: 2, // multiple_choice exerciseNumber: exerciseNum++, title: `Gefühle & Zuneigung ${idx + 1} - Übersetzung`, instruction: 'Übersetze den Bisaya-Satz ins ' + nativeLanguageName, questionData: JSON.stringify({ type: 'multiple_choice', question: `Wie sagt man "${conv.bisaya}" auf ${nativeLanguageName}?`, options: [ conv.native, conversations[(idx + 1) % conversations.length].native, conversations[(idx + 2) % conversations.length].native, conversations[(idx + 3) % conversations.length].native ] }), answerData: JSON.stringify({ type: 'multiple_choice', correctAnswer: 0 }), explanation: conv.explanation }); } }); // Gap Fill: Vervollständige Gefühlsausdrücke exercises.push({ exerciseTypeId: 1, // gap_fill exerciseNumber: exerciseNum++, title: 'Gefühle & Zuneigung vervollständigen', instruction: 'Vervollständige den Satz mit den richtigen Bisaya-Wörtern.', questionData: JSON.stringify({ type: 'gap_fill', text: 'Person A: {gap} ko ikaw. (Ich liebe dich)\nPerson B: {gap} ko pud. (Ich liebe dich auch)', gaps: 2 }), answerData: JSON.stringify({ type: 'gap_fill', answers: ['Gihigugma', 'Gihigugma'] }), explanation: '"Gihigugma" bedeutet "lieben" und wird wiederholt, um "auch" auszudrücken' }); // Transformation: Übersetze Muttersprache-Satz nach Bisaya exercises.push({ exerciseTypeId: 3, // transformation exerciseNumber: exerciseNum++, title: 'Gefühle & Zuneigung - Übersetzung nach Bisaya', instruction: 'Übersetze den Satz ins Bisaya.', questionData: JSON.stringify({ type: 'transformation', text: conversations[0].native }), answerData: JSON.stringify({ type: 'transformation', correctAnswer: conversations[0].bisaya }), explanation: `"${conversations[0].bisaya}" bedeutet "${conversations[0].native}" auf Bisaya. ${conversations[0].explanation}` }); // Weitere Multiple Choice: Rückwärts-Übersetzung exercises.push({ exerciseTypeId: 2, // multiple_choice exerciseNumber: exerciseNum++, title: 'Gefühle & Zuneigung - Was bedeutet dieser Satz?', instruction: 'Was bedeutet dieser Bisaya-Satz?', questionData: JSON.stringify({ type: 'multiple_choice', question: `Was bedeutet "${conversations[2].bisaya}"?`, options: [ conversations[2].native, conversations[3].native, conversations[4].native, conversations[5].native ] }), answerData: JSON.stringify({ type: 'multiple_choice', correctAnswer: 0 }), explanation: conversations[2].explanation }); return exercises; } async function updateFeelingsAffectionExercises() { await sequelize.authenticate(); console.log('✅ Datenbankverbindung erfolgreich hergestellt.\n'); const systemUser = await findOrCreateSystemUser(); // Finde Bisaya-Sprache mit SQL const [bisayaLangResult] = await sequelize.query( `SELECT id FROM community.vocab_language WHERE name = 'Bisaya' LIMIT 1`, { type: sequelize.QueryTypes.SELECT } ); if (!bisayaLangResult) { console.error('❌ Bisaya-Sprache nicht gefunden.'); return; } const bisayaLanguageId = bisayaLangResult.id; // Hole alle Bisaya-Kurse mit native language info const courses = await sequelize.query( `SELECT c.id, c.title, c.native_language_id, nl.name as native_language_name FROM community.vocab_course c LEFT JOIN community.vocab_language nl ON c.native_language_id = nl.id WHERE c.language_id = :bisayaLanguageId`, { replacements: { bisayaLanguageId }, type: sequelize.QueryTypes.SELECT } ); console.log(`📚 Gefunden: ${courses.length} Bisaya-Kurse\n`); let totalExercisesCreated = 0; let totalLessonsProcessed = 0; for (const course of courses) { console.log(`📖 Kurs: ${course.title} (ID: ${course.id})`); // Finde native language name const nativeLanguageName = course.native_language_name || 'Deutsch'; console.log(` Muttersprache: ${nativeLanguageName}`); // Finde "Gefühle & Zuneigung" Lektion const lessons = await VocabCourseLesson.findAll({ where: { courseId: course.id, title: 'Gefühle & Zuneigung' }, attributes: ['id', 'title', 'lessonNumber'] }); console.log(` ${lessons.length} "Gefühle & Zuneigung"-Lektion(en) gefunden`); for (const lesson of lessons) { // Lösche vorhandene Übungen const deletedCount = await VocabGrammarExercise.destroy({ where: { lessonId: lesson.id } }); console.log(` 🗑️ Lektion ${lesson.lessonNumber}: "${lesson.title}" - ${deletedCount} alte Übung(en) gelöscht`); // Erstelle neue Übungen const exercises = createFeelingsAffectionExercises(nativeLanguageName); if (exercises.length > 0) { const exercisesToCreate = exercises.map(ex => ({ ...ex, lessonId: lesson.id, createdByUserId: systemUser.id })); await VocabGrammarExercise.bulkCreate(exercisesToCreate); totalExercisesCreated += exercisesToCreate.length; console.log(` ✅ ${exercisesToCreate.length} neue Übung(en) erstellt`); } else { console.log(` ⚠️ Keine Übungen erstellt`); } totalLessonsProcessed++; } console.log(''); } console.log(`\n🎉 Zusammenfassung:`); console.log(` ${totalLessonsProcessed} "Gefühle & Zuneigung"-Lektion(en) verarbeitet`); console.log(` ${totalExercisesCreated} Grammatik-Übungen erstellt`); } updateFeelingsAffectionExercises() .then(() => { sequelize.close(); process.exit(0); }) .catch((error) => { console.error('❌ Fehler:', error); sequelize.close(); process.exit(1); });