feat: erweitere Vokabeltrainer um Unterstützung für Checkpoint-Lektionen und verbessere Übungsauswahl
All checks were successful
Deploy to production / deploy (push) Successful in 2m1s

This commit is contained in:
Torsten Schulz (local)
2026-05-27 16:53:32 +02:00
parent 871456a6f7
commit 0bde421155
2 changed files with 50 additions and 5 deletions

View File

@@ -2900,12 +2900,45 @@ export default class VocabService {
}); });
const isWeeklyReview = plainLesson.lessonType === 'weekly_review'; const isWeeklyReview = plainLesson.lessonType === 'weekly_review';
const isCheckpoint = (String(plainLesson.didacticMode || '').toLowerCase() === 'checkpoint')
|| (/checkpoint/i.test(String(plainLesson.title || '')) && plainLesson.weekNumber != null);
// Lade Vokabeln aus vorherigen Lektionen (für Wiederholung UND für gemischten Vokabeltrainer) // Lade Vokabeln aus vorherigen Lektionen (für Wiederholung UND für gemischten Vokabeltrainer)
if (plainLesson.lessonNumber > 1 && !isWeeklyReview) { if (plainLesson.lessonNumber > 1 && !isWeeklyReview && !isCheckpoint) {
plainLesson.previousLessonExercises = await this._getReviewVocabExercises(plainLesson.courseId, plainLesson.lessonNumber); plainLesson.previousLessonExercises = await this._getReviewVocabExercises(plainLesson.courseId, plainLesson.lessonNumber);
} }
if (isWeeklyReview) {
// Checkpoint-Lektionen: kleine Stichprobe aus den Wochen-Übungen (ca. 10-30%)
if (isCheckpoint) {
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._selectCheckpointExamExercises(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 (isWeeklyReview) {
const weeklyLessons = await this._getReviewLessons( const weeklyLessons = await this._getReviewLessons(
plainLesson.courseId, plainLesson.courseId,
plainLesson.lessonNumber, plainLesson.lessonNumber,
@@ -3210,6 +3243,17 @@ export default class VocabService {
return this._seededShuffle(list.slice(), seed).slice(0, targetCount); return this._seededShuffle(list.slice(), seed).slice(0, targetCount);
} }
_selectCheckpointExamExercises(exercises = [], lessonId) {
const list = Array.isArray(exercises) ? exercises : [];
if (list.length === 0) return [];
const seed = (Number(lessonId) * 100003) >>> 0;
// Checkpoints: smaller sample ~10-30%
const percentage = 10 + (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 * Sammelt GrammatikÜbungen aus vorherigen Lektionen derselben Woche
*/ */

View File

@@ -1390,11 +1390,12 @@ export default {
} }
return core; return core;
}, },
/** Für Wiederholungslektionen: Übungen aus vorherigen Lektionen (Kapitelprüfung). Sonst: eigene Grammatik-Übungen. */ /** Für Wiederholungslektionen und Checkpoints: Übungen aus vorherigen Lektionen (Kapitelprüfung). Sonst: eigene Grammatik-Übungen. */
effectiveExercises() { effectiveExercises() {
if (!this.lesson) return []; if (!this.lesson) return [];
const isReview = ['review', 'vocab_review', 'weekly_review'].includes(this.lesson.lessonType); // Wenn die API bereits reviewVocabExercises liefert (z.B. für Wochenwiederholungen oder Checkpoints),
if (isReview && this.lesson.reviewVocabExercises && Array.isArray(this.lesson.reviewVocabExercises) && this.lesson.reviewVocabExercises.length > 0) { // nutze diese explizit sie enthalten die Kapitel-/Checkpoint-Übungen.
if (this.lesson.reviewVocabExercises && Array.isArray(this.lesson.reviewVocabExercises) && this.lesson.reviewVocabExercises.length > 0) {
return this.lesson.reviewVocabExercises; return this.lesson.reviewVocabExercises;
} }
if (this.lesson.grammarExercises && Array.isArray(this.lesson.grammarExercises)) { if (this.lesson.grammarExercises && Array.isArray(this.lesson.grammarExercises)) {