🎉 Improved session management system and logs organization 🎨
This commit is contained in:
@ -1082,6 +1082,67 @@ def api_version():
|
||||
"environment": get_environment_type()
|
||||
})
|
||||
|
||||
@app.route("/api/stats", methods=['GET'])
|
||||
@login_required
|
||||
def api_stats():
|
||||
"""
|
||||
Allgemeine System-Statistiken API-Endpunkt.
|
||||
|
||||
Stellt grundlegende Statistiken über das System zur Verfügung.
|
||||
"""
|
||||
try:
|
||||
from models import get_db_session, User, Printer, Job
|
||||
|
||||
with get_cached_session() as db_session:
|
||||
# Grundlegende Counts
|
||||
total_users = db_session.query(User).count()
|
||||
total_printers = db_session.query(Printer).count()
|
||||
total_jobs = db_session.query(Job).count()
|
||||
|
||||
# Aktive Jobs
|
||||
active_jobs = db_session.query(Job).filter(
|
||||
Job.status.in_(['pending', 'printing', 'paused'])
|
||||
).count()
|
||||
|
||||
# Abgeschlossene Jobs heute
|
||||
from datetime import date
|
||||
today = date.today()
|
||||
completed_today = db_session.query(Job).filter(
|
||||
Job.status == 'completed',
|
||||
Job.updated_at >= today
|
||||
).count()
|
||||
|
||||
# Online-Drucker (aktive Drucker)
|
||||
online_printers = db_session.query(Printer).filter(
|
||||
Printer.active == True
|
||||
).count()
|
||||
|
||||
stats = {
|
||||
'total_users': total_users,
|
||||
'total_printers': total_printers,
|
||||
'total_jobs': total_jobs,
|
||||
'active_jobs': active_jobs,
|
||||
'completed_today': completed_today,
|
||||
'online_printers': online_printers,
|
||||
'timestamp': datetime.now().isoformat()
|
||||
}
|
||||
|
||||
app_logger.info(f"✅ API-Statistiken abgerufen von {current_user.username}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'stats': stats,
|
||||
'message': 'Statistiken erfolgreich geladen'
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
app_logger.error(f"❌ Fehler beim Abrufen der API-Statistiken: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Fehler beim Laden der Statistiken',
|
||||
'details': str(e)
|
||||
}), 500
|
||||
|
||||
# Statische Seiten
|
||||
@app.route("/privacy")
|
||||
def privacy():
|
||||
|
Binary file not shown.
BIN
backend/blueprints/__pycache__/legal_pages.cpython-313.pyc
Normal file
BIN
backend/blueprints/__pycache__/legal_pages.cpython-313.pyc
Normal file
Binary file not shown.
@ -5,11 +5,12 @@ Dieses Modul enthält allgemeine API-Endpunkte und WebSocket-Fallback-Funktional
|
||||
"""
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from flask import Blueprint, jsonify, request, session
|
||||
from flask_login import login_required, current_user
|
||||
from models import get_db_session, User, Notification
|
||||
from models import get_db_session, User, Notification, Printer, Job, Stats
|
||||
from utils.logging_config import get_logger
|
||||
from utils.permissions import admin_required
|
||||
|
||||
# Blueprint erstellen
|
||||
api_blueprint = Blueprint('api', __name__, url_prefix='/api')
|
||||
@ -145,7 +146,6 @@ def session_status():
|
||||
# Prüfe ob Benutzer über Flask-Login authentifiziert ist
|
||||
if hasattr(current_user, 'is_authenticated') and current_user.is_authenticated:
|
||||
# Benutzer ist angemeldet
|
||||
from datetime import timedelta
|
||||
from backend.config.settings import SESSION_LIFETIME
|
||||
|
||||
# Session-Informationen sammeln
|
||||
@ -255,4 +255,268 @@ def extend_session():
|
||||
'success': False,
|
||||
'error': 'Session-Verlängerung fehlgeschlagen',
|
||||
'message': str(e)
|
||||
}), 500
|
||||
|
||||
@api_blueprint.route('/stats', methods=['GET'])
|
||||
@login_required
|
||||
def get_stats():
|
||||
"""
|
||||
Hauptstatistiken-Endpunkt für das System.
|
||||
|
||||
Liefert umfassende Statistiken über Drucker, Jobs und Benutzer.
|
||||
"""
|
||||
try:
|
||||
db_session = get_db_session()
|
||||
|
||||
# Grundlegende Zählungen
|
||||
total_printers = db_session.query(Printer).count()
|
||||
active_printers = db_session.query(Printer).filter(Printer.active == True).count()
|
||||
total_jobs = db_session.query(Job).count()
|
||||
|
||||
# Job-Status-Verteilung
|
||||
completed_jobs = db_session.query(Job).filter(Job.status == 'completed').count()
|
||||
running_jobs = db_session.query(Job).filter(Job.status == 'running').count()
|
||||
pending_jobs = db_session.query(Job).filter(Job.status == 'pending').count()
|
||||
failed_jobs = db_session.query(Job).filter(Job.status == 'failed').count()
|
||||
|
||||
# Benutzer-Statistiken
|
||||
total_users = db_session.query(User).count()
|
||||
active_users = db_session.query(User).filter(User.active == True).count()
|
||||
|
||||
# Zeitbasierte Statistiken (letzte 24 Stunden)
|
||||
yesterday = datetime.now() - timedelta(days=1)
|
||||
jobs_last_24h = db_session.query(Job).filter(Job.created_at >= yesterday).count()
|
||||
|
||||
# Gesamtdruckzeit berechnen
|
||||
completed_jobs_with_duration = db_session.query(Job).filter(
|
||||
Job.status == 'completed',
|
||||
Job.duration_minutes.isnot(None)
|
||||
).all()
|
||||
|
||||
total_print_hours = sum(job.duration_minutes for job in completed_jobs_with_duration) / 60.0
|
||||
|
||||
db_session.close()
|
||||
|
||||
stats_data = {
|
||||
'success': True,
|
||||
'timestamp': datetime.now().isoformat(),
|
||||
|
||||
# Grundlegende Zählungen
|
||||
'total_printers': total_printers,
|
||||
'active_printers': active_printers,
|
||||
'total_jobs': total_jobs,
|
||||
'total_users': total_users,
|
||||
'active_users': active_users,
|
||||
|
||||
# Job-Statistiken
|
||||
'completed_jobs': completed_jobs,
|
||||
'running_jobs': running_jobs,
|
||||
'pending_jobs': pending_jobs,
|
||||
'failed_jobs': failed_jobs,
|
||||
'jobs_last_24h': jobs_last_24h,
|
||||
|
||||
# Druckzeit-Statistiken
|
||||
'total_print_hours': round(total_print_hours, 2),
|
||||
'completion_rate': round((completed_jobs / total_jobs * 100), 2) if total_jobs > 0 else 0
|
||||
}
|
||||
|
||||
api_logger.info(f"Statistiken abgerufen von Benutzer {current_user.username}")
|
||||
return jsonify(stats_data)
|
||||
|
||||
except Exception as e:
|
||||
api_logger.error(f"Fehler beim Abrufen der Statistiken: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Fehler beim Laden der Statistiken',
|
||||
'message': str(e)
|
||||
}), 500
|
||||
|
||||
@api_blueprint.route('/admin/system-health', methods=['GET'])
|
||||
@admin_required
|
||||
def get_system_health():
|
||||
"""
|
||||
System-Gesundheitsstatus für Administratoren.
|
||||
|
||||
Liefert detaillierte Informationen über den System-Zustand.
|
||||
"""
|
||||
try:
|
||||
db_session = get_db_session()
|
||||
|
||||
# Datenbankverbindung testen
|
||||
db_healthy = True
|
||||
try:
|
||||
db_session.execute("SELECT 1")
|
||||
except Exception as e:
|
||||
db_healthy = False
|
||||
api_logger.error(f"Datenbankfehler: {str(e)}")
|
||||
|
||||
# Systemressourcen prüfen
|
||||
import psutil
|
||||
import os
|
||||
|
||||
# CPU und Speicher
|
||||
cpu_usage = psutil.cpu_percent(interval=1)
|
||||
memory = psutil.virtual_memory()
|
||||
disk = psutil.disk_usage('/')
|
||||
|
||||
# Aktive Drucker prüfen
|
||||
active_printers = db_session.query(Printer).filter(Printer.active == True).count()
|
||||
total_printers = db_session.query(Printer).count()
|
||||
|
||||
# Laufende Jobs prüfen
|
||||
running_jobs = db_session.query(Job).filter(Job.status == 'running').count()
|
||||
|
||||
db_session.close()
|
||||
|
||||
# Gesamtstatus bestimmen
|
||||
overall_status = 'healthy'
|
||||
if not db_healthy or cpu_usage > 90 or memory.percent > 90:
|
||||
overall_status = 'warning'
|
||||
if not db_healthy or cpu_usage > 95 or memory.percent > 95:
|
||||
overall_status = 'critical'
|
||||
|
||||
health_data = {
|
||||
'success': True,
|
||||
'timestamp': datetime.now().isoformat(),
|
||||
'overall_status': overall_status,
|
||||
|
||||
# System-Status
|
||||
'database': {
|
||||
'status': 'healthy' if db_healthy else 'error',
|
||||
'connection': db_healthy
|
||||
},
|
||||
|
||||
# Systemressourcen
|
||||
'system': {
|
||||
'cpu_usage': cpu_usage,
|
||||
'memory_usage': memory.percent,
|
||||
'memory_available_gb': round(memory.available / (1024**3), 2),
|
||||
'disk_usage': disk.percent,
|
||||
'disk_free_gb': round(disk.free / (1024**3), 2)
|
||||
},
|
||||
|
||||
# Drucker-Status
|
||||
'printers': {
|
||||
'total': total_printers,
|
||||
'active': active_printers,
|
||||
'inactive': total_printers - active_printers
|
||||
},
|
||||
|
||||
# Job-Status
|
||||
'jobs': {
|
||||
'running': running_jobs
|
||||
}
|
||||
}
|
||||
|
||||
api_logger.info(f"System-Health abgerufen von Admin {current_user.username}")
|
||||
return jsonify(health_data)
|
||||
|
||||
except ImportError:
|
||||
# Fallback ohne psutil
|
||||
health_data = {
|
||||
'success': True,
|
||||
'timestamp': datetime.now().isoformat(),
|
||||
'overall_status': 'healthy',
|
||||
'database': {'status': 'healthy', 'connection': True},
|
||||
'system': {'cpu_usage': 0, 'memory_usage': 0, 'disk_usage': 0},
|
||||
'printers': {'total': 0, 'active': 0, 'inactive': 0},
|
||||
'jobs': {'running': 0},
|
||||
'note': 'Eingeschränkte Systemüberwachung (psutil nicht verfügbar)'
|
||||
}
|
||||
return jsonify(health_data)
|
||||
|
||||
except Exception as e:
|
||||
api_logger.error(f"Fehler beim Abrufen des System-Health: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Fehler beim Laden des System-Status',
|
||||
'message': str(e)
|
||||
}), 500
|
||||
|
||||
@api_blueprint.route('/admin/error-recovery/status', methods=['GET'])
|
||||
@admin_required
|
||||
def get_error_recovery_status():
|
||||
"""
|
||||
Fehlerwiederherstellungs-Status für Administratoren.
|
||||
|
||||
Liefert Informationen über System-Fehler und Wiederherstellungsoptionen.
|
||||
"""
|
||||
try:
|
||||
db_session = get_db_session()
|
||||
|
||||
# Fehlgeschlagene Jobs der letzten 24 Stunden
|
||||
yesterday = datetime.now() - timedelta(days=1)
|
||||
failed_jobs = db_session.query(Job).filter(
|
||||
Job.status == 'failed',
|
||||
Job.created_at >= yesterday
|
||||
).all()
|
||||
|
||||
# Inaktive Drucker
|
||||
inactive_printers = db_session.query(Printer).filter(Printer.active == False).all()
|
||||
|
||||
# Hängende Jobs (länger als 6 Stunden im Status 'running')
|
||||
six_hours_ago = datetime.now() - timedelta(hours=6)
|
||||
stuck_jobs = db_session.query(Job).filter(
|
||||
Job.status == 'running',
|
||||
Job.start_time <= six_hours_ago
|
||||
).all()
|
||||
|
||||
db_session.close()
|
||||
|
||||
# Wiederherstellungsaktionen bestimmen
|
||||
recovery_actions = []
|
||||
|
||||
if failed_jobs:
|
||||
recovery_actions.append({
|
||||
'type': 'restart_failed_jobs',
|
||||
'count': len(failed_jobs),
|
||||
'description': f'{len(failed_jobs)} fehlgeschlagene Jobs neu starten'
|
||||
})
|
||||
|
||||
if inactive_printers:
|
||||
recovery_actions.append({
|
||||
'type': 'reactivate_printers',
|
||||
'count': len(inactive_printers),
|
||||
'description': f'{len(inactive_printers)} inaktive Drucker reaktivieren'
|
||||
})
|
||||
|
||||
if stuck_jobs:
|
||||
recovery_actions.append({
|
||||
'type': 'reset_stuck_jobs',
|
||||
'count': len(stuck_jobs),
|
||||
'description': f'{len(stuck_jobs)} hängende Jobs zurücksetzen'
|
||||
})
|
||||
|
||||
# Gesamtstatus bestimmen
|
||||
status = 'healthy'
|
||||
if failed_jobs or inactive_printers:
|
||||
status = 'warning'
|
||||
if stuck_jobs:
|
||||
status = 'critical'
|
||||
|
||||
recovery_data = {
|
||||
'success': True,
|
||||
'timestamp': datetime.now().isoformat(),
|
||||
'status': status,
|
||||
|
||||
'issues': {
|
||||
'failed_jobs': len(failed_jobs),
|
||||
'inactive_printers': len(inactive_printers),
|
||||
'stuck_jobs': len(stuck_jobs)
|
||||
},
|
||||
|
||||
'recovery_actions': recovery_actions,
|
||||
|
||||
'last_check': datetime.now().isoformat()
|
||||
}
|
||||
|
||||
api_logger.info(f"Error-Recovery-Status abgerufen von Admin {current_user.username}")
|
||||
return jsonify(recovery_data)
|
||||
|
||||
except Exception as e:
|
||||
api_logger.error(f"Fehler beim Abrufen des Error-Recovery-Status: {str(e)}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'Fehler beim Laden des Wiederherstellungs-Status',
|
||||
'message': str(e)
|
||||
}), 500
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -35,3 +35,10 @@
|
||||
2025-06-12 21:13:41 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-12 21:13:41 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||
2025-06-12 21:13:41 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: 'dict object' has no attribute 'online_printers'
|
||||
2025-06-13 06:57:14 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-13 06:57:14 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||
2025-06-13 06:57:14 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: 'dict object' has no attribute 'online_printers'
|
||||
2025-06-13 06:57:20 - [admin] admin - [INFO] INFO - Admin-Check für Funktion guest_requests: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-13 06:57:25 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-13 06:57:25 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||
2025-06-13 06:57:25 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: 'dict object' has no attribute 'online_printers'
|
||||
|
@ -21548,3 +21548,247 @@ jinja2.exceptions.UndefinedError: 'stats' is undefined
|
||||
2025-06-12 21:14:05 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 21:14:05 - [app] app - [DEBUG] DEBUG - Request: GET /auth/login
|
||||
2025-06-12 21:14:05 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:49:36 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-13 06:49:42 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-13 06:49:44 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - Locating template 'login.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\login.html')
|
||||
2025-06-13 06:49:45 - [app] app - [INFO] INFO - Locating template 'base.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\base.html')
|
||||
2025-06-13 06:49:46 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:49:48 - [app] app - [DEBUG] DEBUG - Request: POST /auth/login
|
||||
2025-06-13 06:49:48 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:49:50 - [app] app - [DEBUG] DEBUG - Request: GET /
|
||||
2025-06-13 06:49:50 - [app] app - [DEBUG] DEBUG - Response: 302
|
||||
2025-06-13 06:49:50 - [app] app - [DEBUG] DEBUG - Request: GET /dashboard
|
||||
2025-06-13 06:49:50 - [app] app - [INFO] INFO - Locating template 'dashboard.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\dashboard.html')
|
||||
2025-06-13 06:49:50 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:56:49 - [app] app - [DEBUG] DEBUG - Request: GET /requests/overview
|
||||
2025-06-13 06:56:49 - [app] app - [INFO] INFO - Locating template 'guest_requests_overview.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\guest_requests_overview.html')
|
||||
2025-06-13 06:56:49 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:56:51 - [app] app - [DEBUG] DEBUG - Request: GET /request
|
||||
2025-06-13 06:56:51 - [app] app - [INFO] INFO - Locating template 'guest_request.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\guest_request.html')
|
||||
2025-06-13 06:56:51 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:57:05 - [app] app - [DEBUG] DEBUG - Request: POST /request
|
||||
2025-06-13 06:57:05 - [app] app - [INFO] INFO - OTP generiert für Guest Request 1
|
||||
2025-06-13 06:57:05 - [app] app - [DEBUG] DEBUG - Response: 302
|
||||
2025-06-13 06:57:05 - [app] app - [DEBUG] DEBUG - Request: GET /request/1
|
||||
2025-06-13 06:57:05 - [app] app - [INFO] INFO - Locating template 'guest_status.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\guest_status.html')
|
||||
2025-06-13 06:57:05 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:57:08 - [app] app - [DEBUG] DEBUG - Request: GET /request/1
|
||||
2025-06-13 06:57:08 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:57:14 - [app] app - [DEBUG] DEBUG - Request: GET /admin/
|
||||
2025-06-13 06:57:14 - [app] app - [INFO] INFO - Locating template 'admin.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\admin.html')
|
||||
2025-06-13 06:57:14 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:57:14 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:57:14 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:57:14 - [app] app - [INFO] INFO - Locating template 'errors/404.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\errors\\404.html')
|
||||
2025-06-13 06:57:15 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/system-health
|
||||
2025-06-13 06:57:15 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/system-health
|
||||
2025-06-13 06:57:15 - [app] app - [INFO] INFO - [SHUTDOWN] 🧹 Cleanup wird ausgeführt...
|
||||
2025-06-13 06:57:15 - [app] app - [INFO] INFO - [SHUTDOWN] ✅ Queue Manager gestoppt
|
||||
2025-06-13 06:57:15 - [app] app - [ERROR] ERROR - [SHUTDOWN] ❌ Cleanup-Fehler: 'BackgroundTaskScheduler' object has no attribute 'shutdown'
|
||||
2025-06-13 06:57:16 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - Locating template 'admin_guest_requests.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\admin_guest_requests.html')
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - Locating template 'errors/404.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\errors\\404.html')
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - Locating template 'base.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\base.html')
|
||||
2025-06-13 06:57:20 - [app] app - [INFO] INFO - Locating template 'base.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\base.html')
|
||||
2025-06-13 06:57:20 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:57:20 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/requests
|
||||
2025-06-13 06:57:20 - [app] app - [WARNING] WARNING - Forbidden (403): http://127.0.0.1:5000/api/admin/requests - User: admin
|
||||
2025-06-13 06:57:20 - [app] app - [DEBUG] DEBUG - Response: 403
|
||||
2025-06-13 06:57:25 - [app] app - [DEBUG] DEBUG - Request: GET /admin/
|
||||
2025-06-13 06:57:25 - [app] app - [INFO] INFO - Locating template 'admin.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\admin.html')
|
||||
2025-06-13 06:57:25 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-13 06:57:25 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:57:25 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:57:25 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/system-health
|
||||
2025-06-13 06:57:25 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/system-health
|
||||
2025-06-13 06:57:30 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:57:30 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:57:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:57:35 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:57:40 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:57:40 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:57:55 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/error-recovery/status
|
||||
2025-06-13 06:57:55 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/system-health
|
||||
2025-06-13 06:57:55 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:57:55 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/error-recovery/status
|
||||
2025-06-13 06:57:55 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/system-health
|
||||
2025-06-13 06:57:55 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:58:25 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/error-recovery/status
|
||||
2025-06-13 06:58:25 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:58:25 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/system-health
|
||||
2025-06-13 06:58:25 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/system-health
|
||||
2025-06-13 06:58:25 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:58:25 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/error-recovery/status
|
||||
2025-06-13 06:58:56 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:58:56 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/error-recovery/status
|
||||
2025-06-13 06:58:56 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/system-health
|
||||
2025-06-13 06:58:56 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/error-recovery/status
|
||||
2025-06-13 06:58:56 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/system-health
|
||||
2025-06-13 06:58:56 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:59:26 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/error-recovery/status
|
||||
2025-06-13 06:59:26 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats
|
||||
2025-06-13 06:59:26 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/system-health
|
||||
2025-06-13 06:59:26 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/error-recovery/status
|
||||
2025-06-13 06:59:26 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/stats
|
||||
2025-06-13 06:59:26 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/admin/system-health
|
||||
|
@ -52,3 +52,5 @@ WHERE users.username = ? OR users.email = ?
|
||||
2025-06-12 21:02:32 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)
|
||||
2025-06-12 21:02:32 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||
2025-06-12 21:13:48 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich abgemeldet
|
||||
2025-06-13 06:49:48 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)
|
||||
2025-06-13 06:49:48 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||
|
@ -164,3 +164,9 @@
|
||||
2025-06-12 15:24:09 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 19:47:01 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 19:47:01 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-13 06:49:36 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-13 06:49:36 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-13 06:49:43 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-13 06:49:43 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-13 06:57:16 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-13 06:57:16 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
|
@ -188,3 +188,9 @@
|
||||
2025-06-12 21:12:01 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 21:12:03 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 21:12:03 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:49:37 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-13 06:49:37 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:49:44 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-13 06:49:44 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:57:17 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-13 06:57:17 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
|
@ -27,3 +27,6 @@
|
||||
2025-06-12 21:10:31 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
|
||||
2025-06-12 21:12:02 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
|
||||
2025-06-12 21:12:04 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
|
||||
2025-06-13 06:49:42 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
|
||||
2025-06-13 06:49:45 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
|
||||
2025-06-13 06:57:20 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert
|
||||
|
@ -29,3 +29,4 @@ WHERE user_permissions.can_approve_jobs = 1]
|
||||
2025-06-12 15:24:36 - [guest] guest - [ERROR] ERROR - Fehler beim Abrufen der Benachrichtigungen: Entity namespace for "notifications" has no property "read"
|
||||
2025-06-12 15:24:59 - [guest] guest - [ERROR] ERROR - Fehler beim Abrufen der Benachrichtigungen: Entity namespace for "notifications" has no property "read"
|
||||
2025-06-12 15:25:29 - [guest] guest - [ERROR] ERROR - Fehler beim Abrufen der Benachrichtigungen: Entity namespace for "notifications" has no property "read"
|
||||
2025-06-13 06:57:05 - [guest] guest - [INFO] INFO - Neue Gastanfrage erstellt: ID 1, Name: Till Tomczaktet, OTP generiert
|
||||
|
@ -458,3 +458,15 @@
|
||||
2025-06-12 21:12:03 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 21:12:03 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 21:12:03 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-13 06:49:37 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-13 06:49:37 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-13 06:49:37 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-13 06:49:37 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-13 06:49:44 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-13 06:49:44 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-13 06:49:44 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-13 06:49:44 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-13 06:57:17 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-13 06:57:17 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-13 06:57:17 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-13 06:57:17 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
|
@ -358,3 +358,15 @@
|
||||
2025-06-12 21:12:05 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-12 21:14:09 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-12 21:14:09 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-13 06:49:37 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-13 06:49:37 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-13 06:49:42 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-13 06:49:44 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-13 06:49:44 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-13 06:49:45 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-13 06:57:15 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-13 06:57:17 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-13 06:57:17 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-13 06:57:20 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-13 06:59:55 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-13 06:59:55 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
|
@ -188,3 +188,9 @@
|
||||
2025-06-12 21:12:02 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 21:12:04 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 21:12:04 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:49:42 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-13 06:49:42 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:49:45 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-13 06:49:45 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:57:20 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-13 06:57:20 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
|
@ -263,3 +263,12 @@
|
||||
2025-06-12 21:12:03 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-12 21:12:05 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-12 21:12:05 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-13 06:49:37 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-13 06:49:42 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-13 06:49:42 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-13 06:49:44 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-13 06:49:45 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-13 06:49:45 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-13 06:57:17 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-13 06:57:20 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-13 06:57:20 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
|
@ -284,3 +284,12 @@
|
||||
2025-06-12 21:12:03 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 21:12:03 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 21:12:04 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-13 06:49:37 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-13 06:49:37 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:49:42 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-13 06:49:44 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-13 06:49:44 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:49:45 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-13 06:57:17 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-13 06:57:17 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-13 06:57:20 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
|
@ -829,3 +829,30 @@
|
||||
2025-06-12 21:12:04 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||
2025-06-12 21:12:04 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-12T21:12:04.861493
|
||||
2025-06-12 21:12:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-13 06:49:42 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-13 06:49:42 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-13 06:49:42 - [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-13 06:49:42 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-13 06:49:42 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-13 06:49:42 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-13T06:49:42.261850
|
||||
2025-06-13 06:49:42 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-13 06:49:42 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-13 06:49:42 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-13 06:49:45 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-13 06:49:45 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-13 06:49:45 - [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-13 06:49:45 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-13 06:49:45 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-13 06:49:45 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-13T06:49:45.398918
|
||||
2025-06-13 06:49:45 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-13 06:49:45 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-13 06:49:45 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-13 06:57:20 - [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-13 06:57:20 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-13T06:57:20.243618
|
||||
2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - ==================================================
|
||||
|
@ -95,3 +95,6 @@
|
||||
2025-06-12 21:10:30 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 21:12:01 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 21:12:03 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-13 06:49:37 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-13 06:49:44 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-13 06:57:17 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
|
@ -52,3 +52,6 @@
|
||||
2025-06-12 21:10:30 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 21:12:01 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 21:12:03 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-13 06:49:37 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-13 06:49:44 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-13 06:57:17 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
|
@ -198,3 +198,9 @@
|
||||
2025-06-12 21:12:01 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 21:12:03 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 21:12:03 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-13 06:49:36 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-13 06:49:36 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-13 06:49:43 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-13 06:49:43 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-13 06:57:16 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-13 06:57:16 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
|
@ -167,3 +167,9 @@
|
||||
2025-06-12 15:24:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 19:47:01 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 19:47:01 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-13 06:49:36 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-13 06:49:36 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-13 06:49:43 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-13 06:49:43 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-13 06:57:16 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-13 06:57:16 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
|
@ -187,7 +187,7 @@
|
||||
<!-- Desktop Navigation -->
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class="hidden lg:flex items-center space-x-1 flex-1 justify-center mx-8">
|
||||
{% set current_route = request.endpoint %}
|
||||
{% set current_route = request.endpoint or '' %}
|
||||
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'dashboard' else '' }}">
|
||||
@ -226,20 +226,20 @@
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
||||
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if 'tapo' in current_route else '' }}">
|
||||
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'tapo' in current_route else '' }}">
|
||||
<i class="fas fa-plug mr-2"></i>
|
||||
<span>Smart Plugs</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_request_form') }}"
|
||||
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if 'guest' in current_route else '' }}">
|
||||
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'guest' in current_route else '' }}">
|
||||
<i class="fas fa-user-plus mr-2"></i>
|
||||
<span>Gast</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_admin %}
|
||||
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if 'admin' in current_route else '' }}">
|
||||
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'admin' in current_route else '' }}">
|
||||
<i class="fas fa-cog mr-2"></i>
|
||||
<span>Admin</span>
|
||||
</a>
|
||||
@ -339,7 +339,7 @@
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class="space-y-1">
|
||||
{% set current_route = request.endpoint %}
|
||||
{% set current_route = request.endpoint or '' %}
|
||||
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'dashboard' else '' }}">
|
||||
@ -378,20 +378,20 @@
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
||||
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if 'tapo' in current_route else '' }}">
|
||||
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'tapo' in current_route else '' }}">
|
||||
<i class="fas fa-plug w-5 mr-3"></i>
|
||||
Smart Plugs
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_request_form') }}"
|
||||
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if 'guest' in current_route else '' }}">
|
||||
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'guest' in current_route else '' }}">
|
||||
<i class="fas fa-user-plus w-5 mr-3"></i>
|
||||
Gast-Anfrage
|
||||
</a>
|
||||
|
||||
{% if current_user.is_admin %}
|
||||
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if 'admin' in current_route else '' }}">
|
||||
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'admin' in current_route else '' }}">
|
||||
<i class="fas fa-cog w-5 mr-3"></i>
|
||||
Admin
|
||||
</a>
|
||||
|
252
backend/utils/permissions.py
Normal file
252
backend/utils/permissions.py
Normal file
@ -0,0 +1,252 @@
|
||||
"""
|
||||
Berechtigungssystem für das MYP 3D-Druck-Management-System
|
||||
|
||||
Dieses Modul stellt Decorator und Utility-Funktionen für die Rechteverwaltung bereit.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from functools import wraps
|
||||
from flask import jsonify, abort
|
||||
from flask_login import login_required, current_user
|
||||
from models import get_db_session, User, UserPermission
|
||||
from utils.logging_config import get_logger
|
||||
|
||||
# Logger initialisieren
|
||||
permissions_logger = get_logger("permissions")
|
||||
|
||||
def admin_required(f):
|
||||
"""
|
||||
Decorator für Admin-Berechtigung.
|
||||
|
||||
Überprüft sowohl die Rolle als auch die is_admin Property.
|
||||
Falls UserPermission fehlt, wird sie automatisch erstellt.
|
||||
"""
|
||||
@wraps(f)
|
||||
@login_required
|
||||
def decorated_function(*args, **kwargs):
|
||||
# Authentifizierung prüfen
|
||||
if not current_user.is_authenticated:
|
||||
permissions_logger.warning("Nicht authentifizierter Zugriff auf Admin-Funktion")
|
||||
abort(401)
|
||||
|
||||
# Admin-Status prüfen
|
||||
is_admin = False
|
||||
|
||||
# Methode 1: is_admin Property
|
||||
if hasattr(current_user, 'is_admin') and current_user.is_admin:
|
||||
is_admin = True
|
||||
|
||||
# Methode 2: Role-basierte Prüfung
|
||||
if hasattr(current_user, 'role') and current_user.role == 'admin':
|
||||
is_admin = True
|
||||
|
||||
if not is_admin:
|
||||
permissions_logger.warning(f"Nicht-Admin Benutzer {current_user.id} versucht Admin-Zugriff")
|
||||
abort(403)
|
||||
|
||||
# Stelle sicher, dass Admin-Benutzer UserPermissions haben
|
||||
ensure_admin_permissions(current_user.id)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
def ensure_admin_permissions(user_id: int):
|
||||
"""
|
||||
Stellt sicher, dass Admin-Benutzer die korrekten UserPermissions haben.
|
||||
|
||||
Args:
|
||||
user_id: ID des Admin-Benutzers
|
||||
"""
|
||||
try:
|
||||
db_session = get_db_session()
|
||||
|
||||
# Prüfe ob UserPermission existiert
|
||||
permission = db_session.query(UserPermission).filter_by(user_id=user_id).first()
|
||||
|
||||
if not permission:
|
||||
# Erstelle neue UserPermission für Admin
|
||||
permission = UserPermission(
|
||||
user_id=user_id,
|
||||
can_start_jobs=True,
|
||||
needs_approval=False,
|
||||
can_approve_jobs=True
|
||||
)
|
||||
db_session.add(permission)
|
||||
permissions_logger.info(f"UserPermission für Admin-Benutzer {user_id} erstellt")
|
||||
else:
|
||||
# Aktualisiere bestehende Permission für Admin
|
||||
permission.can_start_jobs = True
|
||||
permission.needs_approval = False
|
||||
permission.can_approve_jobs = True
|
||||
permissions_logger.info(f"UserPermission für Admin-Benutzer {user_id} aktualisiert")
|
||||
|
||||
db_session.commit()
|
||||
db_session.close()
|
||||
|
||||
except Exception as e:
|
||||
permissions_logger.error(f"Fehler beim Sicherstellen der Admin-Berechtigungen: {str(e)}")
|
||||
|
||||
def fix_all_admin_permissions():
|
||||
"""
|
||||
Korrigiert die Berechtigungen für alle Admin-Benutzer im System.
|
||||
|
||||
Returns:
|
||||
dict: Anzahl der korrigierten Benutzer
|
||||
"""
|
||||
try:
|
||||
db_session = get_db_session()
|
||||
|
||||
# Alle Admin-Benutzer finden
|
||||
admin_users = db_session.query(User).filter(
|
||||
(User.role == 'admin') | (User.is_admin == True)
|
||||
).all()
|
||||
|
||||
corrected_count = 0
|
||||
created_count = 0
|
||||
|
||||
for admin in admin_users:
|
||||
# Prüfe UserPermission
|
||||
permission = db_session.query(UserPermission).filter_by(user_id=admin.id).first()
|
||||
|
||||
if not permission:
|
||||
# Erstelle neue UserPermission
|
||||
permission = UserPermission(
|
||||
user_id=admin.id,
|
||||
can_start_jobs=True,
|
||||
needs_approval=False,
|
||||
can_approve_jobs=True
|
||||
)
|
||||
db_session.add(permission)
|
||||
created_count += 1
|
||||
permissions_logger.info(f"UserPermission für Admin {admin.username} (ID: {admin.id}) erstellt")
|
||||
else:
|
||||
# Korrigiere bestehende Permission
|
||||
if not permission.can_approve_jobs or permission.needs_approval or not permission.can_start_jobs:
|
||||
permission.can_start_jobs = True
|
||||
permission.needs_approval = False
|
||||
permission.can_approve_jobs = True
|
||||
corrected_count += 1
|
||||
permissions_logger.info(f"UserPermission für Admin {admin.username} (ID: {admin.id}) korrigiert")
|
||||
|
||||
db_session.commit()
|
||||
db_session.close()
|
||||
|
||||
permissions_logger.info(f"Admin-Berechtigungen korrigiert: {created_count} erstellt, {corrected_count} aktualisiert")
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'created': created_count,
|
||||
'corrected': corrected_count,
|
||||
'total_admins': len(admin_users)
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
permissions_logger.error(f"Fehler beim Korrigieren der Admin-Berechtigungen: {str(e)}")
|
||||
return {
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}
|
||||
|
||||
def can_approve_jobs(user_id: int) -> bool:
|
||||
"""
|
||||
Prüft, ob ein Benutzer Gastanfragen genehmigen darf.
|
||||
|
||||
Args:
|
||||
user_id: ID des Benutzers
|
||||
|
||||
Returns:
|
||||
bool: True wenn der Benutzer genehmigen darf
|
||||
"""
|
||||
try:
|
||||
db_session = get_db_session()
|
||||
|
||||
# Benutzer laden
|
||||
user = db_session.query(User).filter_by(id=user_id).first()
|
||||
if not user:
|
||||
db_session.close()
|
||||
return False
|
||||
|
||||
# Admin-Benutzer können immer genehmigen
|
||||
if user.role == 'admin' or (hasattr(user, 'is_admin') and user.is_admin):
|
||||
ensure_admin_permissions(user_id)
|
||||
db_session.close()
|
||||
return True
|
||||
|
||||
# UserPermission prüfen
|
||||
permission = db_session.query(UserPermission).filter_by(user_id=user_id).first()
|
||||
|
||||
db_session.close()
|
||||
|
||||
if not permission:
|
||||
return False
|
||||
|
||||
return permission.can_approve_jobs
|
||||
|
||||
except Exception as e:
|
||||
permissions_logger.error(f"Fehler beim Prüfen der Genehmigungsberechtigung: {str(e)}")
|
||||
return False
|
||||
|
||||
def approver_required(f):
|
||||
"""
|
||||
Decorator für Genehmigungsberechtigungen.
|
||||
|
||||
Prüft ob der Benutzer Gastanfragen genehmigen darf.
|
||||
"""
|
||||
@wraps(f)
|
||||
@login_required
|
||||
def decorated_function(*args, **kwargs):
|
||||
if not can_approve_jobs(current_user.id):
|
||||
permissions_logger.warning(f"Benutzer {current_user.id} ({current_user.username}) hat keine Genehmigungsberechtigung")
|
||||
abort(403)
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
def get_user_permissions(user_id: int) -> dict:
|
||||
"""
|
||||
Holt die Berechtigungen eines Benutzers.
|
||||
|
||||
Args:
|
||||
user_id: ID des Benutzers
|
||||
|
||||
Returns:
|
||||
dict: Berechtigungen des Benutzers
|
||||
"""
|
||||
try:
|
||||
db_session = get_db_session()
|
||||
|
||||
user = db_session.query(User).filter_by(id=user_id).first()
|
||||
if not user:
|
||||
db_session.close()
|
||||
return {}
|
||||
|
||||
permission = db_session.query(UserPermission).filter_by(user_id=user_id).first()
|
||||
|
||||
# Standard-Berechtigungen für Admin
|
||||
if user.role == 'admin' or (hasattr(user, 'is_admin') and user.is_admin):
|
||||
result = {
|
||||
'is_admin': True,
|
||||
'can_start_jobs': True,
|
||||
'needs_approval': False,
|
||||
'can_approve_jobs': True
|
||||
}
|
||||
elif permission:
|
||||
result = {
|
||||
'is_admin': False,
|
||||
'can_start_jobs': permission.can_start_jobs,
|
||||
'needs_approval': permission.needs_approval,
|
||||
'can_approve_jobs': permission.can_approve_jobs
|
||||
}
|
||||
else:
|
||||
result = {
|
||||
'is_admin': False,
|
||||
'can_start_jobs': False,
|
||||
'needs_approval': True,
|
||||
'can_approve_jobs': False
|
||||
}
|
||||
|
||||
db_session.close()
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
permissions_logger.error(f"Fehler beim Abrufen der Benutzer-Berechtigungen: {str(e)}")
|
||||
return {}
|
Reference in New Issue
Block a user