From 712370cad3e93ffa379cff4b004ba5a2625d88f8 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Thu, 16 Apr 2026 22:44:57 +0200 Subject: [PATCH] feat(bisaya-course): add didactics fragments for "Haus & Familie" lessons - Introduced comprehensive didactics snippets for the "Haus & Familie" lesson, including learning goals, core patterns, grammar focus, speaking prompts, and practical tasks. - Updated the lesson retrieval logic to incorporate these new fragments as a fallback for core patterns, enhancing the robustness of lesson content delivery. - Modified the vocab service to utilize the new didactics fragments, ensuring a seamless integration into the existing lesson structure. --- backend/scripts/bisaya-course-phase1.js | 60 ++++++++++++++++++++++ backend/scripts/update-bisaya-didactics.js | 2 + backend/services/vocabService.js | 21 ++++++-- 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/backend/scripts/bisaya-course-phase1.js b/backend/scripts/bisaya-course-phase1.js index d15c38c..411dec8 100644 --- a/backend/scripts/bisaya-course-phase1.js +++ b/backend/scripts/bisaya-course-phase1.js @@ -22,3 +22,63 @@ export const BISAYA_PHASE1_DIDACTICS = { ] } }; + +/** + * Volle Didaktik-Snippets für Lektionen, die in update-bisaya-didactics.js gepflegt werden sollen + * und als API-Fallback dienen, wenn core_patterns in der DB fehlen (z. B. Kurz-Wiederholung). + */ +export const BISAYA_DIDACTICS_FRAGMENTS = { + 'Haus & Familie': { + learningGoals: [ + 'Wichtige Wörter für Haus, Räume und Familie zuordnen und aussprechen.', + 'Mit „Naa … sa …“ sagen, wo sich jemand oder etwas im Haus befindet.', + 'Kurze Sätze über Zuhause und Familie verstehen und nachsprechen.' + ], + corePatterns: [ + { target: 'Balay', gloss: 'Haus' }, + { target: 'Kwarto', gloss: 'Zimmer' }, + { target: 'Kusina', gloss: 'Küche' }, + { target: 'Sala', gloss: 'Wohnzimmer' }, + { target: 'Banyo', gloss: 'Badezimmer' }, + { target: 'Pultahan', gloss: 'Tür' }, + { target: 'Bintana', gloss: 'Fenster' }, + { target: 'Atop', gloss: 'Dach' }, + { target: 'Pamilya', gloss: 'Familie' }, + { target: 'Among pamilya', gloss: 'unsere Familie' }, + { target: 'Naa ko sa balay.', gloss: 'Ich bin zu Hause.' }, + { target: 'Naa sila sa kusina.', gloss: 'Sie sind in der Küche.' }, + { target: 'Asa ang kusina?', gloss: 'Wo ist die Küche?' }, + { target: 'Ang among balay.', gloss: 'Unser Haus.' } + ], + grammarFocus: [ + { + title: 'Naa … sa … für Ort', + text: '„Naa“ drückt aus, dass jemand oder etwas irgendwo ist; „sa“ verbindet mit dem Ort.', + example: 'Naa ko sa balay. Naa sila sa kusina.' + }, + { + title: 'among = unser (Plural inklusiv)', + text: '„Among“ passt zu „wir/unsere“ im Sinne von Familie oder Gruppe.', + example: 'Among pamilya. Ang among balay.' + } + ], + speakingPrompts: [ + { + title: 'Räume benennen', + prompt: 'Nenne Küche, Wohnzimmer und Badezimmer auf Bisaya.', + cue: 'Kusina, sala, banyo.' + }, + { + title: 'Wer ist wo?', + prompt: 'Sage, dass du zu Hause bist, und frage, wo die Küche ist.', + cue: 'Naa ko sa balay. Asa ang kusina?' + } + ], + practicalTasks: [ + { + title: 'Rundgang', + text: 'Geh in Gedanken durch dein Zuhause und benenne jeden Raum laut auf Bisaya.' + } + ] + } +}; diff --git a/backend/scripts/update-bisaya-didactics.js b/backend/scripts/update-bisaya-didactics.js index 9fdd682..278a217 100644 --- a/backend/scripts/update-bisaya-didactics.js +++ b/backend/scripts/update-bisaya-didactics.js @@ -9,6 +9,7 @@ import { sequelize } from '../utils/sequelize.js'; import VocabCourseLesson from '../models/community/vocab_course_lesson.js'; import { getBisayaLessonPedagogy } from './bisaya-course-phase2-pedagogy.js'; +import { BISAYA_DIDACTICS_FRAGMENTS } from './bisaya-course-phase1.js'; /** Alte Kurstitel → aktueller Schlüssel in LESSON_DIDACTICS (bestehende Datenbanken). */ export const LEGACY_DIDACTICS_TITLE_MAP = { @@ -140,6 +141,7 @@ export const LESSON_DIDACTICS = { { title: 'Gesprächspraxis', text: 'Spiele einen kurzen Familienaustausch mit Frage, Antwort und Fürsorge nach.' } ] }, + 'Haus & Familie': BISAYA_DIDACTICS_FRAGMENTS['Haus & Familie'], 'Gefühle & Zuneigung': { learningGoals: [ 'Wichtige Gefühle und Zuneigungsformeln sicher unterscheiden.', diff --git a/backend/services/vocabService.js b/backend/services/vocabService.js index 33d5a01..28efc88 100644 --- a/backend/services/vocabService.js +++ b/backend/services/vocabService.js @@ -12,7 +12,7 @@ import UserParam from '../models/community/user_param.js'; import { sequelize } from '../utils/sequelize.js'; import { notifyUser } from '../utils/socket.js'; import { Op } from 'sequelize'; -import { BISAYA_PHASE1_DIDACTICS } from '../scripts/bisaya-course-phase1.js'; +import { BISAYA_PHASE1_DIDACTICS, BISAYA_DIDACTICS_FRAGMENTS } from '../scripts/bisaya-course-phase1.js'; export default class VocabService { _normalizeIsoDate(value) { @@ -979,13 +979,26 @@ export default class VocabService { const learningGoals = this._normalizeStringList(plainLesson.learningGoals); const extractedTrainerVocabs = this._extractTrainerVocabsFromExercises(grammarExercises); const phase1FallbackCorePatterns = BISAYA_PHASE1_DIDACTICS[plainLesson.title]?.corePatterns || []; - const corePatterns = this._mergeCorePatternGlosses( + let resolvedCorePatterns = this._mergeCorePatternGlosses( this._enrichCorePatternsWithGloss( this._normalizeCorePatternList(plainLesson.corePatterns), extractedTrainerVocabs ), phase1FallbackCorePatterns ); + if ( + !resolvedCorePatterns.length + && BISAYA_DIDACTICS_FRAGMENTS[plainLesson.title]?.corePatterns?.length + ) { + const frag = BISAYA_DIDACTICS_FRAGMENTS[plainLesson.title]; + resolvedCorePatterns = this._mergeCorePatternGlosses( + this._enrichCorePatternsWithGloss( + this._normalizeCorePatternList(frag.corePatterns), + extractedTrainerVocabs + ), + phase1FallbackCorePatterns + ); + } const grammarFocus = this._normalizeStructuredList(plainLesson.grammarFocus, ['title', 'text', 'example']); const explicitSpeakingPrompts = this._normalizeStructuredList(plainLesson.speakingPrompts, ['title', 'prompt', 'cue']); const practicalTasks = this._normalizeStructuredList(plainLesson.practicalTasks, ['title', 'text']); @@ -998,8 +1011,8 @@ export default class VocabService { 'Ein bis zwei Satzmuster aktiv anwenden.', 'Kurze Sätze oder Mini-Dialoge zum Thema selbst bilden.' ], - corePatterns: corePatterns.length > 0 - ? corePatterns + corePatterns: resolvedCorePatterns.length > 0 + ? resolvedCorePatterns : this._mergeCorePatternGlosses( this._enrichCorePatternsWithGloss( uniquePatterns.slice(0, 5).map((s) => ({ target: String(s || '').trim(), gloss: '' })).filter((p) => p.target),