From 09462724e099f5565a8715d282156af6f64d8fc4 Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Sun, 1 Jun 2025 03:25:55 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20Improved=20backend=20structure?= =?UTF-8?q?=20&=20logs=20organization=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/__pycache__/models.cpython-313.pyc | Bin 54312 -> 70466 bytes backend/app.py | 53 +- backend/database/myp.db-shm | Bin 0 -> 32768 bytes backend/database/myp.db-wal | Bin 0 -> 37112 bytes backend/docs/UI_VERBESSERUNGEN.md | 156 ----- .../logs/advanced_tables/advanced_tables.log | 0 backend/logs/analytics/analytics.log | 3 + backend/logs/app/app.log | 186 +++++ backend/logs/backup/backup.log | 3 + backend/logs/calendar/calendar.log | 2 + backend/logs/dashboard/dashboard.log | 12 + backend/logs/database/database.log | 3 + .../database_cleanup/database_cleanup.log | 6 + backend/logs/drag_drop/drag_drop.log | 0 .../email_notification/email_notification.log | 3 + backend/logs/guest/guest.log | 0 backend/logs/jobs/jobs.log | 3 + backend/logs/kiosk/kiosk.log | 0 backend/logs/maintenance/maintenance.log | 6 + .../logs/multi_location/multi_location.log | 6 + backend/logs/permissions/permissions.log | 3 + .../logs/printer_monitor/printer_monitor.log | 167 +++++ backend/logs/printers/printers.log | 108 +++ backend/logs/queue_manager/queue_manager.log | 11 + backend/logs/reports/reports.log | 0 backend/logs/scheduler/scheduler.log | 13 + backend/logs/security/security.log | 3 + .../shutdown_manager/shutdown_manager.log | 14 + backend/logs/startup/startup.log | 27 + backend/logs/user/user.log | 0 backend/logs/users/users.log | 0 backend/logs/validation/validation.log | 0 backend/logs/windows_fixes/windows_fixes.log | 16 + backend/static/css/glassmorphism.css | 428 +++++++++--- backend/static/css/professional-theme.css | 412 ++++++++--- backend/static/js/user-dropdown.js | 1 + backend/templates/base.html | 199 +++--- backend/templates/dashboard.html | 650 ++++++++++++++++++ .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 166 bytes .../advanced_tables.cpython-313.pyc | Bin 0 -> 37797 bytes .../__pycache__/analytics.cpython-313.pyc | Bin 0 -> 29551 bytes .../backup_manager.cpython-313.pyc | Bin 0 -> 1732 bytes .../database_cleanup.cpython-313.pyc | Bin 0 -> 16140 bytes .../database_utils.cpython-313.pyc | Bin 0 -> 20530 bytes .../drag_drop_system.cpython-313.pyc | Bin 0 -> 57200 bytes .../email_notification.cpython-313.pyc | Bin 0 -> 6976 bytes .../__pycache__/file_manager.cpython-313.pyc | Bin 0 -> 17341 bytes .../form_validation.cpython-313.pyc | Bin 0 -> 33948 bytes .../__pycache__/job_scheduler.cpython-313.pyc | Bin 0 -> 31893 bytes .../maintenance_system.cpython-313.pyc | Bin 0 -> 38257 bytes .../multi_location_system.cpython-313.pyc | Bin 0 -> 37191 bytes .../__pycache__/permissions.cpython-313.pyc | Bin 0 -> 27455 bytes .../printer_monitor.cpython-313.pyc | Bin 0 -> 30568 bytes .../__pycache__/queue_manager.cpython-313.pyc | Bin 0 -> 23109 bytes .../__pycache__/rate_limiter.cpython-313.pyc | Bin 0 -> 12184 bytes .../realtime_dashboard.cpython-313.pyc | Bin 0 -> 50059 bytes .../report_generator.cpython-313.pyc | Bin 0 -> 45442 bytes .../__pycache__/security.cpython-313.pyc | Bin 0 -> 12995 bytes .../shutdown_manager.cpython-313.pyc | Bin 0 -> 21713 bytes .../__pycache__/ssl_config.cpython-313.pyc | Bin 0 -> 168 bytes .../template_helpers.cpython-313.pyc | Bin 0 -> 20303 bytes .../__pycache__/windows_fixes.cpython-313.pyc | Bin 0 -> 18214 bytes backend/utils/ssl_config.py | 11 + 63 files changed, 2014 insertions(+), 491 deletions(-) create mode 100644 backend/database/myp.db-shm create mode 100644 backend/database/myp.db-wal delete mode 100644 backend/docs/UI_VERBESSERUNGEN.md create mode 100644 backend/logs/advanced_tables/advanced_tables.log create mode 100644 backend/logs/analytics/analytics.log create mode 100644 backend/logs/backup/backup.log create mode 100644 backend/logs/calendar/calendar.log create mode 100644 backend/logs/dashboard/dashboard.log create mode 100644 backend/logs/database/database.log create mode 100644 backend/logs/database_cleanup/database_cleanup.log create mode 100644 backend/logs/drag_drop/drag_drop.log create mode 100644 backend/logs/email_notification/email_notification.log create mode 100644 backend/logs/guest/guest.log create mode 100644 backend/logs/kiosk/kiosk.log create mode 100644 backend/logs/maintenance/maintenance.log create mode 100644 backend/logs/multi_location/multi_location.log create mode 100644 backend/logs/permissions/permissions.log create mode 100644 backend/logs/printer_monitor/printer_monitor.log create mode 100644 backend/logs/queue_manager/queue_manager.log create mode 100644 backend/logs/reports/reports.log create mode 100644 backend/logs/security/security.log create mode 100644 backend/logs/shutdown_manager/shutdown_manager.log create mode 100644 backend/logs/startup/startup.log create mode 100644 backend/logs/user/user.log create mode 100644 backend/logs/users/users.log create mode 100644 backend/logs/validation/validation.log create mode 100644 backend/logs/windows_fixes/windows_fixes.log create mode 100644 backend/static/js/user-dropdown.js create mode 100644 backend/utils/__pycache__/__init__.cpython-313.pyc create mode 100644 backend/utils/__pycache__/advanced_tables.cpython-313.pyc create mode 100644 backend/utils/__pycache__/analytics.cpython-313.pyc create mode 100644 backend/utils/__pycache__/backup_manager.cpython-313.pyc create mode 100644 backend/utils/__pycache__/database_cleanup.cpython-313.pyc create mode 100644 backend/utils/__pycache__/database_utils.cpython-313.pyc create mode 100644 backend/utils/__pycache__/drag_drop_system.cpython-313.pyc create mode 100644 backend/utils/__pycache__/email_notification.cpython-313.pyc create mode 100644 backend/utils/__pycache__/file_manager.cpython-313.pyc create mode 100644 backend/utils/__pycache__/form_validation.cpython-313.pyc create mode 100644 backend/utils/__pycache__/job_scheduler.cpython-313.pyc create mode 100644 backend/utils/__pycache__/maintenance_system.cpython-313.pyc create mode 100644 backend/utils/__pycache__/multi_location_system.cpython-313.pyc create mode 100644 backend/utils/__pycache__/permissions.cpython-313.pyc create mode 100644 backend/utils/__pycache__/printer_monitor.cpython-313.pyc create mode 100644 backend/utils/__pycache__/queue_manager.cpython-313.pyc create mode 100644 backend/utils/__pycache__/rate_limiter.cpython-313.pyc create mode 100644 backend/utils/__pycache__/realtime_dashboard.cpython-313.pyc create mode 100644 backend/utils/__pycache__/report_generator.cpython-313.pyc create mode 100644 backend/utils/__pycache__/security.cpython-313.pyc create mode 100644 backend/utils/__pycache__/shutdown_manager.cpython-313.pyc create mode 100644 backend/utils/__pycache__/ssl_config.cpython-313.pyc create mode 100644 backend/utils/__pycache__/template_helpers.cpython-313.pyc create mode 100644 backend/utils/__pycache__/windows_fixes.cpython-313.pyc create mode 100644 backend/utils/ssl_config.py diff --git a/backend/__pycache__/models.cpython-313.pyc b/backend/__pycache__/models.cpython-313.pyc index 41a92883170f90da8d45b2906b4fefffb636fe0d..11ecb045b379e89102a85195cf72a6bd18335e05 100644 GIT binary patch delta 26198 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 delta 14499 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 literal 0 HcmV?d00001 diff --git a/backend/database/myp.db-wal b/backend/database/myp.db-wal new file mode 100644 index 0000000000000000000000000000000000000000..d3b395156232a08855c0162adb45c6dc02cc2b39 GIT binary patch literal 37112 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 { - userDropdown.style.transition = 'all 0.15s ease-out'; - userDropdown.style.opacity = '1'; - userDropdown.style.transform = 'scale(1) translateY(0)'; - }); -} -``` - -### 2. ✅ DND Counter Element entfernt - -**Problem**: Das dndCounter-Element war unerwünscht und sollte komplett entfernt werden: -```html - -``` - -**Lösung**: Vollständige Entfernung: - -#### HTML-Bereinigung: -- ✅ `dndCounter`-Element aus `base.html` entfernt -- ✅ Umstrukturierung der DND-Status-Anzeige zu einfachem Text-Format - -#### JavaScript-Bereinigung: -- ✅ Alle dndCounter-Referenzen aus `DoNotDisturbManager` entfernt -- ✅ Counter-Update-Logik entfernt -- ✅ DOM-Queries auf dndCounter entfernt - -#### Vorher: -```javascript -const dndCounter = document.getElementById('dndCounter'); -// Counter aktualisieren -if (dndCounter) { - if (this.suppressedCount > 0 && this.isEnabled) { - dndCounter.textContent = `${this.suppressedCount} unterdrückt`; - dndCounter.classList.remove('hidden'); - } else { - dndCounter.classList.add('hidden'); - } -} -``` - -#### Nachher: -```javascript -// Counter-Logik vollständig entfernt -// Nur noch einfache Textanzeige im DND-Status -``` - -### 3. ✅ Bonus: Mobile Menu Funktionalität - -**Zusätzliche Verbesserung**: Mobile Menu Toggle-Funktionalität implementiert - -#### Features: -- **Responsive Design**: Automatisches Verstecken bei Desktop-Größe -- **Icon-Wechsel**: Hamburger ↔ X Animation -- **ARIA-Labels**: Accessibility-konforme Beschriftung -- **Touch-optimiert**: Bessere Bedienung auf mobilen Geräten - -## Kaskaden-Analyse - -### Betroffene Dateien: -1. **`templates/base.html`**: - - dndCounter HTML-Element entfernt - - User-Dropdown JavaScript hinzugefügt - - Mobile Menu JavaScript hinzugefügt - - DoNotDisturbManager bereinigt - -### Abhängigkeiten geprüft: -- ✅ **Keine anderen Referenzen** auf dndCounter gefunden -- ✅ **User-Dropdown HTML** war bereits korrekt strukturiert -- ✅ **Mobile Menu HTML** war bereits vorhanden -- ✅ **CSS-Klassen** bleiben unverändert funktionsfähig - -### Rückwärts-Kompatibilität: -- ✅ Alle bestehenden Features funktionieren weiterhin -- ✅ DND-Funktionalität arbeitet ohne Counter -- ✅ Navigation auf allen Geräten funktional -- ✅ Keine Breaking Changes - -## Qualitätssicherung - -### Funktionale Tests: -- ✅ User-Dropdown öffnet/schließt korrekt -- ✅ Keyboard-Navigation funktioniert -- ✅ Mobile Menu responsiv -- ✅ DND-Manager funktioniert ohne Counter -- ✅ Keine JavaScript-Fehler in Console - -### Browser-Kompatibilität: -- ✅ Chrome/Edge (Webkit) -- ✅ Firefox -- ✅ Safari -- ✅ Mobile Browser - -### Accessibility: -- ✅ ARIA-Attribute korrekt gesetzt -- ✅ Keyboard-Navigation funktional -- ✅ Screen-Reader kompatibel -- ✅ Focus-Management implementiert - -## Deployment-Status - -**Status**: ✅ **PRODUKTIONSBEREIT** - -**Rollback-Plan**: Falls Probleme auftreten: -1. Git-Revert zu vorherigem Commit -2. Alternativ: User-Dropdown JavaScript deaktivieren -3. dndCounter temporär wieder hinzufügen (falls nötig) - -## Nächste Schritte - -1. **Live-Tests** auf Staging-Environment -2. **User-Feedback** sammeln zur neuen Dropdown-UX -3. **Performance-Monitoring** der neuen JavaScript-Funktionen -4. **Weitere UI-Optimierungen** basierend auf Nutzungsstatistiken - ---- - -**Datum**: Januar 2025 -**Entwickler**: AI Assistant -**Review**: Code-Review erfolgreich abgeschlossen -**Status**: Implementiert und getestet \ No newline at end of file diff --git a/backend/logs/advanced_tables/advanced_tables.log b/backend/logs/advanced_tables/advanced_tables.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/analytics/analytics.log b/backend/logs/analytics/analytics.log new file mode 100644 index 00000000..b9555804 --- /dev/null +++ b/backend/logs/analytics/analytics.log @@ -0,0 +1,3 @@ +2025-06-01 03:01:13 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 03:04:47 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert +2025-06-01 03:06:06 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert diff --git a/backend/logs/app/app.log b/backend/logs/app/app.log index fbef3048..ff55a791 100644 --- a/backend/logs/app/app.log +++ b/backend/logs/app/app.log @@ -4,3 +4,189 @@ 2025-06-01 02:47:47 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db 2025-06-01 02:48:30 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup 2025-06-01 02:48:30 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 03:01:13 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 03:01:14 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 03:01:15 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert +2025-06-01 03:01:15 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen... +2025-06-01 03:01:15 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert +2025-06-01 03:01:15 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden +2025-06-01 03:01:15 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt. +2025-06-01 03:01:15 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen +2025-06-01 03:01:15 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung... +2025-06-01 03:01:15 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden +2025-06-01 03:01:15 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung +2025-06-01 03:01:15 - [app] app - [INFO] INFO - Job-Scheduler gestartet +2025-06-01 03:01:15 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP) +2025-06-01 03:01:15 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert +2025-06-01 03:01:49 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:01:49 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:01:49 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:01:49 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': None, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': None, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:02:25 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:02:25 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:02:25 - [app] app - [ERROR] ERROR - Fehler beim Abrufen der Dashboard-Statistiken: tuple index out of range +2025-06-01 03:02:25 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 0, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:02:25 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:02:56 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:02:56 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:02:56 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:02:56 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1 +2025-06-01 03:02:58 - [app] app - [ERROR] ERROR - Fehler beim Abrufen der Dashboard-Statistiken: tuple index out of range +2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 0, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': None, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0} +2025-06-01 03:04:46 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 03:04:48 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 03:04:48 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert +2025-06-01 03:04:48 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen... +2025-06-01 03:04:48 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert +2025-06-01 03:04:48 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden +2025-06-01 03:04:48 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt. +2025-06-01 03:04:48 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen +2025-06-01 03:04:48 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung... +2025-06-01 03:04:48 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden +2025-06-01 03:04:48 - [app] app - [INFO] INFO - ✅ Printer Queue Manager erfolgreich gestartet +2025-06-01 03:04:48 - [app] app - [INFO] INFO - Job-Scheduler gestartet +2025-06-01 03:04:48 - [app] app - [INFO] INFO - Starte HTTP-Server auf 0.0.0.0:80 +2025-06-01 03:06:06 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db +2025-06-01 03:06:07 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen) +2025-06-01 03:06:07 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert +2025-06-01 03:06:07 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen... +2025-06-01 03:06:07 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert +2025-06-01 03:06:07 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden +2025-06-01 03:06:07 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt. +2025-06-01 03:06:07 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen +2025-06-01 03:06:07 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung... +2025-06-01 03:06:07 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden +2025-06-01 03:06:07 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung +2025-06-01 03:06:07 - [app] app - [INFO] INFO - Job-Scheduler gestartet +2025-06-01 03:06:07 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP) +2025-06-01 03:06:07 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert +2025-06-01 03:06:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:17 - [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 03:06:18 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:18 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:19 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:42 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:42 - [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 03:06:43 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:43 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:44 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:48 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:48 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:48 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:48 - [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 03:06:49 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:49 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:49 - [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 03:06:50 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:50 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:50 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:50 - [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 03:06:50 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:50 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:50 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:51 - [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 03:06:51 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:51 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:51 - [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 03:06:52 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:52 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06: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 03:06:52 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:52 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:53 - [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 03:06:53 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:53 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:53 - [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 03:06:54 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:54 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:54 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:54 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:54 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:55 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:58 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:58 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:58 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:06:58 - [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 03:06:59 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:59 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:06:59 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:00 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:04 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:04 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:04 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:04 - [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 03:07:05 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:05 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:05 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:06 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:13 - [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 03:07:14 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:14 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:14 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:15 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:17 - [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 03:07:18 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:18 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:18 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:19 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:23 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:23 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:23 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:23 - [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 03:07:24 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:24 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:24 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:25 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:27 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:27 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:27 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:27 - [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 03:07:28 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:29 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:29 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:30 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:37 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:37 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:07:38 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible) +2025-06-01 03:07:38 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:08:12 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:08:12 - [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 03:08:13 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) +2025-06-01 03:08:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True +2025-06-01 03:08:14 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible) diff --git a/backend/logs/backup/backup.log b/backend/logs/backup/backup.log new file mode 100644 index 00000000..8607be9c --- /dev/null +++ b/backend/logs/backup/backup.log @@ -0,0 +1,3 @@ +2025-06-01 03:01:13 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 03:04:47 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) +2025-06-01 03:06:06 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) diff --git a/backend/logs/calendar/calendar.log b/backend/logs/calendar/calendar.log new file mode 100644 index 00000000..f1d55167 --- /dev/null +++ b/backend/logs/calendar/calendar.log @@ -0,0 +1,2 @@ +2025-06-01 03:06:34 - [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 03:08:04 - [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 new file mode 100644 index 00000000..e7c28841 --- /dev/null +++ b/backend/logs/dashboard/dashboard.log @@ -0,0 +1,12 @@ +2025-06-01 03:01:14 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 03:01:15 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 03:01:15 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 03:01:15 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 03:04:48 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 03:04:48 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 03:04:48 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 03:04:48 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) +2025-06-01 03:06:07 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 03:06:07 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet +2025-06-01 03:06:07 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) +2025-06-01 03:06:07 - [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 new file mode 100644 index 00000000..58c52f3c --- /dev/null +++ b/backend/logs/database/database.log @@ -0,0 +1,3 @@ +2025-06-01 03:01:13 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 03:04:47 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet +2025-06-01 03:06:06 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet diff --git a/backend/logs/database_cleanup/database_cleanup.log b/backend/logs/database_cleanup/database_cleanup.log new file mode 100644 index 00000000..701c267f --- /dev/null +++ b/backend/logs/database_cleanup/database_cleanup.log @@ -0,0 +1,6 @@ +2025-06-01 03:03:00 - [database_cleanup] database_cleanup - [INFO] INFO - 🧹 Starte umfassendes Datenbank-Cleanup... +2025-06-01 03:03:00 - [database_cleanup] database_cleanup - [INFO] INFO - 📝 Schritt 1: Schließe alle Datenbankverbindungen... +2025-06-01 03:03:00 - [database_cleanup] database_cleanup - [INFO] INFO - 🔄 Schließe alle aktiven Datenbankverbindungen... +2025-06-01 03:04:49 - [database_cleanup] database_cleanup - [INFO] INFO - 🧹 Starte umfassendes Datenbank-Cleanup... +2025-06-01 03:04:49 - [database_cleanup] database_cleanup - [INFO] INFO - 📝 Schritt 1: Schließe alle Datenbankverbindungen... +2025-06-01 03:04:49 - [database_cleanup] database_cleanup - [INFO] INFO - 🔄 Schließe alle aktiven Datenbankverbindungen... diff --git a/backend/logs/drag_drop/drag_drop.log b/backend/logs/drag_drop/drag_drop.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/email_notification/email_notification.log b/backend/logs/email_notification/email_notification.log new file mode 100644 index 00000000..3387f039 --- /dev/null +++ b/backend/logs/email_notification/email_notification.log @@ -0,0 +1,3 @@ +2025-06-01 03:01:14 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 03:04:48 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) +2025-06-01 03:06:07 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) diff --git a/backend/logs/guest/guest.log b/backend/logs/guest/guest.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/jobs/jobs.log b/backend/logs/jobs/jobs.log index 78989efc..06971a44 100644 --- a/backend/logs/jobs/jobs.log +++ b/backend/logs/jobs/jobs.log @@ -31,3 +31,6 @@ 2025-06-01 01:51:40 - myp.jobs - INFO - Jobs abgerufen: 0 von 0 (Seite 1) 2025-06-01 02:42:45 - myp.jobs - INFO - Jobs abgerufen: 0 von 0 (Seite 1) 2025-06-01 02:43:03 - myp.jobs - INFO - Jobs abgerufen: 0 von 0 (Seite 1) +2025-06-01 03:06:28 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) +2025-06-01 03:07:42 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) +2025-06-01 03:07:55 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1) diff --git a/backend/logs/kiosk/kiosk.log b/backend/logs/kiosk/kiosk.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/maintenance/maintenance.log b/backend/logs/maintenance/maintenance.log new file mode 100644 index 00000000..c8601fe5 --- /dev/null +++ b/backend/logs/maintenance/maintenance.log @@ -0,0 +1,6 @@ +2025-06-01 03:01:14 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 03:01:15 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 03:04:48 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 03:04:48 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 03:06:07 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet +2025-06-01 03:06:07 - [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 new file mode 100644 index 00000000..68c92fd6 --- /dev/null +++ b/backend/logs/multi_location/multi_location.log @@ -0,0 +1,6 @@ +2025-06-01 03:01:15 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 03:01:15 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 03:04:48 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 03:04:48 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 03:06:07 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt +2025-06-01 03:06:07 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt diff --git a/backend/logs/permissions/permissions.log b/backend/logs/permissions/permissions.log new file mode 100644 index 00000000..46dfa897 --- /dev/null +++ b/backend/logs/permissions/permissions.log @@ -0,0 +1,3 @@ +2025-06-01 03:01:15 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 03:04:48 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert +2025-06-01 03:06:07 - [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 new file mode 100644 index 00000000..e2e1c3c3 --- /dev/null +++ b/backend/logs/printer_monitor/printer_monitor.log @@ -0,0 +1,167 @@ +2025-06-01 03:01:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 03:01:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart... +2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden +2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung... +2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration +2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103 +2025-06-01 03:01:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:01:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:01:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:01:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:01:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104 +2025-06-01 03:01:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100 +2025-06-01 03:01:33 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101 +2025-06-01 03:01:39 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102 +2025-06-01 03:01:45 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105 +2025-06-01 03:01:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:01:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:01:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:01:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:01:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:01:50 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:01:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:01:50 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:01:51 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.0s +2025-06-01 03:01:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:01:55 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:01:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:01:55 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:26 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:26 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:57 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:57 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:59 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:02:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:02:59 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:04:47 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 03:04:47 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 03:04:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart... +2025-06-01 03:04:48 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden +2025-06-01 03:04:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung... +2025-06-01 03:04:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration +2025-06-01 03:04:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103 +2025-06-01 03:04:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104 +2025-06-01 03:05:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100 +2025-06-01 03:06:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert +2025-06-01 03:06:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet +2025-06-01 03:06:07 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart... +2025-06-01 03:06:07 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden +2025-06-01 03:06:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung... +2025-06-01 03:06:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration +2025-06-01 03:06:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103 +2025-06-01 03:06:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:10 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:10 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104 +2025-06-01 03:06:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:20 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100 +2025-06-01 03:06:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:24 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:24 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101 +2025-06-01 03:06:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102 +2025-06-01 03:06:38 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105 +2025-06-01 03:06:42 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:42 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:42 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:42 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:44 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.0s +2025-06-01 03:06:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:48 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:48 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:50 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:50 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:06:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:06:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:04 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:04 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:13 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:13 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:23 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:23 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:27 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:27 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:39 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:39 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:39 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:39 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:41 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:41 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:07:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:07:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:08:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:08:12 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden +2025-06-01 03:08:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus... +2025-06-01 03:08:12 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden diff --git a/backend/logs/printers/printers.log b/backend/logs/printers/printers.log index 7afea48a..8b19a827 100644 --- a/backend/logs/printers/printers.log +++ b/backend/logs/printers/printers.log @@ -2886,3 +2886,111 @@ 2025-06-01 02:43:37 - myp.printers - INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker 2025-06-01 02:44:06 - myp.printers - INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) 2025-06-01 02:44:07 - myp.printers - INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:01:19 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:01:19 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:01:19 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 15.66ms +2025-06-01 03:01:49 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:01:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:01:49 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.17ms +2025-06-01 03:01:50 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:01:50 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:01:50 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.94ms +2025-06-01 03:01:55 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:01:55 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:01:55 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.06ms +2025-06-01 03:02:25 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:02:25 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:02:25 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.46ms +2025-06-01 03:02:26 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:02:26 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:02:26 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.16ms +2025-06-01 03:02:56 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:02:56 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:02:56 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.40ms +2025-06-01 03:02:57 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:02:57 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:02:57 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.84ms +2025-06-01 03:02:59 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:02:59 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:02:59 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 8.32ms +2025-06-01 03:06:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:10 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.71ms +2025-06-01 03:06:17 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:17 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:17 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.44ms +2025-06-01 03:06:24 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:24 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:24 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.16ms +2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.36ms +2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:06:28 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:06:42 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:42 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:42 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 11.01ms +2025-06-01 03:06:48 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:48 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:48 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.57ms +2025-06-01 03:06:49 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:49 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 14.08ms +2025-06-01 03:06:50 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:50 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:50 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 17.65ms +2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.08ms +2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 12.72ms +2025-06-01 03:06:52 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:52 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:52 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 16.45ms +2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 12.55ms +2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.40ms +2025-06-01 03:06:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:06:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:06:58 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 16.40ms +2025-06-01 03:07:04 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:04 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:04 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 4.09ms +2025-06-01 03:07:13 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:13 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:13 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.67ms +2025-06-01 03:07:17 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:17 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:17 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 8.53ms +2025-06-01 03:07:23 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:23 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:23 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.79ms +2025-06-01 03:07:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:27 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.96ms +2025-06-01 03:07:39 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:39 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:39 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.91ms +2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 4.61ms +2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:07:42 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:07:49 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:49 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.00ms +2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.43ms +2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:07:55 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check) +2025-06-01 03:08:12 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) +2025-06-01 03:08:12 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker +2025-06-01 03:08:12 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 13.12ms diff --git a/backend/logs/queue_manager/queue_manager.log b/backend/logs/queue_manager/queue_manager.log new file mode 100644 index 00000000..01739069 --- /dev/null +++ b/backend/logs/queue_manager/queue_manager.log @@ -0,0 +1,11 @@ +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager... +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager... +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden) +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager... +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread... +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet +2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt diff --git a/backend/logs/reports/reports.log b/backend/logs/reports/reports.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/scheduler/scheduler.log b/backend/logs/scheduler/scheduler.log index c2493c4e..3714d5c1 100644 --- a/backend/logs/scheduler/scheduler.log +++ b/backend/logs/scheduler/scheduler.log @@ -2812,3 +2812,16 @@ 2025-06-01 02:42:28 - myp.scheduler - INFO - Scheduler gestartet 2025-06-01 02:44:24 - myp.scheduler - INFO - Scheduler-Thread beendet 2025-06-01 02:44:24 - myp.scheduler - INFO - Scheduler gestoppt +2025-06-01 03:01:13 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 03:01:15 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet +2025-06-01 03:01:15 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet +2025-06-01 03:03:00 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread beendet +2025-06-01 03:03:00 - [scheduler] scheduler - [INFO] INFO - Scheduler gestoppt +2025-06-01 03:04:47 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 03:04:48 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet +2025-06-01 03:04:48 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet +2025-06-01 03:04:49 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread beendet +2025-06-01 03:04:49 - [scheduler] scheduler - [INFO] INFO - Scheduler gestoppt +2025-06-01 03:06:06 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-01 03:06:07 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet +2025-06-01 03:06:07 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet diff --git a/backend/logs/security/security.log b/backend/logs/security/security.log new file mode 100644 index 00000000..1c9a016b --- /dev/null +++ b/backend/logs/security/security.log @@ -0,0 +1,3 @@ +2025-06-01 03:01:15 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 03:04:48 - [security] security - [INFO] INFO - 🔒 Security System initialisiert +2025-06-01 03:06:07 - [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 new file mode 100644 index 00000000..0880519c --- /dev/null +++ b/backend/logs/shutdown_manager/shutdown_manager.log @@ -0,0 +1,14 @@ +2025-06-01 03:01:15 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [WARNING] WARNING - 🛑 Signal 2 empfangen - starte koordiniertes Shutdown +2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Starte koordiniertes System-Shutdown... +2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🧹 Führe 4 Cleanup-Funktionen aus... +2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Beende Scheduler mit stop()... +2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - ✅ Scheduler erfolgreich gestoppt +2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - 💾 Führe sicheres Datenbank-Cleanup durch... +2025-06-01 03:04:48 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert +2025-06-01 03:04:48 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Starte koordiniertes System-Shutdown... +2025-06-01 03:04:48 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🧹 Führe 4 Cleanup-Funktionen aus... +2025-06-01 03:04:48 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Beende Scheduler mit stop()... +2025-06-01 03:04:49 - [shutdown_manager] shutdown_manager - [INFO] INFO - ✅ Scheduler erfolgreich gestoppt +2025-06-01 03:04:49 - [shutdown_manager] shutdown_manager - [INFO] INFO - 💾 Führe sicheres Datenbank-Cleanup durch... +2025-06-01 03:06:07 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert diff --git a/backend/logs/startup/startup.log b/backend/logs/startup/startup.log new file mode 100644 index 00000000..e901772e --- /dev/null +++ b/backend/logs/startup/startup.log @@ -0,0 +1,27 @@ +2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 03:01:15 - [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 03:01:15 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T03:01:15.112489 +2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 03:04:48 - [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 03:04:48 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T03:04:48.521790 +2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - ================================================== +2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet... +2025-06-01 03:06:07 - [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 03:06:07 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T03:06:07.426354 +2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - ================================================== diff --git a/backend/logs/user/user.log b/backend/logs/user/user.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/users/users.log b/backend/logs/users/users.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/validation/validation.log b/backend/logs/validation/validation.log new file mode 100644 index 00000000..e69de29b diff --git a/backend/logs/windows_fixes/windows_fixes.log b/backend/logs/windows_fixes/windows_fixes.log new file mode 100644 index 00000000..c9af19a2 --- /dev/null +++ b/backend/logs/windows_fixes/windows_fixes.log @@ -0,0 +1,16 @@ +2025-06-01 03:01:13 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 03:01:13 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 03:01:13 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 03:01:13 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 03:03:00 - [windows_fixes] windows_fixes - [INFO] INFO - 🔄 Starte Windows Thread-Shutdown... +2025-06-01 03:03:00 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Windows Thread-Shutdown abgeschlossen +2025-06-01 03:04:46 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 03:04:46 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 03:04:46 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 03:04:46 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-01 03:04:49 - [windows_fixes] windows_fixes - [INFO] INFO - 🔄 Starte Windows Thread-Shutdown... +2025-06-01 03:04:49 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Windows Thread-Shutdown abgeschlossen +2025-06-01 03:06:06 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-01 03:06:06 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) +2025-06-01 03:06:06 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet +2025-06-01 03:06:06 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet diff --git a/backend/static/css/glassmorphism.css b/backend/static/css/glassmorphism.css index 47790c0e..1c75a2b0 100644 --- a/backend/static/css/glassmorphism.css +++ b/backend/static/css/glassmorphism.css @@ -2,163 +2,344 @@ /* Base Glass Effects */ .glass-base { - backdrop-filter: blur(20px) saturate(180%) brightness(110%); - -webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%); - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.1); + backdrop-filter: blur(24px) saturate(200%) brightness(115%); + -webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%); + border: 1px solid rgba(255, 255, 255, 0.25); + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.12), + 0 8px 16px rgba(0, 0, 0, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } .glass-strong { - backdrop-filter: blur(24px) saturate(200%) brightness(120%); - -webkit-backdrop-filter: blur(24px) saturate(200%) brightness(120%); - box-shadow: 0 35px 60px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.1); + backdrop-filter: blur(28px) saturate(220%) brightness(125%); + -webkit-backdrop-filter: blur(28px) saturate(220%) brightness(125%); + box-shadow: + 0 35px 70px rgba(0, 0, 0, 0.15), + 0 12px 24px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.4); } .glass-subtle { - backdrop-filter: blur(16px) saturate(150%) brightness(105%); - -webkit-backdrop-filter: blur(16px) saturate(150%) brightness(105%); - box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(255, 255, 255, 0.05); + backdrop-filter: blur(20px) saturate(180%) brightness(110%); + -webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%); + box-shadow: + 0 15px 35px rgba(0, 0, 0, 0.08), + 0 4px 8px rgba(0, 0, 0, 0.05), + inset 0 1px 0 rgba(255, 255, 255, 0.2); } /* Light Mode Glass */ .glass-light { - background: rgba(255, 255, 255, 0.7); - border: 1px solid rgba(255, 255, 255, 0.3); + background: rgba(255, 255, 255, 0.85); + border: 1px solid rgba(255, 255, 255, 0.4); + box-shadow: + 0 20px 40px rgba(0, 0, 0, 0.1), + 0 8px 16px rgba(0, 115, 206, 0.05), + inset 0 1px 0 rgba(255, 255, 255, 0.6); } .glass-light-strong { - background: rgba(255, 255, 255, 0.6); - border: 1px solid rgba(255, 255, 255, 0.4); + background: rgba(255, 255, 255, 0.75); + border: 1px solid rgba(255, 255, 255, 0.5); + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.12), + 0 10px 20px rgba(0, 115, 206, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.7); +} + +/* Light Mode Glass Premium */ +.glass-light-premium { + background: linear-gradient(135deg, + rgba(255, 255, 255, 0.9) 0%, + rgba(248, 250, 252, 0.8) 50%, + rgba(255, 255, 255, 0.85) 100%); + border: 1px solid rgba(226, 232, 240, 0.6); + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.08), + 0 10px 20px rgba(0, 115, 206, 0.06), + inset 0 2px 0 rgba(255, 255, 255, 0.8), + inset 0 0 20px rgba(255, 255, 255, 0.3); +} + +.glass-light-card { + background: linear-gradient(135deg, + rgba(255, 255, 255, 0.95) 0%, + rgba(250, 251, 252, 0.9) 100%); + border: 1px solid rgba(226, 232, 240, 0.4); + box-shadow: + 0 20px 40px rgba(0, 0, 0, 0.06), + 0 8px 16px rgba(0, 115, 206, 0.04), + inset 0 1px 0 rgba(255, 255, 255, 0.9); } /* Dark Mode Glass */ .glass-dark { - background: rgba(0, 0, 0, 0.7); + background: rgba(15, 23, 42, 0.8); border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.05); + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.4), + 0 8px 16px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.05); } .glass-dark-strong { - background: rgba(0, 0, 0, 0.8); + background: rgba(30, 41, 59, 0.85); border: 1px solid rgba(255, 255, 255, 0.15); - box-shadow: 0 35px 60px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08); + box-shadow: + 0 35px 70px rgba(0, 0, 0, 0.5), + 0 12px 24px rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.08); } /* Interactive Glass Elements */ .glass-interactive { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); cursor: pointer; + position: relative; + overflow: hidden; +} + +.glass-interactive::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, + transparent, + rgba(255, 255, 255, 0.2), + transparent); + transition: left 0.6s ease; + z-index: 1; } .glass-interactive:hover { - transform: translateY(-2px); - backdrop-filter: blur(28px) saturate(220%) brightness(125%); - -webkit-backdrop-filter: blur(28px) saturate(220%) brightness(125%); - box-shadow: 0 40px 80px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.15); + transform: translateY(-3px) scale(1.01); + backdrop-filter: blur(32px) saturate(240%) brightness(130%); + -webkit-backdrop-filter: blur(32px) saturate(240%) brightness(130%); + box-shadow: + 0 40px 80px rgba(0, 0, 0, 0.15), + 0 16px 32px rgba(0, 115, 206, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.4); +} + +.glass-interactive:hover::before { + left: 100%; +} + +.glass-interactive:active { + transform: translateY(-1px) scale(0.99); + transition: transform 0.1s ease; } /* Glass Navigation */ .glass-nav { - background: rgba(255, 255, 255, 0.5); - backdrop-filter: blur(24px) saturate(200%) brightness(120%); - -webkit-backdrop-filter: blur(24px) saturate(200%) brightness(120%); - border-bottom: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.1); + background: linear-gradient(135deg, + rgba(255, 255, 255, 0.9) 0%, + rgba(248, 250, 252, 0.85) 50%, + rgba(255, 255, 255, 0.9) 100%); + backdrop-filter: blur(24px) saturate(200%) brightness(115%); + -webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%); + border: 1px solid rgba(226, 232, 240, 0.5); + border-bottom: 1px solid rgba(203, 213, 225, 0.6); + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.08), + 0 4px 12px rgba(0, 115, 206, 0.05), + inset 0 1px 0 rgba(255, 255, 255, 0.8); } .dark .glass-nav { - background: rgba(0, 0, 0, 0.5); - border-bottom: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.05); + background: rgba(15, 23, 42, 0.85); + border-color: rgba(51, 65, 85, 0.6); + border-bottom-color: rgba(71, 85, 105, 0.7); + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.1); } /* Glass Cards */ -.glass-card-enhanced { - background: rgba(255, 255, 255, 0.7); +.glass-card { + background: linear-gradient(135deg, + rgba(255, 255, 255, 0.95) 0%, + rgba(250, 251, 252, 0.9) 100%); backdrop-filter: blur(20px) saturate(180%) brightness(110%); -webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%); - border: 1px solid rgba(255, 255, 255, 0.2); + border: 1px solid rgba(229, 231, 235, 0.6); border-radius: 16px; - box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.1); - transition: all 0.3s ease; + box-shadow: + 0 20px 40px rgba(0, 0, 0, 0.08), + 0 8px 16px rgba(0, 115, 206, 0.04), + inset 0 1px 0 rgba(255, 255, 255, 0.9); + padding: 1.5rem; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + overflow: hidden; } -.dark .glass-card-enhanced { - background: rgba(0, 0, 0, 0.7); - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.05); +.glass-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, + transparent 0%, + rgba(226, 232, 240, 0.8) 50%, + transparent 100%); } -.glass-card-enhanced:hover { - transform: translateY(-4px); - box-shadow: 0 35px 70px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.15); +.glass-card:hover { + transform: translateY(-2px); + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.12), + 0 12px 24px rgba(0, 115, 206, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.95); } -.dark .glass-card-enhanced:hover { - box-shadow: 0 35px 70px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.1); +.dark .glass-card { + background: rgba(30, 41, 59, 0.85); + border-color: rgba(100, 116, 139, 0.4); + box-shadow: + 0 20px 40px rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +.dark .glass-card:hover { + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.4), + inset 0 1px 0 rgba(255, 255, 255, 0.15); } /* Glass Buttons */ .glass-btn { - background: rgba(255, 255, 255, 0.8); - backdrop-filter: blur(16px) saturate(150%) brightness(110%); - -webkit-backdrop-filter: blur(16px) saturate(150%) brightness(110%); - border: 1px solid rgba(255, 255, 255, 0.3); + background: linear-gradient(135deg, + rgba(255, 255, 255, 0.9) 0%, + rgba(248, 250, 252, 0.8) 100%); + backdrop-filter: blur(16px) saturate(180%); + -webkit-backdrop-filter: blur(16px) saturate(180%); + border: 1px solid rgba(226, 232, 240, 0.6); border-radius: 12px; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.1); + padding: 0.75rem 1.5rem; + color: #0f172a; + font-weight: 600; + text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8); + box-shadow: + 0 4px 12px rgba(0, 0, 0, 0.08), + 0 2px 4px rgba(0, 115, 206, 0.05), + inset 0 1px 0 rgba(255, 255, 255, 0.8); transition: all 0.2s ease; } -.dark .glass-btn { - background: rgba(0, 0, 0, 0.8); - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.08); -} - .glass-btn:hover { transform: translateY(-1px); - backdrop-filter: blur(20px) saturate(170%) brightness(115%); - -webkit-backdrop-filter: blur(20px) saturate(170%) brightness(115%); - box-shadow: 0 25px 50px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.15); + background: linear-gradient(135deg, + rgba(255, 255, 255, 0.95) 0%, + rgba(248, 250, 252, 0.85) 100%); + box-shadow: + 0 8px 20px rgba(0, 0, 0, 0.12), + 0 4px 8px rgba(0, 115, 206, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.9); +} + +.glass-btn:active { + transform: translateY(0); + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.7); +} + +.glass-btn-primary { + background: linear-gradient(135deg, + rgba(0, 115, 206, 0.9) 0%, + rgba(0, 90, 159, 0.85) 100%); + color: white; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); + box-shadow: + 0 4px 12px rgba(0, 115, 206, 0.3), + 0 2px 4px rgba(0, 115, 206, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.2); +} + +.glass-btn-primary:hover { + background: linear-gradient(135deg, + rgba(0, 115, 206, 0.95) 0%, + rgba(0, 90, 159, 0.9) 100%); + box-shadow: + 0 8px 20px rgba(0, 115, 206, 0.4), + 0 4px 8px rgba(0, 115, 206, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.dark .glass-btn { + background: rgba(30, 41, 59, 0.8); + color: #e2e8f0; + border-color: rgba(100, 116, 139, 0.6); + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); + box-shadow: + 0 4px 12px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); } /* Glass Modals */ .glass-modal { - background: rgba(255, 255, 255, 0.85); - backdrop-filter: blur(32px) saturate(200%) brightness(115%); - -webkit-backdrop-filter: blur(32px) saturate(200%) brightness(115%); - border: 1px solid rgba(255, 255, 255, 0.3); + background: linear-gradient(135deg, + rgba(255, 255, 255, 0.98) 0%, + rgba(248, 250, 252, 0.95) 50%, + rgba(255, 255, 255, 0.98) 100%); + backdrop-filter: blur(32px) saturate(220%) brightness(120%); + -webkit-backdrop-filter: blur(32px) saturate(220%) brightness(120%); + border: 1px solid rgba(226, 232, 240, 0.7); border-radius: 20px; - box-shadow: 0 50px 100px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.2); + box-shadow: + 0 50px 100px rgba(0, 0, 0, 0.15), + 0 20px 40px rgba(0, 115, 206, 0.08), + inset 0 2px 0 rgba(255, 255, 255, 0.9), + inset 0 0 40px rgba(255, 255, 255, 0.2); } .dark .glass-modal { - background: rgba(0, 0, 0, 0.85); - border: 1px solid rgba(255, 255, 255, 0.15); - box-shadow: 0 50px 100px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.1); + background: rgba(15, 23, 42, 0.95); + border-color: rgba(51, 65, 85, 0.7); + box-shadow: + 0 50px 100px rgba(0, 0, 0, 0.5), + inset 0 2px 0 rgba(255, 255, 255, 0.1); } /* Glass Form Elements */ .glass-input { - background: rgba(255, 255, 255, 0.6); - backdrop-filter: blur(16px) saturate(150%); - -webkit-backdrop-filter: blur(16px) saturate(150%); - border: 1px solid rgba(255, 255, 255, 0.3); + background: rgba(255, 255, 255, 0.8); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px solid rgba(226, 232, 240, 0.6); border-radius: 8px; - box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(255, 255, 255, 0.05); + padding: 0.75rem 1rem; + color: #0f172a; + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.06), + inset 0 1px 0 rgba(255, 255, 255, 0.8); transition: all 0.2s ease; } -.dark .glass-input { - background: rgba(0, 0, 0, 0.6); - border: 1px solid rgba(255, 255, 255, 0.2); - box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.05); +.glass-input:focus { + outline: none; + border-color: rgba(0, 115, 206, 0.6); + box-shadow: + 0 4px 12px rgba(0, 115, 206, 0.15), + 0 0 0 3px rgba(0, 115, 206, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.9); } -.glass-input:focus { - backdrop-filter: blur(20px) saturate(180%); - -webkit-backdrop-filter: blur(20px) saturate(180%); - box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15), 0 0 0 2px rgba(59, 130, 246, 0.5); +.dark .glass-input { + background: rgba(30, 41, 59, 0.8); + border-color: rgba(100, 116, 139, 0.6); + color: #e2e8f0; + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); } /* Glass Dropdown */ @@ -204,11 +385,13 @@ /* Responsive glass effects */ @media (max-width: 768px) { - .glass-base, - .glass-strong, - .glass-card-enhanced { - backdrop-filter: blur(16px) saturate(150%); - -webkit-backdrop-filter: blur(16px) saturate(150%); + .glass-card { + padding: 1rem; + border-radius: 12px; + } + + .glass-modal { + border-radius: 16px; } } @@ -216,7 +399,7 @@ @media (prefers-contrast: high) { .glass-base, .glass-strong, - .glass-card-enhanced { + .glass-card { border-width: 2px; backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); @@ -226,12 +409,77 @@ /* Reduced motion support */ @media (prefers-reduced-motion: reduce) { .glass-interactive, - .glass-card-enhanced, - .glass-btn { - transition: none; + .glass-btn, + .glass-card { + transition: none !important; } - .glass-float { - animation: none; + .glass-interactive::before { + display: none; } +} + +/* Glass Loading States */ +.glass-loading { + position: relative; + overflow: hidden; +} + +.glass-loading::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, + transparent, + rgba(255, 255, 255, 0.3), + transparent); + animation: glass-shimmer 2s infinite; +} + +.dark .glass-loading::after { + background: linear-gradient(90deg, + transparent, + rgba(255, 255, 255, 0.1), + transparent); +} + +@keyframes glass-shimmer { + 0% { left: -100%; } + 100% { left: 100%; } +} + +/* Premium Glow Effects for Light Mode */ +.glass-glow { + position: relative; +} + +.glass-glow::after { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient(45deg, + rgba(0, 115, 206, 0.1), + rgba(0, 90, 159, 0.05), + rgba(0, 115, 206, 0.1)); + border-radius: inherit; + z-index: -1; + opacity: 0; + transition: opacity 0.3s ease; +} + +.glass-glow:hover::after { + opacity: 1; +} + +.dark .glass-glow::after { + background: linear-gradient(45deg, + rgba(59, 130, 246, 0.2), + rgba(29, 78, 216, 0.1), + rgba(59, 130, 246, 0.2)); } \ No newline at end of file diff --git a/backend/static/css/professional-theme.css b/backend/static/css/professional-theme.css index ced619cd..9a015f37 100644 --- a/backend/static/css/professional-theme.css +++ b/backend/static/css/professional-theme.css @@ -1,31 +1,44 @@ /** - * Mercedes-Benz MYP Platform - Professional Theme - * Professionelle Light/Dark Mode Implementierung + * Mercedes-Benz MYP Platform - Erweiterte Professional Theme + * Verbesserte Light/Dark Mode Implementierung mit optimierten Kontrasten */ /* Globale CSS-Variablen für konsistente Theming */ :root { - /* Mercedes-Benz Markenfarben */ - --mb-primary: #3b82f6; - --mb-primary-dark: #1d4ed8; + /* Mercedes-Benz Markenfarben - Erweitert */ + --mb-primary: #0073ce; + --mb-primary-dark: #005a9f; --mb-secondary: #64748b; --mb-accent: #0ea5e9; + --mb-black: #000000; + --mb-silver: #c0c0c0; - /* Light Mode Farbpalette */ + /* Light Mode Farbpalette - Verbessert */ --light-bg-primary: #ffffff; --light-bg-secondary: #f8fafc; --light-bg-tertiary: #f1f5f9; + --light-bg-accent: #fafbfc; --light-surface: #ffffff; --light-surface-hover: #f8fafc; + --light-surface-active: #f1f5f9; --light-text-primary: #0f172a; --light-text-secondary: #475569; --light-text-muted: #64748b; + --light-text-accent: #0073ce; --light-border: #e2e8f0; --light-border-strong: #cbd5e1; - --light-shadow: rgba(0, 0, 0, 0.1); - --light-shadow-strong: rgba(0, 0, 0, 0.15); + --light-border-accent: #0073ce20; + --light-shadow: rgba(0, 0, 0, 0.08); + --light-shadow-strong: rgba(0, 0, 0, 0.12); + --light-shadow-accent: rgba(0, 115, 206, 0.15); - /* Dark Mode Farbpalette */ + /* Neue Light Mode Gradients */ + --light-gradient-primary: linear-gradient(135deg, #ffffff 0%, #f8fafc 50%, #f1f5f9 100%); + --light-gradient-card: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%); + --light-gradient-hero: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 50%, #f1f5f9 100%); + --light-gradient-accent: linear-gradient(135deg, #0073ce 0%, #005a9f 100%); + + /* Dark Mode Farbpalette - Unverändert */ --dark-bg-primary: #0f172a; --dark-bg-secondary: #1e293b; --dark-bg-tertiary: #334155; @@ -40,16 +53,28 @@ --dark-shadow-strong: rgba(0, 0, 0, 0.5); } -/* Professionelle Hero-Header Stile */ +/* Professionelle Hero-Header Stile - Verbessert */ .professional-hero { position: relative; overflow: hidden; border-radius: 2rem; margin: 1.5rem; margin-bottom: 2rem; - background: linear-gradient(135deg, var(--light-bg-secondary) 0%, var(--light-bg-tertiary) 100%); + background: var(--light-gradient-hero); border: 1px solid var(--light-border); - box-shadow: 0 20px 40px var(--light-shadow); + box-shadow: + 0 20px 40px var(--light-shadow), + 0 8px 16px rgba(0, 115, 206, 0.05), + inset 0 1px 0 rgba(255, 255, 255, 0.8); + transition: all 0.3s ease; +} + +.professional-hero:hover { + transform: translateY(-2px); + box-shadow: + 0 25px 50px var(--light-shadow-strong), + 0 12px 24px var(--light-shadow-accent), + inset 0 1px 0 rgba(255, 255, 255, 0.9); } .dark .professional-hero { @@ -139,19 +164,21 @@ /* Professional Buttons */ .btn-professional { - background: linear-gradient(135deg, var(--mb-primary) 0%, var(--mb-primary-dark) 100%); + background: var(--light-gradient-accent); color: white; border: none; - border-radius: 1rem; - padding: 0.75rem 2rem; + border-radius: 0.5rem; + padding: 0.75rem 1.5rem; font-weight: 600; font-size: 0.875rem; - letter-spacing: 0.025em; text-transform: uppercase; - transition: all 0.3s ease; + letter-spacing: 0.025em; + transition: all 0.2s ease; + box-shadow: + 0 2px 8px rgba(0, 115, 206, 0.25), + 0 1px 3px rgba(0, 115, 206, 0.1); position: relative; overflow: hidden; - box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3); } .btn-professional::before { @@ -162,19 +189,20 @@ width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); - transition: left 0.5s; + transition: left 0.5s ease; +} + +.btn-professional:hover { + transform: translateY(-2px); + box-shadow: + 0 4px 15px rgba(0, 115, 206, 0.35), + 0 2px 8px rgba(0, 115, 206, 0.2); } .btn-professional:hover::before { left: 100%; } -.btn-professional:hover { - background: linear-gradient(135deg, var(--mb-primary-dark) 0%, #1e40af 100%); - transform: translateY(-2px); - box-shadow: 0 8px 25px rgba(59, 130, 246, 0.4); -} - .btn-professional:active { transform: translateY(0); } @@ -246,45 +274,47 @@ /* Professional Cards */ .card-professional { - background: var(--light-surface); + background: var(--light-gradient-card); border: 1px solid var(--light-border); - border-radius: 1.25rem; + border-radius: 1rem; padding: 1.5rem; - box-shadow: 0 4px 20px var(--light-shadow); + box-shadow: + 0 4px 15px var(--light-shadow), + 0 2px 8px rgba(0, 115, 206, 0.05), + inset 0 1px 0 rgba(255, 255, 255, 0.6); transition: all 0.3s ease; position: relative; overflow: hidden; } -.dark .card-professional { - background: var(--dark-surface); - border-color: var(--dark-border); - box-shadow: 0 4px 20px var(--dark-shadow); -} - .card-professional::before { content: ''; position: absolute; top: 0; left: 0; - width: 100%; - height: 4px; - background: linear-gradient(90deg, var(--mb-primary), var(--mb-accent)); - transform: scaleX(0); - transition: transform 0.3s ease; -} - -.card-professional:hover::before { - transform: scaleX(1); + right: 0; + height: 2px; + background: var(--light-gradient-accent); + opacity: 0; + transition: opacity 0.3s ease; } .card-professional:hover { transform: translateY(-4px); - box-shadow: 0 12px 40px var(--light-shadow-strong); + box-shadow: + 0 8px 25px var(--light-shadow-strong), + 0 4px 12px var(--light-shadow-accent), + inset 0 1px 0 rgba(255, 255, 255, 0.8); } -.dark .card-professional:hover { - box-shadow: 0 12px 40px var(--dark-shadow-strong); +.card-professional:hover::before { + opacity: 1; +} + +.dark .card-professional { + background: var(--dark-surface); + border-color: var(--dark-border); + box-shadow: 0 4px 15px var(--dark-shadow); } /* Professional Statistics Cards */ @@ -358,49 +388,106 @@ transform: scale(1.05); } -/* Status-spezifische Farben */ -.status-pending { - background: rgba(251, 191, 36, 0.1); - color: #92400e; - border-color: rgba(251, 191, 36, 0.3); -} - -.dark .status-pending { - background: rgba(251, 191, 36, 0.2); - color: #fbbf24; -} - -.status-approved { - background: rgba(16, 185, 129, 0.1); +/* Verbesserte Status Indicators */ +.status-online { + background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%); color: #065f46; + border: 1px solid rgba(16, 185, 129, 0.2); + box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1); +} + +.dark .status-online { + background: linear-gradient(135deg, rgba(16, 185, 129, 0.15) 0%, rgba(16, 185, 129, 0.05) 100%); + color: #10b981; border-color: rgba(16, 185, 129, 0.3); } +.status-offline { + background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%); + color: #991b1b; + border: 1px solid rgba(239, 68, 68, 0.2); + box-shadow: 0 2px 8px rgba(239, 68, 68, 0.1); +} + +.dark .status-offline { + background: linear-gradient(135deg, rgba(239, 68, 68, 0.15) 0%, rgba(239, 68, 68, 0.05) 100%); + color: #ef4444; + border-color: rgba(239, 68, 68, 0.3); +} + +.status-printing { + background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%); + color: #1d4ed8; + border: 1px solid rgba(59, 130, 246, 0.2); + box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1); +} + +.dark .status-printing { + background: linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(59, 130, 246, 0.05) 100%); + color: #3b82f6; + border-color: rgba(59, 130, 246, 0.3); +} + +.status-maintenance { + background: linear-gradient(135deg, #faf5ff 0%, #ede9fe 100%); + color: #6b21a8; + border: 1px solid rgba(139, 92, 246, 0.2); + box-shadow: 0 2px 8px rgba(139, 92, 246, 0.1); +} + +.dark .status-maintenance { + background: linear-gradient(135deg, rgba(139, 92, 246, 0.15) 0%, rgba(139, 92, 246, 0.05) 100%); + color: #8b5cf6; + border-color: rgba(139, 92, 246, 0.3); +} + +.status-pending { + background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%); + color: #92400e; + border: 1px solid rgba(251, 191, 36, 0.2); + box-shadow: 0 2px 8px rgba(251, 191, 36, 0.1); +} + +.dark .status-pending { + background: linear-gradient(135deg, rgba(251, 191, 36, 0.15) 0%, rgba(251, 191, 36, 0.05) 100%); + color: #fbbf24; + border-color: rgba(251, 191, 36, 0.3); +} + +.status-approved { + background: linear-gradient(135deg, #ecfdf5 0%, #a7f3d0 100%); + color: #065f46; + border: 1px solid rgba(16, 185, 129, 0.3); + box-shadow: 0 2px 8px rgba(16, 185, 129, 0.15); +} + .dark .status-approved { - background: rgba(16, 185, 129, 0.2); + background: linear-gradient(135deg, rgba(16, 185, 129, 0.2) 0%, rgba(16, 185, 129, 0.1) 100%); color: #10b981; } .status-denied { - background: rgba(239, 68, 68, 0.1); + background: linear-gradient(135deg, #fef2f2 0%, #fca5a5 100%); color: #991b1b; - border-color: rgba(239, 68, 68, 0.3); + border: 1px solid rgba(239, 68, 68, 0.3); + box-shadow: 0 2px 8px rgba(239, 68, 68, 0.15); } .dark .status-denied { - background: rgba(239, 68, 68, 0.2); + background: linear-gradient(135deg, rgba(239, 68, 68, 0.2) 0%, rgba(239, 68, 68, 0.1) 100%); color: #ef4444; } /* Professional Typography */ .title-professional { - background: linear-gradient(135deg, var(--light-text-primary) 0%, var(--light-text-secondary) 100%); + background: linear-gradient(135deg, var(--light-text-primary) 0%, var(--light-text-accent) 50%, var(--light-text-secondary) 100%); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .dark .title-professional { @@ -415,6 +502,7 @@ font-size: 1.125rem; line-height: 1.6; font-weight: 400; + opacity: 0.9; } .dark .subtitle-professional { @@ -423,11 +511,14 @@ /* Professional Navigation */ .nav-professional { - background: var(--light-surface); + background: var(--light-gradient-card); border: 1px solid var(--light-border); border-radius: 1rem; padding: 0.5rem; - box-shadow: 0 4px 15px var(--light-shadow); + box-shadow: + 0 4px 15px var(--light-shadow), + 0 2px 8px rgba(0, 115, 206, 0.05), + inset 0 1px 0 rgba(255, 255, 255, 0.6); backdrop-filter: blur(20px); } @@ -448,6 +539,7 @@ font-weight: 500; transition: all 0.2s ease; position: relative; + background: transparent; } .dark .nav-item-professional { @@ -458,6 +550,7 @@ background: var(--light-surface-hover); color: var(--light-text-primary); transform: translateX(4px); + box-shadow: 0 2px 8px var(--light-shadow); } .dark .nav-item-professional:hover { @@ -466,9 +559,11 @@ } .nav-item-professional.active { - background: rgba(59, 130, 246, 0.1); + background: linear-gradient(135deg, rgba(0, 115, 206, 0.1) 0%, rgba(0, 115, 206, 0.05) 100%); color: var(--mb-primary); font-weight: 600; + border: 1px solid var(--light-border-accent); + box-shadow: 0 2px 8px var(--light-shadow-accent); } .dark .nav-item-professional.active { @@ -479,10 +574,14 @@ .table-professional { width: 100%; border-collapse: collapse; - background: var(--light-surface); + background: var(--light-gradient-card); border-radius: 1rem; overflow: hidden; - box-shadow: 0 4px 20px var(--light-shadow); + box-shadow: + 0 4px 20px var(--light-shadow), + 0 2px 8px rgba(0, 115, 206, 0.05), + inset 0 1px 0 rgba(255, 255, 255, 0.6); + border: 1px solid var(--light-border); } .dark .table-professional { @@ -491,12 +590,23 @@ } .table-professional th { - background: var(--light-bg-secondary); + background: linear-gradient(135deg, var(--light-bg-secondary) 0%, var(--light-bg-tertiary) 100%); color: var(--light-text-primary); font-weight: 600; text-align: left; padding: 1rem 1.5rem; border-bottom: 1px solid var(--light-border); + position: relative; +} + +.table-professional th::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, transparent 0%, var(--light-border-strong) 50%, transparent 100%); } .dark .table-professional th { @@ -509,6 +619,7 @@ padding: 1rem 1.5rem; border-bottom: 1px solid var(--light-border); color: var(--light-text-secondary); + transition: all 0.2s ease; } .dark .table-professional td { @@ -518,6 +629,8 @@ .table-professional tbody tr:hover { background: var(--light-surface-hover); + transform: scale(1.005); + box-shadow: 0 2px 8px var(--light-shadow); } .dark .table-professional tbody tr:hover { @@ -534,47 +647,74 @@ gap: 1rem; margin-bottom: 1rem; box-shadow: 0 4px 15px var(--light-shadow); + position: relative; + overflow: hidden; +} + +.alert-professional::before { + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 4px; } .alert-info { - background: rgba(59, 130, 246, 0.1); - border-color: rgba(59, 130, 246, 0.3); + background: linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(59, 130, 246, 0.03) 100%); + border-color: rgba(59, 130, 246, 0.2); color: #1e40af; } +.alert-info::before { + background: linear-gradient(180deg, #3b82f6 0%, #1d4ed8 100%); +} + .dark .alert-info { background: rgba(59, 130, 246, 0.2); color: #60a5fa; } .alert-success { - background: rgba(16, 185, 129, 0.1); - border-color: rgba(16, 185, 129, 0.3); + background: linear-gradient(135deg, rgba(16, 185, 129, 0.08) 0%, rgba(16, 185, 129, 0.03) 100%); + border-color: rgba(16, 185, 129, 0.2); color: #065f46; } +.alert-success::before { + background: linear-gradient(180deg, #10b981 0%, #059669 100%); +} + .dark .alert-success { background: rgba(16, 185, 129, 0.2); color: #10b981; } .alert-warning { - background: rgba(251, 191, 36, 0.1); - border-color: rgba(251, 191, 36, 0.3); + background: linear-gradient(135deg, rgba(251, 191, 36, 0.08) 0%, rgba(251, 191, 36, 0.03) 100%); + border-color: rgba(251, 191, 36, 0.2); color: #92400e; } +.alert-warning::before { + background: linear-gradient(180deg, #fbbf24 0%, #f59e0b 100%); +} + .dark .alert-warning { background: rgba(251, 191, 36, 0.2); color: #fbbf24; } .alert-error { - background: rgba(239, 68, 68, 0.1); - border-color: rgba(239, 68, 68, 0.3); + background: linear-gradient(135deg, rgba(239, 68, 68, 0.08) 0%, rgba(239, 68, 68, 0.03) 100%); + border-color: rgba(239, 68, 68, 0.2); color: #991b1b; } +.alert-error::before { + background: linear-gradient(180deg, #ef4444 0%, #dc2626 100%); +} + .dark .alert-error { background: rgba(239, 68, 68, 0.2); color: #ef4444; @@ -582,8 +722,24 @@ /* Background Gradients für verschiedene Seiten */ .bg-professional { - background: linear-gradient(135deg, var(--light-bg-primary) 0%, var(--light-bg-secondary) 50%, var(--light-bg-tertiary) 100%); + background: var(--light-gradient-primary); min-height: 100vh; + position: relative; +} + +.bg-professional::before { + content: ''; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: + radial-gradient(circle at 20% 50%, rgba(0, 115, 206, 0.03) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(0, 115, 206, 0.02) 0%, transparent 50%), + radial-gradient(circle at 40% 80%, rgba(0, 115, 206, 0.01) 0%, transparent 50%); + pointer-events: none; + z-index: -1; } .dark .bg-professional { @@ -593,6 +749,7 @@ /* Utilities */ .text-professional-primary { color: var(--light-text-primary); + font-weight: 600; } .dark .text-professional-primary { @@ -601,6 +758,7 @@ .text-professional-secondary { color: var(--light-text-secondary); + font-weight: 500; } .dark .text-professional-secondary { @@ -609,12 +767,22 @@ .text-professional-muted { color: var(--light-text-muted); + font-weight: 400; } .dark .text-professional-muted { color: var(--dark-text-muted); } +.text-professional-accent { + color: var(--light-text-accent); + font-weight: 600; +} + +.dark .text-professional-accent { + color: #60a5fa; +} + /* Censored Text for Privacy Protection */ .censored-text { font-family: monospace; @@ -623,13 +791,18 @@ -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 500; + position: relative; } -.dark .censored-text { - background: linear-gradient(45deg, var(--dark-text-secondary), var(--dark-text-muted)); - background-clip: text; - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; +.censored-text::after { + content: ''; + position: absolute; + top: 50%; + left: 0; + right: 0; + height: 1px; + background: currentColor; + opacity: 0.3; } /* Smooth transitions für alle professionellen Komponenten */ @@ -660,6 +833,14 @@ padding: 1rem; } + .nav-professional { + padding: 0.25rem; + } + + .nav-item-professional { + padding: 0.5rem 0.75rem; + } + .stat-number { font-size: 2rem; } @@ -949,10 +1130,6 @@ } /* Professional Accent Colors */ -.text-professional-accent { - color: var(--mb-accent); -} - .bg-professional-accent { background-color: var(--mb-accent); } @@ -980,4 +1157,61 @@ opacity: 0.5; transform: translate(-50%, -50%) scale(1.2); } +} + +/* Neue Premium-Komponenten */ +.glass-professional { + background: rgba(255, 255, 255, 0.8); + backdrop-filter: blur(20px) saturate(180%) brightness(110%); + -webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%); + border: 1px solid rgba(255, 255, 255, 0.3); + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.15), + 0 8px 16px rgba(0, 115, 206, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.6); + border-radius: 1rem; +} + +.dark .glass-professional { + background: rgba(30, 41, 59, 0.8); + border-color: rgba(255, 255, 255, 0.1); + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +/* Enhanced Hover States für Light Mode */ +.hover-lift { + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.hover-lift:hover { + transform: translateY(-2px); + box-shadow: + 0 10px 25px var(--light-shadow-strong), + 0 4px 12px var(--light-shadow-accent); +} + +.dark .hover-lift:hover { + box-shadow: 0 10px 25px var(--dark-shadow-strong); +} + +/* Accessibility Enhancements */ +@media (prefers-reduced-motion: reduce) { + * { + transition: none !important; + animation: none !important; + } +} + +/* Focus States */ +.focus-professional:focus { + outline: 2px solid var(--light-text-accent); + outline-offset: 2px; + box-shadow: 0 0 0 4px rgba(0, 115, 206, 0.15); +} + +.dark .focus-professional:focus { + outline-color: #60a5fa; + box-shadow: 0 0 0 4px rgba(96, 165, 250, 0.15); } \ No newline at end of file diff --git a/backend/static/js/user-dropdown.js b/backend/static/js/user-dropdown.js new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/backend/static/js/user-dropdown.js @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/templates/base.html b/backend/templates/base.html index 8cbee274..ce6d5e04 100644 --- a/backend/templates/base.html +++ b/backend/templates/base.html @@ -92,17 +92,14 @@ } } - // User-Dropdown-Funktionalität initialisieren - initializeUserDropdown(); - - // Mobile Menu Toggle initialisieren - initializeMobileMenu(); - // MYP App für Offline-Funktionalität initialisieren if (typeof MYPApp !== 'undefined') { window.mypApp = new MYPApp(); } + // User-Dropdown-Funktionalität initialisieren + initUserDropdown(); + // Flask Flash Messages über das Glassmorphism-System anzeigen const flashContainer = document.getElementById('flask-flash-messages'); if (flashContainer) { @@ -733,7 +730,7 @@ - +
Alle Benachrichtigungen aktiv
@@ -812,17 +809,14 @@ * Initialisierung aller UI-Komponenten nach DOM-Load */ document.addEventListener('DOMContentLoaded', function() { - // User-Dropdown-Funktionalität initialisieren - initializeUserDropdown(); - - // Mobile Menu Toggle initialisieren - initializeMobileMenu(); - // MYP App für Offline-Funktionalität initialisieren if (typeof MYPApp !== 'undefined') { window.mypApp = new MYPApp(); } + // User-Dropdown-Funktionalität initialisieren + initUserDropdown(); + // Flask Flash Messages über das Glassmorphism-System anzeigen const flashContainer = document.getElementById('flask-flash-messages'); if (flashContainer) { @@ -857,154 +851,139 @@ /** * User-Dropdown-Funktionalität */ - function initializeUserDropdown() { + function initUserDropdown() { const userMenuButton = document.getElementById('user-menu-button'); const userDropdown = document.getElementById('user-dropdown'); - const userMenuContainer = document.getElementById('user-menu-container'); - if (!userMenuButton || !userDropdown) return; + console.log('🔍 User-Dropdown Init:', { userMenuButton, userDropdown }); + + if (!userMenuButton || !userDropdown) { + console.warn('⚠️ User-Dropdown-Elemente nicht gefunden:', { + button: !!userMenuButton, + dropdown: !!userDropdown + }); + return; // Nicht angemeldet oder Elemente nicht gefunden + } + + let isDropdownOpen = false; // Toggle-Funktion - function toggleDropdown(e) { - e.stopPropagation(); - const isExpanded = userMenuButton.getAttribute('aria-expanded') === 'true'; + function toggleDropdown(event) { + if (event) { + event.preventDefault(); + event.stopPropagation(); + } - if (isExpanded) { - closeDropdown(); - } else { + isDropdownOpen = !isDropdownOpen; + console.log('🔄 Toggle Dropdown:', isDropdownOpen); + + if (isDropdownOpen) { openDropdown(); + } else { + closeDropdown(); } } - // Dropdown öffnen function openDropdown() { userDropdown.classList.remove('hidden'); userMenuButton.setAttribute('aria-expanded', 'true'); - // Animation für bessere UX + // Reset any existing styles + userDropdown.style.transition = ''; userDropdown.style.opacity = '0'; - userDropdown.style.transform = 'scale(0.95) translateY(-5px)'; + userDropdown.style.transform = 'translateY(-10px) scale(0.95)'; - // Kleine Verzögerung für Animation + // Force reflow + userDropdown.offsetHeight; + + // Apply opening animation requestAnimationFrame(() => { - userDropdown.style.transition = 'all 0.15s ease-out'; + userDropdown.style.transition = 'all 0.2s ease-out'; userDropdown.style.opacity = '1'; - userDropdown.style.transform = 'scale(1) translateY(0)'; + userDropdown.style.transform = 'translateY(0) scale(1)'; }); + + console.log('✅ Dropdown geöffnet'); } - // Dropdown schließen function closeDropdown() { userDropdown.style.transition = 'all 0.15s ease-in'; userDropdown.style.opacity = '0'; - userDropdown.style.transform = 'scale(0.95) translateY(-5px)'; + userDropdown.style.transform = 'translateY(-10px) scale(0.95)'; setTimeout(() => { userDropdown.classList.add('hidden'); userMenuButton.setAttribute('aria-expanded', 'false'); + // Reset inline styles + userDropdown.style.transition = ''; + userDropdown.style.opacity = ''; + userDropdown.style.transform = ''; }, 150); + + isDropdownOpen = false; + console.log('❌ Dropdown geschlossen'); } - // Event-Listener + // Event-Listener für Button-Click userMenuButton.addEventListener('click', toggleDropdown); - // Außerhalb des Dropdowns klicken schließt es + // Alternative: Auch auf touchstart für mobile Geräte + userMenuButton.addEventListener('touchstart', function(e) { + e.preventDefault(); + toggleDropdown(e); + }, { passive: false }); + + // Event-Listener für Klicks außerhalb des Dropdowns document.addEventListener('click', function(e) { - if (!userMenuContainer.contains(e.target)) { - closeDropdown(); + if (!userMenuButton.contains(e.target) && !userDropdown.contains(e.target)) { + if (isDropdownOpen) { + closeDropdown(); + } } }); - // Escape-Taste schließt das Dropdown + // Touch-Events für mobile Geräte + document.addEventListener('touchstart', function(e) { + if (!userMenuButton.contains(e.target) && !userDropdown.contains(e.target)) { + if (isDropdownOpen) { + closeDropdown(); + } + } + }); + + // Escape-Taste zum Schließen document.addEventListener('keydown', function(e) { - if (e.key === 'Escape' && userMenuButton.getAttribute('aria-expanded') === 'true') { + if (e.key === 'Escape' && isDropdownOpen) { closeDropdown(); userMenuButton.focus(); } }); - // Keyboard-Navigation im Dropdown + // Fokus-Management für bessere Accessibility userDropdown.addEventListener('keydown', function(e) { - const focusableElements = userDropdown.querySelectorAll('a, button'); - const currentIndex = Array.from(focusableElements).indexOf(document.activeElement); - - switch(e.key) { - case 'ArrowDown': - e.preventDefault(); - const nextIndex = (currentIndex + 1) % focusableElements.length; - focusableElements[nextIndex].focus(); - break; - case 'ArrowUp': - e.preventDefault(); - const prevIndex = currentIndex === 0 ? focusableElements.length - 1 : currentIndex - 1; - focusableElements[prevIndex].focus(); - break; - case 'Tab': - // Tab schließt das Dropdown - if (!e.shiftKey && currentIndex === focusableElements.length - 1) { - closeDropdown(); - } else if (e.shiftKey && currentIndex === 0) { - closeDropdown(); - } - break; - } - }); - } - - /** - * Mobile Menu Toggle Funktionalität - */ - function initializeMobileMenu() { - const mobileMenuToggle = document.getElementById('mobileMenuToggle'); - const mobileMenu = document.getElementById('mobileMenu'); - - if (!mobileMenuToggle || !mobileMenu) return; - - mobileMenuToggle.addEventListener('click', function() { - const isExpanded = mobileMenuToggle.getAttribute('aria-expanded') === 'true'; - - if (isExpanded) { - // Menü schließen - mobileMenu.classList.add('hidden'); - mobileMenuToggle.setAttribute('aria-expanded', 'false'); - mobileMenuToggle.setAttribute('aria-label', 'Menü öffnen'); + if (e.key === 'Tab') { + const focusableElements = userDropdown.querySelectorAll('a, button'); + const firstElement = focusableElements[0]; + const lastElement = focusableElements[focusableElements.length - 1]; - // Icon zu Hamburger ändern - mobileMenuToggle.innerHTML = ` - - `; - } else { - // Menü öffnen - mobileMenu.classList.remove('hidden'); - mobileMenuToggle.setAttribute('aria-expanded', 'true'); - mobileMenuToggle.setAttribute('aria-label', 'Menü schließen'); - - // Icon zu X ändern - mobileMenuToggle.innerHTML = ` - - `; + if (e.shiftKey && document.activeElement === firstElement) { + e.preventDefault(); + lastElement.focus(); + } else if (!e.shiftKey && document.activeElement === lastElement) { + e.preventDefault(); + firstElement.focus(); + } } }); - // Mobile Menu bei Resize auf Desktop schließen + // Window resize handler window.addEventListener('resize', function() { - if (window.innerWidth >= 1024) { // lg breakpoint - mobileMenu.classList.add('hidden'); - mobileMenuToggle.setAttribute('aria-expanded', 'false'); - mobileMenuToggle.setAttribute('aria-label', 'Menü öffnen'); - - // Icon zurück zu Hamburger - mobileMenuToggle.innerHTML = ` - - `; + if (isDropdownOpen) { + closeDropdown(); } }); + + console.log('✅ User-Dropdown erfolgreich initialisiert'); } /** diff --git a/backend/templates/dashboard.html b/backend/templates/dashboard.html index 02170a0b..1c62e90e 100644 --- a/backend/templates/dashboard.html +++ b/backend/templates/dashboard.html @@ -357,6 +357,155 @@ + +
+ +
+
+

Session-Timer

+
+
+ Gestoppt +
+
+ + +
+ + +
+

Timer-Einstellungen

+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+ + + +
+
+ + + {% if current_user.is_admin %} +
+
+

Kiosk-Timer

+
+
+ Inaktiv +
+
+ + +
+ + +
+
+ + + +

Administrator-Funktion

+
+

Kiosk-Timer gelten systemweit für alle Benutzer und führen bei Ablauf automatische Aktionen aus.

+ +
+
+ + +
+
+ + +
+
+
+ + +
+ + + +
+
+ {% else %} + +
+

Timer-Übersicht

+
+ +
+ + + +

Keine aktiven Timer

+

Erstellen Sie einen Session-Timer für automatische Verwaltung.

+
+
+
+ {% endif %} +
+

Aktuelle Druckaufträge

@@ -498,6 +647,7 @@ {% endblock %} {% block extra_js %} + {% endblock %} \ No newline at end of file diff --git a/backend/utils/__pycache__/__init__.cpython-313.pyc b/backend/utils/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ddf011dbd3d3eda4f5cab966942ea8dd07698df8 GIT binary patch literal 166 zcmey&%ge<81hq@8GbDiYV-N=h7@>^MEI`IohI9r^M!%H|MNB~6XOPq_S7)o3(Bjmh z;+T*Se_!V)M?F_xSH~Ea)Uud>qWrAX?2^Qyq}0q3UEj!nn54wy?9{xJn9`EWoZ^`H q_{_Y_lK6PNg34PQHo5sJr8%i~MXW$mLADly7$2D#85xV1fh+(nBPj#` literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/advanced_tables.cpython-313.pyc b/backend/utils/__pycache__/advanced_tables.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f79d82fff0dc361d8de2745422d25ba28a9800d9 GIT binary patch literal 37797 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 GkNFoT#m-s) literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/database_cleanup.cpython-313.pyc b/backend/utils/__pycache__/database_cleanup.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3eca905cc95fe36971adb85ee418e6a60d9afd54 GIT binary patch literal 16140 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 a`vlzY>J5q$itA%r1iCMe{Sx2tMEn~Fe~|tF literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/database_utils.cpython-313.pyc b/backend/utils/__pycache__/database_utils.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98609243286c7af3b040470e362e7e7fc888583f GIT binary patch literal 20530 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 literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/file_manager.cpython-313.pyc b/backend/utils/__pycache__/file_manager.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55ea74238c4d530bdcee35ce5ec1f79ffc8c7c20 GIT binary patch literal 17341 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 RPWzIcl<#^YlJ=2B{J(4ak5m8v literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/form_validation.cpython-313.pyc b/backend/utils/__pycache__/form_validation.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba7714a3baeabf771196afdaec9789a831f444b7 GIT binary patch literal 33948 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 z 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 literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/job_scheduler.cpython-313.pyc b/backend/utils/__pycache__/job_scheduler.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..85f422c2a49b984216fefa0662a9da69541a2e0c GIT binary patch literal 31893 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 JhdZ0L{|D7K?}`8b literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/maintenance_system.cpython-313.pyc b/backend/utils/__pycache__/maintenance_system.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8dadfa6acf003b1a35aab61338d8e0a6730a1a8f GIT binary patch literal 38257 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 T(s#PiZ!*|canzf9wi^FG-5~|c literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/permissions.cpython-313.pyc b/backend/utils/__pycache__/permissions.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c468647fd1a9cbf1151b86e9bd3a2261a7d023fc GIT binary patch literal 27455 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 B`ttw) literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/printer_monitor.cpython-313.pyc b/backend/utils/__pycache__/printer_monitor.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a2d461dcee171e5e4a9d9550b4bac87adcb4187 GIT binary patch literal 30568 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 NhK@|l8zvQm{|EL}-hKc8 literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/queue_manager.cpython-313.pyc b/backend/utils/__pycache__/queue_manager.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96fed7e3c0d238aee11d19ccea5337a49be6f049 GIT binary patch literal 23109 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 ap08q6@UZWdA~g6$<5v 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 b2wzOqnK6^gWLv3vK;W{`Y%x8?R{wti0+Fcu literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/realtime_dashboard.cpython-313.pyc b/backend/utils/__pycache__/realtime_dashboard.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..760b21cffe1743dbbb6f1edccdbc04a1b5c3189f GIT binary patch literal 50059 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 literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/report_generator.cpython-313.pyc b/backend/utils/__pycache__/report_generator.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..685df2a00348c40ba2f77c3e7c1539684db88fe0 GIT binary patch literal 45442 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 literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/security.cpython-313.pyc b/backend/utils/__pycache__/security.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..867b72fd511db48d254450486c12a2a4ee947577 GIT binary patch literal 12995 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 literal 0 HcmV?d00001 diff --git a/backend/utils/__pycache__/template_helpers.cpython-313.pyc b/backend/utils/__pycache__/template_helpers.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c1492d36b8cc5d1b56b44dc4da0fe77d58a9781 GIT binary patch literal 20303 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 U#@b%7 literal 0 HcmV?d00001 diff --git a/backend/utils/ssl_config.py b/backend/utils/ssl_config.py new file mode 100644 index 00000000..836420c9 --- /dev/null +++ b/backend/utils/ssl_config.py @@ -0,0 +1,11 @@ +""" +SSL-Konfiguration für HTTPS-Server +Importiert SSL-Funktionalität aus der Hauptkonfiguration +""" + +try: + from config.settings_copy import get_ssl_context +except ImportError: + def get_ssl_context(): + """Fallback wenn settings_copy nicht verfügbar""" + return None \ No newline at end of file