From 8f55f63f77ebb3c52abf791f126d3fde2031bc14 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 19 Jan 2026 19:12:54 +0100 Subject: [PATCH] Enhance logging and conditional rendering in VocabService and VocabLessonView - Added detailed logging in VocabService for lesson retrieval, including lesson ID, title, and exercise count. - Improved conditional rendering in VocabLessonView to handle cases where grammar exercises may not be present, enhancing user experience. - Updated logging in VocabLessonView to provide insights into loaded lessons and exercises, aiding in debugging and monitoring. --- backend/services/vocabService.js | 9 ++- check-lesson-exercises.sh | 33 ++++++++ check-vocab-schema.sql | 38 +++++++++ debug-lesson-exercises.js | 78 +++++++++++++++++++ frontend/src/views/social/VocabLessonView.vue | 18 +++-- 5 files changed, 168 insertions(+), 8 deletions(-) create mode 100755 check-lesson-exercises.sh create mode 100644 check-vocab-schema.sql create mode 100755 debug-lesson-exercises.js diff --git a/backend/services/vocabService.js b/backend/services/vocabService.js index 422d478..dd24dc5 100644 --- a/backend/services/vocabService.js +++ b/backend/services/vocabService.js @@ -883,7 +883,14 @@ export default class VocabService { throw err; } - return lesson.get({ plain: true }); + const plainLesson = lesson.get({ plain: true }); + console.log(`[getLesson] Lektion ${lessonId} geladen:`, { + id: plainLesson.id, + title: plainLesson.title, + exerciseCount: plainLesson.grammarExercises ? plainLesson.grammarExercises.length : 0, + exercises: plainLesson.grammarExercises + }); + return plainLesson; } async addLessonToCourse(hashedUserId, courseId, { chapterId, lessonNumber, title, description, weekNumber, dayNumber, lessonType, audioUrl, culturalNotes, targetMinutes, targetScorePercent, requiresReview }) { diff --git a/check-lesson-exercises.sh b/check-lesson-exercises.sh new file mode 100755 index 0000000..b237568 --- /dev/null +++ b/check-lesson-exercises.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Script zum Prüfen, ob Übungen für eine Lektion vorhanden sind +# Verwendung: ./check-lesson-exercises.sh [lesson_id] + +LESSON_ID="${1:-1}" + +echo "🔍 Prüfe Übungen für Lektion ID: $LESSON_ID" +echo "" + +psql -U yourpart -d yp3 << EOF +-- Prüfe Lektion +SELECT + l.id, + l.title, + l.course_id, + COUNT(e.id) as exercise_count +FROM community.vocab_course_lesson l +LEFT JOIN community.vocab_grammar_exercise e ON e.lesson_id = l.id +WHERE l.id = $LESSON_ID +GROUP BY l.id, l.title, l.course_id; + +-- Zeige alle Übungen für diese Lektion +SELECT + e.id, + e.exercise_number, + e.title, + e.exercise_type_id, + et.name as exercise_type_name +FROM community.vocab_grammar_exercise e +LEFT JOIN community.vocab_grammar_exercise_type et ON et.id = e.exercise_type_id +WHERE e.lesson_id = $LESSON_ID +ORDER BY e.exercise_number; +EOF diff --git a/check-vocab-schema.sql b/check-vocab-schema.sql new file mode 100644 index 0000000..26261cc --- /dev/null +++ b/check-vocab-schema.sql @@ -0,0 +1,38 @@ +-- ============================================ +-- Prüfe ob alle notwendigen Spalten vorhanden sind +-- ============================================ +-- Führe diese Queries auf dem Server aus, um zu prüfen, ob alles vorhanden ist + +-- Prüfe native_language_id in vocab_course +SELECT + column_name, + data_type, + is_nullable +FROM information_schema.columns +WHERE table_schema = 'community' + AND table_name = 'vocab_course' + AND column_name = 'native_language_id'; + +-- Prüfe cultural_notes in vocab_course_lesson +SELECT + column_name, + data_type, + is_nullable +FROM information_schema.columns +WHERE table_schema = 'community' + AND table_name = 'vocab_course_lesson' + AND column_name = 'cultural_notes'; + +-- Prüfe ob vocab_grammar_exercise Tabelle existiert +SELECT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'community' + AND table_name = 'vocab_grammar_exercise' +); + +-- Prüfe ob vocab_grammar_exercise_type Tabelle existiert +SELECT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'community' + AND table_name = 'vocab_grammar_exercise_type' +); diff --git a/debug-lesson-exercises.js b/debug-lesson-exercises.js new file mode 100755 index 0000000..b41d017 --- /dev/null +++ b/debug-lesson-exercises.js @@ -0,0 +1,78 @@ +#!/usr/bin/env node +/** + * Debug-Script zum Prüfen, ob Übungen für eine Lektion vorhanden sind + * Verwendung: node debug-lesson-exercises.js [lessonId] + */ + +import { sequelize } from './backend/utils/sequelize.js'; +import VocabCourseLesson from './backend/models/community/vocab_course_lesson.js'; +import VocabGrammarExercise from './backend/models/community/vocab_grammar_exercise.js'; + +const lessonId = process.argv[2] ? parseInt(process.argv[2]) : 1; + +async function debugLesson() { + try { + await sequelize.authenticate(); + console.log('✅ Datenbankverbindung erfolgreich\n'); + + // Lade Lektion mit Übungen (wie im Backend) + const lesson = await VocabCourseLesson.findByPk(lessonId, { + include: [ + { + model: require('./backend/models/community/vocab_course.js').default, + as: 'course' + }, + { + model: VocabGrammarExercise, + as: 'grammarExercises', + include: [ + { + model: require('./backend/models/community/vocab_grammar_exercise_type.js').default, + as: 'exerciseType' + } + ], + required: false, + separate: true, + order: [['exerciseNumber', 'ASC']] + } + ] + }); + + if (!lesson) { + console.log(`❌ Lektion ${lessonId} nicht gefunden`); + return; + } + + console.log(`📚 Lektion: ${lesson.title} (ID: ${lesson.id})`); + console.log(` Kurs: ${lesson.course?.title || 'N/A'}`); + console.log(` Übungen (via Include): ${lesson.grammarExercises ? lesson.grammarExercises.length : 0}\n`); + + // Prüfe direkt in der Datenbank + const directExercises = await VocabGrammarExercise.findAll({ + where: { lessonId: lesson.id }, + order: [['exerciseNumber', 'ASC']] + }); + + console.log(`📊 Direkte Abfrage: ${directExercises.length} Übung(en) gefunden`); + directExercises.forEach((ex, idx) => { + console.log(` ${idx + 1}. ${ex.title} (ID: ${ex.id}, Typ: ${ex.exerciseTypeId})`); + }); + + // Plain object + const plain = lesson.get({ plain: true }); + console.log(`\n📦 Plain Object:`); + console.log(` grammarExercises: ${plain.grammarExercises ? plain.grammarExercises.length : 'undefined'}`); + if (plain.grammarExercises && plain.grammarExercises.length > 0) { + plain.grammarExercises.forEach((ex, idx) => { + console.log(` ${idx + 1}. ${ex.title} (ID: ${ex.id})`); + }); + } + + } catch (error) { + console.error('❌ Fehler:', error); + } finally { + await sequelize.close(); + } +} + +debugLesson(); diff --git a/frontend/src/views/social/VocabLessonView.vue b/frontend/src/views/social/VocabLessonView.vue index 8e42e32..ff43a45 100644 --- a/frontend/src/views/social/VocabLessonView.vue +++ b/frontend/src/views/social/VocabLessonView.vue @@ -64,9 +64,10 @@ -
-

{{ $t('socialnetwork.vocab.courses.grammarExercises') }}

-
+
+
+

{{ $t('socialnetwork.vocab.courses.grammarExercises') }}

+

{{ exercise.title }}

{{ exercise.instruction }}

@@ -155,10 +156,9 @@
{{ JSON.stringify(exercise, null, 2) }}
-
- -
-

{{ $t('socialnetwork.vocab.courses.noExercises') }}

+
+

{{ $t('socialnetwork.vocab.courses.noExercises') }}

+
@@ -264,13 +264,17 @@ export default { try { const res = await apiClient.get(`/api/vocab/lessons/${this.lessonId}`); this.lesson = res.data; + console.log('[VocabLessonView] Geladene Lektion:', this.lesson); + console.log('[VocabLessonView] Übungen:', this.lesson?.grammarExercises); // Initialisiere Übungen aus der Lektion oder lade sie separat if (this.lesson && this.lesson.id) { if (this.lesson.grammarExercises && this.lesson.grammarExercises.length > 0) { // Übungen sind bereits in der Lektion enthalten + console.log('[VocabLessonView] Übungen bereits in Lektion enthalten:', this.lesson.grammarExercises.length); this.initializeExercises(this.lesson.grammarExercises); } else { // Lade Übungen separat (Fallback) + console.log('[VocabLessonView] Lade Übungen separat...'); await this.loadGrammarExercises(); } }