From 8c621b23cb446bbe740e345068a25976eddecc56 Mon Sep 17 00:00:00 2001 From: dschlueter Date: Mon, 22 Jun 2026 11:49:17 +0200 Subject: [PATCH] Fix: Drei Bugs behoben (debug-Endpoint, shutdown, doppelte Statistik) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /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 --- routes/utils.py | 28 +++++++++++++--------------- services/training_service.py | 18 ++++-------------- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/routes/utils.py b/routes/utils.py index effaea9..fe48b30 100644 --- a/routes/utils.py +++ b/routes/utils.py @@ -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") diff --git a/services/training_service.py b/services/training_service.py index 9b9d131..6495a23 100644 --- a/services/training_service.py +++ b/services/training_service.py @@ -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