Refactor lesson types and update review handling
All checks were successful
Deploy to production / deploy (push) Successful in 2m22s
All checks were successful
Deploy to production / deploy (push) Successful in 2m22s
- Changed lesson type from 'review' to 'weekly_review' in multiple lesson definitions across phase 3 and phase 4 extensions. - Updated the logic in the vocabService to accommodate 'weekly_review' in various methods, ensuring proper handling of weekly review lessons. - Modified the VocabLessonView component to recognize 'weekly_review' as a valid lesson type for calculations and access checks. - Enhanced the didactics update script to include 'weekly_review' in the lesson type checks. - Adjusted the create scripts to reflect the new lesson type for weekly reviews.
This commit is contained in:
@@ -539,11 +539,11 @@ export const BISAYA_PHASE3_LESSONS = [
|
||||
{ week: 5, day: 1, num: 45, type: 'vocab', title: 'Besuch & Haushalt', desc: 'Haus-, Besuchs- und Haushaltswörter in kurzen Ortssätzen verwenden', targetMin: 22, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 5, day: 2, num: 46, type: 'grammar', title: 'Fragen im Alltag vertiefen', desc: 'Rückfragen, Folgefragen, Bedeutung und höfliches Nachhaken sicher kombinieren', targetMin: 26, targetScore: 78, review: true, cultural: null },
|
||||
{ week: 5, day: 2, num: 47, type: 'conversation', title: 'Termine & Verabredungen', desc: 'Treffen planen, Uhrzeiten absprechen, zusagen und weich verschieben', targetMin: 24, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 5, day: 3, num: 48, type: 'review', title: 'Woche 5 - Intensivwiederholung I', desc: 'Besuch, Familie, Fürsorge und Terminplanung in schnellen Rollenwechseln mischen', targetMin: 34, targetScore: 82, review: false, cultural: null },
|
||||
{ week: 5, day: 3, num: 48, type: 'weekly_review', title: 'Woche 5 - Intensivwiederholung I', desc: 'Besuch, Familie, Fürsorge und Terminplanung in schnellen Rollenwechseln mischen', targetMin: 34, targetScore: 82, review: false, cultural: null },
|
||||
{ week: 5, day: 3, num: 49, type: 'vocab', title: 'Spiralwiederholung - Familie & Fürsorge', desc: 'Alte Familien- und Fürsorgemuster aktiv reaktivieren und in neue Szenen übertragen', targetMin: 24, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 5, day: 4, num: 50, type: 'conversation', title: 'Gesundheit im Alltag', desc: 'Beschwerden erfragen, Ruhe/Wasser/Medizin anbieten und nach Besserung fragen', targetMin: 26, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 5, day: 4, num: 51, type: 'vocab', title: 'Medikamente & Beschwerden', desc: 'Symptome, Körperwörter und Hilfewortschatz in Fürsorgesätzen verwenden', targetMin: 24, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 5, day: 5, num: 52, type: 'review', title: 'Woche 5 - Intensivwiederholung II', desc: 'Gesundheit, Besuch, Fragen und Terminplanung unter Abrufdruck kontrastieren', targetMin: 34, targetScore: 82, review: false, cultural: null },
|
||||
{ week: 5, day: 5, num: 52, type: 'weekly_review', title: 'Woche 5 - Intensivwiederholung II', desc: 'Gesundheit, Besuch, Fragen und Terminplanung unter Abrufdruck kontrastieren', targetMin: 34, targetScore: 82, review: false, cultural: null },
|
||||
{ week: 5, day: 5, num: 53, type: 'vocab', title: 'Woche 5 - Checkpoint', desc: 'Diagnostischer Checkpoint zu Besuch, Termin, Frageketten und Gesundheit', targetMin: 24, targetScore: 84, review: true, cultural: null },
|
||||
{ week: 6, day: 1, num: 54, type: 'conversation', title: 'Unterwegs & Transport', desc: 'Nach Weg, Haltestelle, Fahrpreis, Ziel und Ausstieg fragen', targetMin: 26, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 6, day: 1, num: 55, type: 'vocab', title: 'Wege & Verkehr', desc: 'Verkehrs-, Richtungs- und Bewegungswortschatz in einfachen Routen verwenden', targetMin: 24, targetScore: 85, review: true, cultural: null },
|
||||
|
||||
@@ -977,51 +977,51 @@ export const BISAYA_PHASE4_LESSONS = [
|
||||
{ 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: 68, type: 'weekly_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 Sätze)', 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: 72, type: 'weekly_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: 'Stärke, Verlauf, Zeitpunkte und wiederkehrende Beschwerden ausdrücken', 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: 78, type: 'weekly_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: 'Pflegegespräche: 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: 'Körper, Symptome und Pflegewortschatz mit kurzen Schmerzsätzen 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: 82, type: 'weekly_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 },
|
||||
{ week: 9, day: 2, num: 87, type: 'conversation', title: 'Behördengänge & Formulare', desc: 'Nach Formularen, Schaltern und Terminen fragen', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 9, day: 3, num: 88, type: 'review', title: 'Woche 9 - Intensivwiederholung I', desc: 'Einkaufen und Erledigungen intensiv wiederholen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 9, day: 3, num: 88, type: 'weekly_review', title: 'Woche 9 - Intensivwiederholung I', desc: 'Einkaufen und Erledigungen intensiv wiederholen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 9, day: 3, num: 89, type: 'vocab', title: 'Spiralwiederholung - Preise & Erledigungen', desc: 'Preis- und Erledigungsmuster spiralig festigen', targetMin: 20, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 9, day: 4, num: 90, type: 'conversation', title: 'Bank, Geld & Bezahlen', desc: 'Über Bezahlen, Wechselgeld und Geldsituationen sprechen', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 9, day: 4, num: 91, type: 'vocab', title: 'Dokumente & Termine', desc: 'Papierkram, Termine und Dokumente benennen', targetMin: 18, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 9, day: 5, num: 92, type: 'review', title: 'Woche 9 - Intensivwiederholung II', desc: 'Große Mischwiederholung zu Geld, Formularen und Terminen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 9, day: 5, num: 92, type: 'weekly_review', title: 'Woche 9 - Intensivwiederholung II', desc: 'Große Mischwiederholung zu Geld, Formularen und Terminen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 9, day: 5, num: 93, type: 'vocab', title: 'Woche 9 - Checkpoint', desc: 'Checkpoint zu Einkauf, Bezahlen und Erledigungen', targetMin: 16, targetScore: 82, review: true, cultural: null },
|
||||
{ week: 10, day: 1, num: 94, type: 'conversation', title: 'Nachbarschaft & Besuche', desc: 'Mit Nachbarn sprechen und Besuche im Umfeld einordnen', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 10, day: 1, num: 95, type: 'vocab', title: 'Hilfe & Unterstützung', desc: 'Wortschatz für Hilfe, Unterstützung und soziale Nähe', targetMin: 18, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 10, day: 2, num: 96, type: 'grammar', title: 'Höflich reagieren und ablehnen', desc: 'Einladungen, Hilfe und Vorschläge fein abstufen', targetMin: 20, targetScore: 78, review: true, cultural: null },
|
||||
{ week: 10, day: 2, num: 97, type: 'conversation', title: 'Feste & Einladungen', desc: 'Über Feste, Besuche und Einladungen sprechen', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 10, day: 3, num: 98, type: 'review', title: 'Woche 10 - Intensivwiederholung I', desc: 'Soziale Situationen und Hilfe intensiv wiederholen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 10, day: 3, num: 98, type: 'weekly_review', title: 'Woche 10 - Intensivwiederholung I', desc: 'Soziale Situationen und Hilfe intensiv wiederholen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 10, day: 3, num: 99, type: 'vocab', title: 'Spiralwiederholung - Soziale Situationen', desc: 'Besuche, Hilfe und Reaktionen blockübergreifend festigen', targetMin: 20, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 10, day: 4, num: 100, type: 'conversation', title: 'Konflikte ruhig lösen', desc: 'Missverständnisse ansprechen und Spannungen abfedern', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 10, day: 4, num: 101, type: 'vocab', title: 'Gefühle im Gespräch vertiefen', desc: 'Emotionen in sozialen Gesprächen genauer ausdrücken', targetMin: 18, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 10, day: 5, num: 102, type: 'review', title: 'Woche 10 - Intensivwiederholung II', desc: 'Große Mischwiederholung zu sozialen Situationen und Emotionen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 10, day: 5, num: 102, type: 'weekly_review', title: 'Woche 10 - Intensivwiederholung II', desc: 'Große Mischwiederholung zu sozialen Situationen und Emotionen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 10, day: 5, num: 103, type: 'vocab', title: 'Woche 10 - Checkpoint', desc: 'Checkpoint zu Hilfe, Besuchen und Gefühlen', targetMin: 16, targetScore: 82, review: true, cultural: null },
|
||||
{ week: 11, day: 1, num: 104, type: 'conversation', title: 'Zuhause organisieren', desc: 'Ordnung, Haushalt und kleine Aufgaben zuhause besprechen', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 11, day: 1, num: 105, type: 'vocab', title: 'Haushalt & Reparaturen', desc: 'Wörter für Haushalt, Ordnung und kleine Reparaturen', targetMin: 18, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 11, day: 2, num: 106, type: 'grammar', title: 'Vergangenes und Pläne im Alltag', desc: 'Vergangenheit und kommende Schritte in Routinen verbinden', targetMin: 20, targetScore: 78, review: true, cultural: null },
|
||||
{ week: 11, day: 2, num: 107, type: 'conversation', title: 'Arbeit, Schule und Termine verbinden', desc: 'Mehrere Alltagsbereiche in einer Erzählung kombinieren', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 11, day: 3, num: 108, type: 'review', title: 'Woche 11 - Intensivwiederholung I', desc: 'Haushalt, Planung und Alltagslogistik intensiv wiederholen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 11, day: 3, num: 108, type: 'weekly_review', title: 'Woche 11 - Intensivwiederholung I', desc: 'Haushalt, Planung und Alltagslogistik intensiv wiederholen', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 11, day: 3, num: 109, type: 'vocab', title: 'Spiralwiederholung - Alltagsmodule', desc: 'Module 6 bis 10 zusammenziehen und wiederholen', targetMin: 20, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 11, day: 4, num: 110, type: 'conversation', title: 'Unterwegs im Familienalltag', desc: 'Familie, Wege und Termine im Alltag verbinden', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 11, day: 4, num: 111, type: 'vocab', title: 'Nachbarschaft & Orte', desc: 'Wichtige Orte und Nachbarschaftswortschatz vertiefen', targetMin: 18, targetScore: 85, review: true, cultural: null },
|
||||
{ week: 11, day: 5, num: 112, type: 'review', title: 'Woche 11 - Intensivwiederholung II', desc: 'Große Mischwiederholung zu Organisation und Familienlogistik', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 11, day: 5, num: 112, type: 'weekly_review', title: 'Woche 11 - Intensivwiederholung II', desc: 'Große Mischwiederholung zu Organisation und Familienlogistik', targetMin: 28, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 11, day: 5, num: 113, type: 'vocab', title: 'Woche 11 - Checkpoint', desc: 'Checkpoint zu Organisation, Haushalt und Alltagslogistik', targetMin: 16, targetScore: 82, review: true, cultural: null },
|
||||
{ week: 12, day: 1, num: 114, type: 'conversation', title: 'Freies Gespräch - Alltag I', desc: 'Längere Alltagsgespräche freier und stabiler führen', targetMin: 22, targetScore: 78, review: false, cultural: null },
|
||||
{ week: 12, day: 1, num: 115, type: 'vocab', title: 'Mischtraining - Kernwortschatz', desc: 'Kernwortschatz aus allen Modulen gemischt trainieren', targetMin: 20, targetScore: 85, review: true, cultural: null },
|
||||
|
||||
@@ -7,7 +7,7 @@ const BISAYA_LESSONS_24_43_BASE = [
|
||||
{ week: 3, day: 3, num: 29, type: 'conversation', title: 'Bitten & Nachfragen', desc: 'Hilfe, Wiederholung, Bedeutung und langsames Sprechen erbitten', targetMin: 18, targetScore: 80, review: false, cultural: null },
|
||||
{ week: 3, day: 4, num: 30, type: 'conversation', title: 'Kinder & Familie', desc: 'Mit Kindern kurz, klar und freundlich sprechen', targetMin: 18, targetScore: 80, review: false, cultural: 'Kurze klare Sätze funktionieren mit Kindern natürlicher als lange Erklärungen.' },
|
||||
{ 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: 32, type: 'weekly_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.' },
|
||||
|
||||
@@ -806,7 +806,7 @@ function generateExercisesFromDidactics(lesson) {
|
||||
if (String(lesson.title || '').toLowerCase().includes('zeitformen')) {
|
||||
generated.push(...buildZeitformenDrills(lesson.title));
|
||||
}
|
||||
} else if (lesson.lessonType === 'review' || lesson.didacticMode === 'intensive_review') {
|
||||
} else if (lesson.lessonType === 'review' || lesson.lessonType === 'weekly_review' || lesson.didacticMode === 'intensive_review') {
|
||||
generated = [
|
||||
buildReviewChoiceExercise(lesson, didactics, patternA, lessonPool),
|
||||
buildReviewChoiceExercise(lesson, didactics, patternB, lessonPool),
|
||||
@@ -6188,8 +6188,8 @@ async function createBisayaCourseContent() {
|
||||
exerciseNumber,
|
||||
title: exercise.title,
|
||||
instruction: exercise.instruction,
|
||||
questionData: JSON.stringify(exercise.questionData),
|
||||
answerData: JSON.stringify(exercise.answerData),
|
||||
questionData: exercise.questionData,
|
||||
answerData: exercise.answerData,
|
||||
explanation: exercise.explanation,
|
||||
createdByUserId: course.ownerUserId || systemUser.id
|
||||
};
|
||||
@@ -6266,8 +6266,8 @@ async function createBisayaCourseContent() {
|
||||
exerciseNumber: exerciseNumber++,
|
||||
title: exercise.title,
|
||||
instruction: exercise.instruction,
|
||||
questionData: JSON.stringify(exercise.questionData),
|
||||
answerData: JSON.stringify(exercise.answerData),
|
||||
questionData: exercise.questionData,
|
||||
answerData: exercise.answerData,
|
||||
explanation: exercise.explanation,
|
||||
createdByUserId: course.ownerUserId || systemUser.id
|
||||
});
|
||||
|
||||
@@ -896,7 +896,7 @@ const LESSONS = [
|
||||
targetMin: 20, targetScore: 85, review: true,
|
||||
cultural: null },
|
||||
|
||||
{ week: 1, day: 5, num: 9, type: 'review', title: 'Woche 1 - Wiederholung',
|
||||
{ week: 1, day: 5, num: 9, type: 'weekly_review', title: 'Woche 1 - Wiederholung',
|
||||
desc: 'Wiederhole alle Inhalte der ersten Woche',
|
||||
targetMin: 30, targetScore: 80, review: false,
|
||||
cultural: 'Wiederholung ist der Schlüssel zum Erfolg!' },
|
||||
@@ -962,7 +962,7 @@ const LESSONS = [
|
||||
targetMin: 18, targetScore: 85, review: true,
|
||||
cultural: null },
|
||||
|
||||
{ week: 2, day: 5, num: 22, type: 'review', title: 'Woche 2 - Wiederholung',
|
||||
{ week: 2, day: 5, num: 22, type: 'weekly_review', title: 'Woche 2 - Wiederholung',
|
||||
desc: 'Wiederhole alle Inhalte der zweiten Woche',
|
||||
targetMin: 30, targetScore: 80, review: false,
|
||||
cultural: null },
|
||||
|
||||
@@ -66,7 +66,7 @@ const LESSON_TEMPLATE = [
|
||||
targetMin: 20, targetScore: 85, review: true,
|
||||
cultural: null },
|
||||
|
||||
{ week: 1, day: 5, num: 9, type: 'review', title: 'Woche 1 - Wiederholung',
|
||||
{ week: 1, day: 5, num: 9, type: 'weekly_review', title: 'Woche 1 - Wiederholung',
|
||||
desc: 'Wiederhole alle Inhalte der ersten Woche',
|
||||
targetMin: 30, targetScore: 80, review: false,
|
||||
cultural: 'Wiederholung ist der Schlüssel zum Erfolg!' },
|
||||
@@ -132,7 +132,7 @@ const LESSON_TEMPLATE = [
|
||||
targetMin: 18, targetScore: 85, review: true,
|
||||
cultural: null },
|
||||
|
||||
{ week: 2, day: 5, num: 22, type: 'review', title: 'Woche 2 - Wiederholung',
|
||||
{ week: 2, day: 5, num: 22, type: 'weekly_review', title: 'Woche 2 - Wiederholung',
|
||||
desc: 'Wiederhole alle Inhalte der zweiten Woche',
|
||||
targetMin: 30, targetScore: 80, review: false,
|
||||
cultural: null },
|
||||
@@ -183,7 +183,7 @@ const LESSON_TEMPLATE = [
|
||||
targetMin: 20, targetScore: 85, review: true,
|
||||
cultural: null },
|
||||
|
||||
{ week: 3, day: 5, num: 32, type: 'review', title: 'Woche 3 - Wiederholung',
|
||||
{ week: 3, day: 5, num: 32, type: 'weekly_review', title: 'Woche 3 - Wiederholung',
|
||||
desc: 'Wiederhole alle Inhalte der dritten Woche',
|
||||
targetMin: 30, targetScore: 80, review: false,
|
||||
cultural: null },
|
||||
|
||||
@@ -41,6 +41,10 @@ export const LEGACY_DIDACTICS_TITLE_MAP = {
|
||||
'Kulturelle Tipps & Tricks': 'Kultur: Höflichkeit, Familie, Alltag'
|
||||
};
|
||||
|
||||
function isWeeklyReviewTitle(title) {
|
||||
return /^Woche \d+ - (?:Wiederholung|Intensivwiederholung)(?:\s|$)/.test(String(title || '').trim());
|
||||
}
|
||||
|
||||
export const LESSON_DIDACTICS = {
|
||||
'Begrüßungen & Höflichkeit': {
|
||||
learningGoals: [
|
||||
@@ -535,9 +539,13 @@ async function updateBisayaDidactics() {
|
||||
};
|
||||
const didactics = resolveDidacticsForLesson(lessonLike);
|
||||
const pedagogy = getBisayaLessonPedagogy(lessonLike.lessonNumber);
|
||||
if (!didactics && !pedagogy) continue;
|
||||
const weeklyReview = isWeeklyReviewTitle(row.title);
|
||||
if (!didactics && !pedagogy && !weeklyReview) continue;
|
||||
|
||||
const patch = {};
|
||||
if (weeklyReview) {
|
||||
patch.lessonType = 'weekly_review';
|
||||
}
|
||||
if (didactics) {
|
||||
patch.learningGoals = didactics.learningGoals || [];
|
||||
patch.corePatterns = didactics.corePatterns || [];
|
||||
|
||||
@@ -421,7 +421,7 @@ export default class VocabService {
|
||||
_supportsScheduledReview(lessonData = null) {
|
||||
const lessonType = String(lessonData?.lessonType || '').toLowerCase();
|
||||
const didacticMode = String(lessonData?.didacticMode || '').toLowerCase();
|
||||
if (lessonType === 'culture' || lessonType === 'review' || lessonType === 'vocab_review') {
|
||||
if (lessonType === 'culture' || lessonType === 'review' || lessonType === 'vocab_review' || lessonType === 'weekly_review') {
|
||||
return false;
|
||||
}
|
||||
if (didacticMode === 'intensive_review' || didacticMode === 'checkpoint') {
|
||||
@@ -1051,7 +1051,7 @@ export default class VocabService {
|
||||
if (title.includes('abschluss') || title.includes('prüfung') || title.includes('test')) {
|
||||
return 'checkpoint';
|
||||
}
|
||||
if (plainLesson.isIntensiveReview || lessonType === 'review' || lessonType === 'vocab_review' || title.includes('wiederholung')) {
|
||||
if (plainLesson.isIntensiveReview || lessonType === 'review' || lessonType === 'vocab_review' || lessonType === 'weekly_review' || title.includes('wiederholung')) {
|
||||
return 'intensive_review';
|
||||
}
|
||||
if (lessonType === 'grammar') {
|
||||
@@ -2663,7 +2663,7 @@ export default class VocabService {
|
||||
if (!plainLesson?.chapterId) {
|
||||
return list;
|
||||
}
|
||||
if (plainLesson.lessonType === 'review' || plainLesson.lessonType === 'vocab_review') {
|
||||
if (plainLesson.lessonType === 'review' || plainLesson.lessonType === 'vocab_review' || plainLesson.lessonType === 'weekly_review') {
|
||||
return list;
|
||||
}
|
||||
let rows = [];
|
||||
@@ -2899,13 +2899,47 @@ export default class VocabService {
|
||||
}
|
||||
});
|
||||
|
||||
const isWeeklyReview = plainLesson.lessonType === 'weekly_review';
|
||||
|
||||
// Lade Vokabeln aus vorherigen Lektionen (für Wiederholung UND für gemischten Vokabeltrainer)
|
||||
if (plainLesson.lessonNumber > 1) {
|
||||
if (plainLesson.lessonNumber > 1 && !isWeeklyReview) {
|
||||
plainLesson.previousLessonExercises = await this._getReviewVocabExercises(plainLesson.courseId, plainLesson.lessonNumber);
|
||||
}
|
||||
// Bei Wiederholungslektionen: Auch Lektions-Liste für Anzeige
|
||||
if (plainLesson.lessonType === 'review' || plainLesson.lessonType === 'vocab_review') {
|
||||
plainLesson.reviewLessons = await this._getReviewLessons(plainLesson.courseId, plainLesson.lessonNumber);
|
||||
if (isWeeklyReview) {
|
||||
const weeklyLessons = await this._getReviewLessons(
|
||||
plainLesson.courseId,
|
||||
plainLesson.lessonNumber,
|
||||
plainLesson.weekNumber
|
||||
);
|
||||
const weeklyExercises = await this._getReviewVocabExercises(
|
||||
plainLesson.courseId,
|
||||
plainLesson.lessonNumber,
|
||||
plainLesson.weekNumber
|
||||
);
|
||||
plainLesson.reviewLessons = weeklyLessons;
|
||||
plainLesson.previousLessonExercises = [];
|
||||
plainLesson.weeklyReviewTrainingExercises = weeklyExercises;
|
||||
plainLesson.reviewVocabExercises = this._selectWeeklyReviewExamExercises(weeklyExercises, plainLesson.id);
|
||||
plainLesson.weeklyReviewExamCount = plainLesson.reviewVocabExercises.length;
|
||||
plainLesson.weeklyReviewTrainingCount = weeklyExercises.length;
|
||||
plainLesson.corePatterns = weeklyLessons.flatMap((entry) => {
|
||||
if (Array.isArray(entry.corePatterns)) return entry.corePatterns;
|
||||
if (typeof entry.corePatterns === 'string') {
|
||||
try {
|
||||
const parsed = JSON.parse(entry.corePatterns);
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
});
|
||||
} else if (plainLesson.lessonType === 'review' || plainLesson.lessonType === 'vocab_review') {
|
||||
// Kursweite/gezielt kuratierte Reviews behalten das bisherige Verhalten.
|
||||
plainLesson.reviewLessons = await this._getReviewLessons(
|
||||
plainLesson.courseId,
|
||||
plainLesson.lessonNumber
|
||||
);
|
||||
plainLesson.reviewVocabExercises = plainLesson.previousLessonExercises || [];
|
||||
}
|
||||
|
||||
@@ -3091,19 +3125,24 @@ export default class VocabService {
|
||||
/**
|
||||
* Sammelt alle Lektionen, die in einer Wiederholungslektion wiederholt werden sollen
|
||||
*/
|
||||
async _getReviewLessons(courseId, currentLessonNumber) {
|
||||
const lessons = await VocabCourseLesson.findAll({
|
||||
where: {
|
||||
courseId: courseId,
|
||||
lessonNumber: {
|
||||
[Op.lt]: currentLessonNumber // Nur Lektionen mit kleinerer Nummer
|
||||
},
|
||||
lessonType: {
|
||||
[Op.notIn]: ['review', 'vocab_review'] // Keine anderen Wiederholungslektionen
|
||||
}
|
||||
async _getReviewLessons(courseId, currentLessonNumber, weekNumber = null) {
|
||||
const where = {
|
||||
courseId: courseId,
|
||||
lessonNumber: {
|
||||
[Op.lt]: currentLessonNumber // Nur Lektionen mit kleinerer Nummer
|
||||
},
|
||||
lessonType: {
|
||||
[Op.notIn]: ['review', 'vocab_review', 'weekly_review'] // Keine anderen Wiederholungslektionen
|
||||
}
|
||||
};
|
||||
if (weekNumber != null) {
|
||||
where.weekNumber = weekNumber;
|
||||
}
|
||||
|
||||
const lessons = await VocabCourseLesson.findAll({
|
||||
where,
|
||||
order: [['lessonNumber', 'ASC']],
|
||||
attributes: ['id', 'lessonNumber', 'title']
|
||||
attributes: ['id', 'lessonNumber', 'title', 'corePatterns']
|
||||
});
|
||||
return lessons.map(l => l.get({ plain: true }));
|
||||
}
|
||||
@@ -3111,17 +3150,22 @@ export default class VocabService {
|
||||
/**
|
||||
* Sammelt alle Grammatik-Übungen aus vorherigen Lektionen für Wiederholungslektionen
|
||||
*/
|
||||
async _getReviewVocabExercises(courseId, currentLessonNumber) {
|
||||
const previousLessons = await VocabCourseLesson.findAll({
|
||||
where: {
|
||||
courseId: courseId,
|
||||
lessonNumber: {
|
||||
[Op.lt]: currentLessonNumber
|
||||
},
|
||||
lessonType: {
|
||||
[Op.notIn]: ['review', 'vocab_review']
|
||||
}
|
||||
async _getReviewVocabExercises(courseId, currentLessonNumber, weekNumber = null) {
|
||||
const where = {
|
||||
courseId: courseId,
|
||||
lessonNumber: {
|
||||
[Op.lt]: currentLessonNumber
|
||||
},
|
||||
lessonType: {
|
||||
[Op.notIn]: ['review', 'vocab_review', 'weekly_review']
|
||||
}
|
||||
};
|
||||
if (weekNumber != null) {
|
||||
where.weekNumber = weekNumber;
|
||||
}
|
||||
|
||||
const previousLessons = await VocabCourseLesson.findAll({
|
||||
where,
|
||||
attributes: ['id']
|
||||
});
|
||||
|
||||
@@ -3156,6 +3200,16 @@ export default class VocabService {
|
||||
return exercises.map(e => e.get({ plain: true }));
|
||||
}
|
||||
|
||||
_selectWeeklyReviewExamExercises(exercises = [], lessonId) {
|
||||
const list = Array.isArray(exercises) ? exercises : [];
|
||||
if (list.length === 0) return [];
|
||||
|
||||
const seed = (Number(lessonId) * 100003) >>> 0;
|
||||
const percentage = 40 + (seed % 21);
|
||||
const targetCount = Math.max(1, Math.ceil((list.length * percentage) / 100));
|
||||
return this._seededShuffle(list.slice(), seed).slice(0, targetCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sammelt Grammatik‑Übungen aus vorherigen Lektionen derselben Woche
|
||||
*/
|
||||
@@ -3166,7 +3220,7 @@ export default class VocabService {
|
||||
courseId: courseId,
|
||||
weekNumber: weekNumber,
|
||||
lessonNumber: { [Op.lt]: currentLessonNumber },
|
||||
lessonType: { [Op.notIn]: ['review', 'vocab_review'] }
|
||||
lessonType: { [Op.notIn]: ['review', 'vocab_review', 'weekly_review'] }
|
||||
},
|
||||
attributes: ['id']
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user