From f0fe4c29d51f30b5e1b714d6d3a9b345b202f7b5 Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Sun, 1 Jun 2025 04:36:33 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20Improved=20backend=20structure?= =?UTF-8?q?=20&=20documentation,=20added=20new=20GLASSMORPHISM=5FNOTIFICAT?= =?UTF-8?q?IONS=20feature=20=F0=9F=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/__pycache__/app.cpython-313.pyc | Bin 316059 -> 326957 bytes backend/app.py | 256 +++++++-- .../__pycache__/admin_api.cpython-313.pyc | Bin 0 -> 24402 bytes backend/database/myp.db | Bin 118784 -> 118784 bytes backend/database/myp.db-shm | Bin 32768 -> 32768 bytes backend/database/myp.db-wal | Bin 8272 -> 8272 bytes backend/docs/GLASSMORPHISM_NOTIFICATIONS.md | 1 + backend/fix_public_stats.py | 130 +++++ backend/logs/admin_api/admin_api.log | 0 backend/logs/analytics/analytics.log | 7 + backend/logs/app/app.log | 69 +++ backend/logs/backup/backup.log | 7 + backend/logs/calendar/calendar.log | 3 + backend/logs/dashboard/dashboard.log | 28 + backend/logs/database/database.log | 7 + .../email_notification/email_notification.log | 7 + backend/logs/jobs/jobs.log | 5 + backend/logs/maintenance/maintenance.log | 14 + .../logs/multi_location/multi_location.log | 14 + backend/logs/permissions/permissions.log | 7 + .../logs/printer_monitor/printer_monitor.log | 75 +++ backend/logs/printers/printers.log | 25 + backend/logs/scheduler/scheduler.log | 13 + backend/logs/security/security.log | 7 + .../shutdown_manager/shutdown_manager.log | 23 + backend/logs/startup/startup.log | 63 +++ backend/logs/user/user.log | 2 + backend/logs/windows_fixes/windows_fixes.log | 28 + .../static/js/glassmorphism-notifications.js | 513 +++++++++++++----- backend/templates/admin.html | 221 ++++++++ backend/templates/index.html | 5 +- 31 files changed, 1349 insertions(+), 181 deletions(-) create mode 100644 backend/blueprints/__pycache__/admin_api.cpython-313.pyc create mode 100644 backend/docs/GLASSMORPHISM_NOTIFICATIONS.md create mode 100644 backend/fix_public_stats.py create mode 100644 backend/logs/admin_api/admin_api.log diff --git a/backend/__pycache__/app.cpython-313.pyc b/backend/__pycache__/app.cpython-313.pyc index cc980458295c50036833fe5d64effbbb1e13fb0a..90fd997186caea4893d3d4cd080a9d15c807ab10 100644 GIT binary patch delta 28450 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 delta 21137 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 BonHU| diff --git a/backend/app.py b/backend/app.py index 54be710d..5be9b641 100644 --- a/backend/app.py +++ b/backend/app.py @@ -1254,46 +1254,133 @@ def user_update_settings(): finally: db_session.close() -@app.route("/api/user/settings", methods=["GET"]) +@app.route("/api/user/settings", methods=["GET", "POST"]) @login_required def get_user_settings(): - """Holt die aktuellen Benutzereinstellungen""" - try: - # Einstellungen aus Session oder Datenbank laden - user_settings = session.get('user_settings', {}) - - # Standard-Einstellungen falls keine vorhanden - default_settings = { - "theme": "system", - "reduced_motion": False, - "contrast": "normal", - "notifications": { - "new_jobs": True, - "job_updates": True, - "system": True, - "email": False - }, - "privacy": { - "activity_logs": True, - "two_factor": False, - "auto_logout": 60 + """Holt die aktuellen Benutzereinstellungen (GET) oder speichert sie (POST)""" + + if request.method == "GET": + try: + # Einstellungen aus Session oder Datenbank laden + user_settings = session.get('user_settings', {}) + + # Standard-Einstellungen falls keine vorhanden + default_settings = { + "theme": "system", + "reduced_motion": False, + "contrast": "normal", + "notifications": { + "new_jobs": True, + "job_updates": True, + "system": True, + "email": False + }, + "privacy": { + "activity_logs": True, + "two_factor": False, + "auto_logout": 60 + } } - } - - # Merge mit Standard-Einstellungen - settings = {**default_settings, **user_settings} - - return jsonify({ - "success": True, - "settings": settings - }) - - except Exception as e: - user_logger.error(f"Fehler beim Laden der Benutzereinstellungen: {str(e)}") - return jsonify({ - "success": False, - "error": "Fehler beim Laden der Einstellungen" - }), 500 + + # Merge mit Standard-Einstellungen + settings = {**default_settings, **user_settings} + + return jsonify({ + "success": True, + "settings": settings + }) + + except Exception as e: + user_logger.error(f"Fehler beim Laden der Benutzereinstellungen: {str(e)}") + return jsonify({ + "success": False, + "error": "Fehler beim Laden der Einstellungen" + }), 500 + + elif request.method == "POST": + """Benutzereinstellungen über API aktualisieren""" + db_session = get_db_session() + try: + # JSON-Daten extrahieren + if not request.is_json: + return jsonify({"error": "Anfrage muss im JSON-Format sein"}), 400 + + data = request.get_json() + if not data: + return jsonify({"error": "Keine Daten empfangen"}), 400 + + # Einstellungen aus der Anfrage extrahieren + theme = data.get("theme", "system") + reduced_motion = bool(data.get("reduced_motion", False)) + contrast = data.get("contrast", "normal") + notifications = data.get("notifications", {}) + privacy = data.get("privacy", {}) + + # Validierung der Eingaben + valid_themes = ["light", "dark", "system"] + if theme not in valid_themes: + theme = "system" + + valid_contrasts = ["normal", "high"] + if contrast not in valid_contrasts: + contrast = "normal" + + # Benutzer aus der Datenbank laden + user = db_session.query(User).filter(User.id == int(current_user.id)).first() + + if not user: + return jsonify({"error": "Benutzer nicht gefunden"}), 404 + + # Einstellungen-Dictionary erstellen + settings = { + "theme": theme, + "reduced_motion": reduced_motion, + "contrast": contrast, + "notifications": { + "new_jobs": bool(notifications.get("new_jobs", True)), + "job_updates": bool(notifications.get("job_updates", True)), + "system": bool(notifications.get("system", True)), + "email": bool(notifications.get("email", False)) + }, + "privacy": { + "activity_logs": bool(privacy.get("activity_logs", True)), + "two_factor": bool(privacy.get("two_factor", False)), + "auto_logout": max(5, min(480, int(privacy.get("auto_logout", 60)))) # 5-480 Minuten + }, + "last_updated": datetime.now().isoformat() + } + + # Prüfen, ob User-Tabelle eine settings-Spalte hat + if hasattr(user, 'settings'): + # Einstellungen in der Datenbank speichern + import json + user.settings = json.dumps(settings) + else: + # Fallback: In Session speichern (temporär) + session['user_settings'] = settings + + user.updated_at = datetime.now() + db_session.commit() + + user_logger.info(f"Benutzer {current_user.username} hat seine Einstellungen über die API aktualisiert") + + return jsonify({ + "success": True, + "message": "Einstellungen erfolgreich aktualisiert", + "settings": settings + }) + + except ValueError as e: + error = f"Ungültige Eingabedaten: {str(e)}" + user_logger.warning(f"Ungültige Einstellungsdaten von Benutzer {current_user.username}: {str(e)}") + return jsonify({"error": error}), 400 + except Exception as e: + db_session.rollback() + error = f"Fehler beim Aktualisieren der Einstellungen: {str(e)}" + user_logger.error(f"Fehler beim Aktualisieren der Einstellungen für Benutzer {current_user.username}: {str(e)}") + return jsonify({"error": "Interner Serverfehler"}), 500 + finally: + db_session.close() @app.route("/user/change-password", methods=["POST"]) @login_required @@ -1523,8 +1610,6 @@ def kiosk_deactivate(): except Exception as e: kiosk_logger.error(f"Unerwarteter Fehler bei Kiosk-Deaktivierung: {str(e)}") return jsonify({"error": "Unerwarteter Fehler"}), 500 -@app.route('/api/kiosk/activate', methods=['POST']) -@login_required def kiosk_activate(): """Kiosk-Modus aktivieren (nur für Admins).""" try: @@ -6396,6 +6481,99 @@ def api_admin_system_status(): 'health_status': 'error' }), 500 + +# ===== ÖFFENTLICHE STATISTIK-API ===== + +@app.route("/api/statistics/public", methods=['GET']) +def api_public_statistics(): + """ + Öffentliche Statistiken ohne Authentifizierung. + + Stellt grundlegende, nicht-sensible Systemstatistiken bereit, + die auf der Startseite angezeigt werden können. + + Returns: + JSON: Öffentliche Statistiken + """ + try: + db_session = get_db_session() + + # Grundlegende, nicht-sensible Statistiken + total_jobs = db_session.query(Job).count() + completed_jobs = db_session.query(Job).filter(Job.status == "finished").count() + total_printers = db_session.query(Printer).count() + active_printers = db_session.query(Printer).filter( + Printer.active == True, + Printer.status.in_(["online", "available", "idle"]) + ).count() + + # Erfolgsrate berechnen + success_rate = round((completed_jobs / total_jobs * 100) if total_jobs > 0 else 0, 1) + + # Anonymisierte Benutzerstatistiken + total_users = db_session.query(User).filter(User.active == True).count() + + # Letzte 30 Tage Aktivität (anonymisiert) + thirty_days_ago = datetime.now() - timedelta(days=30) + recent_jobs = db_session.query(Job).filter( + Job.created_at >= thirty_days_ago + ).count() + + db_session.close() + + public_stats = { + "system_info": { + "total_jobs": total_jobs, + "completed_jobs": completed_jobs, + "success_rate": success_rate, + "total_printers": total_printers, + "active_printers": active_printers, + "active_users": total_users, + "recent_activity": recent_jobs + }, + "health_indicators": { + "system_status": "operational", + "printer_availability": round((active_printers / total_printers * 100) if total_printers > 0 else 0, 1), + "last_updated": datetime.now().isoformat() + }, + "features": { + "multi_location_support": True, + "real_time_monitoring": True, + "automated_scheduling": True, + "advanced_reporting": True + } + } + + return jsonify(public_stats) + + except Exception as e: + app_logger.error(f"Fehler bei öffentlichen Statistiken: {str(e)}") + + # Fallback-Statistiken bei Fehler + return jsonify({ + "system_info": { + "total_jobs": 0, + "completed_jobs": 0, + "success_rate": 0, + "total_printers": 0, + "active_printers": 0, + "active_users": 0, + "recent_activity": 0 + }, + "health_indicators": { + "system_status": "maintenance", + "printer_availability": 0, + "last_updated": datetime.now().isoformat() + }, + "features": { + "multi_location_support": True, + "real_time_monitoring": True, + "automated_scheduling": True, + "advanced_reporting": True + }, + "error": "Statistiken temporär nicht verfügbar" + }), 200 # 200 statt 500 um Frontend nicht zu brechen + @app.route("/api/stats", methods=['GET']) @login_required def api_stats(): diff --git a/backend/blueprints/__pycache__/admin_api.cpython-313.pyc b/backend/blueprints/__pycache__/admin_api.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb36a3f32efcd88488abf75703c627a89c3d18bd GIT binary patch literal 24402 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 A+W-In literal 0 HcmV?d00001 diff --git a/backend/database/myp.db b/backend/database/myp.db index df4be5db9aae6bd70e617d27cc55d53b64686403..2211b354652fdb185fa30ca9a5f3ac8d15c64fc9 100644 GIT binary patch delta 99 zcmZozz}~QceS$P&?L--8#@dYuAN5T2TwF}Oy-dRcvy7r#{mqJsDocz!^@561{6fOB zQmfKD5={-G!t~tT-BLIhw-~LRWQECAI DaGfBv delta 99 zcmZozz}~QceS$P&*+dy<#&U;M1& diff --git a/backend/database/myp.db-wal b/backend/database/myp.db-wal index b47fe35cd8dc3fdbbd56648c75d38d663661bdaa..a9085d2d0f03545770f18a9931badadf29d3d95b 100644 GIT binary patch delta 487 zcmccMaKRzKyq>LzLHCga1A_nq5HNm^`l`r0NqXD&J8@iT_m6J^itz!lEKK~AnX>r7 z^9^ylKtXoCzYP4h_}B6G@fY%Y@+b1XQKQ%2F?GD-PBMvJ;{oMCK*trpBk{CT8XUl_?lXv#^M3Lo7w8gGtLVvxpm_ zOTr8RYSv<6k#!a>D9X$$!E|(eMLbL<-p~x_a7GqcV{w=e$TAok8U$tvKnRKgmGauZ7wjDeBG#KhpBpa4``2T~8jFrWcsurM%8%+h77+c;wZ FKL9c-oT2~# delta 547 zcmccMaKXXCyq>LzLHCga1A_nq2zWocE`CDT*X7N=mvJvXUpWmFVgzDYn7DD0-TfD` zuB?*-1f&_uC+7$_GnQ}OAh3X61*nP{S*7HaB7=iT5#_ufBlsm5_$B!wHU|3e)i>HP z2{BlTHnNI}ayl|N0;L%k97|G*OB`}ji;`1QQj2wyQuC_xlJj#xqAEs7DuzZXSpmrv zCPrZ{Ro=ONKAGu}If1zmp{d?wh3=s#ZpMB=Ar?u-StWiYiG_Neei<1NAz>+cr6EB5 zrNya5Mg~Tvx&~&t28Id-^@di)rdFn=dL||YmX?OdQZN}aV{>B@6Pz*@jVX*m4A$a} ztm@*Nj*d_tB&OtM=3#mPEDZI7TX2ScRDF({kGppQeyUH7 zS*nL=a(Y!>q<>VfXKqDRMp1TNsk0-<;LPHZqQsK?BCv4~mznAsSt=M>Seckw85`-D wm|L2gm?OK{*viP#%EU;|!qCD9h+sjW4GaSlDz>% diff --git a/backend/docs/GLASSMORPHISM_NOTIFICATIONS.md b/backend/docs/GLASSMORPHISM_NOTIFICATIONS.md new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/backend/docs/GLASSMORPHISM_NOTIFICATIONS.md @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/fix_public_stats.py b/backend/fix_public_stats.py new file mode 100644 index 00000000..1468caec --- /dev/null +++ b/backend/fix_public_stats.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +""" +Temporäres Skript zum Hinzufügen der fehlenden /api/statistics/public Route +""" + +with open('app.py', 'r', encoding='utf-8') as f: + content = f.read() + +# Die neue Route die hinzugefügt werden soll +new_route = ''' +# ===== ÖFFENTLICHE STATISTIK-API ===== + +@app.route("/api/statistics/public", methods=['GET']) +def api_public_statistics(): + """ + Öffentliche Statistiken ohne Authentifizierung. + + Stellt grundlegende, nicht-sensible Systemstatistiken bereit, + die auf der Startseite angezeigt werden können. + + Returns: + JSON: Öffentliche Statistiken + """ + try: + db_session = get_db_session() + + # Grundlegende, nicht-sensible Statistiken + total_jobs = db_session.query(Job).count() + completed_jobs = db_session.query(Job).filter(Job.status == "finished").count() + total_printers = db_session.query(Printer).count() + active_printers = db_session.query(Printer).filter( + Printer.active == True, + Printer.status.in_(["online", "available", "idle"]) + ).count() + + # Erfolgsrate berechnen + success_rate = round((completed_jobs / total_jobs * 100) if total_jobs > 0 else 0, 1) + + # Anonymisierte Benutzerstatistiken + total_users = db_session.query(User).filter(User.active == True).count() + + # Letzte 30 Tage Aktivität (anonymisiert) + thirty_days_ago = datetime.now() - timedelta(days=30) + recent_jobs = db_session.query(Job).filter( + Job.created_at >= thirty_days_ago + ).count() + + db_session.close() + + public_stats = { + "system_info": { + "total_jobs": total_jobs, + "completed_jobs": completed_jobs, + "success_rate": success_rate, + "total_printers": total_printers, + "active_printers": active_printers, + "active_users": total_users, + "recent_activity": recent_jobs + }, + "health_indicators": { + "system_status": "operational", + "printer_availability": round((active_printers / total_printers * 100) if total_printers > 0 else 0, 1), + "last_updated": datetime.now().isoformat() + }, + "features": { + "multi_location_support": True, + "real_time_monitoring": True, + "automated_scheduling": True, + "advanced_reporting": True + } + } + + return jsonify(public_stats) + + except Exception as e: + app_logger.error(f"Fehler bei öffentlichen Statistiken: {str(e)}") + + # Fallback-Statistiken bei Fehler + return jsonify({ + "system_info": { + "total_jobs": 0, + "completed_jobs": 0, + "success_rate": 0, + "total_printers": 0, + "active_printers": 0, + "active_users": 0, + "recent_activity": 0 + }, + "health_indicators": { + "system_status": "maintenance", + "printer_availability": 0, + "last_updated": datetime.now().isoformat() + }, + "features": { + "multi_location_support": True, + "real_time_monitoring": True, + "automated_scheduling": True, + "advanced_reporting": True + }, + "error": "Statistiken temporär nicht verfügbar" + }), 200 # 200 statt 500 um Frontend nicht zu brechen + +''' + +# Füge die Route vor @app.route("/api/stats", methods=['GET']) hinzu +marker = '@app.route("/api/stats", methods=[\'GET\'])' +if marker in content: + parts = content.split(marker, 1) + new_content = parts[0] + new_route + marker + parts[1] + + with open('app.py', 'w', encoding='utf-8') as f: + f.write(new_content) + print('✅ Öffentliche Statistik-API Route hinzugefügt') +else: + print('❌ Marker nicht gefunden - versuche alternativen Marker') + # Versuche alternativen Marker + alt_marker = '@app.route("/api/stats", methods=[\"GET\"])' + if alt_marker in content: + parts = content.split(alt_marker, 1) + new_content = parts[0] + new_route + alt_marker + parts[1] + + with open('app.py', 'w', encoding='utf-8') as f: + f.write(new_content) + print('✅ Öffentliche Statistik-API Route mit alternativem Marker hinzugefügt') + else: + print('❌ Auch alternativer Marker nicht gefunden') + print('Suche verfügbare Marker...') + import re + stats_markers = re.findall(r'@app\.route\("/api/stats".*?\)', content) + print(f'Gefundene Stats-Marker: {stats_markers}') \ No newline at end of file diff --git a/backend/logs/admin_api/admin_api.log b/backend/logs/admin_api/admin_api.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/analytics/analytics.log b/backend/logs/analytics/analytics.log index b4925290..44ca440b 100644 --- a/backend/logs/analytics/analytics.log +++ b/backend/logs/analytics/analytics.log @@ -17,3 +17,10 @@ 2025-06-01 04:14:22 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert 2025-06-01 04:16:09 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert 2025-06-01 04:22:49 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 04:26:29 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 04:26:32 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 04:28:39 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 04:28:58 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 04:29:28 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 04:31:09 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 04:36:21 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert diff --git a/backend/logs/app/app.log b/backend/logs/app/app.log index f0b1a22e..7766ac1d 100644 --- a/backend/logs/app/app.log +++ b/backend/logs/app/app.log @@ -616,3 +616,72 @@ WHERE users.id = ? 2025-06-01 04:24:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True 2025-06-01 04:25:22 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True 2025-06-01 04:25:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 04:26:22 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 04:26:29 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 04:26:30 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 04:26:30 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen +2025-06-01 04:26:30 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert +2025-06-01 04:26:30 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen... +2025-06-01 04:26:30 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert +2025-06-01 04:26:30 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden +2025-06-01 04:26:31 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt. +2025-06-01 04:26:31 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen +2025-06-01 04:26:31 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung... +2025-06-01 04:26:31 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden +2025-06-01 04:26:31 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung +2025-06-01 04:26:31 - [app] app - [INFO] INFO - Job-Scheduler gestartet +2025-06-01 04:26:31 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP) +2025-06-01 04:26:31 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert +2025-06-01 04:26:32 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 04:26:33 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 04:26:33 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen +2025-06-01 04:26:34 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:26:44 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:26:54 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:27:06 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:27:09 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:28:39 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 04:28:40 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 04:28:40 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen +2025-06-01 04:28:58 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 04:28:59 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 04:28:59 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen +2025-06-01 04:29:27 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 04:29:28 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 04:29:29 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen +2025-06-01 04:29:29 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert +2025-06-01 04:29:29 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen... +2025-06-01 04:29:29 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert +2025-06-01 04:29:29 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden +2025-06-01 04:29:29 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt. +2025-06-01 04:29:29 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen +2025-06-01 04:29:29 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung... +2025-06-01 04:29:29 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden +2025-06-01 04:29:29 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung +2025-06-01 04:29:29 - [app] app - [INFO] INFO - Job-Scheduler gestartet +2025-06-01 04:29:29 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP) +2025-06-01 04:29:29 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert +2025-06-01 04:29:36 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:29:45 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:29:53 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:30:34 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:30:42 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:31:08 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 04:31:10 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 04:31:10 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen +2025-06-01 04:31:10 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert +2025-06-01 04:31:10 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen... +2025-06-01 04:31:10 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert +2025-06-01 04:31:10 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden +2025-06-01 04:31:10 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt. +2025-06-01 04:31:10 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen +2025-06-01 04:31:10 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung... +2025-06-01 04:31:10 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden +2025-06-01 04:31:10 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung +2025-06-01 04:31:10 - [app] app - [INFO] INFO - Job-Scheduler gestartet +2025-06-01 04:31:10 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP) +2025-06-01 04:31:10 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert +2025-06-01 04:31:12 - [app] app - [ERROR] ERROR - Fehler beim Laden der Admin-Dashboard-Daten: Could not build url for endpoint 'admin_settings'. Did you mean 'optimization_settings' instead? +2025-06-01 04:36:21 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 04:36:22 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 04:36:22 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen diff --git a/backend/logs/backup/backup.log b/backend/logs/backup/backup.log index 731c6da2..46c1f3b3 100644 --- a/backend/logs/backup/backup.log +++ b/backend/logs/backup/backup.log @@ -17,3 +17,10 @@ 2025-06-01 04:14:22 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) 2025-06-01 04:16:09 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) 2025-06-01 04:22:49 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 04:26:29 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 04:26:32 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 04:28:39 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 04:28:58 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 04:29:28 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 04:31:09 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 04:36:21 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) diff --git a/backend/logs/calendar/calendar.log b/backend/logs/calendar/calendar.log index 895f121d..88417a9d 100644 --- a/backend/logs/calendar/calendar.log +++ b/backend/logs/calendar/calendar.log @@ -10,3 +10,6 @@ 2025-06-01 04:08:27 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 2025-06-01 04:08:48 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 2025-06-01 04:16:18 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 +2025-06-01 04:31:18 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 +2025-06-01 04:31:38 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 +2025-06-01 04:31:41 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 diff --git a/backend/logs/dashboard/dashboard.log b/backend/logs/dashboard/dashboard.log index 2dfdcd7c..63673cbd 100644 --- a/backend/logs/dashboard/dashboard.log +++ b/backend/logs/dashboard/dashboard.log @@ -61,3 +61,31 @@ 2025-06-01 04:22:50 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet 2025-06-01 04:22:50 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) 2025-06-01 04:22:50 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 04:26:30 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:26:30 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:26:30 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 04:26:30 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 04:26:33 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:26:33 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:26:33 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 04:26:33 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 04:28:40 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:28:40 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:28:40 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 04:28:40 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 04:28:59 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:28:59 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:28:59 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 04:28:59 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 04:29:28 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:29:29 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:29:29 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 04:29:29 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 04:31:10 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:31:10 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:31:10 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 04:31:10 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 04:36:22 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:36:22 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 04:36:22 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 04:36:22 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) diff --git a/backend/logs/database/database.log b/backend/logs/database/database.log index 3b4a67ff..756ca047 100644 --- a/backend/logs/database/database.log +++ b/backend/logs/database/database.log @@ -17,3 +17,10 @@ 2025-06-01 04:14:22 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet 2025-06-01 04:16:09 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet 2025-06-01 04:22:49 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 04:26:29 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 04:26:32 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 04:28:39 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 04:28:58 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 04:29:28 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 04:31:09 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 04:36:21 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet diff --git a/backend/logs/email_notification/email_notification.log b/backend/logs/email_notification/email_notification.log index e40485ba..37c7f702 100644 --- a/backend/logs/email_notification/email_notification.log +++ b/backend/logs/email_notification/email_notification.log @@ -15,3 +15,10 @@ 2025-06-01 04:14:23 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) 2025-06-01 04:16:10 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) 2025-06-01 04:22:50 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 04:26:30 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 04:26:33 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 04:28:40 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 04:28:59 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 04:29:28 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 04:31:10 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 04:36:22 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) diff --git a/backend/logs/jobs/jobs.log b/backend/logs/jobs/jobs.log index 5d5dc0e4..431d6def 100644 --- a/backend/logs/jobs/jobs.log +++ b/backend/logs/jobs/jobs.log @@ -47,3 +47,8 @@ 2025-06-01 04:16:16 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) 2025-06-01 04:16:58 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) 2025-06-01 04:17:52 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) +2025-06-01 04:22:55 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) +2025-06-01 04:31:23 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) +2025-06-01 04:31:36 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) +2025-06-01 04:31:53 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) +2025-06-01 04:32:03 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) diff --git a/backend/logs/maintenance/maintenance.log b/backend/logs/maintenance/maintenance.log index f7cac34d..cddaf251 100644 --- a/backend/logs/maintenance/maintenance.log +++ b/backend/logs/maintenance/maintenance.log @@ -30,3 +30,17 @@ 2025-06-01 04:16:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet 2025-06-01 04:22:50 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet 2025-06-01 04:22:50 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:26:30 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:26:30 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:26:33 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:26:33 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:28:40 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:28:40 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:28:59 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:28:59 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:29:28 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:29:29 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:31:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:31:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:36:22 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 04:36:22 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet diff --git a/backend/logs/multi_location/multi_location.log b/backend/logs/multi_location/multi_location.log index 04441e76..99886626 100644 --- a/backend/logs/multi_location/multi_location.log +++ b/backend/logs/multi_location/multi_location.log @@ -30,3 +30,17 @@ 2025-06-01 04:16:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt 2025-06-01 04:22:50 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt 2025-06-01 04:22:50 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:26:30 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:26:30 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:26:33 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:26:33 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:28:40 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:28:40 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:28:59 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:28:59 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:29:28 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:29:29 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:31:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:31:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:36:22 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 04:36:22 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt diff --git a/backend/logs/permissions/permissions.log b/backend/logs/permissions/permissions.log index 5a8ef51b..29e32d27 100644 --- a/backend/logs/permissions/permissions.log +++ b/backend/logs/permissions/permissions.log @@ -13,3 +13,10 @@ 2025-06-01 04:14:23 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert 2025-06-01 04:16:10 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert 2025-06-01 04:22:50 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 04:26:30 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 04:26:33 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 04:28:40 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 04:28:59 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 04:29:29 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 04:31:10 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 04:36:22 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert diff --git a/backend/logs/printer_monitor/printer_monitor.log b/backend/logs/printer_monitor/printer_monitor.log index 7aa915c2..208bd630 100644 --- a/backend/logs/printer_monitor/printer_monitor.log +++ b/backend/logs/printer_monitor/printer_monitor.log @@ -638,3 +638,78 @@ 2025-06-01 04:25:57 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden 2025-06-01 04:25:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... 2025-06-01 04:25:57 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:26:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 04:26:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 04:26:31 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart... +2025-06-01 04:26:31 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden +2025-06-01 04:26:31 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung... +2025-06-01 04:26:31 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration +2025-06-01 04:26:31 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103 +2025-06-01 04:26:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 04:26:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 04:26:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:26:32 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:26:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:26:32 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:26:37 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104 +2025-06-01 04:26:43 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100 +2025-06-01 04:26:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101 +2025-06-01 04:26:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102 +2025-06-01 04:27:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105 +2025-06-01 04:27:07 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.0s +2025-06-01 04:28:39 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 04:28:39 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 04:28:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 04:28:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 04:29:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 04:29:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 04:29:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart... +2025-06-01 04:29:29 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden +2025-06-01 04:29:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung... +2025-06-01 04:29:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration +2025-06-01 04:29:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103 +2025-06-01 04:29:31 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:29:31 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:29:31 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:29:31 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:29:36 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104 +2025-06-01 04:29:42 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100 +2025-06-01 04:29:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101 +2025-06-01 04:29:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:29:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:29:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:29:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:29:54 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102 +2025-06-01 04:30:00 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105 +2025-06-01 04:30:06 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.0s +2025-06-01 04:31:09 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 04:31:09 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 04:31:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart... +2025-06-01 04:31:10 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden +2025-06-01 04:31:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung... +2025-06-01 04:31:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration +2025-06-01 04:31:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103 +2025-06-01 04:31:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104 +2025-06-01 04:31:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100 +2025-06-01 04:31:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:31:26 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:31:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:31:26 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:31:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101 +2025-06-01 04:31:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:31:29 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:31:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:31:29 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:31:35 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102 +2025-06-01 04:31:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105 +2025-06-01 04:31:47 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.0s +2025-06-01 04:32:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:32:10 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:32:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:32:10 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:32:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:32:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:32:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 04:32:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 04:36:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 04:36:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet diff --git a/backend/logs/printers/printers.log b/backend/logs/printers/printers.log index 6b03436c..0d2edcfa 100644 --- a/backend/logs/printers/printers.log +++ b/backend/logs/printers/printers.log @@ -3312,3 +3312,28 @@ 2025-06-01 04:25:57 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) 2025-06-01 04:25:57 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker 2025-06-01 04:25:57 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.68ms +2025-06-01 04:26:32 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 04:26:32 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 04:26:32 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.53ms +2025-06-01 04:29:31 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 04:29:31 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 04:29:31 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.65ms +2025-06-01 04:29:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 04:29:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 04:29:51 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.38ms +2025-06-01 04:31:23 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 04:31:26 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 04:31:26 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 04:31:26 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 04:31:26 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.61ms +2025-06-01 04:31:26 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 04:31:29 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 04:31:29 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 04:31:29 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.46ms +2025-06-01 04:31:36 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 04:32:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 04:32:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 04:32:10 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.91ms +2025-06-01 04:32:52 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 04:32:52 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 04:32:52 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.71ms diff --git a/backend/logs/scheduler/scheduler.log b/backend/logs/scheduler/scheduler.log index 97b90515..00806711 100644 --- a/backend/logs/scheduler/scheduler.log +++ b/backend/logs/scheduler/scheduler.log @@ -2869,3 +2869,16 @@ 2025-06-01 04:22:49 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True 2025-06-01 04:22:50 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet 2025-06-01 04:22:50 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet +2025-06-01 04:26:29 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 04:26:31 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet +2025-06-01 04:26:31 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet +2025-06-01 04:26:32 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 04:28:39 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 04:28:58 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 04:29:28 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 04:29:29 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet +2025-06-01 04:29:29 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet +2025-06-01 04:31:09 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 04:31:10 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet +2025-06-01 04:31:10 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet +2025-06-01 04:36:21 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True diff --git a/backend/logs/security/security.log b/backend/logs/security/security.log index a5ed1df7..e1e5920b 100644 --- a/backend/logs/security/security.log +++ b/backend/logs/security/security.log @@ -13,3 +13,10 @@ 2025-06-01 04:14:23 - [security] security - [INFO] INFO - 🔒 Security System initialisiert 2025-06-01 04:16:10 - [security] security - [INFO] INFO - 🔒 Security System initialisiert 2025-06-01 04:22:50 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 04:26:30 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 04:26:33 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 04:28:40 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 04:28:59 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 04:29:29 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 04:31:10 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 04:36:22 - [security] security - [INFO] INFO - 🔒 Security System initialisiert diff --git a/backend/logs/shutdown_manager/shutdown_manager.log b/backend/logs/shutdown_manager/shutdown_manager.log index 2ffadc47..b2866e1e 100644 --- a/backend/logs/shutdown_manager/shutdown_manager.log +++ b/backend/logs/shutdown_manager/shutdown_manager.log @@ -46,3 +46,26 @@ 2025-06-01 04:14:23 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert 2025-06-01 04:16:10 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert 2025-06-01 04:22:50 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 04:26:30 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 04:26:33 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 04:26:33 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Starte koordiniertes System-Shutdown... +2025-06-01 04:26:33 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🧹 Führe 1 Cleanup-Funktionen aus... +2025-06-01 04:26:33 - [shutdown_manager] shutdown_manager - [INFO] INFO - ✅ Koordiniertes Shutdown abgeschlossen in 0.0s +2025-06-01 04:26:33 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🏁 System wird beendet... +2025-06-01 04:28:40 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 04:28:40 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Starte koordiniertes System-Shutdown... +2025-06-01 04:28:40 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🧹 Führe 1 Cleanup-Funktionen aus... +2025-06-01 04:28:40 - [shutdown_manager] shutdown_manager - [INFO] INFO - ✅ Koordiniertes Shutdown abgeschlossen in 0.0s +2025-06-01 04:28:40 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🏁 System wird beendet... +2025-06-01 04:28:59 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 04:28:59 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Starte koordiniertes System-Shutdown... +2025-06-01 04:28:59 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🧹 Führe 1 Cleanup-Funktionen aus... +2025-06-01 04:28:59 - [shutdown_manager] shutdown_manager - [INFO] INFO - ✅ Koordiniertes Shutdown abgeschlossen in 0.0s +2025-06-01 04:28:59 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🏁 System wird beendet... +2025-06-01 04:29:29 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 04:31:10 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 04:36:22 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 04:36:22 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Starte koordiniertes System-Shutdown... +2025-06-01 04:36:22 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🧹 Führe 1 Cleanup-Funktionen aus... +2025-06-01 04:36:22 - [shutdown_manager] shutdown_manager - [INFO] INFO - ✅ Koordiniertes Shutdown abgeschlossen in 0.0s +2025-06-01 04:36:22 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🏁 System wird beendet... diff --git a/backend/logs/startup/startup.log b/backend/logs/startup/startup.log index 011a2eaa..2523603b 100644 --- a/backend/logs/startup/startup.log +++ b/backend/logs/startup/startup.log @@ -129,3 +129,66 @@ 2025-06-01 04:22:50 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert 2025-06-01 04:22:50 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert 2025-06-01 04:22:50 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T04:26:30.681481 +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 04:26:30 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T04:26:33.469002 +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 04:26:33 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T04:28:40.487299 +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 04:28:40 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T04:28:59.128550 +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 04:28:59 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T04:29:28.997767 +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 04:29:28 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T04:31:10.171279 +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 04:31:10 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T04:36:22.434555 +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 04:36:22 - [startup] startup - [INFO] INFO - ================================================== diff --git a/backend/logs/user/user.log b/backend/logs/user/user.log index 8d3c2af7..5d9b4a64 100644 --- a/backend/logs/user/user.log +++ b/backend/logs/user/user.log @@ -1 +1,3 @@ 2025-06-01 04:07:12 - [user] user - [INFO] INFO - Benutzer admin hat seine Einstellungsseite aufgerufen +2025-06-01 04:32:24 - [user] user - [INFO] INFO - Benutzer admin hat seine Einstellungsseite aufgerufen +2025-06-01 04:33:16 - [user] user - [INFO] INFO - Benutzer admin hat seine Einstellungsseite aufgerufen diff --git a/backend/logs/windows_fixes/windows_fixes.log b/backend/logs/windows_fixes/windows_fixes.log index c048f17c..9f9a249c 100644 --- a/backend/logs/windows_fixes/windows_fixes.log +++ b/backend/logs/windows_fixes/windows_fixes.log @@ -66,3 +66,31 @@ 2025-06-01 04:22:49 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) 2025-06-01 04:22:49 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet 2025-06-01 04:22:49 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 04:26:29 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 04:26:29 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 04:26:29 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 04:26:29 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 04:26:32 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 04:26:32 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 04:26:32 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 04:26:32 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 04:28:39 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 04:28:39 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 04:28:39 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 04:28:39 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 04:28:58 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 04:28:58 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 04:28:58 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 04:28:58 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 04:29:27 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 04:29:27 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 04:29:27 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 04:29:27 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 04:31:08 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 04:31:08 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 04:31:08 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 04:31:08 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 04:36:21 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 04:36:21 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 04:36:21 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 04:36:21 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet diff --git a/backend/static/js/glassmorphism-notifications.js b/backend/static/js/glassmorphism-notifications.js index 490a0568..993074d3 100644 --- a/backend/static/js/glassmorphism-notifications.js +++ b/backend/static/js/glassmorphism-notifications.js @@ -309,13 +309,13 @@ class GlassmorphismNotificationSystem { const toasts = Array.from(container.children); toasts.forEach((toast, index) => { // Gestaffelte Positionierung mit smooth transition - toast.style.top = `${1 + index * 4.5}rem`; + toast.style.top = `${1 + index * 3.75}rem`; toast.style.zIndex = 1000 - index; // Leichter Versatz für Tiefeneffekt if (index > 0) { - toast.style.transform = `scale(${1 - index * 0.02})`; - toast.style.opacity = `${1 - index * 0.1}`; + toast.style.transform = `scale(${1 - index * 0.015})`; + toast.style.opacity = `${1 - index * 0.08}`; } }); } @@ -579,31 +579,31 @@ class GlassmorphismNotificationSystem { styles.id = 'glassmorphism-notification-styles'; styles.textContent = ` .glassmorphism-toast { - margin-bottom: 0.75rem; + margin-bottom: 0.625rem; transform: translateX(100%); opacity: 0; - transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1); + transition: all 0.7s cubic-bezier(0.34, 1.56, 0.64, 1); will-change: transform, opacity, filter; /* Erweiterte Premium Glassmorphism-Eigenschaften */ - backdrop-filter: blur(60px) saturate(220%) brightness(125%) contrast(115%); - -webkit-backdrop-filter: blur(60px) saturate(220%) brightness(125%) contrast(115%); + backdrop-filter: blur(50px) saturate(200%) brightness(120%) contrast(110%); + -webkit-backdrop-filter: blur(50px) saturate(200%) brightness(120%) contrast(110%); box-shadow: - 0 40px 80px rgba(0, 0, 0, 0.12), - 0 20px 40px rgba(0, 0, 0, 0.08), - 0 8px 16px rgba(0, 0, 0, 0.06), - inset 0 3px 0 rgba(255, 255, 255, 0.5), - inset 0 1px 2px rgba(255, 255, 255, 0.8), - 0 0 0 1px rgba(255, 255, 255, 0.2); - border-radius: 1.75rem; + 0 32px 64px rgba(0, 0, 0, 0.1), + 0 16px 32px rgba(0, 0, 0, 0.06), + 0 6px 12px rgba(0, 0, 0, 0.05), + inset 0 2px 0 rgba(255, 255, 255, 0.4), + inset 0 1px 2px rgba(255, 255, 255, 0.7), + 0 0 0 1px rgba(255, 255, 255, 0.18); + border-radius: 1.5rem; overflow: hidden; position: relative; /* Subtile Farbverläufe */ background: linear-gradient(145deg, - rgba(255, 255, 255, 0.15) 0%, - rgba(255, 255, 255, 0.08) 25%, - rgba(255, 255, 255, 0.12) 50%, - rgba(255, 255, 255, 0.06) 75%, - rgba(255, 255, 255, 0.1) 100%); + rgba(255, 255, 255, 0.12) 0%, + rgba(255, 255, 255, 0.06) 25%, + rgba(255, 255, 255, 0.1) 50%, + rgba(255, 255, 255, 0.05) 75%, + rgba(255, 255, 255, 0.08) 100%); } /* Erweiterte Glassmorphism-Overlay-Effekte */ @@ -873,37 +873,37 @@ class GlassmorphismNotificationSystem { .toast-content { position: relative; overflow: hidden; - padding: 1.5rem; + padding: 1rem; border-radius: inherit; } .toast-header { display: flex; align-items: flex-start; - gap: 1.25rem; + gap: 0.875rem; } .toast-icon { flex-shrink: 0; - width: 3rem; - height: 3rem; + width: 2.25rem; + height: 2.25rem; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: linear-gradient(145deg, - rgba(255, 255, 255, 0.4) 0%, - rgba(255, 255, 255, 0.25) 50%, - rgba(255, 255, 255, 0.35) 100%); - backdrop-filter: blur(20px) saturate(150%); - -webkit-backdrop-filter: blur(20px) saturate(150%); - border: 1px solid rgba(255, 255, 255, 0.5); + rgba(255, 255, 255, 0.35) 0%, + rgba(255, 255, 255, 0.2) 50%, + rgba(255, 255, 255, 0.3) 100%); + backdrop-filter: blur(16px) saturate(140%); + -webkit-backdrop-filter: blur(16px) saturate(140%); + border: 1px solid rgba(255, 255, 255, 0.4); box-shadow: - 0 12px 24px rgba(0, 0, 0, 0.08), - 0 4px 8px rgba(0, 0, 0, 0.05), - inset 0 2px 0 rgba(255, 255, 255, 0.7), - inset 0 -1px 0 rgba(0, 0, 0, 0.05); - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + 0 8px 16px rgba(0, 0, 0, 0.06), + 0 2px 4px rgba(0, 0, 0, 0.04), + inset 0 1px 0 rgba(255, 255, 255, 0.6), + inset 0 -1px 0 rgba(0, 0, 0, 0.03); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); position: relative; overflow: hidden; } @@ -916,7 +916,7 @@ class GlassmorphismNotificationSystem { left: -50%; width: 200%; height: 200%; - background: radial-gradient(circle, rgba(255, 255, 255, 0.3) 0%, transparent 70%); + background: radial-gradient(circle, rgba(255, 255, 255, 0.25) 0%, transparent 70%); opacity: 0; transition: opacity 0.3s ease; animation: icon-pulse 3s ease-in-out infinite; @@ -924,7 +924,7 @@ class GlassmorphismNotificationSystem { @keyframes icon-pulse { 0%, 100% { opacity: 0; transform: scale(0.8); } - 50% { opacity: 0.5; transform: scale(1.2); } + 50% { opacity: 0.4; transform: scale(1.1); } } .toast-icon:hover::before { @@ -933,29 +933,29 @@ class GlassmorphismNotificationSystem { } .toast-icon:hover { - transform: scale(1.15) rotate(10deg); + transform: scale(1.08) rotate(8deg); box-shadow: - 0 20px 40px rgba(0, 0, 0, 0.12), - 0 8px 16px rgba(0, 0, 0, 0.08), - inset 0 2px 0 rgba(255, 255, 255, 0.8), - inset 0 -1px 0 rgba(0, 0, 0, 0.08); + 0 12px 24px rgba(0, 0, 0, 0.08), + 0 4px 8px rgba(0, 0, 0, 0.06), + inset 0 1px 0 rgba(255, 255, 255, 0.7), + inset 0 -1px 0 rgba(0, 0, 0, 0.05); } .dark .toast-icon { background: linear-gradient(145deg, - rgba(0, 0, 0, 0.4) 0%, - rgba(15, 15, 15, 0.3) 50%, - rgba(0, 0, 0, 0.35) 100%); - border: 1px solid rgba(255, 255, 255, 0.15); + rgba(0, 0, 0, 0.35) 0%, + rgba(15, 15, 15, 0.25) 50%, + rgba(0, 0, 0, 0.3) 100%); + border: 1px solid rgba(255, 255, 255, 0.12); box-shadow: - 0 12px 24px rgba(0, 0, 0, 0.3), - 0 4px 8px rgba(0, 0, 0, 0.2), - inset 0 2px 0 rgba(255, 255, 255, 0.15), - inset 0 -1px 0 rgba(255, 255, 255, 0.05); + 0 8px 16px rgba(0, 0, 0, 0.25), + 0 2px 4px rgba(0, 0, 0, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.12), + inset 0 -1px 0 rgba(255, 255, 255, 0.03); } .dark .toast-icon::before { - background: radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%); + background: radial-gradient(circle, rgba(255, 255, 255, 0.12) 0%, transparent 70%); } .toast-body { @@ -964,56 +964,90 @@ class GlassmorphismNotificationSystem { } .toast-title { - font-weight: 700; - font-size: 1rem; - margin-bottom: 0.5rem; - line-height: 1.4; - letter-spacing: 0.015em; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); + font-weight: 600; + font-size: 0.875rem; + margin-bottom: 0.375rem; + line-height: 1.3; + letter-spacing: 0.01em; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.06); background: linear-gradient(135deg, currentColor 0%, currentColor 100%); -webkit-background-clip: text; background-clip: text; } .toast-message { - font-size: 0.9rem; - line-height: 1.6; - opacity: 0.92; - font-weight: 500; - text-shadow: 0 1px 3px rgba(0, 0, 0, 0.06); + font-size: 0.8125rem; + line-height: 1.4; + opacity: 0.9; + font-weight: 450; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); } .toast-actions { display: flex; - gap: 0.625rem; + gap: 0.5rem; align-items: flex-start; flex-shrink: 0; } .toast-action-btn { - padding: 0.5rem 1rem; + padding: 0.5rem 0.875rem; border-radius: 0.75rem; - font-size: 0.8125rem; - font-weight: 600; + font-size: 0.75rem; + font-weight: 500; border: none; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: flex; align-items: center; gap: 0.375rem; - background: rgba(255, 255, 255, 0.2); + background: linear-gradient(145deg, + rgba(255, 255, 255, 0.25) 0%, + rgba(255, 255, 255, 0.12) 50%, + rgba(255, 255, 255, 0.2) 100%); color: inherit; - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); + backdrop-filter: blur(16px) saturate(130%); + -webkit-backdrop-filter: blur(16px) saturate(130%); border: 1px solid rgba(255, 255, 255, 0.3); - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: + 0 4px 8px rgba(0, 0, 0, 0.06), + 0 1px 2px rgba(0, 0, 0, 0.04), + inset 0 1px 0 rgba(255, 255, 255, 0.5); + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.06); + position: relative; + overflow: hidden; + } + + /* Button-Shimmer-Effekt */ + .toast-action-btn::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, + transparent 0%, + rgba(255, 255, 255, 0.3) 50%, + transparent 100%); + transition: left 0.4s cubic-bezier(0.4, 0, 0.2, 1); + } + + .toast-action-btn:hover::before { + left: 100%; } .toast-action-btn:hover { - background: rgba(255, 255, 255, 0.35); - transform: translateY(-2px) scale(1.05); - box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); + background: linear-gradient(145deg, + rgba(255, 255, 255, 0.35) 0%, + rgba(255, 255, 255, 0.2) 50%, + rgba(255, 255, 255, 0.3) 100%); + transform: translateY(-2px) scale(1.04); + box-shadow: + 0 8px 16px rgba(0, 0, 0, 0.08), + 0 2px 4px rgba(0, 0, 0, 0.06), + inset 0 1px 0 rgba(255, 255, 255, 0.6); + border-color: rgba(255, 255, 255, 0.5); } .toast-action-btn:active { @@ -1022,71 +1056,148 @@ class GlassmorphismNotificationSystem { } .toast-action-primary { - background: linear-gradient(135deg, - rgba(59, 130, 246, 0.9) 0%, - rgba(37, 99, 235, 0.9) 100%); + background: linear-gradient(145deg, + rgba(59, 130, 246, 0.8) 0%, + rgba(37, 99, 235, 0.85) 50%, + rgba(59, 130, 246, 0.75) 100%); color: white; border-color: rgba(59, 130, 246, 0.6); - box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3); + box-shadow: + 0 4px 12px rgba(59, 130, 246, 0.2), + 0 1px 3px rgba(59, 130, 246, 0.12), + inset 0 1px 0 rgba(255, 255, 255, 0.25); + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); + } + + .toast-action-primary::before { + background: linear-gradient(90deg, + transparent 0%, + rgba(255, 255, 255, 0.25) 50%, + transparent 100%); } .toast-action-primary:hover { - background: linear-gradient(135deg, - rgba(59, 130, 246, 1) 0%, - rgba(37, 99, 235, 1) 100%); - box-shadow: 0 8px 20px rgba(59, 130, 246, 0.4); + background: linear-gradient(145deg, + rgba(59, 130, 246, 0.9) 0%, + rgba(37, 99, 235, 0.95) 50%, + rgba(59, 130, 246, 0.85) 100%); + box-shadow: + 0 8px 20px rgba(59, 130, 246, 0.25), + 0 2px 6px rgba(59, 130, 246, 0.18), + inset 0 1px 0 rgba(255, 255, 255, 0.3); } .dark .toast-action-btn { - background: rgba(0, 0, 0, 0.3); - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + background: linear-gradient(145deg, + rgba(0, 0, 0, 0.35) 0%, + rgba(15, 15, 15, 0.25) 50%, + rgba(0, 0, 0, 0.3) 100%); + border: 1px solid rgba(255, 255, 255, 0.12); + box-shadow: + 0 4px 8px rgba(0, 0, 0, 0.15), + 0 1px 2px rgba(0, 0, 0, 0.12), + inset 0 1px 0 rgba(255, 255, 255, 0.08); } .dark .toast-action-btn:hover { - background: rgba(0, 0, 0, 0.4); - box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); + background: linear-gradient(145deg, + rgba(0, 0, 0, 0.45) 0%, + rgba(15, 15, 15, 0.35) 50%, + rgba(0, 0, 0, 0.4) 100%); + box-shadow: + 0 8px 16px rgba(0, 0, 0, 0.2), + 0 2px 4px rgba(0, 0, 0, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.12); } .toast-close { padding: 0.375rem; - border-radius: 0.5rem; + border-radius: 0.625rem; border: none; - background: rgba(255, 255, 255, 0.15); + background: linear-gradient(145deg, + rgba(255, 255, 255, 0.18) 0%, + rgba(255, 255, 255, 0.08) 50%, + rgba(255, 255, 255, 0.12) 100%); color: inherit; cursor: pointer; - opacity: 0.8; + opacity: 0.75; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: flex; align-items: center; justify-content: center; - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); + backdrop-filter: blur(16px) saturate(110%); + -webkit-backdrop-filter: blur(16px) saturate(110%); border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-shadow: + 0 2px 4px rgba(0, 0, 0, 0.06), + 0 1px 2px rgba(0, 0, 0, 0.04), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + position: relative; + overflow: hidden; + } + + /* Close-Button-Ripple-Effekt */ + .toast-close::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + border-radius: 50%; + background: rgba(255, 255, 255, 0.3); + transform: translate(-50%, -50%); + transition: width 0.25s ease, height 0.25s ease; + } + + .toast-close:hover::after { + width: 100%; + height: 100%; } .toast-close:hover { opacity: 1; - background: rgba(255, 255, 255, 0.25); - transform: scale(1.15) rotate(90deg); - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); + background: linear-gradient(145deg, + rgba(255, 255, 255, 0.28) 0%, + rgba(255, 255, 255, 0.15) 50%, + rgba(255, 255, 255, 0.22) 100%); + transform: scale(1.1) rotate(90deg); + box-shadow: + 0 4px 8px rgba(0, 0, 0, 0.08), + 0 1px 2px rgba(0, 0, 0, 0.06), + inset 0 1px 0 rgba(255, 255, 255, 0.5); } .toast-close:active { - transform: scale(1.1) rotate(90deg); + transform: scale(1.05) rotate(90deg); transition: transform 0.1s ease; } .dark .toast-close { - background: rgba(0, 0, 0, 0.2); - border: 1px solid rgba(255, 255, 255, 0.15); - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + background: linear-gradient(145deg, + rgba(0, 0, 0, 0.25) 0%, + rgba(15, 15, 15, 0.15) 50%, + rgba(0, 0, 0, 0.2) 100%); + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: + 0 2px 4px rgba(0, 0, 0, 0.15), + 0 1px 2px rgba(0, 0, 0, 0.12), + inset 0 1px 0 rgba(255, 255, 255, 0.06); + } + + .dark .toast-close::after { + background: rgba(255, 255, 255, 0.15); } .dark .toast-close:hover { - background: rgba(0, 0, 0, 0.3); - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); + background: linear-gradient(145deg, + rgba(0, 0, 0, 0.35) 0%, + rgba(15, 15, 15, 0.25) 50%, + rgba(0, 0, 0, 0.4) 100%); + box-shadow: + 0 4px 8px rgba(0, 0, 0, 0.25), + 0 1px 2px rgba(0, 0, 0, 0.18), + inset 0 1px 0 rgba(255, 255, 255, 0.1); } .toast-progress { @@ -1094,25 +1205,51 @@ class GlassmorphismNotificationSystem { bottom: 0; left: 0; right: 0; - height: 4px; - background: rgba(255, 255, 255, 0.15); + height: 3px; + background: linear-gradient(90deg, + rgba(255, 255, 255, 0.08) 0%, + rgba(255, 255, 255, 0.04) 50%, + rgba(255, 255, 255, 0.08) 100%); overflow: hidden; - border-radius: 0 0 1.5rem 1.5rem; + border-radius: 0 0 1.75rem 1.75rem; + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); } .toast-progress-bar { height: 100%; background: linear-gradient(90deg, - rgba(255, 255, 255, 0.7) 0%, + rgba(255, 255, 255, 0.6) 0%, + rgba(255, 255, 255, 0.8) 25%, rgba(255, 255, 255, 0.9) 50%, - rgba(255, 255, 255, 0.7) 100%); + rgba(255, 255, 255, 0.8) 75%, + rgba(255, 255, 255, 0.6) 100%); width: 0%; - transition: width 0.3s ease; + transition: width 0.25s ease; position: relative; border-radius: inherit; box-shadow: - 0 0 8px rgba(255, 255, 255, 0.5), - inset 0 1px 0 rgba(255, 255, 255, 0.8); + 0 0 8px rgba(255, 255, 255, 0.4), + 0 0 4px rgba(255, 255, 255, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.7); + overflow: hidden; + } + + /* Progress-Bar-Animationen */ + .toast-progress-bar::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(90deg, + transparent 0%, + rgba(255, 255, 255, 0.4) 25%, + rgba(255, 255, 255, 0.6) 50%, + rgba(255, 255, 255, 0.4) 75%, + transparent 100%); + animation: progress-shimmer 2s ease-in-out infinite; } .toast-progress-bar::after { @@ -1122,11 +1259,15 @@ class GlassmorphismNotificationSystem { left: 0; right: 0; bottom: 0; - background: linear-gradient(90deg, - transparent 0%, - rgba(255, 255, 255, 0.4) 50%, - transparent 100%); - animation: progress-shimmer 2s ease-in-out infinite; + background: linear-gradient(45deg, + transparent 25%, + rgba(255, 255, 255, 0.2) 25%, + rgba(255, 255, 255, 0.2) 50%, + transparent 50%, + transparent 75%, + rgba(255, 255, 255, 0.2) 75%); + background-size: 12px 12px; + animation: progress-stripes 0.8s linear infinite; } @keyframes progress-shimmer { @@ -1134,21 +1275,55 @@ class GlassmorphismNotificationSystem { 100% { transform: translateX(100%); } } + @keyframes progress-stripes { + 0% { background-position: 0 0; } + 100% { background-position: 12px 0; } + } + @keyframes toast-progress { from { width: 100%; } to { width: 0%; } } .notification-settings { - max-width: 350px; - padding: 0.5rem 0; + max-width: 320px; + padding: 0.875rem; + background: linear-gradient(145deg, + rgba(255, 255, 255, 0.12) 0%, + rgba(255, 255, 255, 0.06) 50%, + rgba(255, 255, 255, 0.1) 100%); + border-radius: 1.25rem; + backdrop-filter: blur(24px) saturate(140%); + -webkit-backdrop-filter: blur(24px) saturate(140%); + border: 1px solid rgba(255, 255, 255, 0.25); + box-shadow: + 0 16px 32px rgba(0, 0, 0, 0.08), + 0 6px 12px rgba(0, 0, 0, 0.04), + inset 0 1px 0 rgba(255, 255, 255, 0.4); + } + + .dark .notification-settings { + background: linear-gradient(145deg, + rgba(0, 0, 0, 0.35) 0%, + rgba(15, 15, 15, 0.25) 50%, + rgba(0, 0, 0, 0.3) 100%); + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: + 0 16px 32px rgba(0, 0, 0, 0.25), + 0 6px 12px rgba(0, 0, 0, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.06); } .notification-settings h3 { margin-bottom: 1rem; - font-size: 1.1rem; - font-weight: 700; + font-size: 1rem; + font-weight: 600; color: inherit; + text-align: center; + background: linear-gradient(135deg, currentColor 0%, currentColor 100%); + -webkit-background-clip: text; + background-clip: text; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); } .setting-item { @@ -1157,40 +1332,98 @@ class GlassmorphismNotificationSystem { gap: 0.75rem; margin: 1rem 0; cursor: pointer; - font-size: 0.9rem; - font-weight: 500; - padding: 0.5rem; - border-radius: 0.5rem; - transition: all 0.2s ease; + font-size: 0.875rem; + font-weight: 450; + padding: 0.75rem; + border-radius: 0.875rem; + transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); + background: linear-gradient(145deg, + rgba(255, 255, 255, 0.08) 0%, + rgba(255, 255, 255, 0.04) 100%); + border: 1px solid rgba(255, 255, 255, 0.12); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + position: relative; + overflow: hidden; + } + + /* Setting-Item-Hover-Effekt */ + .setting-item::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, + transparent 0%, + rgba(255, 255, 255, 0.08) 50%, + transparent 100%); + transition: left 0.3s ease; + } + + .setting-item:hover::before { + left: 100%; } .setting-item:hover { - background: rgba(255, 255, 255, 0.1); - transform: translateX(4px); + background: linear-gradient(145deg, + rgba(255, 255, 255, 0.16) 0%, + rgba(255, 255, 255, 0.08) 100%); + transform: translateX(6px) scale(1.01); + box-shadow: + 0 6px 12px rgba(0, 0, 0, 0.06), + 0 1px 2px rgba(0, 0, 0, 0.04), + inset 0 1px 0 rgba(255, 255, 255, 0.25); + } + + .dark .setting-item { + background: linear-gradient(145deg, + rgba(0, 0, 0, 0.18) 0%, + rgba(15, 15, 15, 0.12) 100%); + border: 1px solid rgba(255, 255, 255, 0.06); + } + + .dark .setting-item:hover { + background: linear-gradient(145deg, + rgba(0, 0, 0, 0.25) 0%, + rgba(15, 15, 15, 0.18) 100%); + box-shadow: + 0 6px 12px rgba(0, 0, 0, 0.15), + 0 1px 2px rgba(0, 0, 0, 0.12), + inset 0 1px 0 rgba(255, 255, 255, 0.08); } .setting-item input[type="checkbox"] { margin: 0; - width: 1.2rem; - height: 1.2rem; + width: 1.25rem; + height: 1.25rem; accent-color: currentColor; + cursor: pointer; + border-radius: 0.3rem; + transition: all 0.2s ease; + } + + .setting-item input[type="checkbox"]:checked { + transform: scale(1.05); + box-shadow: 0 0 6px rgba(59, 130, 246, 0.3); } /* Responsive Design */ @media (max-width: 640px) { .notifications-container { - left: 0.75rem; - right: 0.75rem; - top: 0.75rem; + left: 0.5rem; + right: 0.5rem; + top: 0.5rem; } .glassmorphism-toast { margin-bottom: 0.5rem; - border-radius: 1rem; + border-radius: 1.25rem; } .toast-content { - padding: 1rem; + padding: 0.875rem; } .toast-header { @@ -1203,17 +1436,21 @@ class GlassmorphismNotificationSystem { } .toast-title { - font-size: 0.85rem; - } - - .toast-message { font-size: 0.8125rem; } - .toast-action-btn { - padding: 0.4rem 0.8rem; + .toast-message { font-size: 0.75rem; } + + .toast-action-btn { + padding: 0.4rem 0.7rem; + font-size: 0.7rem; + } + + .toast-close { + padding: 0.3rem; + } } /* High Contrast Mode */ diff --git a/backend/templates/admin.html b/backend/templates/admin.html index 2544f711..adade0a8 100644 --- a/backend/templates/admin.html +++ b/backend/templates/admin.html @@ -575,4 +575,225 @@ + + + + + {% endblock %} diff --git a/backend/templates/index.html b/backend/templates/index.html index 0c486d3d..6ae655d8 100644 --- a/backend/templates/index.html +++ b/backend/templates/index.html @@ -1108,10 +1108,7 @@ function setupErrorHandling() { function setupPerformanceOptimizations() { // Preload critical resources const preloadLinks = [ - '/api/statistics/public', - '/static/icons/iso-27001.svg', - '/static/icons/mercedes-star.svg', - '/static/icons/gdpr.svg' + '/api/statistics/public' ]; preloadLinks.forEach(href => {