diff --git a/backend/scripts/create-bisaya-course-content.js b/backend/scripts/create-bisaya-course-content.js index 48a5c87..87ac683 100644 --- a/backend/scripts/create-bisaya-course-content.js +++ b/backend/scripts/create-bisaya-course-content.js @@ -13,7 +13,7 @@ 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 { BISAYA_DIDACTICS_24_43, BISAYA_RELATIONSHIP_ANCHOR_DIDACTICS } from './bisaya-course-plan-24-43.js'; +import { BISAYA_DIDACTICS_24_43, BISAYA_LESSONS_24_43_BY_NUMBER, BISAYA_RELATIONSHIP_ANCHOR_DIDACTICS } from './bisaya-course-plan-24-43.js'; import { BISAYA_PHASE3_DIDACTICS, BISAYA_PHASE3_LESSONS } from './bisaya-course-phase3-extension.js'; import { BISAYA_PHASE4_DIDACTICS, BISAYA_PHASE4_LESSONS } from './bisaya-course-phase4-extension.js'; import { BISAYA_PHASE5_DIDACTICS, BISAYA_PHASE5_LESSONS } from './bisaya-course-phase5-extension.js'; @@ -36,6 +36,14 @@ const GENERATED_BISAYA_DIDACTICS = { const SAFE_EXERCISE_UPDATE_TITLES = new Set([ 'Gefühle im Alltag', 'Gefühlswortschatz & Reaktionen', + 'Gesundheit & Wohlbefinden', + 'Körper & Symptome', + 'Höflichkeitsformen praktisch', + 'Bitten & Nachfragen', + 'Kinder & Familie', + 'Körper & Gesundheit', + 'Höflichkeitsformen', + 'Bitten & Fragen', ...BISAYA_PHASE3_LESSONS.map((lesson) => lesson.title), ...BISAYA_PHASE4_LESSONS.map((lesson) => lesson.title), ...BISAYA_PHASE5_LESSONS.map((lesson) => lesson.title) @@ -956,6 +964,394 @@ const BISAYA_EXERCISES = { } ], + // Lektion 26: Gesundheit & Wohlbefinden + 'Gesundheit & Wohlbefinden': [ + { + exerciseTypeId: 2, + title: 'Beschwerde erkennen', + instruction: 'Wähle die richtige Bedeutung.', + questionData: { + type: 'multiple_choice', + question: 'Was bedeutet "Sakit akong ulo."?', + options: ['Mein Kopf tut weh.', 'Mein Bauch tut weh.', 'Ich habe Fieber.', 'Ich bin müde.'] + }, + answerData: { + type: 'multiple_choice', + correctAnswer: 0 + }, + explanation: '"akong ulo" bedeutet "mein Kopf".' + }, + { + exerciseTypeId: 1, + title: 'Gesundheitsfrage ergänzen', + instruction: 'Fülle die Lücken mit den passenden Bisaya-Wörtern.', + questionData: { + type: 'gap_fill', + text: 'Sakit imong {gap}? Mas maayo na {gap}?', + gaps: 2 + }, + answerData: { + type: 'gap_fill', + answers: ['tiyan', 'ka'] + }, + explanation: '"Sakit imong tiyan?" fragt nach Bauchschmerzen; "ka" bezieht sich auf die andere Person.' + }, + { + exerciseTypeId: 4, + title: 'Fürsorge anbieten', + instruction: 'Übersetze ins Bisaya.', + questionData: { + type: 'transformation', + text: 'Ruh dich erst einmal aus. Trink Wasser.', + sourceLanguage: 'Deutsch', + targetLanguage: 'Bisaya' + }, + answerData: { + type: 'transformation', + correct: 'Magpahuway sa. Uminom og tubig.', + alternatives: ['Pahuway sa. Uminom og tubig.', 'Magpahuway usa. Uminom og tubig.'] + }, + explanation: 'Die beiden kurzen Sätze klingen fürsorglich und praktisch.' + }, + { + exerciseTypeId: 3, + title: 'Pflege-Mini-Dialog bauen', + instruction: 'Ordne die Sätze zu einem natürlichen Mini-Dialog.', + questionData: { + type: 'sentence_building', + question: 'Baue: Frage nach Schmerz, schlage Ruhe vor, frage nach Medizin.', + tokens: ['Sakit imong ulo?', 'Magpahuway sa.', 'Niinom ka og tambal?'] + }, + answerData: { + correct: ['Sakit imong ulo? Magpahuway sa. Niinom ka og tambal?'] + }, + explanation: 'Gesundheitssprache funktioniert gut in kurzen Abfolgen.' + }, + { + exerciseTypeId: 10, + title: 'Gesundheitssituation', + instruction: 'Antworte kurz und fürsorglich.', + questionData: { + type: 'situational_response', + question: 'Ein Kind sagt, dass der Kopf weh tut. Frage nach und biete Wasser oder Ruhe an.', + keywords: ['sakit', 'ulo', 'pahuway', 'tubig'] + }, + answerData: { + modelAnswer: 'Sakit imong ulo? Magpahuway sa. Uminom og tubig.', + keywords: ['sakit', 'ulo', 'pahuway', 'tubig'] + }, + explanation: 'Die Antwort fragt nach und gibt direkt eine einfache Pflegehandlung.' + } + ], + + // Lektion 27: Körper & Symptome + 'Körper & Symptome': [ + { + exerciseTypeId: 2, + title: 'Körperwort erkennen', + instruction: 'Wähle die richtige Bedeutung.', + questionData: { + type: 'multiple_choice', + question: 'Was bedeutet "tiyan"?', + options: ['Bauch', 'Kopf', 'Zahn', 'Husten'] + }, + answerData: { + type: 'multiple_choice', + correctAnswer: 0 + }, + explanation: '"tiyan" bedeutet "Bauch".' + }, + { + exerciseTypeId: 2, + title: 'Symptom erkennen', + instruction: 'Wähle die richtige Bedeutung.', + questionData: { + type: 'multiple_choice', + question: 'Was bedeutet "hilanat"?', + options: ['Fieber', 'Medizin', 'Schmerz', 'Arzt'] + }, + answerData: { + type: 'multiple_choice', + correctAnswer: 0 + }, + explanation: '"hilanat" bedeutet "Fieber".' + }, + { + exerciseTypeId: 1, + title: 'Symptom-Satz ergänzen', + instruction: 'Fülle die Lücke.', + questionData: { + type: 'gap_fill', + text: 'Sakit akong {gap}. (Mein Hals tut weh.)', + gaps: 1 + }, + answerData: { + type: 'gap_fill', + answers: ['tutunlan'] + }, + explanation: '"tutunlan" bedeutet "Hals / Kehle".' + }, + { + exerciseTypeId: 4, + title: 'Nach Medizin fragen', + instruction: 'Übersetze ins Bisaya.', + questionData: { + type: 'transformation', + text: 'Wo ist die Medizin?', + sourceLanguage: 'Deutsch', + targetLanguage: 'Bisaya' + }, + answerData: { + type: 'transformation', + correct: 'Asa ang tambal?', + alternatives: ['Hain ang tambal?'] + }, + explanation: '"tambal" ist das Kernwort für Medizin.' + } + ], + + // Lektion 28: Höflichkeitsformen praktisch + 'Höflichkeitsformen praktisch': [ + { + exerciseTypeId: 2, + title: 'Höfliche Bitte erkennen', + instruction: 'Wähle die richtige Bedeutung.', + questionData: { + type: 'multiple_choice', + question: 'Was bedeutet "Pwede ko mangutana?"?', + options: ['Darf ich fragen?', 'Kannst du warten?', 'Schon okay.', 'Danke fürs Verstehen.'] + }, + answerData: { + type: 'multiple_choice', + correctAnswer: 0 + }, + explanation: '"Pwede ko mangutana?" ist eine höfliche Erlaubnisfrage.' + }, + { + exerciseTypeId: 1, + title: 'Weich ablehnen', + instruction: 'Fülle die Lücken.', + questionData: { + type: 'gap_fill', + text: 'Dili lang sa {gap}. Sunod na {gap}.', + gaps: 2 + }, + answerData: { + type: 'gap_fill', + answers: ['karon', 'lang'] + }, + explanation: 'Die Kombination lehnt weich ab und bietet später an.' + }, + { + exerciseTypeId: 4, + title: 'Entschuldigung formulieren', + instruction: 'Übersetze ins Bisaya.', + questionData: { + type: 'transformation', + text: 'Entschuldige mich. Bitte wiederhole es.', + sourceLanguage: 'Deutsch', + targetLanguage: 'Bisaya' + }, + answerData: { + type: 'transformation', + correct: 'Pasayloa ko. Palihug ka mubalik?', + alternatives: ['Pasayloa ko. Balika palihug.', 'Pasayloa ko. Palihug balika.'] + }, + explanation: 'Erst entschuldigen, dann höflich um Wiederholung bitten.' + }, + { + exerciseTypeId: 10, + title: 'Höflich reagieren', + instruction: 'Antworte weich und höflich.', + questionData: { + type: 'situational_response', + question: 'Du möchtest jetzt lieber nicht. Lehn höflich ab und bedanke dich fürs Verständnis.', + keywords: ['dili', 'karon', 'salamat', 'pagsabot'] + }, + answerData: { + modelAnswer: 'Dili lang sa karon. Salamat sa pagsabot.', + keywords: ['dili', 'karon', 'salamat', 'pagsabot'] + }, + explanation: 'Diese Antwort bleibt klar, aber nicht hart.' + }, + { + exerciseTypeId: 11, + title: 'Höflichkeitsmuster üben', + instruction: 'Bilde eine höfliche Reparatur in zwei kurzen Sätzen.', + questionData: { + type: 'pattern_drill', + question: 'Entschuldige dich und bitte um Wiederholung.', + pattern: 'Pasayloa ko. ...', + prompt: 'Bitte wiederhole es.' + }, + answerData: { + modelAnswer: 'Pasayloa ko. Palihug ka mubalik?', + correct: ['Pasayloa ko. Palihug ka mubalik?', 'Pasayloa ko. Balika palihug.'] + }, + explanation: 'Das Muster ist besonders nützlich, wenn du etwas nicht verstanden hast.' + } + ], + + // Lektion 29: Bitten & Nachfragen + 'Bitten & Nachfragen': [ + { + exerciseTypeId: 2, + title: 'Verständnisproblem erkennen', + instruction: 'Wähle die richtige Bedeutung.', + questionData: { + type: 'multiple_choice', + question: 'Was bedeutet "Wala ko kasabot."?', + options: ['Ich verstehe nicht.', 'Bitte langsam.', 'Hilf mir bitte.', 'Was kommt als Nächstes?'] + }, + answerData: { + type: 'multiple_choice', + correctAnswer: 0 + }, + explanation: '"Wala ko kasabot" ist der wichtigste Satz bei Verständnisproblemen.' + }, + { + exerciseTypeId: 1, + title: 'Nachfragen ergänzen', + instruction: 'Fülle die Lücken.', + questionData: { + type: 'gap_fill', + text: 'Hinay-hinay {gap}. Unsay pasabot {gap}?', + gaps: 2 + }, + answerData: { + type: 'gap_fill', + answers: ['lang', 'ani'] + }, + explanation: 'Damit bittest du um langsamere Sprache und fragst nach Bedeutung.' + }, + { + exerciseTypeId: 4, + title: 'Um Hilfe bitten', + instruction: 'Übersetze ins Bisaya.', + questionData: { + type: 'transformation', + text: 'Hilf mir bitte.', + sourceLanguage: 'Deutsch', + targetLanguage: 'Bisaya' + }, + answerData: { + type: 'transformation', + correct: 'Tabangi ko, palihug.', + alternatives: ['Tabangi ko palihug.', 'Palihug tabangi ko.'] + }, + explanation: '"palihug" macht die Bitte höflicher.' + }, + { + exerciseTypeId: 3, + title: 'Reparaturdialog bauen', + instruction: 'Ordne die Sätze zu einer sinnvollen Reihenfolge.', + questionData: { + type: 'sentence_building', + question: 'Baue: Nicht verstehen, langsam bitten, Bedeutung fragen.', + tokens: ['Wala ko kasabot.', 'Hinay-hinay lang.', 'Unsay pasabot ani?'] + }, + answerData: { + correct: ['Wala ko kasabot. Hinay-hinay lang. Unsay pasabot ani?'] + }, + explanation: 'Diese Reihenfolge löst viele echte Gesprächsprobleme.' + }, + { + exerciseTypeId: 10, + title: 'Nachfragen in der Situation', + instruction: 'Reagiere auf ein Verständnisproblem.', + questionData: { + type: 'situational_response', + question: 'Jemand spricht zu schnell. Sag, dass du nicht verstehst, und bitte um langsames Wiederholen.', + keywords: ['wala', 'kasabot', 'hinay', 'mubalik'] + }, + answerData: { + modelAnswer: 'Wala ko kasabot. Hinay-hinay lang. Palihug ka mubalik?', + keywords: ['wala', 'kasabot', 'hinay', 'mubalik'] + }, + explanation: 'Du signalisierst das Problem und gibst direkt die gewünschte Lösung.' + } + ], + + // Lektion 30: Kinder & Familie + 'Kinder & Familie': [ + { + exerciseTypeId: 2, + title: 'Kinderfrage erkennen', + instruction: 'Wähle die richtige Bedeutung.', + questionData: { + type: 'multiple_choice', + question: 'Was bedeutet "Andam na ka?"?', + options: ['Bist du fertig?', 'Wo ist deine Tasche?', 'Hast du gegessen?', 'Komm her.'] + }, + answerData: { + type: 'multiple_choice', + correctAnswer: 0 + }, + explanation: '"Andam na ka?" fragt, ob jemand bereit oder fertig ist.' + }, + { + exerciseTypeId: 1, + title: 'Kindersatz ergänzen', + instruction: 'Fülle die Lücken.', + questionData: { + type: 'gap_fill', + text: 'Asa imong {gap}? Kuhaa imong {gap}.', + gaps: 2 + }, + answerData: { + type: 'gap_fill', + answers: ['bag', 'bag'] + }, + explanation: 'Die Tasche ist ein typisches Wort in Schul- und Morgenroutinen.' + }, + { + exerciseTypeId: 4, + title: 'Essen fragen', + instruction: 'Übersetze ins Bisaya.', + questionData: { + type: 'transformation', + text: 'Hast du schon gegessen?', + sourceLanguage: 'Deutsch', + targetLanguage: 'Bisaya' + }, + answerData: { + type: 'transformation', + correct: 'Nikaon na ka?', + alternatives: ['Nakaon na ka?'] + }, + explanation: 'Das ist eine sehr häufige fürsorgliche Familienfrage.' + }, + { + exerciseTypeId: 3, + title: 'Morgenszene bauen', + instruction: 'Ordne die Sätze zu einer kurzen Szene.', + questionData: { + type: 'sentence_building', + question: 'Baue: Komm her, frag nach Essen, frag nach Tasche, frag ob fertig.', + tokens: ['Ali diri.', 'Nikaon na ka?', 'Asa imong bag?', 'Andam na ka?'] + }, + answerData: { + correct: ['Ali diri. Nikaon na ka? Asa imong bag? Andam na ka?'] + }, + explanation: 'Die Szene bleibt kurz und funktioniert im Alltag mit Kindern.' + }, + { + exerciseTypeId: 10, + title: 'Kind ansprechen', + instruction: 'Reagiere mit kurzen klaren Sätzen.', + questionData: { + type: 'situational_response', + question: 'Vor der Schule soll ein Kind Tasche holen und fertig werden. Sprich freundlich und klar.', + keywords: ['kuhaa', 'bag', 'andam'] + }, + answerData: { + modelAnswer: 'Kuhaa imong bag. Andam na ka?', + keywords: ['kuhaa', 'bag', 'andam'] + }, + explanation: 'Kurze Sätze sind in Kindersituationen natürlicher.' + } + ], + // Lektion 1: Begrüßungen & Höflichkeit 'Begrüßungen & Höflichkeit': [ { @@ -5413,6 +5809,14 @@ const PLACEHOLDER_REBUILD_TITLES = new Set([ 'Gefühle & Emotionen', 'Gefühle im Alltag', 'Gefühlswortschatz & Reaktionen', + 'Gesundheit & Wohlbefinden', + 'Körper & Symptome', + 'Höflichkeitsformen praktisch', + 'Bitten & Nachfragen', + 'Kinder & Familie', + 'Körper & Gesundheit', + 'Höflichkeitsformen', + 'Bitten & Fragen', 'Familie - Verwandte & Stieffamilie', 'Rollenspiele - echte Situationen' ]); @@ -5444,6 +5848,10 @@ function getExercisesForLesson(lesson) { return BISAYA_EXERCISES['Gefühlswortschatz & Reaktionen']; } } + const plannedTitle = BISAYA_LESSONS_24_43_BY_NUMBER[Number(lesson.lessonNumber)]?.title; + if (plannedTitle && BISAYA_EXERCISES[plannedTitle]) { + return BISAYA_EXERCISES[plannedTitle]; + } // Suche nach exaktem Titel if (BISAYA_EXERCISES[lessonTitle]) { return BISAYA_EXERCISES[lessonTitle]; @@ -5508,6 +5916,21 @@ async function createBisayaCourseContent() { console.log(` ${lessons.length} Lektionen gefunden\n`); for (const lesson of lessons) { + const plannedLesson = BISAYA_LESSONS_24_43_BY_NUMBER[Number(lesson.lessonNumber)]; + if (plannedLesson) { + await lesson.update({ + title: plannedLesson.title, + description: plannedLesson.desc, + weekNumber: plannedLesson.week, + dayNumber: plannedLesson.day, + lessonType: plannedLesson.type, + culturalNotes: plannedLesson.cultural, + targetMinutes: plannedLesson.targetMin, + targetScorePercent: plannedLesson.targetScore, + requiresReview: plannedLesson.review + }); + } + const exercises = getExercisesForLesson(lesson); if (exercises.length === 0) { const existingCount = await VocabGrammarExercise.count({ where: { lessonId: lesson.id } }); diff --git a/backend/scripts/update-bisaya-didactics.js b/backend/scripts/update-bisaya-didactics.js index ca174f7..37cfde1 100644 --- a/backend/scripts/update-bisaya-didactics.js +++ b/backend/scripts/update-bisaya-didactics.js @@ -23,7 +23,9 @@ import { BISAYA_PHASE4_DIDACTICS } from './bisaya-course-phase4-extension.js'; export const LEGACY_DIDACTICS_TITLE_MAP = { 'Zahlen & Preise': 'Zahlen 1–20', 'Gefühle & Emotionen': 'Gefühle im Alltag', + 'Körper & Gesundheit': 'Körper & Symptome', 'Höflichkeitsformen': 'Höflichkeitsformen praktisch', + 'Bitten & Fragen': 'Bitten & Nachfragen', 'Kinder & Spiel': 'Kinder, Spiel & Routine', 'Woche 3 - Wiederholung': 'Woche 3 - Intensivwiederholung', 'Woche 3 - Vokabeltest': 'Woche 3 - Checkpoint', diff --git a/backend/services/vocabService.js b/backend/services/vocabService.js index d7e9aaa..1610413 100644 --- a/backend/services/vocabService.js +++ b/backend/services/vocabService.js @@ -730,6 +730,26 @@ export default class VocabService { if (content) variants.add(content); }); + // Splitte auf Schrägstriche, Semikolons oder Pipes, damit z.B. "A / B" als "A" und "B" gilt + const slashParts = raw.split(/\s*[\/|;]\s*/); + if (slashParts.length > 1) { + slashParts.forEach((p) => { + const pp = String(p || '').trim(); + if (pp) variants.add(pp); + }); + } + + // Auch Varianten trennen, die mit '/' in der ohneParentheses-Version vorkommen + if (withoutParentheses) { + const parts2 = withoutParentheses.split(/\s*[\/|;]\s*/); + if (parts2.length > 1) { + parts2.forEach((p) => { + const pp = String(p || '').trim(); + if (pp) variants.add(pp); + }); + } + } + return Array.from(variants); }