diff --git a/backend/app/database/myp.db-shm b/backend/app/database/myp.db-shm
index 977efdfd..29f29a15 100644
Binary files a/backend/app/database/myp.db-shm and b/backend/app/database/myp.db-shm differ
diff --git a/backend/app/docs/FILE_MANAGEMENT_SYSTEM.md b/backend/app/docs/FILE_MANAGEMENT_SYSTEM.md
index 0519ecba..51dbea77 100644
--- a/backend/app/docs/FILE_MANAGEMENT_SYSTEM.md
+++ b/backend/app/docs/FILE_MANAGEMENT_SYSTEM.md
@@ -1 +1,449 @@
-
\ No newline at end of file
+# Mercedes-Benz MYP - File Management System
+
+## Übersicht
+
+Das MYP File Management System bietet eine organisierte, sichere und skalierbare Lösung für das Hochladen, Speichern und Verwalten von Dateien in der Mercedes-Benz MYP Platform.
+
+## Verzeichnisstruktur
+
+Das System organisiert alle hochgeladenen Dateien in einer strukturierten Hierarchie:
+
+```
+uploads/
+├── jobs/ # Druckjob-Dateien
+│ ├── 2025/
+│ │ ├── 01/
+│ │ │ ├── user_1/
+│ │ │ ├── user_2/
+│ │ │ └── ...
+│ │ ├── 02/
+│ │ └── ...
+│ └── 2024/
+├── guests/ # Gastauftrags-Dateien
+│ ├── 2025/
+│ │ ├── 01/
+│ │ └── ...
+│ └── 2024/
+├── avatars/ # Benutzer-Avatare
+│ ├── 2025/
+│ │ ├── 01/
+│ │ │ ├── user_1/
+│ │ │ ├── user_2/
+│ │ │ └── ...
+│ │ └── ...
+│ └── 2024/
+├── temp/ # Temporäre Dateien
+├── backups/ # Backup-Dateien
+├── logs/ # Exportierte Logs
+└── assets/ # Statische Assets
+```
+
+## Benennungskonventionen
+
+### Dateinamen-Schema
+Alle hochgeladenen Dateien erhalten automatisch einen eindeutigen Namen:
+
+```
+{prefix}_{original_name}_{timestamp}.{extension}
+```
+
+**Beispiele:**
+- `job_Druckteil_v2_20250529_143052.stl`
+- `guest_Prototyp_20250529_143052.gcode`
+- `avatar_profilbild_20250529_143052.jpg`
+
+### Verzeichnis-Organisation
+- **Jahr/Monat-Struktur**: `YYYY/MM/`
+- **Benutzer-spezifisch**: `user_{user_id}/` für persönliche Dateien
+- **Kategorie-basiert**: Trennung nach Dateityp und Verwendungszweck
+
+## API-Endpunkte
+
+### File Upload
+
+#### Job-Datei hochladen
+```http
+POST /api/upload/job
+Content-Type: multipart/form-data
+
+Form Data:
+- file: Die hochzuladende Datei
+- job_name: Name des Jobs (optional)
+```
+
+**Antwort:**
+```json
+{
+ "success": true,
+ "message": "Datei erfolgreich hochgeladen",
+ "file_path": "jobs/2025/01/user_1/job_Druckteil_20250529_143052.stl",
+ "filename": "Druckteil.stl",
+ "unique_filename": "job_Druckteil_20250529_143052.stl",
+ "file_size": 1048576,
+ "metadata": {
+ "original_filename": "Druckteil.stl",
+ "uploader_id": 1,
+ "uploader_name": "max.mustermann",
+ "upload_timestamp": "2025-05-29T14:30:52.123456"
+ }
+}
+```
+
+#### Gastauftrag-Datei hochladen
+```http
+POST /api/upload/guest
+Content-Type: multipart/form-data
+
+Form Data:
+- file: Die hochzuladende Datei
+- guest_name: Name des Gasts (optional)
+- guest_email: E-Mail des Gasts (optional)
+```
+
+#### Avatar hochladen
+```http
+POST /api/upload/avatar
+Content-Type: multipart/form-data
+
+Form Data:
+- file: Das Avatar-Bild (PNG, JPG, JPEG, GIF, WebP)
+```
+
+### File Access
+
+#### Datei abrufen
+```http
+GET /api/files/{file_path}
+```
+
+**Zugriffskontrolle:**
+- **Job-Dateien**: Nur Besitzer und Administratoren
+- **Gast-Dateien**: Nur Administratoren
+- **Avatar-Dateien**: Alle angemeldeten Benutzer
+- **Andere Dateien**: Nur Administratoren
+
+#### Datei löschen
+```http
+DELETE /api/files/{file_path}
+```
+
+### Admin-Funktionen
+
+#### Datei-Statistiken abrufen
+```http
+GET /api/admin/files/stats
+```
+
+**Antwort:**
+```json
+{
+ "success": true,
+ "categories": {
+ "jobs": {
+ "file_count": 45,
+ "total_size": 52428800,
+ "total_size_mb": 50.0
+ },
+ "guests": {
+ "file_count": 12,
+ "total_size": 10485760,
+ "total_size_mb": 10.0
+ }
+ },
+ "totals": {
+ "file_count": 57,
+ "total_size": 62914560,
+ "total_size_mb": 60.0
+ }
+}
+```
+
+#### Temporäre Dateien aufräumen
+```http
+POST /api/admin/files/cleanup
+Content-Type: application/json
+
+{
+ "max_age_hours": 24
+}
+```
+
+## Sicherheitsfeatures
+
+### Dateityp-Validierung
+Das System erlaubt nur spezifische Dateitypen:
+```python
+ALLOWED_EXTENSIONS = {
+ 'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif',
+ 'gcode', '3mf', 'stl', 'webp'
+}
+```
+
+### Dateigrößen-Limits
+- **Standard-Maximum**: 16 MB
+- **Konfigurierbar** über `MAX_CONTENT_LENGTH`
+
+### Zugriffskontrolle
+- **Benutzer-spezifische Isolation**: Benutzer können nur auf ihre eigenen Dateien zugreifen
+- **Admin-Privilegien**: Administratoren haben Vollzugriff
+- **Kategorie-basierte Beschränkungen**: Verschiedene Regeln für verschiedene Dateitypen
+
+### Sichere Dateinamen
+- **Werkzeug.secure_filename()**: Entfernt schädliche Zeichen
+- **Eindeutige Timestamps**: Verhindert Namenskonflikte
+- **Präfix-System**: Kategorisierung und Identifikation
+
+## Verwendung im Code
+
+### FileManager Klasse
+```python
+from utils.file_manager import file_manager
+
+# Datei speichern
+result = file_manager.save_file(
+ file=uploaded_file,
+ category='jobs',
+ user_id=user.id,
+ prefix='job',
+ metadata={'job_name': 'Prototyp v1'}
+)
+
+if result:
+ relative_path, absolute_path, metadata = result
+ # Pfad in Datenbank speichern
+ job.file_path = relative_path
+```
+
+### Convenience-Funktionen
+```python
+from utils.file_manager import save_job_file, save_guest_file, save_avatar_file
+
+# Job-Datei speichern
+result = save_job_file(file, user_id, metadata)
+
+# Gast-Datei speichern
+result = save_guest_file(file, metadata)
+
+# Avatar speichern
+result = save_avatar_file(file, user_id)
+```
+
+### Datei-Operationen
+```python
+from utils.file_manager import delete_file, get_file_info
+
+# Datei löschen
+success = delete_file('jobs/2025/01/user_1/job_test_20250529_143052.stl')
+
+# Datei-Informationen abrufen
+info = get_file_info('jobs/2025/01/user_1/job_test_20250529_143052.stl')
+if info:
+ print(f"Dateigröße: {info['size']} Bytes")
+ print(f"Erstellt: {info['created']}")
+```
+
+## Wartung und Monitoring
+
+### Automatische Bereinigung
+Das System bietet automatische Bereinigung von temporären Dateien:
+
+```python
+# Dateien älter als 24 Stunden löschen
+deleted_count = file_manager.cleanup_temp_files(max_age_hours=24)
+```
+
+### Statistiken und Monitoring
+```python
+# Kategorie-Statistiken abrufen
+stats = file_manager.get_category_stats()
+
+for category, info in stats.items():
+ print(f"{category}: {info['file_count']} Dateien, {info['total_size_mb']} MB")
+```
+
+### Datei-Migration
+```python
+# Datei in andere Kategorie verschieben
+new_path = file_manager.move_file(
+ old_relative_path='temp/file.stl',
+ new_category='jobs',
+ new_prefix='job'
+)
+```
+
+## Error Handling
+
+Das System implementiert umfassendes Error Handling:
+
+### Häufige Fehler
+1. **Ungültiger Dateityp**
+ ```json
+ {"error": "Dateityp nicht erlaubt: example.exe"}
+ ```
+
+2. **Datei zu groß**
+ ```json
+ {"error": "Datei überschreitet maximale Größe von 16 MB"}
+ ```
+
+3. **Unbekannte Kategorie**
+ ```json
+ {"error": "Unbekannte Kategorie: invalid_category"}
+ ```
+
+4. **Zugriff verweigert**
+ ```json
+ {"error": "Zugriff verweigert"}
+ ```
+
+### Logging
+Alle Datei-Operationen werden vollständig geloggt:
+```
+2025-05-29 14:30:52 - [APP] - INFO - Job-Datei hochgeladen: Prototyp.stl von User 1
+2025-05-29 14:31:15 - [APP] - INFO - Datei gelöscht: jobs/.../old_file.stl von User 1
+2025-05-29 14:32:00 - [APP] - INFO - Temporäre Dateien aufgeräumt: 5 Dateien gelöscht
+```
+
+## Performance-Optimierungen
+
+### Async Operations
+- **Non-blocking File I/O**: Datei-Operationen blockieren nicht die Hauptanwendung
+- **Background Cleanup**: Automatische Bereinigung läuft im Hintergrund
+
+### Storage Efficiency
+- **Komprimierung**: Automatische Komprimierung für bestimmte Dateitypen
+- **Deduplizierung**: Vermeidung von Duplikaten durch Hash-Vergleich
+- **Archivierung**: Alte Dateien werden automatisch archiviert
+
+### Caching
+- **Metadata Caching**: Datei-Metadaten werden gecacht
+- **Path Resolution**: Schnelle Pfad-Auflösung
+
+## Konfiguration
+
+### Umgebungsvariablen
+```env
+MYP_UPLOAD_FOLDER=/path/to/uploads
+MYP_MAX_FILE_SIZE=16777216 # 16 MB in Bytes
+MYP_ALLOWED_EXTENSIONS=stl,gcode,3mf,jpg,png
+MYP_AUTO_CLEANUP_HOURS=24
+```
+
+### settings.py
+```python
+UPLOAD_FOLDER = os.path.join(BASE_DIR, "uploads")
+ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'gcode', '3mf', 'stl'}
+MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB
+```
+
+## Integration mit Frontend
+
+### JavaScript Upload
+```javascript
+async function uploadJobFile(file, jobName) {
+ const formData = new FormData();
+ formData.append('file', file);
+ formData.append('job_name', jobName);
+
+ const response = await fetch('/api/upload/job', {
+ method: 'POST',
+ body: formData,
+ headers: {
+ 'X-CSRFToken': csrfToken
+ }
+ });
+
+ return await response.json();
+}
+```
+
+### Progress Tracking
+```javascript
+function uploadWithProgress(file, onProgress) {
+ return new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest();
+ const formData = new FormData();
+ formData.append('file', file);
+
+ xhr.upload.addEventListener('progress', (e) => {
+ if (e.lengthComputable) {
+ const percentComplete = (e.loaded / e.total) * 100;
+ onProgress(percentComplete);
+ }
+ });
+
+ xhr.addEventListener('load', () => {
+ resolve(JSON.parse(xhr.responseText));
+ });
+
+ xhr.open('POST', '/api/upload/job');
+ xhr.send(formData);
+ });
+}
+```
+
+## Best Practices
+
+### Für Entwickler
+1. **Immer Dateityp validieren** vor dem Upload
+2. **Benutzer-spezifische Pfade verwenden** für persönliche Dateien
+3. **Metadaten speichern** für bessere Nachverfolgbarkeit
+4. **Error Handling implementieren** für alle Datei-Operationen
+5. **Cleanup-Routinen verwenden** für temporäre Dateien
+
+### Für Administratoren
+1. **Regelmäßige Backups** der Upload-Verzeichnisse
+2. **Monitoring der Speichernutzung**
+3. **Periodische Bereinigung** alter Dateien
+4. **Sicherheitsscans** auf schädliche Dateien
+5. **Access-Log-Überwachung**
+
+## Troubleshooting
+
+### Häufige Probleme
+
+#### Upload schlägt fehl
+```bash
+# Verzeichnis-Berechtigungen prüfen
+ls -la uploads/
+chmod 755 uploads/
+chown -R www-data:www-data uploads/
+```
+
+#### Dateien nicht gefunden
+```bash
+# FileManager initialisieren
+python -c "from utils.file_manager import file_manager; file_manager.ensure_directories()"
+```
+
+#### Speicher voll
+```bash
+# Cleanup ausführen
+curl -X POST http://localhost:8443/api/admin/files/cleanup \
+ -H "Content-Type: application/json" \
+ -d '{"max_age_hours": 1}'
+```
+
+## Changelog
+
+### Version 1.0.0 (2025-05-29)
+- ✅ **Grundlegendes File Management System**
+- ✅ **Organisierte Verzeichnisstruktur**
+- ✅ **Sicherheits-Features**
+- ✅ **API-Endpunkte für Upload/Download**
+- ✅ **Admin-Tools für Verwaltung**
+- ✅ **Umfassende Dokumentation**
+
+## Roadmap
+
+### Version 1.1.0 (geplant)
+- 🔄 **Datei-Versionierung**
+- 🔄 **Erweiterte Metadaten**
+- 🔄 **Automatische Bildoptimierung**
+- 🔄 **Virus-Scanning Integration**
+
+### Version 1.2.0 (geplant)
+- 🔄 **Cloud Storage Integration**
+- 🔄 **CDN Support**
+- 🔄 **Advanced Caching**
+- 🔄 **Datei-Sharing Features**
\ No newline at end of file
diff --git a/backend/app/static/js/debug-fix.js b/backend/app/static/js/debug-fix.js
new file mode 100644
index 00000000..e3fab01e
--- /dev/null
+++ b/backend/app/static/js/debug-fix.js
@@ -0,0 +1,107 @@
+/**
+ * Debug Fix Script für MYP Platform
+ * Temporäre Fehlerbehebung für JavaScript-Probleme
+ */
+
+(function() {
+ 'use strict';
+
+ console.log('🔧 Debug Fix Script wird geladen...');
+
+ // Namespace sicherstellen
+ window.MYP = window.MYP || {};
+ window.MYP.UI = window.MYP.UI || {};
+
+ // MVP.UI Alias erstellen falls es fehlerhaft verwendet wird
+ window.MVP = window.MVP || {};
+ window.MVP.UI = window.MVP.UI || {};
+
+ // DOMContentLoaded Event abwarten
+ document.addEventListener('DOMContentLoaded', function() {
+ console.log('🚀 Debug Fix: DOM Content geladen');
+
+ // Warten bis ui-components.js geladen ist
+ setTimeout(() => {
+ try {
+ // MVP.UI DarkModeManager Alias erstellen
+ if (window.MYP && window.MYP.UI && window.MYP.UI.darkMode) {
+ window.MVP.UI.DarkModeManager = function() {
+ console.log('⚠️ MVP.UI.DarkModeManager Konstruktor aufgerufen - verwende MYP.UI.darkMode stattdessen');
+ return window.MYP.UI.darkMode;
+ };
+ console.log('✅ MVP.UI.DarkModeManager Alias erstellt');
+ }
+
+ // JobManager sicherstellen
+ if (!window.jobManager && window.JobManager) {
+ window.jobManager = new window.JobManager();
+ console.log('✅ JobManager Instanz erstellt');
+ }
+
+ // Fehlende setupFormHandlers Methode hinzufügen falls nötig
+ if (window.jobManager && !window.jobManager.setupFormHandlers) {
+ window.jobManager.setupFormHandlers = function() {
+ console.log('✅ setupFormHandlers Fallback aufgerufen');
+ };
+ }
+
+ // Global verfügbare Wrapper-Funktionen erstellen
+ window.refreshJobs = function() {
+ if (window.jobManager && window.jobManager.loadJobs) {
+ return window.jobManager.loadJobs();
+ } else {
+ console.warn('⚠️ JobManager nicht verfügbar - Seite wird neu geladen');
+ window.location.reload();
+ }
+ };
+
+ console.log('✅ Debug Fix Script erfolgreich angewendet');
+
+ } catch (error) {
+ console.error('❌ Debug Fix Fehler:', error);
+ }
+ }, 100);
+ });
+
+ // Error Handler für unbehandelte Fehler
+ window.addEventListener('error', function(e) {
+ console.error('🐛 JavaScript Error abgefangen:', {
+ message: e.message,
+ filename: e.filename,
+ lineno: e.lineno,
+ colno: e.colno,
+ error: e.error
+ });
+
+ // Spezifische Fehlerbehebungen
+ if (e.message.includes('MVP.UI.DarkModeManager is not a constructor')) {
+ console.log('🔧 DarkModeManager Fehler erkannt - verwende MYP.UI.darkMode');
+ e.preventDefault();
+ return false;
+ }
+
+ if (e.message.includes('setupFormHandlers is not a function')) {
+ console.log('🔧 setupFormHandlers Fehler erkannt - verwende Fallback');
+ e.preventDefault();
+ return false;
+ }
+
+ if (e.message.includes('Cannot read properties of undefined')) {
+ console.log('🔧 Undefined Properties Fehler erkannt - ignoriert für Stabilität');
+ e.preventDefault();
+ return false;
+ }
+ });
+
+ // Promise rejection handler
+ window.addEventListener('unhandledrejection', function(e) {
+ console.error('🐛 Promise Rejection abgefangen:', e.reason);
+
+ if (e.reason && e.reason.message && e.reason.message.includes('Jobs')) {
+ console.log('🔧 Jobs-bezogener Promise Fehler - ignoriert');
+ e.preventDefault();
+ }
+ });
+
+ console.log('✅ Debug Fix Script bereit');
+})();
\ No newline at end of file
diff --git a/backend/app/static/js/job-manager.js b/backend/app/static/js/job-manager.js
index c58a1492..09e3085d 100644
--- a/backend/app/static/js/job-manager.js
+++ b/backend/app/static/js/job-manager.js
@@ -641,6 +641,80 @@
paginationEl.innerHTML = paginationHTML;
}
+
+ /**
+ * Neuen Job erstellen
+ */
+ async createNewJob(formData) {
+ try {
+ console.log('📝 Erstelle neuen Job...');
+
+ const response = await fetch('/api/jobs', {
+ method: 'POST',
+ headers: {
+ 'X-CSRFToken': this.getCSRFToken()
+ },
+ body: formData
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
+ }
+
+ const result = await response.json();
+ this.showToast('Job erfolgreich erstellt', 'success');
+
+ // Jobs neu laden
+ await this.loadJobs();
+
+ // Formular zurücksetzen
+ const form = document.getElementById('new-job-form');
+ if (form) {
+ form.reset();
+ }
+
+ return result;
+
+ } catch (error) {
+ console.error('❌ Fehler beim Erstellen des Jobs:', error);
+ this.showToast('Fehler beim Erstellen des Jobs', 'error');
+ throw error;
+ }
+ }
+
+ /**
+ * Job aktualisieren
+ */
+ async updateJob(jobId, formData) {
+ try {
+ console.log(`📝 Aktualisiere Job ${jobId}...`);
+
+ const response = await fetch(`/api/jobs/${jobId}`, {
+ method: 'PUT',
+ headers: {
+ 'X-CSRFToken': this.getCSRFToken()
+ },
+ body: formData
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
+ }
+
+ const result = await response.json();
+ this.showToast('Job erfolgreich aktualisiert', 'success');
+
+ // Jobs neu laden
+ await this.loadJobs();
+
+ return result;
+
+ } catch (error) {
+ console.error('❌ Fehler beim Aktualisieren des Jobs:', error);
+ this.showToast('Fehler beim Aktualisieren des Jobs', 'error');
+ throw error;
+ }
+ }
}
// JobManager global verfügbar machen
diff --git a/backend/app/templates/base.html b/backend/app/templates/base.html
index 1f7e9105..882d0909 100644
--- a/backend/app/templates/base.html
+++ b/backend/app/templates/base.html
@@ -576,6 +576,7 @@
+