- Enhanced the loadLesson and checkLessonCompletion methods to streamline lesson transitions and prevent redundant executions, improving user experience. - Updated navigation logic to utilize more efficient history management, ensuring smoother course and lesson changes. - Added detailed console logging for better insights during lesson loading and completion checks, aiding in debugging and user interaction.
522 lines
18 KiB
JavaScript
Executable File
522 lines
18 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* Script zum Erstellen von Übungen für die "Familien-Gespräche" Lektion
|
|
*
|
|
* Verwendung:
|
|
* node backend/scripts/update-family-conversations-exercises.js
|
|
*
|
|
* Erstellt Gesprächsübungen für die "Familien-Gespräche" 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 VocabLanguage from '../models/community/vocab_language.js';
|
|
import VocabGrammarExerciseType from '../models/community/vocab_grammar_exercise_type.js';
|
|
import User from '../models/community/user.js';
|
|
import crypto from 'crypto';
|
|
import bcrypt from 'bcryptjs';
|
|
import { Op } from 'sequelize';
|
|
|
|
// Familiengespräche auf Bisaya mit verschiedenen Muttersprachen
|
|
const FAMILY_CONVERSATIONS = {
|
|
// Deutsch -> Bisaya
|
|
'Deutsch': {
|
|
conversations: [
|
|
{
|
|
bisaya: 'Kumusta ka, Nanay?',
|
|
native: 'Wie geht es dir, Mama?',
|
|
explanation: '"Kumusta ka" ist "Wie geht es dir?" und "Nanay" ist "Mama"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ko, Salamat. Ikaw?',
|
|
native: 'Mir geht es gut, danke. Und dir?',
|
|
explanation: '"Maayo ko" bedeutet "Mir geht es gut", "Ikaw" ist "du" (formal)'
|
|
},
|
|
{
|
|
bisaya: 'Asa si Tatay?',
|
|
native: 'Wo ist Papa?',
|
|
explanation: '"Asa" bedeutet "wo", "si" ist ein Marker für Personen, "Tatay" ist "Papa"'
|
|
},
|
|
{
|
|
bisaya: 'Naa siya sa balay.',
|
|
native: 'Er ist zu Hause.',
|
|
explanation: '"Naa" bedeutet "ist/sein", "siya" ist "er/sie", "sa balay" ist "zu Hause"'
|
|
},
|
|
{
|
|
bisaya: 'Kumusta na ang Kuya?',
|
|
native: 'Wie geht es dem älteren Bruder?',
|
|
explanation: '"Kumusta na" ist "Wie geht es", "ang" ist ein Artikel, "Kuya" ist "älterer Bruder"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ra siya.',
|
|
native: 'Es geht ihm gut.',
|
|
explanation: '"Maayo ra" bedeutet "gut/gut geht es", "siya" ist "ihm"'
|
|
},
|
|
{
|
|
bisaya: 'Gutom na ko, Nanay.',
|
|
native: 'Ich bin hungrig, Mama.',
|
|
explanation: '"Gutom" bedeutet "hungrig", "na" zeigt einen Zustand, "ko" ist "ich"'
|
|
},
|
|
{
|
|
bisaya: 'Hulata lang, hapit na ang pagkaon.',
|
|
native: 'Warte nur, das Essen ist fast fertig.',
|
|
explanation: '"Hulata" ist "warte", "lang" ist "nur", "hapit na" ist "fast", "pagkaon" ist "Essen"'
|
|
}
|
|
]
|
|
},
|
|
// Englisch -> Bisaya
|
|
'Englisch': {
|
|
conversations: [
|
|
{
|
|
bisaya: 'Kumusta ka, Nanay?',
|
|
native: 'How are you, Mom?',
|
|
explanation: '"Kumusta ka" means "How are you?" and "Nanay" means "Mom"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ko, Salamat. Ikaw?',
|
|
native: 'I\'m fine, thank you. And you?',
|
|
explanation: '"Maayo ko" means "I\'m fine", "Ikaw" is "you" (formal)'
|
|
},
|
|
{
|
|
bisaya: 'Asa si Tatay?',
|
|
native: 'Where is Dad?',
|
|
explanation: '"Asa" means "where", "si" is a person marker, "Tatay" means "Dad"'
|
|
},
|
|
{
|
|
bisaya: 'Naa siya sa balay.',
|
|
native: 'He is at home.',
|
|
explanation: '"Naa" means "is/be", "siya" is "he/she", "sa balay" means "at home"'
|
|
},
|
|
{
|
|
bisaya: 'Kumusta na ang Kuya?',
|
|
native: 'How is the older brother?',
|
|
explanation: '"Kumusta na" means "How is", "ang" is an article, "Kuya" means "older brother"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ra siya.',
|
|
native: 'He is fine.',
|
|
explanation: '"Maayo ra" means "fine/well", "siya" means "he"'
|
|
},
|
|
{
|
|
bisaya: 'Gutom na ko, Nanay.',
|
|
native: 'I\'m hungry, Mom.',
|
|
explanation: '"Gutom" means "hungry", "na" shows a state, "ko" is "I"'
|
|
},
|
|
{
|
|
bisaya: 'Hulata lang, hapit na ang pagkaon.',
|
|
native: 'Just wait, the food is almost ready.',
|
|
explanation: '"Hulata" means "wait", "lang" means "just", "hapit na" means "almost", "pagkaon" means "food"'
|
|
}
|
|
]
|
|
},
|
|
// Spanisch -> Bisaya
|
|
'Spanisch': {
|
|
conversations: [
|
|
{
|
|
bisaya: 'Kumusta ka, Nanay?',
|
|
native: '¿Cómo estás, Mamá?',
|
|
explanation: '"Kumusta ka" significa "¿Cómo estás?" y "Nanay" significa "Mamá"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ko, Salamat. Ikaw?',
|
|
native: 'Estoy bien, gracias. ¿Y tú?',
|
|
explanation: '"Maayo ko" significa "Estoy bien", "Ikaw" es "tú" (formal)'
|
|
},
|
|
{
|
|
bisaya: 'Asa si Tatay?',
|
|
native: '¿Dónde está Papá?',
|
|
explanation: '"Asa" significa "dónde", "si" es un marcador de persona, "Tatay" significa "Papá"'
|
|
},
|
|
{
|
|
bisaya: 'Naa siya sa balay.',
|
|
native: 'Él está en casa.',
|
|
explanation: '"Naa" significa "está/ser", "siya" es "él/ella", "sa balay" significa "en casa"'
|
|
},
|
|
{
|
|
bisaya: 'Kumusta na ang Kuya?',
|
|
native: '¿Cómo está el hermano mayor?',
|
|
explanation: '"Kumusta na" significa "¿Cómo está?", "ang" es un artículo, "Kuya" significa "hermano mayor"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ra siya.',
|
|
native: 'Él está bien.',
|
|
explanation: '"Maayo ra" significa "bien", "siya" significa "él"'
|
|
},
|
|
{
|
|
bisaya: 'Gutom na ko, Nanay.',
|
|
native: 'Tengo hambre, Mamá.',
|
|
explanation: '"Gutom" significa "hambriento", "na" muestra un estado, "ko" es "yo"'
|
|
},
|
|
{
|
|
bisaya: 'Hulata lang, hapit na ang pagkaon.',
|
|
native: 'Solo espera, la comida está casi lista.',
|
|
explanation: '"Hulata" significa "espera", "lang" significa "solo", "hapit na" significa "casi", "pagkaon" significa "comida"'
|
|
}
|
|
]
|
|
},
|
|
// Französisch -> Bisaya
|
|
'Französisch': {
|
|
conversations: [
|
|
{
|
|
bisaya: 'Kumusta ka, Nanay?',
|
|
native: 'Comment vas-tu, Maman?',
|
|
explanation: '"Kumusta ka" signifie "Comment vas-tu?" et "Nanay" signifie "Maman"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ko, Salamat. Ikaw?',
|
|
native: 'Je vais bien, merci. Et toi?',
|
|
explanation: '"Maayo ko" signifie "Je vais bien", "Ikaw" est "tu" (formel)'
|
|
},
|
|
{
|
|
bisaya: 'Asa si Tatay?',
|
|
native: 'Où est Papa?',
|
|
explanation: '"Asa" signifie "où", "si" est un marqueur de personne, "Tatay" signifie "Papa"'
|
|
},
|
|
{
|
|
bisaya: 'Naa siya sa balay.',
|
|
native: 'Il est à la maison.',
|
|
explanation: '"Naa" signifie "est/être", "siya" est "il/elle", "sa balay" signifie "à la maison"'
|
|
},
|
|
{
|
|
bisaya: 'Kumusta na ang Kuya?',
|
|
native: 'Comment va le grand frère?',
|
|
explanation: '"Kumusta na" signifie "Comment va", "ang" est un article, "Kuya" signifie "grand frère"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ra siya.',
|
|
native: 'Il va bien.',
|
|
explanation: '"Maayo ra" signifie "bien", "siya" signifie "il"'
|
|
},
|
|
{
|
|
bisaya: 'Gutom na ko, Nanay.',
|
|
native: 'J\'ai faim, Maman.',
|
|
explanation: '"Gutom" signifie "faim", "na" montre un état, "ko" est "je"'
|
|
},
|
|
{
|
|
bisaya: 'Hulata lang, hapit na ang pagkaon.',
|
|
native: 'Attends juste, la nourriture est presque prête.',
|
|
explanation: '"Hulata" signifie "attends", "lang" signifie "juste", "hapit na" signifie "presque", "pagkaon" signifie "nourriture"'
|
|
}
|
|
]
|
|
},
|
|
// Italienisch -> Bisaya
|
|
'Italienisch': {
|
|
conversations: [
|
|
{
|
|
bisaya: 'Kumusta ka, Nanay?',
|
|
native: 'Come stai, Mamma?',
|
|
explanation: '"Kumusta ka" significa "Come stai?" e "Nanay" significa "Mamma"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ko, Salamat. Ikaw?',
|
|
native: 'Sto bene, grazie. E tu?',
|
|
explanation: '"Maayo ko" significa "Sto bene", "Ikaw" è "tu" (formale)'
|
|
},
|
|
{
|
|
bisaya: 'Asa si Tatay?',
|
|
native: 'Dove è Papà?',
|
|
explanation: '"Asa" significa "dove", "si" è un marcatore di persona, "Tatay" significa "Papà"'
|
|
},
|
|
{
|
|
bisaya: 'Naa siya sa balay.',
|
|
native: 'È a casa.',
|
|
explanation: '"Naa" significa "è/essere", "siya" è "lui/lei", "sa balay" significa "a casa"'
|
|
},
|
|
{
|
|
bisaya: 'Kumusta na ang Kuya?',
|
|
native: 'Come sta il fratello maggiore?',
|
|
explanation: '"Kumusta na" significa "Come sta", "ang" è un articolo, "Kuya" significa "fratello maggiore"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ra siya.',
|
|
native: 'Sta bene.',
|
|
explanation: '"Maayo ra" significa "bene", "siya" significa "lui"'
|
|
},
|
|
{
|
|
bisaya: 'Gutom na ko, Nanay.',
|
|
native: 'Ho fame, Mamma.',
|
|
explanation: '"Gutom" significa "fame", "na" mostra uno stato, "ko" è "io"'
|
|
},
|
|
{
|
|
bisaya: 'Hulata lang, hapit na ang pagkaon.',
|
|
native: 'Aspetta solo, il cibo è quasi pronto.',
|
|
explanation: '"Hulata" significa "aspetta", "lang" significa "solo", "hapit na" significa "quasi", "pagkaon" significa "cibo"'
|
|
}
|
|
]
|
|
},
|
|
// Portugiesisch -> Bisaya
|
|
'Portugiesisch': {
|
|
conversations: [
|
|
{
|
|
bisaya: 'Kumusta ka, Nanay?',
|
|
native: 'Como você está, Mãe?',
|
|
explanation: '"Kumusta ka" significa "Como você está?" e "Nanay" significa "Mãe"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ko, Salamat. Ikaw?',
|
|
native: 'Estou bem, obrigado. E você?',
|
|
explanation: '"Maayo ko" significa "Estou bem", "Ikaw" é "você" (formal)'
|
|
},
|
|
{
|
|
bisaya: 'Asa si Tatay?',
|
|
native: 'Onde está o Papai?',
|
|
explanation: '"Asa" significa "onde", "si" é um marcador de pessoa, "Tatay" significa "Papai"'
|
|
},
|
|
{
|
|
bisaya: 'Naa siya sa balay.',
|
|
native: 'Ele está em casa.',
|
|
explanation: '"Naa" significa "está/ser", "siya" é "ele/ela", "sa balay" significa "em casa"'
|
|
},
|
|
{
|
|
bisaya: 'Kumusta na ang Kuya?',
|
|
native: 'Como está o irmão mais velho?',
|
|
explanation: '"Kumusta na" significa "Como está", "ang" é um artigo, "Kuya" significa "irmão mais velho"'
|
|
},
|
|
{
|
|
bisaya: 'Maayo ra siya.',
|
|
native: 'Ele está bem.',
|
|
explanation: '"Maayo ra" significa "bem", "siya" significa "ele"'
|
|
},
|
|
{
|
|
bisaya: 'Gutom na ko, Nanay.',
|
|
native: 'Estou com fome, Mãe.',
|
|
explanation: '"Gutom" significa "fome", "na" mostra um estado, "ko" é "eu"'
|
|
},
|
|
{
|
|
bisaya: 'Hulata lang, hapit na ang pagkaon.',
|
|
native: 'Apenas espere, a comida está quase pronta.',
|
|
explanation: '"Hulata" significa "espere", "lang" significa "apenas", "hapit na" significa "quase", "pagkaon" significa "comida"'
|
|
}
|
|
]
|
|
}
|
|
};
|
|
|
|
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 createFamilyConversationExercises(nativeLanguageName) {
|
|
const exercises = [];
|
|
const conversations = FAMILY_CONVERSATIONS[nativeLanguageName]?.conversations || [];
|
|
|
|
if (conversations.length === 0) {
|
|
console.warn(`⚠️ Keine Gespräche für Muttersprache "${nativeLanguageName}" gefunden. Verwende Deutsch als Fallback.`);
|
|
return createFamilyConversationExercises('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: `Familien-Gespräch ${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 Familiengespräche
|
|
exercises.push({
|
|
exerciseTypeId: 1, // gap_fill
|
|
exerciseNumber: exerciseNum++,
|
|
title: 'Familien-Gespräch vervollständigen',
|
|
instruction: 'Vervollständige das Gespräch mit den richtigen Bisaya-Wörtern.',
|
|
questionData: JSON.stringify({
|
|
type: 'gap_fill',
|
|
text: 'Person A: Kumusta ka, {gap}? (Mama)\nPerson B: {gap} ko, Salamat. Ikaw? (Mir geht es gut)',
|
|
gaps: 2
|
|
}),
|
|
answerData: JSON.stringify({
|
|
type: 'gap_fill',
|
|
answers: ['Nanay', 'Maayo']
|
|
}),
|
|
explanation: '"Nanay" ist "Mama" und "Maayo ko" bedeutet "Mir geht es gut"'
|
|
});
|
|
|
|
// Transformation: Übersetze Muttersprache-Satz nach Bisaya
|
|
exercises.push({
|
|
exerciseTypeId: 3, // transformation
|
|
exerciseNumber: exerciseNum++,
|
|
title: 'Familien-Gespräch - Ü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: 'Familien-Gespräch - 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 updateFamilyConversationExercises() {
|
|
await sequelize.authenticate();
|
|
console.log('✅ Datenbankverbindung erfolgreich hergestellt.\n');
|
|
|
|
const systemUser = await findOrCreateSystemUser();
|
|
const bisayaLanguage = await VocabLanguage.findOne({ where: { name: 'Bisaya' } });
|
|
|
|
if (!bisayaLanguage) {
|
|
console.error('❌ Bisaya-Sprache nicht gefunden.');
|
|
return;
|
|
}
|
|
|
|
// Hole alle Bisaya-Kurse
|
|
const courses = await VocabCourse.findAll({
|
|
where: { languageId: bisayaLanguage.id },
|
|
attributes: ['id', 'title', 'nativeLanguageId']
|
|
});
|
|
|
|
// Hole native language info für jeden Kurs
|
|
const coursesWithNativeLang = await Promise.all(
|
|
courses.map(async (course) => {
|
|
let nativeLanguage = null;
|
|
if (course.nativeLanguageId) {
|
|
nativeLanguage = await VocabLanguage.findByPk(course.nativeLanguageId);
|
|
}
|
|
return {
|
|
...course.get({ plain: true }),
|
|
nativeLanguage: nativeLanguage ? nativeLanguage.get({ plain: true }) : null
|
|
};
|
|
})
|
|
);
|
|
|
|
console.log(`📚 Gefunden: ${courses.length} Bisaya-Kurse\n`);
|
|
|
|
let totalExercisesCreated = 0;
|
|
let totalLessonsProcessed = 0;
|
|
|
|
for (const course of coursesWithNativeLang) {
|
|
console.log(`📖 Kurs: ${course.title} (ID: ${course.id})`);
|
|
|
|
// Finde native language name
|
|
const nativeLanguageName = course.nativeLanguage?.name || 'Deutsch';
|
|
console.log(` Muttersprache: ${nativeLanguageName}`);
|
|
|
|
// Finde "Familien-Gespräche" Lektion
|
|
const lessons = await VocabCourseLesson.findAll({
|
|
where: {
|
|
courseId: course.id,
|
|
title: 'Familien-Gespräche'
|
|
},
|
|
attributes: ['id', 'title', 'lessonNumber']
|
|
});
|
|
|
|
console.log(` ${lessons.length} "Familien-Gespräche"-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 = createFamilyConversationExercises(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} "Familien-Gespräche"-Lektion(en) verarbeitet`);
|
|
console.log(` ${totalExercisesCreated} Grammatik-Übungen erstellt`);
|
|
}
|
|
|
|
updateFamilyConversationExercises()
|
|
.then(() => {
|
|
sequelize.close();
|
|
process.exit(0);
|
|
})
|
|
.catch((error) => {
|
|
console.error('❌ Fehler:', error);
|
|
sequelize.close();
|
|
process.exit(1);
|
|
});
|