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.
This commit is contained in:
Torsten Schulz (local)
2026-01-19 19:12:54 +01:00
parent 0331ffeb93
commit 8f55f63f77
5 changed files with 168 additions and 8 deletions

View File

@@ -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 }) {

33
check-lesson-exercises.sh Executable file
View File

@@ -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

38
check-vocab-schema.sql Normal file
View File

@@ -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'
);

78
debug-lesson-exercises.js Executable file
View File

@@ -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();

View File

@@ -64,9 +64,10 @@
</div>
<!-- Übungen-Tab -->
<div v-if="activeTab === 'exercises' && lesson.grammarExercises && lesson.grammarExercises.length > 0" class="grammar-exercises">
<h3>{{ $t('socialnetwork.vocab.courses.grammarExercises') }}</h3>
<div v-for="exercise in lesson.grammarExercises" :key="exercise.id" class="exercise-item">
<div v-if="activeTab === 'exercises'" class="grammar-exercises">
<div v-if="lesson.grammarExercises && lesson.grammarExercises.length > 0">
<h3>{{ $t('socialnetwork.vocab.courses.grammarExercises') }}</h3>
<div v-for="exercise in lesson.grammarExercises" :key="exercise.id" class="exercise-item">
<h4>{{ exercise.title }}</h4>
<p v-if="exercise.instruction" class="exercise-instruction">{{ exercise.instruction }}</p>
@@ -155,10 +156,9 @@
<pre>{{ JSON.stringify(exercise, null, 2) }}</pre>
</div>
</div>
</div>
<div v-else>
<p>{{ $t('socialnetwork.vocab.courses.noExercises') }}</p>
<div v-else>
<p>{{ $t('socialnetwork.vocab.courses.noExercises') }}</p>
</div>
</div>
</div>
</div>
@@ -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();
}
}