Fix: Drei Bugs behoben (debug-Endpoint, shutdown, doppelte Statistik)

- /debug zeigte immer 0 Lektionen: stale Modul-Import durch
  Attributzugriff (helpers.lessons/DATA_PATH) ersetzt
- /shutdown stürzte mit ImportError ab: defekten, ungenutzten
  Import 'from flask_wtf.csrf import csrf' entfernt
- Doppelte LessonStatistic-Einträge bei Lektionsabschluss:
  redundanten serverseitigen save_lesson_statistics-Aufruf entfernt
  (Frontend speichert via /save_lesson_statistics); Completion-
  Erkennung und Fortschritt-Reset bleiben erhalten

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-22 11:49:17 +02:00
commit 8c621b23cb
2 changed files with 18 additions and 30 deletions

View file

@ -9,9 +9,8 @@ import logging
import threading
import time
from flask import Blueprint, request, jsonify, current_app
from services import helpers
from services.helpers import (
lessons,
DATA_PATH,
repair_json,
load_lessons,
create_sample_lessons
@ -37,19 +36,19 @@ def debug():
json_content = "Datei nicht gefunden"
json_error = None
try:
if os.path.exists(DATA_PATH):
with open(DATA_PATH, "r", encoding="utf-8") as f:
if os.path.exists(helpers.DATA_PATH):
with open(helpers.DATA_PATH, "r", encoding="utf-8") as f:
json_content = f.read()
except Exception as e:
json_content = f"Fehler beim Lesen der Datei: {e}"
json_error = str(e)
debug_info = {
'lessons_loaded': len(lessons),
'lessons_sample': lessons[:3] if lessons else [], # Nur erste 3 anzeigen
'data_path': DATA_PATH,
'file_exists': os.path.exists(DATA_PATH),
'file_size': os.path.getsize(DATA_PATH) if os.path.exists(DATA_PATH) else 0,
'lessons_loaded': len(helpers.lessons),
'lessons_sample': helpers.lessons[:3] if helpers.lessons else [], # Nur erste 3 anzeigen
'data_path': helpers.DATA_PATH,
'file_exists': os.path.exists(helpers.DATA_PATH),
'file_size': os.path.getsize(helpers.DATA_PATH) if os.path.exists(helpers.DATA_PATH) else 0,
'file_content_preview': json_content[:500] + '...' if len(json_content) > 500 else json_content,
'json_error': json_error,
'current_progress': {
@ -69,8 +68,8 @@ def debug():
def repair_json_endpoint():
"""Endpoint zum manuellen Reparieren der JSON-Datei"""
try:
if os.path.exists(DATA_PATH):
with open(DATA_PATH, "r", encoding="utf-8") as f:
if os.path.exists(helpers.DATA_PATH):
with open(helpers.DATA_PATH, "r", encoding="utf-8") as f:
content = f.read()
repaired_content = repair_json(content)
@ -80,12 +79,12 @@ def repair_json_endpoint():
json.loads(repaired_content)
# Backup der originalen Datei erstellen
backup_path = DATA_PATH + ".backup"
backup_path = helpers.DATA_PATH + ".backup"
with open(backup_path, "w", encoding="utf-8") as f:
f.write(content)
# Reparierte Version speichern
with open(DATA_PATH, "w", encoding="utf-8") as f:
with open(helpers.DATA_PATH, "w", encoding="utf-8") as f:
f.write(repaired_content)
# Lektionen neu laden
@ -94,7 +93,7 @@ def repair_json_endpoint():
return jsonify({
'status': 'success',
'message': f'JSON erfolgreich repariert. Backup erstellt: {backup_path}',
'lessons_loaded': len(lessons)
'lessons_loaded': len(helpers.lessons)
})
except json.JSONDecodeError as e:
@ -135,7 +134,6 @@ def recreate_lessons():
@utils_bp.route('/shutdown', methods=['POST'])
def shutdown():
"""Beendet den Flask-Server (nur für lokale Desktop-Nutzung)"""
from flask_wtf.csrf import csrf
try:
logger.info("Server-Shutdown angefordert")

View file

@ -141,21 +141,11 @@ class TrainingService:
if lesson_completed:
logger.info(f"Lektion {lesson_index} abgeschlossen!")
# Calculate final statistics
stats = self.statistics_service.calculate_typing_statistics(
user_input, current_text, elapsed_time
)
# Hinweis: Das Speichern der Statistik übernimmt das Frontend über
# den dedizierten Endpoint /save_lesson_statistics. Hier wird NICHT
# zusätzlich gespeichert, um doppelte Statistik-Einträge zu vermeiden.
# Save statistics
self.statistics_service.save_lesson_statistics(
lesson_index=lesson_index,
chars_per_minute=stats['typing_speed'],
error_rate=stats['error_rate'],
wpm=stats['words_per_minute'],
training_duration=total_elapsed_time / 1000.0
)
# Reset lesson progress
# Lektions-Fortschritt zurücksetzen
self.progress_service.complete_lesson(lesson_index)
# Update session