From 9b9afac66e070cae4ed219ef5fca64e76243f8be Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 22 May 2026 15:15:26 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20f=C3=BCge=20neue=20=C3=9Cbungen=20zur?= =?UTF-8?q?=20Lektion=20"Kinder,=20Spiel=20&=20Routine"=20hinzu,=20einschl?= =?UTF-8?q?ie=C3=9Flich=20L=C3=BCckenf=C3=BCllung=20und=20Satzreihenfolge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/scripts/bisaya-course-plan-24-43.js | 156 +++++++++++++++++- .../scripts/create-bisaya-course-content.js | 52 ++++++ 2 files changed, 200 insertions(+), 8 deletions(-) diff --git a/backend/scripts/bisaya-course-plan-24-43.js b/backend/scripts/bisaya-course-plan-24-43.js index 854895b..8498186 100644 --- a/backend/scripts/bisaya-course-plan-24-43.js +++ b/backend/scripts/bisaya-course-plan-24-43.js @@ -9,6 +9,7 @@ const BISAYA_LESSONS_24_43_BASE = [ { week: 3, day: 4, num: 31, type: 'vocab', title: 'Kinder, Spiel & Routine', desc: 'Kinderalltag mit Spielen, Fertigsein und Schlaf verbinden', targetMin: 20, targetScore: 85, review: true, cultural: null }, { week: 3, day: 5, num: 32, type: 'review', title: 'Woche 3 - Intensivwiederholung', desc: 'Gefühle, Gesundheit, Kinder und Höflichkeit kontrastieren', targetMin: 30, targetScore: 82, review: false, cultural: null }, { week: 3, day: 5, num: 33, type: 'vocab', title: 'Woche 3 - Checkpoint', desc: 'Aktiver Checkpoint zur ersten Alltagserweiterung', targetMin: 18, targetScore: 84, review: true, cultural: null }, + { week: 3, day: 5, num: 44, type: 'vocab', title: 'Zahlen & Zählen (Woche 3)', desc: 'Gezielte Zählübungen 1–20 und runde Zahlen', targetMin: 14, targetScore: 85, review: true, cultural: null }, { week: 4, day: 1, num: 34, type: 'conversation', title: 'Alltagsszene: Zuhause morgens', desc: 'Morgens zuhause über Aufstehen, Essen, Schule und Aufgaben sprechen', targetMin: 22, targetScore: 78, review: false, cultural: 'Morgenszenen verbinden Fürsorge, Zeit und Familienorganisation.' }, { week: 4, day: 1, num: 35, type: 'review', title: 'Spiralreview: Woche 1-2 im Alltag', desc: 'Grundlagen aus Begrüßung, Familie, Essen, Zeit und Zahlen in Alltagsszenen anwenden', targetMin: 28, targetScore: 84, review: false, cultural: null }, { week: 4, day: 2, num: 36, type: 'conversation', title: 'Alltagsszene: Besuch am Nachmittag', desc: 'Besuch empfangen, hereinbitten und etwas anbieten', targetMin: 22, targetScore: 78, review: false, cultural: 'Gastfreundschaft ist oft praktischer als formelle Höflichkeit.' }, @@ -19,6 +20,7 @@ const BISAYA_LESSONS_24_43_BASE = [ { week: 4, day: 4, num: 41, type: 'vocab', title: 'Abschlusstest Wortschatz aktiv', desc: 'Kernwortschatz der Grundphase in beide Richtungen abrufen', targetMin: 20, targetScore: 84, review: true, cultural: null }, { week: 4, day: 5, num: 42, type: 'review', title: 'Abschlussprüfung Grundphase', desc: 'Dialog, Wortschatz und freie Mini-Antworten der Grundphase prüfen', targetMin: 32, targetScore: 84, review: false, cultural: 'Die Prüfung misst Verständlichkeit und Handlungssicherheit, nicht perfekte Grammatik.' }, { week: 4, day: 5, num: 43, type: 'culture', title: 'Kultur: Höflichkeit, Familie, Alltag', desc: 'Respekt, indirekte Bitte und Familiennähe sprachlich einordnen', targetMin: 16, targetScore: 0, review: false, cultural: 'Kulturelles Verständnis hilft, Sätze passend und nicht nur wörtlich zu verwenden.' } + ,{ week: 4, day: 5, num: 45, type: 'vocab', title: 'Zahlen & Zählen (Woche 4)', desc: 'Wiederholung der Kernzahlen und Anwendung in Preisen', targetMin: 14, targetScore: 85, review: true, cultural: null } ]; const BISAYA_LESSON_24_43_TARGET_MINUTES = { @@ -42,6 +44,9 @@ const BISAYA_LESSON_24_43_TARGET_MINUTES = { 41: 24, 42: 38, 43: 22 + , + 44: 14, + 45: 14 }; export const BISAYA_LESSONS_24_43 = BISAYA_LESSONS_24_43_BASE.map((lesson) => ({ @@ -187,7 +192,13 @@ const BISAYA_DIDACTICS_24_43_ENRICHMENTS = { { target: 'Ayaw kalimot.', gloss: 'Vergiss es nicht.' }, { target: 'Hugas sa kamot.', gloss: 'Wasch dir die Hände.' }, { target: 'Kumusta imong tulog?', gloss: 'Wie hast du geschlafen?' }, - { target: 'Patya ang suga.', gloss: 'Mach das Licht aus.' } + { target: 'Patya ang suga.', gloss: 'Mach das Licht aus.' }, + { target: 'Magdula ta', gloss: 'Lass uns spielen.' }, + { target: 'Matulog na ta.', gloss: 'Jetzt schlafen wir.' }, + { target: 'Nikaon na ka?', gloss: 'Hast du schon gegessen?' }, + { target: 'Andam na ka?', gloss: 'Bist du fertig / bereit?' }, + { target: 'Kuhaa imong bag.', gloss: 'Hol deine Tasche.' }, + { target: 'Ayaw pagdali.', gloss: 'Beeil dich nicht / Kein Stress.' } ], grammarFocus: [ { title: 'Routineketten', text: 'Routinen bestehen aus kurzen Handlungsaufforderungen in fester Reihenfolge.', example: 'Hugas sa kamot. Matulog na ta. Patya ang suga.' } @@ -197,20 +208,50 @@ const BISAYA_DIDACTICS_24_43_ENRICHMENTS = { corePatterns: [ { target: 'Naa ra ko diri.', gloss: 'Ich bin hier.' }, { target: 'Hugas sa kamot.', gloss: 'Wasch dir die Hände.' }, - { target: 'Balika palihug.', gloss: 'Wiederhole es bitte.' } + { target: 'Balika palihug.', gloss: 'Wiederhole es bitte.' }, + { target: 'Gimingaw ko nimo.', gloss: 'Ich vermisse dich.' }, + { target: 'Sakit pa?', gloss: 'Tut es noch weh?' }, + { target: 'Andam na ka?', gloss: 'Bist du fertig / bereit?' }, + { target: 'Ayaw pagdali.', gloss: 'Beeil dich nicht / Kein Stress.' }, + { target: 'Palihug.', gloss: 'Bitte.' }, + { target: 'Hinay-hinay lang.', gloss: 'Bitte langsam.' }, + { target: 'Kuhaa imong bag.', gloss: 'Hol deine Tasche.' } ], speakingPrompts: [ - { title: 'Acht schnelle Antworten', prompt: 'Reagiere auf acht gemischte Situationen aus Gefühl, Gesundheit, Kind und Verständnisproblem.', cue: 'Naa ra ko diri. Sakit pa? Hugas sa kamot. Balika palihug.' } + { title: 'Acht schnelle Antworten', prompt: 'Reagiere auf acht gemischte Situationen aus Gefühl, Gesundheit, Kind und Verständnisproblem.', cue: 'Naa ra ko diri. Sakit pa? Hugas sa kamot. Balika palihug.' }, + { title: 'Schnelle Routine-Antworten', prompt: 'Gib in drei kurzen Sätzen eine Abendroutine-Anweisung für ein Kind.', cue: 'Kuhaa imong bag. Hugas sa kamot. Matulog na ta.' }, + { title: 'Fürsorge-Kurzdialog', prompt: 'Antworte auf eine kurze Sorge mit zwei fürsorglichen Sätzen.', cue: 'Sakit pa? Magpahuway sa. Naa ra ko diri.' } + ], + practicalTasks: [ + { title: '8× Rapid-Response', text: 'Ziehe acht Karten mit Situationen (Gefühl/Gesundheit/Kind/Bitte) und antworte jeweils spontan mit einem Satz.' }, + { title: 'Routinekette', text: 'Bilde drei verschiedene Routineketten (z. B. Spiel → Abendessen → Hände waschen → Schlafen) und sprich jede als fließende Abfolge.' } ] }, 'Woche 3 - Checkpoint': { corePatterns: [ - { target: 'Sakit pa?', gloss: 'Tut es noch weh?' }, - { target: 'Ayaw pagdali.', gloss: 'Kein Stress.' }, - { target: 'Pwede nimo isulat?', gloss: 'Kannst du es aufschreiben?' } + { target: 'Naguol ko gamay.', gloss: 'Ich bin ein bisschen besorgt.' }, + { target: 'Mas maayo na ka?', gloss: 'Geht es dir schon besser?' }, + { target: 'Pwede ko mangutana?', gloss: 'Darf ich fragen?' }, + { target: 'Ali diri.', gloss: 'Komm her.' }, + { target: 'Magdula ta.', gloss: 'Lass uns spielen.' }, + { target: 'Amping kanunay.', gloss: 'Pass immer auf dich auf.' }, + { target: 'Maayong gabii.', gloss: 'Guten Abend.' }, + { target: 'Katulog og maayo.', gloss: 'Schlaf gut.' }, + { target: 'Hugas sa kamot.', gloss: 'Wasch dir die Hände.' }, + { target: 'Balika palihug.', gloss: 'Wiederhole es bitte.' } ], grammarFocus: [ - { title: 'Checkpoint als Diagnose', text: 'Der Checkpoint soll zeigen, ob du spontan reagieren kannst, nicht nur wiedererkennst.', example: 'Naguol ka? Naa ra ko diri.' } + { title: 'Checkpoint als Diagnose', text: 'Der Checkpoint soll zeigen, ob du spontan reagieren kannst, nicht nur wiedererkennst.', example: 'Naguol ka? Naa ra ko diri.' }, + { title: 'Kurzantworten + Folge', text: 'Kurzantwort + ein Folgeangebot (Hilfe, Ruhe, Routine) macht Antworten handlungsorientiert.', example: 'Sakit pa? Magpahuway sa.' } + ], + speakingPrompts: [ + { title: 'Freie Antwort', prompt: 'Eine nahe Person ist müde und traurig. Reagiere mit zwei fürsorglichen Sätzen.', cue: 'Magpahuway sa. Naa ra ko diri.' }, + { title: 'Kurzdialog (3 Sätze)', prompt: 'Begrüße, frage nach Befinden, biete Hilfe an.', cue: 'Maayong buntag. Sakit pa? Magpahuway sa.' }, + { title: 'Routineanweisung', prompt: 'Gib in zwei Sätzen klare Anweisungen für eine Abendroutine mit einem Kind.', cue: 'Kuhaa imong bag. Hugas sa kamot.' } + ], + practicalTasks: [ + { title: 'Selbstcheck', text: 'Markiere alle Sätze, die du ohne Lesen sagen kannst, und wiederhole die unsicheren sofort im SRS.' }, + { title: 'Mini‑Checkpoint', text: 'Führe mit einem Partner drei kurze Checkpoint‑Dialoge: Gesundheit, Kind, Bitte. Jeder Dialog 2–3 Sätze.' } ] }, 'Alltagsszene: Zuhause morgens': { @@ -800,9 +841,108 @@ const BISAYA_DIDACTICS_24_43_BASE = { } }; -export const BISAYA_DIDACTICS_24_43 = Object.fromEntries( +// Sichtbare Zähllektionen als eigene didaktische Einträge +const NUMBERS_DIDACTIC = { + learningGoals: [ + 'Zahlen bis 20 sicher abrufen.', + 'Runde Zahlen (30,40,..90,100) erkennen und nutzen.', + 'Große Zahlen (200, 1000, 2000) in Preisen und Mengen verstehen.' + ], + corePatterns: [ + { target: '1', gloss: 'eins' }, { target: '2', gloss: 'zwei' }, { target: '3', gloss: 'drei' }, { target: '4', gloss: 'vier' }, { target: '5', gloss: 'fünf' }, + { target: '6', gloss: 'sechs' }, { target: '7', gloss: 'sieben' }, { target: '8', gloss: 'acht' }, { target: '9', gloss: 'neun' }, { target: '10', gloss: 'zehn' }, + { target: '11', gloss: 'elf' }, { target: '12', gloss: 'zwölf' }, { target: '13', gloss: 'dreizehn' }, { target: '14', gloss: 'vierzehn' }, { target: '15', gloss: 'fünfzehn' }, + { target: '16', gloss: 'sechzehn' }, { target: '17', gloss: 'siebzehn' }, { target: '18', gloss: 'achtzehn' }, { target: '19', gloss: 'neunzehn' }, { target: '20', gloss: 'zwanzig' }, + { target: '30', gloss: 'dreißig' }, { target: '40', gloss: 'vierzig' }, { target: '50', gloss: 'fünfzig' }, { target: '60', gloss: 'sechzig' }, { target: '70', gloss: 'siebzig' }, + { target: '80', gloss: 'achtzig' }, { target: '90', gloss: 'neunzig' }, { target: '100', gloss: 'einhundert' }, { target: '200', gloss: 'zweihundert' }, + { target: '1000', gloss: 'tausend' }, { target: '2000', gloss: 'zweitausend' } + ], + speakingPrompts: [ + { title: 'Zähle bis 20', prompt: 'Zähle laut von 1 bis 20.' }, + { title: 'Preisangaben', prompt: 'Nenne den Preis in ganzen Zahlen, z.B. 50, 100, 2000.' } + ], + practicalTasks: [ + { title: 'Zähllektionen', text: 'Mindestens einmal pro Woche eine 3–5 Minuten Zählübung: 1–20, dann runde Zahlen.' } + ] +}; +BISAYA_DIDACTICS_24_43_BASE['Zahlen & Zählen (Woche 3)'] = mergeDidactics({}, NUMBERS_DIDACTIC); +BISAYA_DIDACTICS_24_43_BASE['Zahlen & Zählen (Woche 4)'] = mergeDidactics({}, NUMBERS_DIDACTIC); + +// Zusatz: Zahlen & Zählübungen (werden in Wochenaggregaten eingebunden) + +import { GERMAN_FOR_BISAYA_PHASE1_LESSONS, GERMAN_FOR_BISAYA_PHASE1_DIDACTICS } from './german-for-bisaya-phase1.js'; + +const BISAYA_DIDACTICS_24_43_INITIAL = Object.fromEntries( Object.entries(BISAYA_DIDACTICS_24_43_BASE).map(([title, didactics]) => [ title, mergeDidactics(didactics, BISAYA_DIDACTICS_24_43_ENRICHMENTS[title]) ]) ); + +function buildWeekAggregate(weekNum, targetTitle, perLessonOrPercent = 1) { + if (!BISAYA_LESSONS_24_43) return; + const lessonTitles = BISAYA_LESSONS_24_43 + .filter((l) => l.week === weekNum && l.type !== 'review' && !String(l.title).startsWith('Woche')) + .map((l) => l.title); + const germanLessonTitles = (GERMAN_FOR_BISAYA_PHASE1_LESSONS || []) + .filter((l) => l.week === weekNum && !String(l.title).startsWith('Woche')) + .map((l) => l.title); + const collected = []; + const seen = new Set(); + for (const t of [...lessonTitles, ...germanLessonTitles]) { + const did = BISAYA_DIDACTICS_24_43_INITIAL[t] || GERMAN_FOR_BISAYA_PHASE1_DIDACTICS?.[t]; + if (!did || !did.corePatterns) continue; + const totalPatterns = did.corePatterns.length || 0; + let take = perLessonOrPercent; + if (typeof perLessonOrPercent === 'number' && perLessonOrPercent > 0 && perLessonOrPercent < 1) { + take = Math.max(1, Math.ceil(totalPatterns * perLessonOrPercent)); + } + for (let i = 0; i < take && i < did.corePatterns.length; i++) { + const p = did.corePatterns[i]; + const key = typeof p === 'string' ? p : p.target; + if (!key || seen.has(key)) continue; + seen.add(key); + collected.push(p); + } + } + if (BISAYA_DIDACTICS_24_43_INITIAL[targetTitle]) { + BISAYA_DIDACTICS_24_43_INITIAL[targetTitle].corePatterns = mergePatternLists( + BISAYA_DIDACTICS_24_43_INITIAL[targetTitle].corePatterns || [], + collected + ); + } +} + +// Ensure Woche 3 review and checkpoint include (at least) one pattern per lesson +// Intensivwiederholung: sammeln wir ~60% der Muster pro Lektion +buildWeekAggregate(3, 'Woche 3 - Intensivwiederholung', 0.6); +// Checkpoint: kurze Diagnose, 1 Muster pro Lektion +buildWeekAggregate(3, 'Woche 3 - Checkpoint', 1); + +export const BISAYA_DIDACTICS_24_43 = BISAYA_DIDACTICS_24_43_INITIAL; + +// Merge number practice into Woche 3 and Woche 4 reviews/checkpoints so each week has counting +if (BISAYA_DIDACTICS_24_43['Woche 3 - Intensivwiederholung']) { + BISAYA_DIDACTICS_24_43['Woche 3 - Intensivwiederholung'] = mergeDidactics( + BISAYA_DIDACTICS_24_43['Woche 3 - Intensivwiederholung'], + NUMBERS_DIDACTIC + ); +} +if (BISAYA_DIDACTICS_24_43['Woche 3 - Checkpoint']) { + BISAYA_DIDACTICS_24_43['Woche 3 - Checkpoint'] = mergeDidactics( + BISAYA_DIDACTICS_24_43['Woche 3 - Checkpoint'], + NUMBERS_DIDACTIC + ); +} +if (BISAYA_DIDACTICS_24_43['Woche 4 - Intensivwiederholung']) { + BISAYA_DIDACTICS_24_43['Woche 4 - Intensivwiederholung'] = mergeDidactics( + BISAYA_DIDACTICS_24_43['Woche 4 - Intensivwiederholung'], + NUMBERS_DIDACTIC + ); +} +if (BISAYA_DIDACTICS_24_43['Woche 4 - Checkpoint']) { + BISAYA_DIDACTICS_24_43['Woche 4 - Checkpoint'] = mergeDidactics( + BISAYA_DIDACTICS_24_43['Woche 4 - Checkpoint'], + NUMBERS_DIDACTIC + ); +} diff --git a/backend/scripts/create-bisaya-course-content.js b/backend/scripts/create-bisaya-course-content.js index 3213c02..9c4c1ca 100644 --- a/backend/scripts/create-bisaya-course-content.js +++ b/backend/scripts/create-bisaya-course-content.js @@ -1367,6 +1367,57 @@ const BISAYA_EXERCISES = { } ], + // Lektion: Kinder, Spiel & Routine + 'Kinder, Spiel & Routine': [ + { + exerciseTypeId: 2, + title: 'Routinebefehl erkennen', + instruction: 'Wähle die richtige Bedeutung.', + questionData: { + type: 'multiple_choice', + question: 'Was bedeutet "Hugas sa kamot"?', + options: ['Wasch dir die Hände.', 'Hol deine Tasche.', 'Geh schlafen.', 'Iss zuerst.'] + }, + answerData: { type: 'multiple_choice', correctAnswer: 0 }, + explanation: '"Hugas sa kamot" ist eine typische Aufforderung zur Hygiene.' + }, + { + exerciseTypeId: 1, + title: 'Lücken: Morgenroutine', + instruction: 'Fülle die Lücken.', + questionData: { type: 'gap_fill', text: 'Kuhaa imong {gap}. Hugas sa {gap}.', gaps: 2 }, + answerData: { type: 'gap_fill', answers: ['bag', 'kamot'] }, + explanation: 'Tasche und Hände sind Kernwörter in Morgenroutinen.' + }, + { + exerciseTypeId: 3, + title: 'Routine Reihenfolge', + instruction: 'Ordne die Sätze zu einer natürlichen Reihenfolge.', + questionData: { + type: 'sentence_building', + question: 'Ordne: Hände waschen, Tasche holen, Licht aus, Schlafen.', + tokens: ['Kuhaa imong bag.', 'Hugas sa kamot.', 'Patya ang suga.', 'Matulog na ta.'] + }, + answerData: { correct: ['Kuhaa imong bag. Hugas sa kamot. Patya ang suga. Matulog na ta.'] }, + explanation: 'Typische Abfolge für Abend-/Morgenroutinen.' + }, + { + exerciseTypeId: 10, + title: 'Kind-Ansage', + instruction: 'Gib eine kurze, freundliche Anweisung.', + questionData: { + type: 'situational_response', + question: 'Du möchtest, dass ein Kind seine Tasche holt und sich die Hände wäscht.', + keywords: ['kuhaa', 'bag', 'hugas', 'kamot'] + }, + answerData: { + modelAnswer: 'Kuhaa imong bag. Hugas sa kamot.', + keywords: ['kuhaa', 'bag', 'hugas', 'kamot'] + }, + explanation: 'Kurze klare Sätze funktionieren bei Kindern am besten.' + } + ], + // Lektion 1: Begrüßungen & Höflichkeit 'Begrüßungen & Höflichkeit': [ { @@ -5908,6 +5959,7 @@ const PLACEHOLDER_REBUILD_TITLES = new Set([ 'Körper & Symptome', 'Höflichkeitsformen praktisch', 'Bitten & Nachfragen', + 'Kinder, Spiel & Routine', 'Kinder & Familie', 'Körper & Gesundheit', 'Höflichkeitsformen',