fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
202
backend/PLAN_KLAUSURKORREKTUR.md
Normal file
202
backend/PLAN_KLAUSURKORREKTUR.md
Normal file
@@ -0,0 +1,202 @@
|
||||
# Klausurkorrektur - Privacy-by-Design Implementation Plan
|
||||
|
||||
## Übersicht
|
||||
|
||||
Implementierung eines DSGVO-konformen Klausurkorrektur-Moduls mit QR-Code-basierter Pseudonymisierung. Keine personenbezogenen Daten werden an das LLM gesendet.
|
||||
|
||||
## Architektur-Prinzipien
|
||||
|
||||
1. **Pseudonymisierung (Art. 4 Nr. 5 DSGVO)**: `doc_token` (128-bit random) als einziger Join-Key
|
||||
2. **Teacher Namespace Isolation**: Jeder Lehrer hat isolierten Workspace
|
||||
3. **Privacy by Architecture**: Backend kann Schüler nicht identifizieren
|
||||
4. **Self-hosted LLM**: SysEleven, kein OpenAI/externe Datenübertragung
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Backend-Infrastruktur
|
||||
|
||||
### 1.1 Datenmodelle erstellen
|
||||
**Datei**: `/backend/klausur/db_models.py` (NEU)
|
||||
|
||||
```python
|
||||
# Modelle:
|
||||
- ExamSession: teacher_id, session_id, created_at, status
|
||||
- PseudonymizedDocument: doc_token (UUID), session_id, ocr_text, ai_feedback, created_at
|
||||
- TeacherVault: teacher_id, encrypted_identity_map (lokal verschlüsselt)
|
||||
```
|
||||
|
||||
### 1.2 Repository-Klasse
|
||||
**Datei**: `/backend/klausur/repository.py` (NEU)
|
||||
|
||||
- CRUD für ExamSession, PseudonymizedDocument
|
||||
- Teacher-Isolation durch `teacher_id` Filter
|
||||
- Keine Speicherung von Klarnamen im Backend
|
||||
|
||||
### 1.3 Pseudonymisierung-Service
|
||||
**Datei**: `/backend/klausur/services/pseudonymizer.py` (NEU)
|
||||
|
||||
```python
|
||||
class PseudonymizationService:
|
||||
def generate_doc_token() -> str # 128-bit UUID
|
||||
def generate_qr_overlay(doc_token: str) -> bytes # QR-Code PNG
|
||||
def redact_header(image: bytes) -> bytes # Entfernt Kopfzeile mit Namen
|
||||
def extract_doc_token_from_qr(image: bytes) -> str # QR-Code lesen
|
||||
```
|
||||
|
||||
### 1.4 OCR-Integration erweitern
|
||||
**Datei**: `/backend/services/file_processor.py` (ERWEITERN)
|
||||
|
||||
- Neue Methode: `process_exam_page(image, redact_header=True)`
|
||||
- Integration mit PaddleOCR für Handschrift
|
||||
- Header-Redaction vor OCR
|
||||
|
||||
### 1.5 LLM-Korrektur-Service
|
||||
**Datei**: `/backend/klausur/services/correction_service.py` (NEU)
|
||||
|
||||
```python
|
||||
class ExamCorrectionService:
|
||||
def correct_answer(doc_token: str, question: str, student_answer: str, rubric: str) -> CorrectionResult
|
||||
def batch_correct(session_id: str) -> List[CorrectionResult]
|
||||
```
|
||||
|
||||
- Nutzt bestehenden LLM-Gateway (Ollama/vLLM)
|
||||
- Nur pseudonymisierte Texte werden gesendet
|
||||
- `doc_token` als einzige Referenz
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: API-Endpunkte
|
||||
|
||||
### 2.1 Klausur-API
|
||||
**Datei**: `/backend/klausur/routes.py` (NEU)
|
||||
|
||||
```
|
||||
POST /api/klausur/session # Neue Korrektur-Session erstellen
|
||||
GET /api/klausur/session/{session_id} # Session-Status abrufen
|
||||
POST /api/klausur/session/{session_id}/upload # Gescannte Seiten hochladen
|
||||
GET /api/klausur/session/{session_id}/qr-sheet # QR-Overlay-Bogen generieren
|
||||
POST /api/klausur/session/{session_id}/process # OCR + KI-Korrektur starten
|
||||
GET /api/klausur/session/{session_id}/results # Pseudonymisierte Ergebnisse
|
||||
DELETE /api/klausur/session/{session_id} # Session löschen
|
||||
```
|
||||
|
||||
### 2.2 Teacher Vault API (Client-seitig)
|
||||
**Datei**: `/backend/klausur/routes.py`
|
||||
|
||||
```
|
||||
POST /api/klausur/vault/encrypt # Identity-Map clientseitig verschlüsseln
|
||||
POST /api/klausur/vault/decrypt # Identity-Map clientseitig entschlüsseln
|
||||
```
|
||||
|
||||
- Server speichert nur verschlüsselte Blobs
|
||||
- Schlüssel bleibt beim Lehrer (Browser/LocalStorage)
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: PWA Frontend-Modul
|
||||
|
||||
### 3.1 Klausurkorrektur-Modul ersetzen
|
||||
**Datei**: `/backend/frontend/modules/klausur_korrektur.py` (ÜBERSCHREIBEN)
|
||||
|
||||
**Tabs im Modul**:
|
||||
1. **Neue Session**: QR-Bogen generieren, Schülerliste eingeben
|
||||
2. **Upload**: Gescannte Klausuren hochladen (Drag & Drop)
|
||||
3. **Verarbeitung**: OCR + KI-Korrektur Status
|
||||
4. **Ergebnisse**: Pseudonymisierte Bewertungen → Re-Join mit lokaler Identity-Map
|
||||
5. **Export**: Excel/PDF Export der Ergebnisse
|
||||
|
||||
### 3.2 Identity-Map (Teacher Vault)
|
||||
**Client-seitig in JavaScript**:
|
||||
|
||||
```javascript
|
||||
class TeacherVault {
|
||||
constructor(teacherId)
|
||||
generateIdentityMap(studentNames) // Erstellt doc_token → Name Mapping
|
||||
encrypt(password) // AES-256 Verschlüsselung im Browser
|
||||
decrypt(password) // Entschlüsselung im Browser
|
||||
rejoinResults(pseudonymizedResults) // Verknüpft Ergebnisse mit Namen
|
||||
exportToLocalStorage()
|
||||
importFromLocalStorage()
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 QR-Code Workflow
|
||||
**UI-Flow**:
|
||||
1. Lehrer gibt Schülerliste ein (Namen)
|
||||
2. System generiert für jeden Schüler einen `doc_token`
|
||||
3. Identity-Map wird lokal im Browser verschlüsselt gespeichert
|
||||
4. QR-Bogen wird zum Ausdrucken generiert (jeder QR = ein doc_token)
|
||||
5. Schüler kleben QR auf ihre Klausur
|
||||
6. Nach Scan: QR wird erkannt, Header redacted, nur Text an LLM
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Admin-Panel Integration
|
||||
|
||||
### 4.1 GPU/LLM-Tab erweitern
|
||||
**Datei**: `/backend/frontend/components/admin_gpu.py` (ERWEITERN)
|
||||
|
||||
Neue Abschnitte:
|
||||
- **Klausur-Queue**: Warteschlange der Korrektur-Jobs
|
||||
- **LLM-Status**: Verbindung zu SysEleven vLLM
|
||||
- **OCR-Status**: PaddleOCR Verfügbarkeit
|
||||
- **Session-Übersicht**: Aktive Korrektur-Sessions (nur Anzahl, keine Namen)
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Sicherheits-Features
|
||||
|
||||
### 5.1 Zero-Knowledge Design
|
||||
- Backend speichert niemals Klarnamen
|
||||
- Identity-Map nur verschlüsselt (Client-Key)
|
||||
- doc_token ist kryptografisch zufällig (UUID4)
|
||||
- Keine Korrelation zwischen Sessions möglich
|
||||
|
||||
### 5.2 Daten-Retention
|
||||
- Pseudonymisierte Daten: 30 Tage, dann auto-delete
|
||||
- Verschlüsselte Vault-Daten: Lehrer kann jederzeit löschen
|
||||
- Audit-Log ohne PII
|
||||
|
||||
### 5.3 Teacher-Isolation
|
||||
- Alle Queries gefiltert nach `teacher_id`
|
||||
- Kein Cross-Teacher-Zugriff möglich
|
||||
- Row-Level Security in PostgreSQL
|
||||
|
||||
---
|
||||
|
||||
## Implementierungs-Reihenfolge
|
||||
|
||||
1. **Backend-Modelle** (`/backend/klausur/db_models.py`)
|
||||
2. **Repository** (`/backend/klausur/repository.py`)
|
||||
3. **Pseudonymizer-Service** (`/backend/klausur/services/pseudonymizer.py`)
|
||||
4. **Correction-Service** (`/backend/klausur/services/correction_service.py`)
|
||||
5. **API-Routes** (`/backend/klausur/routes.py`)
|
||||
6. **PWA-Modul** (`/backend/frontend/modules/klausur_korrektur.py`)
|
||||
7. **TeacherVault JS** (eingebettet in Modul)
|
||||
8. **Admin-Panel** (`/backend/frontend/components/admin_gpu.py`)
|
||||
9. **Tests** (`/backend/klausur/tests/`)
|
||||
10. **Migration** (Alembic für neue Tabellen)
|
||||
|
||||
---
|
||||
|
||||
## Technologie-Stack
|
||||
|
||||
| Komponente | Technologie |
|
||||
|------------|-------------|
|
||||
| QR-Code | `qrcode` + `Pillow` |
|
||||
| OCR | PaddleOCR (bereits vorhanden) |
|
||||
| Verschlüsselung (Client) | Web Crypto API (AES-256-GCM) |
|
||||
| Verschlüsselung (Server) | `cryptography` (Fernet) |
|
||||
| LLM | vLLM @ SysEleven (via llm_gateway) |
|
||||
| DB | PostgreSQL + SQLAlchemy |
|
||||
|
||||
---
|
||||
|
||||
## Datenschutz-Garantien
|
||||
|
||||
✅ Keine Schülernamen im Backend gespeichert
|
||||
✅ Keine Schülernamen an LLM gesendet
|
||||
✅ Identity-Map nur verschlüsselt (Client-Schlüssel)
|
||||
✅ Teacher-Namespace-Isolation
|
||||
✅ Automatische Daten-Löschung nach 30 Tagen
|
||||
✅ Vergleichbar mit lokaler PC-Verarbeitung (Art. 4 Nr. 5 DSGVO)
|
||||
Reference in New Issue
Block a user