feat(bisaya-course): enhance phase 4 didactics with new learning goals and speaking prompts
All checks were successful
Deploy to production / deploy (push) Successful in 1m31s

- Expanded the BISAYA_PHASE4_DIDACTICS by adding new learning goals, core patterns, speaking prompts, and practical tasks to improve language acquisition.
- Updated the course content generation scripts to incorporate the new lesson structures and ensure alignment with the latest didactic updates.
- Enhanced the logic for generating exercises based on lesson types, introducing additional situational and speaking exercises for advanced lessons.
This commit is contained in:
Torsten Schulz (local)
2026-04-17 15:12:21 +02:00
parent 4df8f97a41
commit 4205639de3
10 changed files with 599 additions and 69 deletions

View File

@@ -3,14 +3,36 @@ export const BISAYA_PHASE4_DIDACTICS = {
learningGoals: [
'Über Kinder im Familienalltag sprechen.',
'Einfache Fragen zu Hunger, Müdigkeit und Schule stellen.',
'Kurze Fürsorge-Dialoge mit Kindern laut üben.'
'Kurze Fürsorge-Dialoge mit Kindern laut üben.',
'Kinderroutinen mit kurzen Handlungsaufforderungen strukturieren.'
],
corePatterns: [
{ target: 'Nikaon na ka?', gloss: 'Hast du schon gegessen?' },
{ target: 'Kapoy na ka?', gloss: 'Bist du schon müde?' },
{ target: 'Andam na ka sa eskwela?', gloss: 'Bist du bereit für die Schule?' },
{ target: 'Asa ang bata?', gloss: 'Wo ist das Kind?' },
{ target: 'Ali diri.', gloss: 'Komm her.' },
{ target: 'Ayaw pagdali.', gloss: 'Kein Stress / Beeil dich nicht.' },
{ target: 'Kuhaa imong bag.', gloss: 'Hol deine Tasche.' },
{ target: 'Hugas sa kamot.', gloss: 'Wasch dir die Hände.' },
{ target: 'Matulog na ta.', gloss: 'Lass uns schlafen gehen.' }
],
corePatterns: ['Nikaon na ang bata?', 'Asa ang bata?', 'Kapoy na ka?', 'Andam na ka sa eskwela?'],
speakingPrompts: [
{
title: 'Mit Kind sprechen',
prompt: 'Frage ein Kind nach Essen, Müdigkeit und Schule.',
cue: 'Nikaon na ka? Kapoy na ka?'
},
{
title: 'Morgen mit Kind',
prompt: 'Baue eine kurze Morgenroutine mit Tasche und Losgehen.',
cue: 'Ali diri. Kuhaa imong bag. Andam na ka sa eskwela?'
}
],
practicalTasks: [
{
title: 'Routine in 5 Saetzen',
text: 'Sprich eine Routine mit fuenf kurzen Saetzen (Essen, Tasche, Haende, Schule, Losgehen).'
}
]
},
@@ -20,7 +42,30 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Über Tasche, Hefte, Lehrkraft und Unterricht sprechen.',
'Kinder- und Schulwortschatz mit Familienalltag verbinden.'
],
corePatterns: ['eskwela', 'maestra', 'bag', 'leksyon']
corePatterns: [
{ target: 'eskwela', gloss: 'Schule' },
{ target: 'maestra', gloss: 'Lehrerin' },
{ target: 'maestro', gloss: 'Lehrer' },
{ target: 'bag', gloss: 'Tasche' },
{ target: 'leksyon', gloss: 'Lektion / Unterricht' },
{ target: 'assignment', gloss: 'Hausaufgabe' },
{ target: 'libro', gloss: 'Buch' },
{ target: 'lapis', gloss: 'Stift' },
{ target: 'Asa imong bag?', gloss: 'Wo ist deine Tasche?' }
],
speakingPrompts: [
{
title: 'Schulsachen',
prompt: 'Frage nach Tasche und Buch und sage, dass Schule gleich losgeht.',
cue: 'Asa imong bag? Asa ang libro? Andam na ta sa eskwela.'
}
],
practicalTasks: [
{
title: 'Zeige und sage',
text: 'Nenne vier Schulsachen und bilde je einen kurzen Satz oder eine Frage dazu.'
}
]
},
'Fragen an Kinder vereinfachen': {
learningGoals: [
@@ -28,13 +73,35 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Aufforderungen und Fragen freundlich unterscheiden.',
'Kindgerechte Alltagsmuster wiederholt anwenden.'
],
corePatterns: ['Unsa ni?', 'Asa imong bag?', 'Andam na ka?', 'Ali diri.'],
corePatterns: [
{ target: 'Unsa ni?', gloss: 'Was ist das?' },
{ target: 'Asa ni?', gloss: 'Wo ist das?' },
{ target: 'Kinsa ni?', gloss: 'Wer ist das?' },
{ target: 'Asa imong bag?', gloss: 'Wo ist deine Tasche?' },
{ target: 'Andam na ka?', gloss: 'Bist du fertig?' },
{ target: 'Ganahan ka?', gloss: 'Moechtest du?' },
{ target: 'Ali diri.', gloss: 'Komm her.' },
{ target: 'Ayaw.', gloss: 'Nicht (tu das nicht).' }
],
grammarFocus: [
{
title: 'Kurze Fragen',
text: 'Mit Kindern funktionieren kurze, klare Fragen oft besser als lange Sätze.',
example: 'Asa imong bag? Andam na ka?'
}
],
speakingPrompts: [
{
title: 'Vier Kurzfragen',
prompt: 'Stelle vier kurze Kinderfragen hintereinander.',
cue: 'Unsa ni? Asa ni? Andam na ka? Asa imong bag?'
}
],
practicalTasks: [
{
title: 'Frage oder Aufforderung',
text: 'Forme drei deutsche Saetze einmal als Frage und einmal als kurze Aufforderung auf Bisaya.'
}
]
},
'Hausaufgaben & Routine': {
@@ -43,7 +110,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Einfachen Tagesablauf mit Schule und Zuhause verbinden.',
'Kurze Organisationsgespräche führen.'
],
corePatterns: ['Naa kay assignment?', 'Human na ka?', 'Magtuon ta.', 'Sunod, matulog na.']
corePatterns: [
{ target: 'Naa kay assignment?', gloss: 'Hast du Hausaufgaben?' },
{ target: 'Human na ka?', gloss: 'Bist du fertig?' },
{ target: 'Wala pa ko nahuman.', gloss: 'Ich bin noch nicht fertig.' },
{ target: 'Magtuon ta.', gloss: 'Lass uns lernen.' },
{ target: 'Sunod, matulog na ta.', gloss: 'Danach gehen wir schlafen.' },
{ target: 'Ayaw sa ug dula.', gloss: 'Spiel erst mal nicht.' },
{ target: 'Pagkahuman, magdula ta.', gloss: 'Danach spielen wir.' },
{ target: 'Tabangi ko, palihug.', gloss: 'Hilf mir bitte.' }
],
speakingPrompts: [
{
title: 'Hausaufgaben-Dialog',
prompt: 'Frage nach Hausaufgaben, ob das Kind fertig ist, und mache eine Routineansage.',
cue: 'Naa kay assignment? Human na ka? Sunod, matulog na ta.'
}
],
practicalTasks: [
{
title: 'Routinekette',
text: 'Sprich eine Kette mit Lernen, Aufgabe, Hilfe, Spielen und Schlafen.'
}
]
},
'Woche 7 - Intensivwiederholung I': {
learningGoals: [
@@ -51,7 +140,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Frühere Fürsorgeformen mit Schulalltag verbinden.',
'Schneller zwischen Themen wechseln.'
],
corePatterns: ['Nikaon na ka?', 'Asa ang bata?', 'Magtuon ta.', 'Palihug lingkod.']
corePatterns: [
{ target: 'Nikaon na ka?', gloss: 'Hast du schon gegessen?' },
{ target: 'Asa ang bata?', gloss: 'Wo ist das Kind?' },
{ target: 'Andam na ka?', gloss: 'Bist du fertig?' },
{ target: 'Asa imong bag?', gloss: 'Wo ist deine Tasche?' },
{ target: 'Magtuon ta.', gloss: 'Lass uns lernen.' },
{ target: 'Hugas sa kamot.', gloss: 'Wasch dir die Haende.' },
{ target: 'Pagkahuman, magdula ta.', gloss: 'Danach spielen wir.' },
{ target: 'Sunod, matulog na ta.', gloss: 'Danach gehen wir schlafen.' }
],
speakingPrompts: [
{
title: 'Schnelle Rollenwechsel',
prompt: 'Wechsle zwischen Betreuung, Schule und Routine in kurzen Antworten.',
cue: 'Asa imong bag? Andam na ka? Magtuon ta. Sunod, matulog na ta.'
}
],
practicalTasks: [
{
title: '8 Situationen',
text: 'Beantworte acht Situationen: Hunger, Tasche, Haende, Hausaufgaben, Spielen, Schlafen.'
}
]
},
'Spiralwiederholung - Familie, Kinder & Fürsorge': {
learningGoals: [
@@ -59,7 +170,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Bekannte Kernwörter schneller abrufen.',
'Alte Inhalte in neuen Situationen festigen.'
],
corePatterns: ['Nanay', 'Tatay', 'bata', 'eskwela']
corePatterns: [
{ target: 'Nanay', gloss: 'Mutter' },
{ target: 'Tatay', gloss: 'Vater' },
{ target: 'bata', gloss: 'Kind' },
{ target: 'pamilya', gloss: 'Familie' },
{ target: 'eskwela', gloss: 'Schule' },
{ target: 'tabang', gloss: 'Hilfe' },
{ target: 'Kapoy na ka?', gloss: 'Bist du muede?' },
{ target: 'Ayaw kabalaka.', gloss: 'Mach dir keine Sorgen.' }
],
speakingPrompts: [
{
title: 'Familien-Fuersorge',
prompt: 'Sprich zwei kurze Fuersorgesetze zu Kind und Schule.',
cue: 'Ayaw kabalaka. Andam na ka sa eskwela?'
}
],
practicalTasks: [
{
title: 'Spiralabruf',
text: 'Nimm vier alte Woerter (Nanay/Tatay/bata/eskwela) und baue vier kurze Saetze.'
}
]
},
'Spielen & Freizeit': {
learningGoals: [
@@ -67,7 +200,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Kinder zu Spiel und Pause begleiten.',
'Leichte Alltagsdialoge mit Bewegung verbinden.'
],
corePatterns: ['Magdula ta.', 'Ganahan ka modula?', 'Lingaw ka?', 'Human na ang duwa.']
corePatterns: [
{ target: 'Magdula ta.', gloss: 'Lass uns spielen.' },
{ target: 'Ganahan ka modula?', gloss: 'Moechtest du spielen?' },
{ target: 'Lingaw ka?', gloss: 'Hast du Spass?' },
{ target: 'Human na ang duwa.', gloss: 'Das Spiel ist vorbei.' },
{ target: 'Pahuway sa.', gloss: 'Mach erst mal Pause.' },
{ target: 'Dali na.', gloss: 'Komm, beeil dich.' },
{ target: 'Ayaw pag-away.', gloss: 'Streitet nicht.' },
{ target: 'Pag-ampo sa.', gloss: 'Bete erst mal.' }
],
speakingPrompts: [
{
title: 'Freizeit mit Regeln',
prompt: 'Biete Spiel an, mache eine Pauseansage und stoppe Streit freundlich.',
cue: 'Magdula ta. Pahuway sa. Ayaw pag-away.'
}
],
practicalTasks: [
{
title: '3 Mini-Dialoge',
text: 'Sprich drei Mini-Dialoge: anfangen, stoppen, Pause.'
}
]
},
'Spielsachen & Aktivitäten': {
learningGoals: [
@@ -75,7 +230,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Aktivitäten benennen und vergleichen.',
'Kinderalltag mit neuen Nomen anreichern.'
],
corePatterns: ['duwa', 'bola', 'libro', 'kanta']
corePatterns: [
{ target: 'duwa', gloss: 'Spiel' },
{ target: 'bola', gloss: 'Ball' },
{ target: 'libro', gloss: 'Buch' },
{ target: 'kanta', gloss: 'Lied' },
{ target: 'sayaw', gloss: 'Tanz' },
{ target: 'drawing', gloss: 'Malen/Zeichnen' },
{ target: 'Ganahan ka ani?', gloss: 'Magst du das?' },
{ target: 'Pilia.', gloss: 'Waehle.' }
],
speakingPrompts: [
{
title: 'Auswahl anbieten',
prompt: 'Biete zwei Aktivitaeten an und lasse das Kind waehlen.',
cue: 'Ganahan ka og kanta o sayaw? Pilia.'
}
],
practicalTasks: [
{
title: 'Wortschatz aktiv',
text: 'Nenne sechs Spielsachen/Aktivitaeten und bilde zwei kurze Fragen dazu.'
}
]
},
'Woche 7 - Intensivwiederholung II': {
learningGoals: [
@@ -83,7 +260,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Schwierige Formen gezielt wiederholen.',
'Mehr Sicherheit in Alltagsszenen mit Kindern gewinnen.'
],
corePatterns: ['Andam na ka?', 'Magdula ta.', 'Human na ka?', 'Asa imong bag?']
corePatterns: [
{ target: 'Andam na ka?', gloss: 'Bist du fertig?' },
{ target: 'Asa imong bag?', gloss: 'Wo ist deine Tasche?' },
{ target: 'Magdula ta.', gloss: 'Lass uns spielen.' },
{ target: 'Human na ka?', gloss: 'Bist du fertig?' },
{ target: 'Naa kay assignment?', gloss: 'Hast du Hausaufgaben?' },
{ target: 'Hugas sa kamot.', gloss: 'Wasch dir die Haende.' },
{ target: 'Ayaw pagdali.', gloss: 'Kein Stress.' },
{ target: 'Sunod, matulog na ta.', gloss: 'Danach schlafen wir.' }
],
speakingPrompts: [
{
title: 'Mischszene',
prompt: 'Baue eine Szene aus Schule, Hausaufgaben, Spiel und Schlaf.',
cue: 'Andam na ka sa eskwela? Naa kay assignment? Pagkahuman, magdula ta. Sunod, matulog na ta.'
}
],
practicalTasks: [
{
title: 'Tempo',
text: 'Sag acht Saetze laut und schnell (aber klar), ohne zu stolpern.'
}
]
},
'Woche 7 - Checkpoint': {
learningGoals: [
@@ -91,7 +290,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Abruf und Anwendung im Familienalltag testen.',
'Lücken vor Woche 8 sichtbar machen.'
],
corePatterns: ['eskwela', 'assignment', 'bata', 'magdula']
corePatterns: [
{ target: 'eskwela', gloss: 'Schule' },
{ target: 'assignment', gloss: 'Hausaufgabe' },
{ target: 'bata', gloss: 'Kind' },
{ target: 'magdula', gloss: 'spielen' },
{ target: 'Andam na ka?', gloss: 'Bist du fertig?' },
{ target: 'Asa imong bag?', gloss: 'Wo ist deine Tasche?' },
{ target: 'Magtuon ta.', gloss: 'Lass uns lernen.' },
{ target: 'Sunod, matulog na ta.', gloss: 'Danach schlafen wir.' }
],
speakingPrompts: [
{
title: 'Checkpoint-Szene',
prompt: 'Loese eine kurze Szene: Schule, Tasche, Hausaufgabe, Routine.',
cue: 'Asa imong bag? Andam na ka sa eskwela? Naa kay assignment? Sunod, matulog na ta.'
}
],
practicalTasks: [
{
title: 'Diagnose',
text: 'Markiere die Saetze, die nicht sofort kamen, und wiederhole sie dreimal im Typing.'
}
]
},
'Arzt & Termin': {
learningGoals: [
@@ -99,7 +320,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Über Beschwerden, Termin und Wartezeit sprechen.',
'Einfache Gesundheitsgespräche strukturieren.'
],
corePatterns: ['Adto ta sa doktor.', 'Naa moy appointment?', 'Unsay gibati nimo?', 'Maghulat ta.']
corePatterns: [
{ target: 'Adto ta sa doktor.', gloss: 'Wir gehen zum Arzt.' },
{ target: 'Naa mi appointment.', gloss: 'Wir haben einen Termin.' },
{ target: 'Naa moy appointment?', gloss: 'Haben Sie einen Termin?' },
{ target: 'Unsay gibati nimo?', gloss: 'Was fuehlst du / was hast du?' },
{ target: 'Sakit diri.', gloss: 'Es tut hier weh.' },
{ target: 'Pila ka oras ang hulat?', gloss: 'Wie lange ist die Wartezeit?' },
{ target: 'Maghulat ta.', gloss: 'Wir warten.' },
{ target: 'Palihug tabang.', gloss: 'Bitte helfen.' }
],
speakingPrompts: [
{
title: 'Arzttermin',
prompt: 'Sage, dass ihr zum Arzt geht, ihr einen Termin habt und frage nach Wartezeit.',
cue: 'Adto ta sa doktor. Naa mi appointment. Pila ka oras ang hulat?'
}
],
practicalTasks: [
{
title: '3 Fragen',
text: 'Uebe drei Fragen fuer den Arztbesuch: Termin, Beschwerden, Wartezeit.'
}
]
},
'Apotheke & Medikamente': {
learningGoals: [
@@ -107,7 +350,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Zwischen Medikament, Rezept und Dosierung unterscheiden.',
'Gesundheitswortschatz in Erledigungen einordnen.'
],
corePatterns: ['tambal', 'botika', 'reseta', 'dose']
corePatterns: [
{ target: 'botika', gloss: 'Apotheke' },
{ target: 'tambal', gloss: 'Medizin' },
{ target: 'reseta', gloss: 'Rezept' },
{ target: 'dose', gloss: 'Dosis' },
{ target: 'Pila ang dose?', gloss: 'Wie ist die Dosierung?' },
{ target: 'Pila ka adlaw?', gloss: 'Wie viele Tage?' },
{ target: 'Naa moy tambal ani?', gloss: 'Haben Sie Medizin dafuer?' },
{ target: 'Unsaon pag-inom?', gloss: 'Wie nimmt man das ein?' }
],
speakingPrompts: [
{
title: 'In der Apotheke',
prompt: 'Frage nach Medizin, Rezept und Dosierung.',
cue: 'Naa moy tambal ani? Naa koy reseta. Unsaon pag-inom?'
}
],
practicalTasks: [
{
title: 'Etikett lesen',
text: 'Sag laut: Dosis, Tage, wie einnehmen, und wiederhole es in eigenen Worten.'
}
]
},
'Beschwerden genauer beschreiben': {
learningGoals: [
@@ -115,13 +380,35 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Zwischen leicht, stark und wiederkehrend unterscheiden.',
'Fragen und Antworten zu Schmerzen vertiefen.'
],
corePatterns: ['Sakit kaayo.', 'Gamaya ra ang sakit.', 'Nagsugod ganiha.', 'Mas maayo na karon.'],
corePatterns: [
{ target: 'Sakit kaayo.', gloss: 'Es tut sehr weh.' },
{ target: 'Gamaya ra ang sakit.', gloss: 'Der Schmerz ist nur leicht.' },
{ target: 'Sakit pa?', gloss: 'Tut es noch weh?' },
{ target: 'Nagsugod ganiha.', gloss: 'Es hat vorhin angefangen.' },
{ target: 'Balik-balik.', gloss: 'Es kommt immer wieder.' },
{ target: 'Mas maayo na karon.', gloss: 'Es ist jetzt besser.' },
{ target: 'Naa koy hilanat.', gloss: 'Ich habe Fieber.' },
{ target: 'Ubo ko.', gloss: 'Ich habe Husten.' }
],
grammarFocus: [
{
title: 'Beschwerden abstufen',
text: 'Im Alltag helfen kurze Verstärker und Zeitangaben, um Schmerzen genauer zu beschreiben.',
example: 'Sakit kaayo. Nagsugod ganiha.'
}
],
speakingPrompts: [
{
title: 'Verlauf beschreiben',
prompt: 'Sag, wie stark es ist, wann es anfing und ob es besser wird.',
cue: 'Gamaya ra ang sakit. Nagsugod ganiha. Mas maayo na karon.'
}
],
practicalTasks: [
{
title: '3 Varianten',
text: 'Bilde drei Varianten derselben Beschwerde: leicht, stark, wiederkehrend.'
}
]
},
'Notfälle & Hilfe': {
@@ -130,7 +417,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Klare, kurze Anweisungen geben.',
'Grundmuster für schnelle Reaktion beherrschen.'
],
corePatterns: ['Tabang!', 'Tawag ug doktor.', 'Dali lang.', 'Asa ang tambal?']
corePatterns: [
{ target: 'Tabang!', gloss: 'Hilfe!' },
{ target: 'Dali lang!', gloss: 'Schnell!' },
{ target: 'Tawag ug doktor.', gloss: 'Ruf einen Arzt.' },
{ target: 'Tawag ug ambulansya.', gloss: 'Ruf einen Krankenwagen.' },
{ target: 'Asa ang tambal?', gloss: 'Wo ist die Medizin?' },
{ target: 'Palihug tabang.', gloss: 'Bitte helfen.' },
{ target: 'Dili ko ginhawa.', gloss: 'Ich bekomme keine Luft.' },
{ target: 'Magpabilin diri.', gloss: 'Bleib hier.' }
],
speakingPrompts: [
{
title: 'Notfallansage',
prompt: 'Rufe Hilfe und gib eine kurze Anweisung.',
cue: 'Tabang! Tawag ug doktor. Dali lang!'
}
],
practicalTasks: [
{
title: 'Notfallanker',
text: 'Uebe vier Notfallsaetze, bis sie ohne Lesen kommen.'
}
]
},
'Woche 8 - Intensivwiederholung I': {
learningGoals: [
@@ -138,7 +447,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Beschwerden schneller abrufen und zuordnen.',
'Gesundheitskommunikation stabilisieren.'
],
corePatterns: ['doktor', 'tambal', 'tabang', 'sakit kaayo']
corePatterns: [
{ target: 'Adto ta sa doktor.', gloss: 'Wir gehen zum Arzt.' },
{ target: 'Naa mi appointment.', gloss: 'Wir haben einen Termin.' },
{ target: 'Naa moy tambal ani?', gloss: 'Haben Sie Medizin dafuer?' },
{ target: 'Unsaon pag-inom?', gloss: 'Wie nimmt man das ein?' },
{ target: 'Sakit kaayo.', gloss: 'Es tut sehr weh.' },
{ target: 'Nagsugod ganiha.', gloss: 'Es fing vorhin an.' },
{ target: 'Tabang!', gloss: 'Hilfe!' },
{ target: 'Tawag ug doktor.', gloss: 'Ruf einen Arzt.' }
],
speakingPrompts: [
{
title: 'Mischszene Gesundheit',
prompt: 'Verbinde Arzttermin, Apotheke und Hilfe in einer Szene.',
cue: 'Adto ta sa doktor. Naa mi appointment. Naa moy tambal ani? Tabang!'
}
],
practicalTasks: [
{
title: 'Tempo-Mix',
text: 'Sag acht Saetze schnell hintereinander, ohne zu stolpern.'
}
]
},
'Spiralwiederholung - Gesundheit': {
learningGoals: [
@@ -146,7 +477,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Bekannte Wörter in neuen Gesundheitsdialogen wiederholen.',
'Gesundheitswortschatz langfristig verankern.'
],
corePatterns: ['Nikaon na ka?', 'Magpahuway sa.', 'doktor', 'tambal']
corePatterns: [
{ target: 'Magpahuway sa.', gloss: 'Ruh dich erst mal aus.' },
{ target: 'Uminom og tubig.', gloss: 'Trink Wasser.' },
{ target: 'Niinom ka og tambal?', gloss: 'Hast du Medizin genommen?' },
{ target: 'Mas maayo na ka?', gloss: 'Geht es dir besser?' },
{ target: 'doktor', gloss: 'Arzt' },
{ target: 'tambal', gloss: 'Medizin' },
{ target: 'Sakit pa?', gloss: 'Tut es noch weh?' },
{ target: 'Ayaw kabalaka.', gloss: 'Mach dir keine Sorgen.' }
],
speakingPrompts: [
{
title: 'Fuersorgefolge',
prompt: 'Reagiere mit drei Fuersorgesatzen auf eine Beschwerde.',
cue: 'Ayaw kabalaka. Magpahuway sa. Uminom og tubig.'
}
],
practicalTasks: [
{
title: 'Problem -> Antwort',
text: 'Bilde fuenf Paare aus Problem und Antwort (z.B. sakit -> magpahuway).'
}
]
},
'Essen, Ruhe & Genesung': {
learningGoals: [
@@ -154,7 +507,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Kurze Pflegegespräche im Familienalltag führen.',
'Fürsorge und Gesundheit verbinden.'
],
corePatterns: ['Magpahuway sa.', 'Mokaon sa ka.', 'Uminom og tubig.', 'Mas maayo na ka?']
corePatterns: [
{ target: 'Magpahuway sa.', gloss: 'Ruh dich erst mal aus.' },
{ target: 'Mokaon sa ka.', gloss: 'Iss erst einmal.' },
{ target: 'Uminom og tubig.', gloss: 'Trink Wasser.' },
{ target: 'Inom sa og tambal.', gloss: 'Nimm erst mal Medizin.' },
{ target: 'Mas maayo na ka?', gloss: 'Geht es dir besser?' },
{ target: 'Dili sa daghan.', gloss: 'Nicht zu viel.' },
{ target: 'Katulog og maayo.', gloss: 'Schlaf gut.' },
{ target: 'Naa ra ko diri.', gloss: 'Ich bin hier.' }
],
speakingPrompts: [
{
title: 'Pflegegespraech',
prompt: 'Biete Essen, Wasser, Ruhe an und frage nach Besserung.',
cue: 'Mokaon sa ka. Uminom og tubig. Magpahuway sa. Mas maayo na ka?'
}
],
practicalTasks: [
{
title: 'Pflegekette',
text: 'Sprich eine Pflegekette mit mindestens fuenf kurzen Saetzen.'
}
]
},
'Körper, Symptome & Pflege': {
learningGoals: [
@@ -162,7 +537,30 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Zwischen Ort und Art einer Beschwerde unterscheiden.',
'Pflegealltag mit konkreterem Wortschatz stützen.'
],
corePatterns: ['ulo', 'tiyan', 'hilanat', 'alaga']
corePatterns: [
{ target: 'ulo', gloss: 'Kopf' },
{ target: 'tiyan', gloss: 'Bauch' },
{ target: 'likod', gloss: 'Ruecken' },
{ target: 'tutunlan', gloss: 'Hals' },
{ target: 'hilanat', gloss: 'Fieber' },
{ target: 'ubo', gloss: 'Husten' },
{ target: 'alaga', gloss: 'Pflege' },
{ target: 'doktor', gloss: 'Arzt' },
{ target: 'Sakit akong tutunlan.', gloss: 'Mein Hals tut weh.' }
],
speakingPrompts: [
{
title: 'Koerper + Schmerz',
prompt: 'Sage drei Saetze: wo es weh tut und was du brauchst.',
cue: 'Sakit akong ulo. Sakit akong tiyan. Asa ang tambal?'
}
],
practicalTasks: [
{
title: 'Koerperrunde',
text: 'Nenne vier Koerperteile und bilde zu jedem einen kurzen Satz mit sakit.'
}
]
},
'Woche 8 - Intensivwiederholung II': {
learningGoals: [
@@ -170,7 +568,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Fragen, Antworten und Reaktionen zügig abrufen.',
'Vor dem Wochenabschluss Sicherheit erhöhen.'
],
corePatterns: ['Mas maayo na ka?', 'Adto ta sa doktor.', 'Uminom og tubig.', 'Tabang!']
corePatterns: [
{ target: 'Mas maayo na ka?', gloss: 'Geht es dir besser?' },
{ target: 'Adto ta sa doktor.', gloss: 'Wir gehen zum Arzt.' },
{ target: 'Naa moy appointment?', gloss: 'Haben Sie einen Termin?' },
{ target: 'Unsaon pag-inom?', gloss: 'Wie nimmt man das ein?' },
{ target: 'Uminom og tubig.', gloss: 'Trink Wasser.' },
{ target: 'Magpahuway sa.', gloss: 'Ruh dich aus.' },
{ target: 'Tabang!', gloss: 'Hilfe!' },
{ target: 'Dali lang!', gloss: 'Schnell!' }
],
speakingPrompts: [
{
title: 'Acht Antworten',
prompt: 'Reagiere auf acht gemischte Gesundheits- und Notfallsituationen.',
cue: 'Magpahuway sa. Uminom og tubig. Adto ta sa doktor. Tabang!'
}
],
practicalTasks: [
{
title: 'Kontrast',
text: 'Kontrastiere: leicht vs stark, Arzt vs Apotheke, Bitte vs Notfall.'
}
]
},
'Woche 8 - Checkpoint': {
learningGoals: [
@@ -178,7 +598,29 @@ export const BISAYA_PHASE4_DIDACTICS = {
'Abruf, Verständnis und situative Anwendung prüfen.',
'Stärken und Lücken für Woche 9 festhalten.'
],
corePatterns: ['doktor', 'botika', 'hilanat', 'tabang']
corePatterns: [
{ target: 'doktor', gloss: 'Arzt' },
{ target: 'botika', gloss: 'Apotheke' },
{ target: 'hilanat', gloss: 'Fieber' },
{ target: 'tabang', gloss: 'Hilfe' },
{ target: 'Naa mi appointment.', gloss: 'Wir haben einen Termin.' },
{ target: 'Sakit kaayo.', gloss: 'Es tut sehr weh.' },
{ target: 'Unsaon pag-inom?', gloss: 'Wie nimmt man das ein?' },
{ target: 'Tawag ug doktor.', gloss: 'Ruf einen Arzt.' }
],
speakingPrompts: [
{
title: 'Checkpoint-Szene',
prompt: 'Loese eine Szene: Termin, Beschwerden, Apotheke, Notfall.',
cue: 'Naa mi appointment. Sakit kaayo. Naa moy tambal ani? Tawag ug doktor.'
}
],
practicalTasks: [
{
title: 'Diagnose',
text: 'Markiere die unsicheren Saetze und wiederhole sie im Typing bis sie sofort kommen.'
}
]
},
'Einkaufen vertiefen': {
learningGoals: [
@@ -531,26 +973,26 @@ export const BISAYA_PHASE4_DIDACTICS = {
};
export const BISAYA_PHASE4_LESSONS = [
{ week: 7, day: 1, num: 64, type: 'conversation', title: 'Kinder im Alltag', desc: 'Mit Kindern sprechen und Fürsorge im Alltag ausdrücken', targetMin: 18, targetScore: 80, review: false, cultural: null },
{ week: 7, day: 1, num: 65, type: 'vocab', title: 'Schule & Betreuung', desc: 'Wortschatz für Schule, Tasche, Unterricht und Betreuung', targetMin: 18, targetScore: 85, review: true, cultural: null },
{ week: 7, day: 2, num: 66, type: 'grammar', title: 'Fragen an Kinder vereinfachen', desc: 'Kurze, klare Fragen für Kinder und Betreuungssituationen', targetMin: 20, targetScore: 78, review: true, cultural: null },
{ week: 7, day: 2, num: 67, type: 'conversation', title: 'Hausaufgaben & Routine', desc: 'Über Schule, Lernen und Routinen zuhause sprechen', targetMin: 18, targetScore: 80, review: false, cultural: null },
{ week: 7, day: 3, num: 68, type: 'review', title: 'Woche 7 - Intensivwiederholung I', desc: 'Kinder, Schule und Familienroutine intensiv wiederholen', targetMin: 28, targetScore: 80, review: false, cultural: null },
{ week: 7, day: 3, num: 69, type: 'vocab', title: 'Spiralwiederholung - Familie, Kinder & Fürsorge', desc: 'Frühe Kernmuster mit Kinderalltag verbinden', targetMin: 20, targetScore: 85, review: true, cultural: null },
{ week: 7, day: 4, num: 70, type: 'conversation', title: 'Spielen & Freizeit', desc: 'Mit Kindern über Spiel, Pause und Freizeit sprechen', targetMin: 18, targetScore: 80, review: false, cultural: null },
{ week: 7, day: 4, num: 71, type: 'vocab', title: 'Spielsachen & Aktivitäten', desc: 'Spiel- und Freizeitwortschatz für Familienalltag', targetMin: 18, targetScore: 85, review: true, cultural: null },
{ week: 7, day: 5, num: 72, type: 'review', title: 'Woche 7 - Intensivwiederholung II', desc: 'Große Mischwiederholung zur Kinder- und Schulwoche', targetMin: 28, targetScore: 80, review: false, cultural: null },
{ week: 7, day: 5, num: 73, type: 'vocab', title: 'Woche 7 - Checkpoint', desc: 'Checkpoint zu Familie, Kindern und Schule', targetMin: 16, targetScore: 82, review: true, cultural: null },
{ week: 8, day: 1, num: 74, type: 'conversation', title: 'Arzt & Termin', desc: 'Arzttermine vereinbaren und Gesundheitsfragen stellen', targetMin: 18, targetScore: 80, review: false, cultural: null },
{ week: 8, day: 1, num: 75, type: 'vocab', title: 'Apotheke & Medikamente', desc: 'Wichtiger Wortschatz für Apotheke und Medizin', targetMin: 18, targetScore: 85, review: true, cultural: null },
{ week: 8, day: 2, num: 76, type: 'grammar', title: 'Beschwerden genauer beschreiben', desc: 'Schmerz, Verlauf und Stärke konkreter ausdrücken', targetMin: 20, targetScore: 78, review: true, cultural: null },
{ week: 8, day: 2, num: 77, type: 'conversation', title: 'Notfälle & Hilfe', desc: 'In einfachen Notfällen Hilfe holen und reagieren', targetMin: 18, targetScore: 80, review: false, cultural: null },
{ week: 8, day: 3, num: 78, type: 'review', title: 'Woche 8 - Intensivwiederholung I', desc: 'Gesundheit, Arzt und Hilfe intensiv wiederholen', targetMin: 28, targetScore: 80, review: false, cultural: null },
{ week: 8, day: 3, num: 79, type: 'vocab', title: 'Spiralwiederholung - Gesundheit', desc: 'Frühere Fürsorge mit Gesundheit und Pflege verbinden', targetMin: 20, targetScore: 85, review: true, cultural: null },
{ week: 8, day: 4, num: 80, type: 'conversation', title: 'Essen, Ruhe & Genesung', desc: 'Pflege, Ruhe und Essen bei Krankheit besprechen', targetMin: 18, targetScore: 80, review: false, cultural: null },
{ week: 8, day: 4, num: 81, type: 'vocab', title: 'Körper, Symptome & Pflege', desc: 'Körper- und Pflegewortschatz ausbauen', targetMin: 18, targetScore: 85, review: true, cultural: null },
{ week: 8, day: 5, num: 82, type: 'review', title: 'Woche 8 - Intensivwiederholung II', desc: 'Große Mischwiederholung zu Gesundheit und Hilfe', targetMin: 28, targetScore: 80, review: false, cultural: null },
{ week: 8, day: 5, num: 83, type: 'vocab', title: 'Woche 8 - Checkpoint', desc: 'Checkpoint zu Arzt, Apotheke und Pflege', targetMin: 16, targetScore: 82, review: true, cultural: null },
{ week: 7, day: 1, num: 64, type: 'conversation', title: 'Kinder im Alltag', desc: 'Mit Kindern sprechen, Routinen strukturieren und Fürsorge ausdrücken', targetMin: 26, targetScore: 80, review: false, cultural: null },
{ week: 7, day: 1, num: 65, type: 'vocab', title: 'Schule & Betreuung', desc: 'Schul- und Betreuungsvokabeln plus kurze Alltagssätze (Tasche, Buch, Lehrkraft, Aufgabe)', targetMin: 24, targetScore: 85, review: true, cultural: null },
{ week: 7, day: 2, num: 66, type: 'grammar', title: 'Fragen an Kinder vereinfachen', desc: 'Kurze Fragen vs. Aufforderungen in Betreuungssituationen sicher bauen', targetMin: 26, targetScore: 78, review: true, cultural: null },
{ week: 7, day: 2, num: 67, type: 'conversation', title: 'Hausaufgaben & Routine', desc: 'Hausaufgaben, Lernen, Spielen und Schlafen in eine klare Routine bringen', targetMin: 26, targetScore: 80, review: false, cultural: null },
{ week: 7, day: 3, num: 68, type: 'review', title: 'Woche 7 - Intensivwiederholung I', desc: 'Kinder, Schule und Familienroutine intensiv wiederholen (Abruf + Rollenwechsel)', targetMin: 34, targetScore: 82, review: false, cultural: null },
{ week: 7, day: 3, num: 69, type: 'vocab', title: 'Spiralwiederholung - Familie, Kinder & Fürsorge', desc: 'Frühe Kernmuster in Kinder-/Schulszenen reaktivieren', targetMin: 24, targetScore: 85, review: true, cultural: null },
{ week: 7, day: 4, num: 70, type: 'conversation', title: 'Spielen & Freizeit', desc: 'Spiel, Pause, Regeln und ruhige Korrektur im Kinderalltag sprechen', targetMin: 24, targetScore: 80, review: false, cultural: null },
{ week: 7, day: 4, num: 71, type: 'vocab', title: 'Spielsachen & Aktivitäten', desc: 'Spiel- und Freizeitwortschatz aktiv nutzen (Auswahl, Fragen, kurze Saetze)', targetMin: 24, targetScore: 85, review: true, cultural: null },
{ week: 7, day: 5, num: 72, type: 'review', title: 'Woche 7 - Intensivwiederholung II', desc: 'Große Mischwiederholung zur Kinder- und Schulwoche (Szene bauen)', targetMin: 34, targetScore: 82, review: false, cultural: null },
{ week: 7, day: 5, num: 73, type: 'vocab', title: 'Woche 7 - Checkpoint', desc: 'Checkpoint zu Kindern, Schule, Hausaufgaben und Routine (Diagnose + freie Szene)', targetMin: 24, targetScore: 84, review: true, cultural: null },
{ week: 8, day: 1, num: 74, type: 'conversation', title: 'Arzt & Termin', desc: 'Arzttermine, Beschwerden und Wartezeit als Mini-Dialog organisieren', targetMin: 26, targetScore: 80, review: false, cultural: null },
{ week: 8, day: 1, num: 75, type: 'vocab', title: 'Apotheke & Medikamente', desc: 'Apotheke, Rezept, Dosierung und Einnahmefragen aktiv abrufen', targetMin: 24, targetScore: 85, review: true, cultural: null },
{ week: 8, day: 2, num: 76, type: 'grammar', title: 'Beschwerden genauer beschreiben', desc: 'Staerke, Verlauf, Zeitpunkte und wiederkehrende Beschwerden ausdruecken', targetMin: 26, targetScore: 78, review: true, cultural: null },
{ week: 8, day: 2, num: 77, type: 'conversation', title: 'Notfälle & Hilfe', desc: 'Hilfe rufen, kurze Anweisungen geben und Notfallanker sicher sprechen', targetMin: 26, targetScore: 80, review: false, cultural: null },
{ week: 8, day: 3, num: 78, type: 'review', title: 'Woche 8 - Intensivwiederholung I', desc: 'Arzt, Apotheke, Beschwerden und Hilfe intensiv wiederholen (Tempo + Abruf)', targetMin: 34, targetScore: 82, review: false, cultural: null },
{ week: 8, day: 3, num: 79, type: 'vocab', title: 'Spiralwiederholung - Gesundheit', desc: 'Fürsorge und Gesundheit als Langzeitabruf (Problem -> Antwort)', targetMin: 24, targetScore: 85, review: true, cultural: null },
{ week: 8, day: 4, num: 80, type: 'conversation', title: 'Essen, Ruhe & Genesung', desc: 'Pflegegespraeche: Essen, Wasser, Ruhe, Medizin und Besserung verbinden', targetMin: 24, targetScore: 80, review: false, cultural: null },
{ week: 8, day: 4, num: 81, type: 'vocab', title: 'Körper, Symptome & Pflege', desc: 'Koerper, Symptome und Pflegewortschatz mit kurzen Schmerzsaetzen kombinieren', targetMin: 24, targetScore: 85, review: true, cultural: null },
{ week: 8, day: 5, num: 82, type: 'review', title: 'Woche 8 - Intensivwiederholung II', desc: 'Große Mischwiederholung zu Gesundheit und Hilfe (Kontraste + freie Antworten)', targetMin: 34, targetScore: 82, review: false, cultural: null },
{ week: 8, day: 5, num: 83, type: 'vocab', title: 'Woche 8 - Checkpoint', desc: 'Checkpoint zu Arzt, Apotheke, Beschwerden und Notfall (Diagnose + Typing)', targetMin: 24, targetScore: 84, review: true, cultural: null },
{ week: 9, day: 1, num: 84, type: 'conversation', title: 'Einkaufen vertiefen', desc: 'Komplexere Einkaufs- und Auswahlgespräche führen', targetMin: 18, targetScore: 80, review: false, cultural: null },
{ week: 9, day: 1, num: 85, type: 'vocab', title: 'Markt & Mengen', desc: 'Wortschatz für Markt, Mengen und Auswahl', targetMin: 18, targetScore: 85, review: true, cultural: null },
{ week: 9, day: 2, num: 86, type: 'grammar', title: 'Wünsche, Bedarf und Bitte', desc: 'Wunsch, Notwendigkeit und höfliche Bitte unterscheiden', targetMin: 20, targetScore: 78, review: true, cultural: null },

View File

@@ -15,7 +15,7 @@ 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_PHASE3_DIDACTICS, BISAYA_PHASE3_LESSONS } from './bisaya-course-phase3-extension.js';
import { BISAYA_PHASE4_DIDACTICS } from './bisaya-course-phase4-extension.js';
import { BISAYA_PHASE4_DIDACTICS, BISAYA_PHASE4_LESSONS } from './bisaya-course-phase4-extension.js';
import { BISAYA_PHASE5_DIDACTICS } from './bisaya-course-phase5-extension.js';
function withTypeName(exerciseTypeName, exercise) {
@@ -33,9 +33,10 @@ const GENERATED_BISAYA_DIDACTICS = {
...BISAYA_PHASE5_DIDACTICS
};
const SAFE_EXERCISE_UPDATE_TITLES = new Set(
BISAYA_PHASE3_LESSONS.map((lesson) => lesson.title)
);
const SAFE_EXERCISE_UPDATE_TITLES = new Set([
...BISAYA_PHASE3_LESSONS.map((lesson) => lesson.title),
...BISAYA_PHASE4_LESSONS.map((lesson) => lesson.title)
]);
function normalizeText(value) {
return String(value || '')

View File

@@ -285,13 +285,24 @@ function generateExercisesFromDidactics(lesson) {
const pool = getLessonPatternPool(didactics);
if (lesson.lessonType === 'conversation') {
return [
const exercises = [
buildChoiceExercise(lesson, didactics, patternA, pool, 0),
buildGapExercise(lesson.title, patternA),
buildSentenceExercise(lesson.title, patternB),
buildSituationalExercise(lesson.title, didactics, patternA),
buildSpeakingExercise(lesson.title, didactics, patternB)
].filter(Boolean);
// Ab Alltag/Stabilisierung konsequent mehr produktive Leistung verlangen.
if (Number(lesson.lessonNumber) >= 91) {
const extraSituational = buildSituationalExercise(lesson.title, didactics, patternB);
if (extraSituational) exercises.push(extraSituational);
}
if (Number(lesson.lessonNumber) >= 121) {
const extraSpeaking = buildSpeakingExercise(lesson.title, didactics, patternA);
if (extraSpeaking) exercises.push(extraSpeaking);
}
return exercises;
}
if (lesson.lessonType === 'grammar') {
@@ -305,7 +316,7 @@ function generateExercisesFromDidactics(lesson) {
}
if (lesson.lessonType === 'review' || lesson.didacticMode === 'intensive_review') {
return [
const exercises = [
buildChoiceExercise(lesson, didactics, patternA, pool, 0),
buildChoiceExercise(lesson, didactics, patternB, pool, 1),
buildGapExercise(lesson.title, patternA),
@@ -313,6 +324,16 @@ function generateExercisesFromDidactics(lesson) {
buildSituationalExercise(lesson.title, didactics, patternA),
buildSpeakingExercise(lesson.title, didactics, patternB)
].filter(Boolean);
if (Number(lesson.lessonNumber) >= 91) {
const extraSpeaking = buildSpeakingExercise(lesson.title, didactics, patternA);
if (extraSpeaking) exercises.push(extraSpeaking);
}
if (String(lesson.title || '').toLowerCase().includes('checkpoint')) {
const extraSituational = buildSituationalExercise(lesson.title, didactics, patternB);
if (extraSituational) exercises.push(extraSituational);
}
return exercises;
}
if (lesson.lessonType === 'culture') {

View File

@@ -16,7 +16,10 @@ import { GERMAN_FOR_BISAYA_PHASE1_DIDACTICS, GERMAN_FOR_BISAYA_PHASE1_LESSONS }
import { GERMAN_FOR_BISAYA_PHASE3_DIDACTICS, GERMAN_FOR_BISAYA_PHASE3_LESSONS } from './german-for-bisaya-phase3-extension.js';
import { GERMAN_FOR_BISAYA_PHASE4_DIDACTICS, GERMAN_FOR_BISAYA_PHASE4_LESSONS } from './german-for-bisaya-phase4-extension.js';
import { GERMAN_FOR_BISAYA_PHASE5_DIDACTICS, GERMAN_FOR_BISAYA_PHASE5_LESSONS } from './german-for-bisaya-phase5-extension.js';
import { getGermanForBisayaLessonPedagogy } from './german-for-bisaya-phase2-pedagogy.js';
import {
getGermanForBisayaLessonPedagogy,
getGermanForBisayaProgressTargets
} from './german-for-bisaya-phase2-pedagogy.js';
const ALL_GERMAN_FOR_BISAYA_LESSONS = [
...GERMAN_FOR_BISAYA_PHASE1_LESSONS,
@@ -107,6 +110,7 @@ async function createGermanForBisayaCourse(ownerHashedId) {
for (const lessonData of ALL_GERMAN_FOR_BISAYA_LESSONS) {
const didactics = ALL_GERMAN_FOR_BISAYA_DIDACTICS[lessonData.title] || {};
const pedagogy = getGermanForBisayaLessonPedagogy(lessonData.num, lessonData.type, lessonData.title);
const progressTargets = getGermanForBisayaProgressTargets(lessonData, pedagogy);
await VocabCourseLesson.create({
courseId: course.id,
@@ -130,8 +134,8 @@ async function createGermanForBisayaCourse(ownerHashedId) {
grammarFocus: didactics.grammarFocus || null,
speakingPrompts: didactics.speakingPrompts || null,
practicalTasks: didactics.practicalTasks || null,
targetMinutes: lessonData.targetMin,
targetScorePercent: lessonData.targetScore,
targetMinutes: progressTargets.targetMinutes,
targetScorePercent: progressTargets.targetScorePercent,
requiresReview: lessonData.review
});
}

View File

@@ -30,6 +30,7 @@ async function extendBisayaCoursePhase4() {
});
let addedLessons = 0;
let updatedLessons = 0;
for (const course of courses) {
await course.update({
@@ -45,17 +46,9 @@ async function extendBisayaCoursePhase4() {
}
});
if (existing) {
continue;
}
const didactics = BISAYA_PHASE4_DIDACTICS[lessonData.title] || {};
const pedagogy = getBisayaLessonPedagogy(lessonData.num) || {};
await VocabCourseLesson.create({
courseId: course.id,
chapterId: null,
lessonNumber: lessonData.num,
const lessonPayload = {
title: lessonData.title,
description: lessonData.desc,
weekNumber: lessonData.week,
@@ -77,6 +70,20 @@ async function extendBisayaCoursePhase4() {
newUnitTarget: pedagogy.newUnitTarget ?? null,
reviewWeight: pedagogy.reviewWeight ?? null,
isIntensiveReview: Boolean(pedagogy.isIntensiveReview)
};
if (existing) {
await existing.update(lessonPayload);
updatedLessons++;
console.log(`🔄 Kurs ${course.id}: Lektion ${lessonData.num} - ${lessonData.title} aktualisiert`);
continue;
}
await VocabCourseLesson.create({
...lessonPayload,
courseId: course.id,
chapterId: null,
lessonNumber: lessonData.num
});
addedLessons++;
@@ -87,6 +94,7 @@ async function extendBisayaCoursePhase4() {
console.log(`\n🎉 Phase 4 vorbereitet.`);
console.log(` Kurse: ${courses.length}`);
console.log(` Neue Lektionen ergänzt: ${addedLessons}`);
console.log(` Bestehende Lektionen aktualisiert: ${updatedLessons}`);
console.log(' Das Einspielen in die DB kann später gesammelt mit den übrigen Phasen erfolgen.');
}

View File

@@ -4,7 +4,10 @@ import { sequelize } from '../utils/sequelize.js';
import VocabCourse from '../models/community/vocab_course.js';
import VocabCourseLesson from '../models/community/vocab_course_lesson.js';
import { GERMAN_FOR_BISAYA_PHASE3_DIDACTICS, GERMAN_FOR_BISAYA_PHASE3_LESSONS } from './german-for-bisaya-phase3-extension.js';
import { getGermanForBisayaLessonPedagogy } from './german-for-bisaya-phase2-pedagogy.js';
import {
getGermanForBisayaLessonPedagogy,
getGermanForBisayaProgressTargets
} from './german-for-bisaya-phase2-pedagogy.js';
async function getLanguageId(name) {
const [language] = await sequelize.query(
@@ -38,6 +41,7 @@ async function extendGermanForBisayaPhase3() {
const didactics = GERMAN_FOR_BISAYA_PHASE3_DIDACTICS[lessonData.title] || {};
const pedagogy = getGermanForBisayaLessonPedagogy(lessonData.num, lessonData.type, lessonData.title);
const progressTargets = getGermanForBisayaProgressTargets(lessonData, pedagogy);
await VocabCourseLesson.create({
courseId: course.id,
@@ -61,8 +65,8 @@ async function extendGermanForBisayaPhase3() {
grammarFocus: didactics.grammarFocus || null,
speakingPrompts: didactics.speakingPrompts || null,
practicalTasks: didactics.practicalTasks || null,
targetMinutes: lessonData.targetMin,
targetScorePercent: lessonData.targetScore,
targetMinutes: progressTargets.targetMinutes,
targetScorePercent: progressTargets.targetScorePercent,
requiresReview: lessonData.review
});
}

View File

@@ -4,7 +4,10 @@ import { sequelize } from '../utils/sequelize.js';
import VocabCourse from '../models/community/vocab_course.js';
import VocabCourseLesson from '../models/community/vocab_course_lesson.js';
import { GERMAN_FOR_BISAYA_PHASE4_DIDACTICS, GERMAN_FOR_BISAYA_PHASE4_LESSONS } from './german-for-bisaya-phase4-extension.js';
import { getGermanForBisayaLessonPedagogy } from './german-for-bisaya-phase2-pedagogy.js';
import {
getGermanForBisayaLessonPedagogy,
getGermanForBisayaProgressTargets
} from './german-for-bisaya-phase2-pedagogy.js';
async function getLanguageId(name) {
const [language] = await sequelize.query(
@@ -38,6 +41,7 @@ async function extendGermanForBisayaPhase4() {
const didactics = GERMAN_FOR_BISAYA_PHASE4_DIDACTICS[lessonData.title] || {};
const pedagogy = getGermanForBisayaLessonPedagogy(lessonData.num, lessonData.type, lessonData.title);
const progressTargets = getGermanForBisayaProgressTargets(lessonData, pedagogy);
await VocabCourseLesson.create({
courseId: course.id,
@@ -61,8 +65,8 @@ async function extendGermanForBisayaPhase4() {
grammarFocus: didactics.grammarFocus || null,
speakingPrompts: didactics.speakingPrompts || null,
practicalTasks: didactics.practicalTasks || null,
targetMinutes: lessonData.targetMin,
targetScorePercent: lessonData.targetScore,
targetMinutes: progressTargets.targetMinutes,
targetScorePercent: progressTargets.targetScorePercent,
requiresReview: lessonData.review
});
}

View File

@@ -4,7 +4,10 @@ import { sequelize } from '../utils/sequelize.js';
import VocabCourse from '../models/community/vocab_course.js';
import VocabCourseLesson from '../models/community/vocab_course_lesson.js';
import { GERMAN_FOR_BISAYA_PHASE5_DIDACTICS, GERMAN_FOR_BISAYA_PHASE5_LESSONS } from './german-for-bisaya-phase5-extension.js';
import { getGermanForBisayaLessonPedagogy } from './german-for-bisaya-phase2-pedagogy.js';
import {
getGermanForBisayaLessonPedagogy,
getGermanForBisayaProgressTargets
} from './german-for-bisaya-phase2-pedagogy.js';
async function getLanguageId(name) {
const [language] = await sequelize.query(
@@ -38,6 +41,7 @@ async function extendGermanForBisayaPhase5() {
const didactics = GERMAN_FOR_BISAYA_PHASE5_DIDACTICS[lessonData.title] || {};
const pedagogy = getGermanForBisayaLessonPedagogy(lessonData.num, lessonData.type, lessonData.title);
const progressTargets = getGermanForBisayaProgressTargets(lessonData, pedagogy);
await VocabCourseLesson.create({
courseId: course.id,
@@ -61,8 +65,8 @@ async function extendGermanForBisayaPhase5() {
grammarFocus: didactics.grammarFocus || null,
speakingPrompts: didactics.speakingPrompts || null,
practicalTasks: didactics.practicalTasks || null,
targetMinutes: lessonData.targetMin,
targetScorePercent: lessonData.targetScore,
targetMinutes: progressTargets.targetMinutes,
targetScorePercent: progressTargets.targetScorePercent,
requiresReview: lessonData.review
});
}

View File

@@ -63,3 +63,43 @@ export function getGermanForBisayaLessonPedagogy(lessonNumber, lessonType, lesso
isIntensiveReview: lessonType === 'review'
};
}
export function getGermanForBisayaProgressTargets(lessonData, pedagogy) {
const baseMinutes = Number(lessonData?.targetMin || 18);
const baseScore = Number(lessonData?.targetScore || 80);
const lessonNumber = Number(lessonData?.num || 1);
const lessonType = String(lessonData?.type || '');
const didacticMode = String(pedagogy?.didacticMode || '');
const isCheckpoint = String(lessonData?.title || '').toLowerCase().includes('checkpoint');
// Spuerbar steilere Progression: spaetere Wochen bekommen mehr Produktionszeit
// und hoehere Zielwerte, ohne den Einstieg zu ueberfrachten.
let minutesBump = 0;
if (lessonNumber >= 61 && lessonNumber <= 90) minutesBump += 2;
if (lessonNumber >= 91 && lessonNumber <= 120) minutesBump += 4;
if (lessonNumber >= 121) minutesBump += 6;
if (lessonType === 'conversation' && lessonNumber >= 91) minutesBump += 2;
if (lessonType === 'review') minutesBump += 3;
if (isCheckpoint) minutesBump += 2;
let scoreBump = 0;
if (lessonNumber >= 61 && lessonNumber <= 90) scoreBump += 2;
if (lessonNumber >= 91 && lessonNumber <= 120) scoreBump += 4;
if (lessonNumber >= 121) scoreBump += 6;
if (lessonType === 'grammar') scoreBump += 2;
if (lessonType === 'review') scoreBump += 2;
if (didacticMode === 'contrast_training') scoreBump += 1;
if (isCheckpoint) scoreBump += 3;
const targetMinutes = Math.min(45, baseMinutes + minutesBump);
const targetScorePercent = lessonType === 'culture'
? 0
: Math.min(96, baseScore + scoreBump);
return {
targetMinutes,
targetScorePercent
};
}

View File

@@ -17,6 +17,7 @@ import {
BISAYA_RELATIONSHIP_ANCHOR_DIDACTICS
} from './bisaya-course-plan-24-43.js';
import { BISAYA_PHASE3_DIDACTICS } from './bisaya-course-phase3-extension.js';
import { BISAYA_PHASE4_DIDACTICS } from './bisaya-course-phase4-extension.js';
/** Alte Kurstitel → aktueller Schlüssel in LESSON_DIDACTICS (bestehende Datenbanken). */
export const LEGACY_DIDACTICS_TITLE_MAP = {
@@ -488,7 +489,8 @@ export const LESSON_DIDACTICS = {
},
...BISAYA_RELATIONSHIP_ANCHOR_DIDACTICS,
...BISAYA_DIDACTICS_24_43,
...BISAYA_PHASE3_DIDACTICS
...BISAYA_PHASE3_DIDACTICS,
...BISAYA_PHASE4_DIDACTICS
};
function resolveDidacticsForLesson(lesson) {