jojojojo aua
This commit is contained in:
@@ -1 +1,363 @@
|
||||
|
||||
# Drag & Drop System für Job-Reihenfolge-Verwaltung
|
||||
**Implementiert am:** ${new Date().toLocaleDateString('de-DE')}
|
||||
**Status:** ✅ Vollständig implementiert und getestet
|
||||
|
||||
## Überblick
|
||||
|
||||
Das Drag & Drop System ermöglicht es Benutzern, die Reihenfolge der Druckjobs per Drag & Drop zu ändern. Die Implementierung umfasst eine vollständige Backend-API, Datenbank-Persistierung und erweiterte Funktionen für Job-Management.
|
||||
|
||||
## 🎯 Hauptfunktionen
|
||||
|
||||
### ✅ Implementierte Features
|
||||
- **Persistent Job-Reihenfolge**: Jobs werden in der Datenbank gespeichert und überleben Neustarts
|
||||
- **Benutzerberechtigungen**: Nur autorisierte Benutzer können Job-Reihenfolgen ändern
|
||||
- **Automatische Bereinigung**: Abgeschlossene Jobs werden automatisch aus der Reihenfolge entfernt
|
||||
- **Cache-System**: Optimierte Performance durch intelligentes Caching
|
||||
- **Audit-Trail**: Vollständige Nachverfolgung wer wann Änderungen vorgenommen hat
|
||||
- **API-Endpoints**: RESTful API für Frontend-Integration
|
||||
- **Drucker-spezifische Reihenfolgen**: Jeder Drucker hat seine eigene Job-Reihenfolge
|
||||
|
||||
## 🗄️ Datenbank-Schema
|
||||
|
||||
### JobOrder-Tabelle
|
||||
```sql
|
||||
CREATE TABLE job_orders (
|
||||
id INTEGER PRIMARY KEY,
|
||||
printer_id INTEGER NOT NULL,
|
||||
job_id INTEGER NOT NULL,
|
||||
order_position INTEGER NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
last_modified_by INTEGER,
|
||||
FOREIGN KEY (printer_id) REFERENCES printers(id),
|
||||
FOREIGN KEY (job_id) REFERENCES jobs(id),
|
||||
FOREIGN KEY (last_modified_by) REFERENCES users(id)
|
||||
);
|
||||
```
|
||||
|
||||
### Eigenschaften
|
||||
- **Eindeutige Job-Position**: Jeder Job hat nur eine Position pro Drucker
|
||||
- **Automatische Zeitstempel**: created_at und updated_at werden automatisch verwaltet
|
||||
- **Benutzer-Nachverfolgung**: last_modified_by speichert wer die Änderung vorgenommen hat
|
||||
- **Referentielle Integrität**: Foreign Keys gewährleisten Datenkonsistenz
|
||||
|
||||
## 🔧 Backend-Implementierung
|
||||
|
||||
### DragDropManager-Klasse
|
||||
```python
|
||||
# utils/drag_drop_system.py
|
||||
|
||||
class DragDropManager:
|
||||
def __init__(self):
|
||||
self.upload_sessions = {}
|
||||
self.job_order_cache = {} # Cache für bessere Performance
|
||||
|
||||
def update_job_order(self, printer_id: int, job_ids: List[int]) -> bool:
|
||||
"""Aktualisiert die Job-Reihenfolge mit vollständiger Validierung"""
|
||||
|
||||
def get_ordered_jobs_for_printer(self, printer_id: int) -> List[Job]:
|
||||
"""Holt Jobs in der korrekten benutzerdefinierten Reihenfolge"""
|
||||
|
||||
def remove_job_from_order(self, job_id: int) -> bool:
|
||||
"""Entfernt einen Job aus allen Reihenfolgen"""
|
||||
|
||||
def cleanup_invalid_orders(self):
|
||||
"""Bereinigt ungültige oder abgeschlossene Jobs"""
|
||||
```
|
||||
|
||||
### JobOrder-Model
|
||||
```python
|
||||
# models.py
|
||||
|
||||
class JobOrder(Base):
|
||||
"""Speichert die benutzerdefinierte Job-Reihenfolge pro Drucker"""
|
||||
|
||||
@classmethod
|
||||
def update_printer_order(cls, printer_id: int, job_ids: List[int],
|
||||
modified_by_user_id: int = None) -> bool:
|
||||
"""Aktualisiert die komplette Job-Reihenfolge für einen Drucker"""
|
||||
|
||||
@classmethod
|
||||
def get_ordered_job_ids(cls, printer_id: int) -> List[int]:
|
||||
"""Holt die Job-IDs in der korrekten Reihenfolge"""
|
||||
|
||||
@classmethod
|
||||
def cleanup_invalid_orders(cls):
|
||||
"""Bereinigt ungültige Order-Einträge"""
|
||||
```
|
||||
|
||||
## 🌐 API-Endpoints
|
||||
|
||||
### 1. Job-Reihenfolge abrufen
|
||||
```http
|
||||
GET /api/printers/{printer_id}/jobs/order
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"printer": {
|
||||
"id": 1,
|
||||
"name": "Drucker A1",
|
||||
"model": "Prusa i3 MK3S+",
|
||||
"location": "Raum A.123"
|
||||
},
|
||||
"jobs": [
|
||||
{
|
||||
"id": 15,
|
||||
"name": "Smartphone-Hülle",
|
||||
"user_name": "Max Mustermann",
|
||||
"duration_minutes": 45,
|
||||
"status": "scheduled"
|
||||
}
|
||||
],
|
||||
"job_order": [15, 23, 7],
|
||||
"total_jobs": 3,
|
||||
"total_duration_minutes": 120
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Job-Reihenfolge aktualisieren
|
||||
```http
|
||||
POST /api/printers/{printer_id}/jobs/order
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"job_ids": [23, 15, 7] // Neue Reihenfolge
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Job-Reihenfolge erfolgreich aktualisiert",
|
||||
"printer": {
|
||||
"id": 1,
|
||||
"name": "Drucker A1"
|
||||
},
|
||||
"old_order": [23, 15, 7],
|
||||
"new_order": [23, 15, 7],
|
||||
"total_jobs": 3,
|
||||
"updated_by": {
|
||||
"id": 5,
|
||||
"name": "Max Mustermann"
|
||||
},
|
||||
"timestamp": "2025-01-13T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Drucker-Job-Zusammenfassung
|
||||
```http
|
||||
GET /api/printers/{printer_id}/jobs/summary
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"printer": {
|
||||
"id": 1,
|
||||
"name": "Drucker A1",
|
||||
"status": "idle"
|
||||
},
|
||||
"summary": {
|
||||
"printer_id": 1,
|
||||
"total_jobs": 3,
|
||||
"total_duration_minutes": 120,
|
||||
"estimated_completion": "2025-01-13T12:30:00Z",
|
||||
"next_job": {
|
||||
"id": 23,
|
||||
"name": "Ersatzteil XY",
|
||||
"user": "Anna Schmidt"
|
||||
},
|
||||
"jobs": [
|
||||
{
|
||||
"position": 0,
|
||||
"job_id": 23,
|
||||
"name": "Ersatzteil XY",
|
||||
"duration_minutes": 30,
|
||||
"user_name": "Anna Schmidt",
|
||||
"status": "scheduled"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Bereinigung ungültiger Reihenfolgen (Admin)
|
||||
```http
|
||||
POST /api/printers/jobs/cleanup-orders
|
||||
```
|
||||
|
||||
### 5. Drag-Drop-Konfiguration abrufen
|
||||
```http
|
||||
GET /api/printers/drag-drop/config
|
||||
```
|
||||
|
||||
## 🔐 Berechtigungen
|
||||
|
||||
### Erforderliche Rechte
|
||||
- **Job-Reihenfolge anzeigen**: Alle angemeldeten Benutzer
|
||||
- **Job-Reihenfolge ändern**: `Permission.APPROVE_JOBS` erforderlich
|
||||
- **Eigene Jobs verschieben**: Benutzer können nur ihre eigenen Jobs verschieben
|
||||
- **Alle Jobs verwalten**: Administratoren können alle Jobs verschieben
|
||||
- **System-Bereinigung**: Nur Administratoren (`Permission.ADMIN`)
|
||||
|
||||
### Validierung
|
||||
```python
|
||||
# Beispiel aus dem Code
|
||||
if not current_user.is_admin:
|
||||
user_job_ids = {job.id for job in valid_jobs if job.user_id == current_user.id}
|
||||
if user_job_ids != set(job_ids):
|
||||
return jsonify({"error": "Keine Berechtigung für fremde Jobs"}), 403
|
||||
```
|
||||
|
||||
## 🚀 Performance-Optimierungen
|
||||
|
||||
### 1. Intelligentes Caching
|
||||
- **Job-Reihenfolgen**: Im Speicher-Cache für schnelle Zugriffe
|
||||
- **TTL-basiert**: Automatische Cache-Invalidierung nach bestimmter Zeit
|
||||
- **Event-basiert**: Cache wird bei Änderungen sofort invalidiert
|
||||
|
||||
### 2. Datenbank-Optimierungen
|
||||
- **Indizierte Abfragen**: Foreign Keys sind automatisch indiziert
|
||||
- **Batch-Updates**: Mehrere Änderungen in einer Transaktion
|
||||
- **Optimierte Joins**: Effiziente Datenbankabfragen für Job-Details
|
||||
|
||||
### 3. Hintergrund-Bereinigung
|
||||
```python
|
||||
def _schedule_cleanup(self):
|
||||
"""Plant eine Bereinigung für später (non-blocking)"""
|
||||
cleanup_thread = threading.Thread(target=cleanup_worker, daemon=True)
|
||||
cleanup_thread.start()
|
||||
```
|
||||
|
||||
## 🛠️ Verwendung für Entwickler
|
||||
|
||||
### Frontend-Integration
|
||||
```javascript
|
||||
// Drag-Drop-Konfiguration laden
|
||||
const response = await fetch('/api/printers/drag-drop/config');
|
||||
const config = await response.json();
|
||||
|
||||
// Job-Reihenfolge aktualisieren
|
||||
const updateOrder = async (printerId, jobIds) => {
|
||||
const response = await fetch(`/api/printers/${printerId}/jobs/order`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ job_ids: jobIds })
|
||||
});
|
||||
return response.json();
|
||||
};
|
||||
```
|
||||
|
||||
### Neue Jobs automatisch einordnen
|
||||
```python
|
||||
# Beispiel: Neuer Job wird automatisch ans Ende der Reihenfolge gesetzt
|
||||
def add_new_job_to_order(job):
|
||||
current_order = drag_drop_manager.get_job_order(job.printer_id)
|
||||
new_order = current_order + [job.id]
|
||||
drag_drop_manager.update_job_order(job.printer_id, new_order)
|
||||
```
|
||||
|
||||
## 🔧 Migration und Setup
|
||||
|
||||
### Automatische Datenbank-Migration
|
||||
Die JobOrder-Tabelle wird automatisch beim Anwendungsstart erstellt:
|
||||
|
||||
```python
|
||||
# In app.py wird setup_database_with_migrations() aufgerufen
|
||||
def setup_database_with_migrations():
|
||||
# Erstellt alle Tabellen inklusive JobOrder
|
||||
Base.metadata.create_all(engine)
|
||||
|
||||
# Prüft spezifisch auf JobOrder-Tabelle
|
||||
if 'job_orders' not in existing_tables:
|
||||
JobOrder.__table__.create(engine, checkfirst=True)
|
||||
```
|
||||
|
||||
## 🐛 Fehlerbehandlung
|
||||
|
||||
### Typische Fehlerszenarien
|
||||
1. **Ungültige Job-IDs**: Jobs existieren nicht oder gehören zu anderem Drucker
|
||||
2. **Berechtigungsfehler**: Benutzer versucht fremde Jobs zu verschieben
|
||||
3. **Datenbankfehler**: Transaktions-Rollback bei Fehlern
|
||||
4. **Cache-Inkonsistenz**: Automatische Cache-Bereinigung bei Fehlern
|
||||
|
||||
### Robuste Error-Recovery
|
||||
```python
|
||||
try:
|
||||
success = JobOrder.update_printer_order(printer_id, job_ids, user_id)
|
||||
if success:
|
||||
self.job_order_cache[printer_id] = job_ids
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Aktualisieren: {str(e)}")
|
||||
# Cache bereinigen bei Fehlern
|
||||
self.job_order_cache.pop(printer_id, None)
|
||||
return False
|
||||
```
|
||||
|
||||
## 📊 Monitoring und Logging
|
||||
|
||||
### Ausführliche Protokollierung
|
||||
```python
|
||||
logger.info(f"Job-Reihenfolge für Drucker {printer.name} aktualisiert")
|
||||
logger.info(f" Neue Reihenfolge: {job_ids}")
|
||||
logger.info(f" Benutzer: {current_user.name} (ID: {current_user.id})")
|
||||
```
|
||||
|
||||
### Statistiken
|
||||
- Anzahl der Drag-Drop-Operationen pro Benutzer
|
||||
- Häufigste Reihenfolge-Änderungen
|
||||
- Performance-Metriken für Cache-Hits/Misses
|
||||
|
||||
## 🔄 Maintenance und Wartung
|
||||
|
||||
### Automatische Bereinigung
|
||||
- **Scheduler-Integration**: Regelmäßige Bereinigung ungültiger Einträge
|
||||
- **On-Demand-Cleanup**: Manuelle Bereinigung über Admin-API
|
||||
- **Cache-Management**: Automatische Cache-Größenkontrolle
|
||||
|
||||
### Datenbank-Wartung
|
||||
```sql
|
||||
-- Regelmäßige Bereinigung abgeschlossener Jobs
|
||||
DELETE FROM job_orders
|
||||
WHERE job_id IN (
|
||||
SELECT id FROM jobs
|
||||
WHERE status IN ('finished', 'aborted', 'cancelled')
|
||||
);
|
||||
```
|
||||
|
||||
## 🚀 Zukünftige Erweiterungen
|
||||
|
||||
### Geplante Features
|
||||
1. **Bulk-Operationen**: Mehrere Jobs gleichzeitig verschieben
|
||||
2. **Templates**: Vordefinierte Job-Reihenfolgen speichern
|
||||
3. **Automatische Optimierung**: KI-basierte Reihenfolge-Vorschläge
|
||||
4. **Grafisches Dashboard**: Visuelles Drag-Drop-Interface
|
||||
5. **Mobile-Optimierung**: Touch-freundliche Drag-Drop-Funktionen
|
||||
|
||||
### Erweiterbarkeit
|
||||
```python
|
||||
# Plugin-System für benutzerdefinierte Sortier-Algorithmen
|
||||
class CustomSortingPlugin:
|
||||
def sort_jobs(self, jobs: List[Job]) -> List[Job]:
|
||||
# Benutzerdefinierte Sortierlogik
|
||||
return sorted_jobs
|
||||
```
|
||||
|
||||
## 🎯 Zusammenfassung
|
||||
|
||||
Das Drag & Drop System für Job-Reihenfolge-Verwaltung ist vollständig implementiert und bietet:
|
||||
|
||||
✅ **Vollständige Persistierung** - Alle Änderungen werden in der Datenbank gespeichert
|
||||
✅ **Benutzerfreundliche API** - RESTful Endpoints für einfache Frontend-Integration
|
||||
✅ **Robuste Berechtigungen** - Sichere Zugriffskontrolle und Validierung
|
||||
✅ **Optimierte Performance** - Caching und effiziente Datenbankabfragen
|
||||
✅ **Wartungsfreundlich** - Automatische Bereinigung und Monitoring
|
||||
✅ **Erweiterbar** - Modularer Aufbau für zukünftige Features
|
||||
|
||||
Die Implementierung ist produktionsreif und kann sofort verwendet werden. Alle Funktionen sind getestet und dokumentiert.
|
Reference in New Issue
Block a user