feat: füge generische Fallback-Übungen hinzu, wenn keine didaktischen Inhalte vorhanden sind
All checks were successful
Deploy to production / deploy (push) Successful in 30s
All checks were successful
Deploy to production / deploy (push) Successful in 30s
This commit is contained in:
@@ -119,7 +119,7 @@ jobs:
|
||||
# By default we run the deploy script in --dry-run mode. To enable the
|
||||
# actual run set the secret PHASE3_UPDATE=1 in the repo settings.
|
||||
RUN_FLAG="--dry-run"
|
||||
if [ "${{ secrets.PHASE3_UPDATE:-}}" = "1" ]; then
|
||||
if [ "${{ secrets.PHASE3_UPDATE }}" = "1" ]; then
|
||||
RUN_FLAG=""
|
||||
fi
|
||||
|
||||
|
||||
@@ -826,6 +826,50 @@ function generateExercisesFromDidactics(lesson) {
|
||||
return generated.filter(Boolean);
|
||||
}
|
||||
|
||||
// Generic fallback exercises when no didactics/exercises are present.
|
||||
function buildGenericFallbackExercises(lesson) {
|
||||
const title = lesson.title || 'Unbekannte Lektion';
|
||||
const clean = String(title).replace(/[^\w\säöüÄÖÜß-]/g, '').trim();
|
||||
const tokens = clean.split(/\s+/).slice(0, 4);
|
||||
|
||||
const mcOptions = [clean, ...tokens.map((t, i) => `${t} alt ${i+1}`)].slice(0,4);
|
||||
|
||||
const multipleChoice = {
|
||||
exerciseTypeId: 2,
|
||||
title: `${title}: Beispielprüfung (automatisch)` ,
|
||||
instruction: 'Wähle die passende Formulierung (Platzhalter).',
|
||||
questionData: {
|
||||
type: 'multiple_choice',
|
||||
question: `Welcher Ausdruck passt am besten zur Lektion "${title}"?`,
|
||||
options: mcOptions
|
||||
},
|
||||
answerData: {
|
||||
type: 'multiple_choice',
|
||||
correctAnswer: 0
|
||||
},
|
||||
explanation: 'Automatisch erstellte Platzhalterprüfung — bitte durch sprachspezifische Übungen ersetzen.'
|
||||
};
|
||||
|
||||
const gapText = tokens.length ? `${tokens.join(' ')} {gap}` : `{gap}`;
|
||||
const gapFill = {
|
||||
exerciseTypeId: 1,
|
||||
title: `${title}: Lückentest (automatisch)`,
|
||||
instruction: 'Fülle die Lücke mit dem passenden Wort.',
|
||||
questionData: {
|
||||
type: 'gap_fill',
|
||||
text: gapText,
|
||||
gaps: 1
|
||||
},
|
||||
answerData: {
|
||||
type: 'gap_fill',
|
||||
answers: [tokens[0] || '']
|
||||
},
|
||||
explanation: 'Automatisch erzeugte Lücke, dient als Kurznotbehelf.'
|
||||
};
|
||||
|
||||
return [multipleChoice, gapFill];
|
||||
}
|
||||
|
||||
// Bisaya-spezifische Übungen basierend auf Lektionsthemen
|
||||
const BISAYA_EXERCISES = {
|
||||
// Lektion 24: Gefühle im Alltag
|
||||
@@ -6078,7 +6122,17 @@ async function createBisayaCourseContent() {
|
||||
});
|
||||
}
|
||||
|
||||
const exercises = getExercisesForLesson(lesson);
|
||||
let exercises = getExercisesForLesson(lesson);
|
||||
|
||||
// If generator produced nothing, create a small safe fallback so the UI
|
||||
// doesn't show the generic placeholder. This keeps behaviour deterministic
|
||||
// and avoids empty lesson pages when didactics are missing.
|
||||
if ((!exercises || exercises.length === 0) && !forceRebuildAll) {
|
||||
const fallback = buildGenericFallbackExercises(lesson);
|
||||
if (fallback && fallback.length) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
if (exercises.length === 0) {
|
||||
const existingCount = await VocabGrammarExercise.count({ where: { lessonId: lesson.id } });
|
||||
if (existingCount > 0) {
|
||||
|
||||
Reference in New Issue
Block a user