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>
1362 lines
25 KiB
Markdown
1362 lines
25 KiB
Markdown
# BreakPilot Backend API Dokumentation
|
|
|
|
## Übersicht
|
|
|
|
Base URL: `http://localhost:8000/api`
|
|
|
|
Alle Endpoints erfordern Authentifizierung via JWT im Authorization-Header:
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
---
|
|
|
|
## Worksheets API
|
|
|
|
Generiert Lernmaterialien (MC-Tests, Lückentexte, Mindmaps, Quiz).
|
|
|
|
### POST /worksheets/generate/multiple-choice
|
|
|
|
Generiert Multiple-Choice-Fragen aus Quelltext.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"source_text": "Der Text, aus dem Fragen generiert werden sollen...",
|
|
"num_questions": 5,
|
|
"difficulty": "medium",
|
|
"topic": "Thema",
|
|
"subject": "Deutsch"
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"content": {
|
|
"type": "multiple_choice",
|
|
"data": {
|
|
"questions": [
|
|
{
|
|
"question": "Was ist...?",
|
|
"options": ["A", "B", "C", "D"],
|
|
"correct": 0,
|
|
"explanation": "Erklärung..."
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /worksheets/generate/cloze
|
|
|
|
Generiert Lückentexte.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"source_text": "Quelltext...",
|
|
"num_gaps": 5,
|
|
"gap_type": "word",
|
|
"hint_type": "first_letter"
|
|
}
|
|
```
|
|
|
|
### POST /worksheets/generate/mindmap
|
|
|
|
Generiert Mindmap als Mermaid-Diagramm.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"source_text": "Quelltext...",
|
|
"max_branches": 5,
|
|
"depth": 2
|
|
}
|
|
```
|
|
|
|
### POST /worksheets/generate/quiz
|
|
|
|
Generiert Mix aus verschiedenen Fragetypen.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"source_text": "Quelltext...",
|
|
"num_questions": 5,
|
|
"include_types": ["mc", "open", "truefalse"]
|
|
}
|
|
```
|
|
|
|
### POST /worksheets/generate/batch
|
|
|
|
Generiert mehrere Inhaltstypen gleichzeitig.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"source_text": "Quelltext...",
|
|
"types": ["multiple_choice", "cloze", "mindmap"]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Corrections API
|
|
|
|
OCR-basierte Klausurkorrektur mit automatischer Bewertung.
|
|
|
|
### POST /corrections/
|
|
|
|
Erstellt neue Korrektur-Session.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"student_id": "student-123",
|
|
"student_name": "Max Mustermann",
|
|
"class_name": "10a",
|
|
"exam_title": "Klassenarbeit Nr. 3",
|
|
"subject": "Mathematik",
|
|
"max_points": 100
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"correction": {
|
|
"id": "uuid",
|
|
"status": "uploaded",
|
|
"student_name": "Max Mustermann",
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /corrections/{id}/upload
|
|
|
|
Lädt gescannte Klausur hoch und startet OCR im Hintergrund.
|
|
|
|
**Request (multipart/form-data):**
|
|
- `file`: PDF/PNG/JPG Datei
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"correction": {
|
|
"id": "uuid",
|
|
"status": "processing"
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /corrections/{id}
|
|
|
|
Ruft Korrektur-Status ab.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"correction": {
|
|
"id": "uuid",
|
|
"status": "ocr_complete",
|
|
"extracted_text": "Erkannter Text...",
|
|
"evaluations": [],
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
**Status-Werte:**
|
|
- `uploaded` - Datei hochgeladen
|
|
- `processing` - OCR läuft
|
|
- `ocr_complete` - OCR fertig
|
|
- `analyzing` - Analyse läuft
|
|
- `analyzed` - Analyse abgeschlossen
|
|
- `reviewing` - In Review
|
|
- `completed` - Fertig
|
|
- `error` - Fehler
|
|
|
|
### POST /corrections/{id}/analyze
|
|
|
|
Analysiert extrahierten Text und bewertet Antworten.
|
|
|
|
**Request Body (optional):**
|
|
```json
|
|
{
|
|
"expected_answers": {
|
|
"1": "Musterlösung für Aufgabe 1",
|
|
"2": "Musterlösung für Aufgabe 2"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"evaluations": [
|
|
{
|
|
"question_number": 1,
|
|
"extracted_text": "Schülerantwort...",
|
|
"points_possible": 10,
|
|
"points_awarded": 8,
|
|
"feedback": "Gut gelöst...",
|
|
"is_correct": true,
|
|
"confidence": 0.85
|
|
}
|
|
],
|
|
"total_points": 85,
|
|
"percentage": 85.0,
|
|
"suggested_grade": "2",
|
|
"ai_feedback": "Insgesamt gute Arbeit..."
|
|
}
|
|
```
|
|
|
|
### PUT /corrections/{id}
|
|
|
|
Aktualisiert Korrektur (manuelle Anpassungen).
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"evaluations": [...],
|
|
"total_points": 90,
|
|
"grade": "1",
|
|
"teacher_notes": "Sehr gute Verbesserung",
|
|
"status": "reviewing"
|
|
}
|
|
```
|
|
|
|
### POST /corrections/{id}/complete
|
|
|
|
Markiert Korrektur als abgeschlossen.
|
|
|
|
### GET /corrections/{id}/export-pdf
|
|
|
|
Exportiert korrigierte Arbeit als PDF.
|
|
|
|
**Response:** `application/pdf`
|
|
|
|
### GET /corrections/class/{class_name}/summary
|
|
|
|
Klassenübersicht mit Statistiken.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"class_name": "10a",
|
|
"total_students": 25,
|
|
"average_percentage": 72.5,
|
|
"average_points": 72.5,
|
|
"grade_distribution": {"1": 2, "2": 8, "3": 10, "4": 4, "5": 1},
|
|
"corrections": [...]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Letters API
|
|
|
|
Elternbriefe mit GFK-Integration und PDF-Export.
|
|
|
|
### POST /letters/
|
|
|
|
Erstellt neuen Elternbrief.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"recipient_name": "Familie Müller",
|
|
"recipient_address": "Musterstr. 1, 12345 Stadt",
|
|
"student_name": "Max Müller",
|
|
"student_class": "7a",
|
|
"subject": "Information zum Leistungsstand",
|
|
"content": "Sehr geehrte Eltern...",
|
|
"letter_type": "halbjahr",
|
|
"tone": "professional",
|
|
"teacher_name": "Frau Schmidt",
|
|
"teacher_title": "Klassenlehrerin"
|
|
}
|
|
```
|
|
|
|
**letter_type Werte:**
|
|
- `general` - Allgemeine Information
|
|
- `halbjahr` - Halbjahresinformation
|
|
- `fehlzeiten` - Fehlzeiten-Mitteilung
|
|
- `elternabend` - Einladung Elternabend
|
|
- `lob` - Positives Feedback
|
|
- `custom` - Benutzerdefiniert
|
|
|
|
**tone Werte:**
|
|
- `formal` - Sehr förmlich
|
|
- `professional` - Professionell-freundlich
|
|
- `warm` - Warmherzig
|
|
- `concerned` - Besorgt
|
|
- `appreciative` - Wertschätzend
|
|
|
|
### GET /letters/{id}
|
|
|
|
Lädt gespeicherten Brief.
|
|
|
|
### GET /letters/
|
|
|
|
Listet alle Briefe (mit Filterung).
|
|
|
|
**Query Parameter:**
|
|
- `class_name` - Filter nach Klasse
|
|
- `letter_type` - Filter nach Typ
|
|
- `status` - Filter nach Status (draft/sent/archived)
|
|
- `page` - Seitennummer
|
|
- `page_size` - Einträge pro Seite
|
|
|
|
### PUT /letters/{id}
|
|
|
|
Aktualisiert Brief.
|
|
|
|
### DELETE /letters/{id}
|
|
|
|
Löscht Brief.
|
|
|
|
### POST /letters/export-pdf
|
|
|
|
Exportiert Brief als PDF.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"letter_id": "uuid"
|
|
}
|
|
```
|
|
oder
|
|
```json
|
|
{
|
|
"letter_data": { ... }
|
|
}
|
|
```
|
|
|
|
**Response:** `application/pdf`
|
|
|
|
### POST /letters/improve
|
|
|
|
Verbessert Text nach GFK-Prinzipien.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"content": "Text zur Verbesserung...",
|
|
"communication_type": "general_info",
|
|
"tone": "professional"
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"improved_content": "Verbesserter Text...",
|
|
"changes": ["Hinweis 1", "Hinweis 2"],
|
|
"gfk_score": 0.85,
|
|
"gfk_principles_applied": ["Ich-Botschaften", "Offene Fragen"]
|
|
}
|
|
```
|
|
|
|
### POST /letters/{id}/send
|
|
|
|
Versendet Brief per Email.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"letter_id": "uuid",
|
|
"recipient_email": "eltern@example.com",
|
|
"cc_emails": ["schulleitung@example.com"],
|
|
"include_pdf": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## State Engine API
|
|
|
|
Begleiter-Modus mit Phasen-Management und Antizipation.
|
|
|
|
### GET /state/context
|
|
|
|
Ruft Lehrer-Kontext ab.
|
|
|
|
**Query Parameter:**
|
|
- `teacher_id` (required)
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"context": {
|
|
"teacher_id": "xxx",
|
|
"current_phase": "school_year_start",
|
|
"completed_milestones": ["consent_accept", "profile_complete"],
|
|
"classes": [...],
|
|
"stats": {...}
|
|
},
|
|
"phase_info": {
|
|
"name": "Schuljahresbeginn",
|
|
"description": "..."
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /state/phase
|
|
|
|
Ruft aktuelle Phase ab.
|
|
|
|
### GET /state/phases
|
|
|
|
Listet alle verfügbaren Phasen.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"phases": [
|
|
{"id": "onboarding", "name": "Onboarding", "description": "..."},
|
|
{"id": "school_year_start", "name": "Schuljahresbeginn", "description": "..."},
|
|
...
|
|
]
|
|
}
|
|
```
|
|
|
|
### GET /state/suggestions
|
|
|
|
Ruft Vorschläge für Lehrer ab.
|
|
|
|
**Query Parameter:**
|
|
- `teacher_id` (required)
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"suggestions": [
|
|
{
|
|
"id": "create_first_class",
|
|
"title": "Erste Klasse anlegen",
|
|
"description": "...",
|
|
"priority": "urgent",
|
|
"category": "setup",
|
|
"action": {"type": "navigate", "target": "/school"}
|
|
}
|
|
],
|
|
"current_phase": "school_year_start",
|
|
"priority_counts": {"urgent": 1, "high": 2, "medium": 3}
|
|
}
|
|
```
|
|
|
|
### GET /state/suggestions/top
|
|
|
|
Ruft wichtigsten Vorschlag ab.
|
|
|
|
### GET /state/dashboard
|
|
|
|
Komplettes Dashboard für Begleiter-Modus.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"context": {...},
|
|
"suggestions": [...],
|
|
"stats": {...},
|
|
"progress": {
|
|
"milestones_completed": 3,
|
|
"milestones_total": 5
|
|
},
|
|
"phases": [...]
|
|
}
|
|
```
|
|
|
|
### POST /state/milestone
|
|
|
|
Schließt Meilenstein ab.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"milestone": "consent_accept"
|
|
}
|
|
```
|
|
|
|
### POST /state/transition
|
|
|
|
Manueller Phasenübergang.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"target_phase": "teaching_setup"
|
|
}
|
|
```
|
|
|
|
### GET /state/next-phase
|
|
|
|
Zeigt nächste Phase und Bedingungen.
|
|
|
|
---
|
|
|
|
## Schuljahr-Phasen
|
|
|
|
| Phase | ID | Beschreibung |
|
|
|-------|-----|--------------|
|
|
| Onboarding | `onboarding` | Ersteinrichtung |
|
|
| Schuljahresbeginn | `school_year_start` | Klassen anlegen |
|
|
| Unterrichtsvorbereitung | `teaching_setup` | Materialien erstellen |
|
|
| 1. Leistungsphase | `performance_1` | Tests & Klausuren |
|
|
| Halbjahr | `semester_end` | Zeugnisse |
|
|
| 2. Leistungsphase | `performance_2` | Tests & Klausuren |
|
|
| Prüfungsphase | `exam_phase` | Abschlussprüfungen |
|
|
| Schuljahresende | `year_end` | Abschluss |
|
|
| Archiviert | `archived` | Abgeschlossen |
|
|
|
|
---
|
|
|
|
## Klausur-Korrektur API (Abitur)
|
|
|
|
Abitur-Klausurkorrektur mit 15-Punkte-System, Erst-/Zweitprüfer-Workflow und KI-gestützter Bewertung.
|
|
|
|
### Klausur-Modi
|
|
|
|
| Modus | Beschreibung |
|
|
|-------|--------------|
|
|
| `landes_abitur` | NiBiS Niedersachsen - rechtlich geklärte Aufgaben |
|
|
| `vorabitur` | Lehrer-erstellte Klausuren mit Rights-Gate |
|
|
|
|
### POST /klausur-korrektur/klausuren
|
|
|
|
Erstellt neue Abitur-Klausur.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"title": "Deutsch LK Q4",
|
|
"subject": "deutsch",
|
|
"modus": "landes_abitur",
|
|
"year": 2025,
|
|
"semester": "Q4"
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"klausur": {
|
|
"id": "uuid",
|
|
"title": "Deutsch LK Q4",
|
|
"modus": "landes_abitur",
|
|
"status": "draft",
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /klausur-korrektur/klausuren
|
|
|
|
Listet alle Klausuren.
|
|
|
|
**Query Parameter:**
|
|
- `subject` - Filter nach Fach
|
|
- `year` - Filter nach Jahr
|
|
- `status` - Filter nach Status
|
|
|
|
### GET /klausur-korrektur/klausuren/{id}
|
|
|
|
Ruft Klausur-Details ab.
|
|
|
|
### PUT /klausur-korrektur/klausuren/{id}
|
|
|
|
Aktualisiert Klausur.
|
|
|
|
### DELETE /klausur-korrektur/klausuren/{id}
|
|
|
|
Löscht Klausur.
|
|
|
|
### POST /klausur-korrektur/klausuren/{id}/text-sources
|
|
|
|
Fügt Text-Quelle hinzu (Vorabitur-Modus).
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"source_type": "eigentext",
|
|
"title": "Kafka - Die Verwandlung",
|
|
"author": "Franz Kafka",
|
|
"content": "Als Gregor Samsa eines Morgens..."
|
|
}
|
|
```
|
|
|
|
### POST /klausur-korrektur/text-sources/{id}/verify
|
|
|
|
Prüft Text-Quelle mit Rights-Gate.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"verified": true,
|
|
"license_status": "verified",
|
|
"license_info": {
|
|
"license": "PD",
|
|
"source": "Projekt Gutenberg"
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /klausur-korrektur/nibis/aufgaben
|
|
|
|
Listet verfügbare NiBiS-Aufgaben.
|
|
|
|
**Query Parameter:**
|
|
- `fach` - Filter nach Fach
|
|
- `jahr` - Filter nach Jahr
|
|
- `niveau` - Filter nach Niveau (eA/gA)
|
|
|
|
### POST /klausur-korrektur/klausuren/{id}/erwartungshorizont/generate
|
|
|
|
Generiert Erwartungshorizont mit KI.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"aufgabenstellung": "Analysieren Sie den vorliegenden Text...",
|
|
"text_context": "Kafka - Die Verwandlung..."
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"erwartungshorizont": {
|
|
"aufgaben": [
|
|
{
|
|
"nummer": "1",
|
|
"operator": "analysieren",
|
|
"anforderungsbereich": 2,
|
|
"erwartete_leistungen": ["Erkennt den Erzähler", "..."],
|
|
"punkte": 30
|
|
}
|
|
],
|
|
"max_points": 100
|
|
}
|
|
}
|
|
```
|
|
|
|
### PUT /klausur-korrektur/klausuren/{id}/erwartungshorizont
|
|
|
|
Aktualisiert Erwartungshorizont manuell.
|
|
|
|
### POST /klausur-korrektur/klausuren/{id}/students
|
|
|
|
Lädt Schülerarbeit hoch.
|
|
|
|
**Request (multipart/form-data):**
|
|
- `file`: PDF/PNG/JPG Datei
|
|
- `student_name`: Name des Schülers
|
|
|
|
### POST /klausur-korrektur/students/{id}/ocr
|
|
|
|
Startet OCR für Schülerarbeit.
|
|
|
|
### POST /klausur-korrektur/students/{id}/evaluate
|
|
|
|
Startet KI-Bewertung.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"criteria_scores": {
|
|
"rechtschreibung": {"score": 85, "weight": 0.15, "annotations": ["..."]},
|
|
"grammatik": {"score": 90, "weight": 0.15, "annotations": ["..."]},
|
|
"inhalt": {"score": 75, "weight": 0.40, "annotations": ["..."]},
|
|
"struktur": {"score": 80, "weight": 0.15, "annotations": ["..."]},
|
|
"stil": {"score": 85, "weight": 0.15, "annotations": ["..."]}
|
|
},
|
|
"raw_points": 80,
|
|
"grade_points": 11,
|
|
"grade_label": "2"
|
|
}
|
|
```
|
|
|
|
### PUT /klausur-korrektur/students/{id}/criteria
|
|
|
|
Passt Bewertungskriterien manuell an.
|
|
|
|
### POST /klausur-korrektur/students/{id}/annotations
|
|
|
|
Fügt Annotation zu Dokument hinzu.
|
|
|
|
### POST /klausur-korrektur/students/{id}/gutachten/generate
|
|
|
|
Generiert Gutachten mit KI.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"gutachten": {
|
|
"einleitung": "Die vorliegende Arbeit...",
|
|
"hauptteil": "Der Verfasser zeigt...",
|
|
"fazit": "Zusammenfassend lässt sich...",
|
|
"staerken": ["Gute Argumentation", "..."],
|
|
"schwaechen": ["Rechtschreibfehler", "..."]
|
|
}
|
|
}
|
|
```
|
|
|
|
### PUT /klausur-korrektur/students/{id}/gutachten
|
|
|
|
Bearbeitet Gutachten manuell.
|
|
|
|
### POST /klausur-korrektur/students/{id}/grade
|
|
|
|
Berechnet 15-Punkte-Note.
|
|
|
|
### PUT /klausur-korrektur/students/{id}/finalize
|
|
|
|
Schließt Bewertung ab.
|
|
|
|
### POST /klausur-korrektur/students/{id}/examiner
|
|
|
|
Weist Erst-/Zweitprüfer zu.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"examiner_type": "first",
|
|
"examiner_id": "teacher-uuid"
|
|
}
|
|
```
|
|
|
|
### GET /klausur-korrektur/examiner/queue
|
|
|
|
Listet Prüfer-Warteschlange.
|
|
|
|
### GET /klausur-korrektur/klausuren/{id}/fairness
|
|
|
|
Vergleichsanalyse aller Schüler.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"average_score": 75.5,
|
|
"median_score": 76,
|
|
"standard_deviation": 8.2,
|
|
"grade_distribution": {"15": 1, "14": 2, "13": 4, ...},
|
|
"outliers": ["student-uuid-1", "student-uuid-2"]
|
|
}
|
|
```
|
|
|
|
### POST /klausur-korrektur/klausuren/{id}/export
|
|
|
|
Exportiert Klausur als PDF.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"include_gutachten": true,
|
|
"include_annotations": true
|
|
}
|
|
```
|
|
|
|
**Response:** `application/pdf`
|
|
|
|
### 15-Punkte-Notenschlüssel
|
|
|
|
| Punkte | Prozent | Note |
|
|
|--------|---------|------|
|
|
| 15 | ≥95% | 1+ |
|
|
| 14 | ≥90% | 1 |
|
|
| 13 | ≥85% | 1- |
|
|
| 12 | ≥80% | 2+ |
|
|
| 11 | ≥75% | 2 |
|
|
| 10 | ≥70% | 2- |
|
|
| 9 | ≥65% | 3+ |
|
|
| 8 | ≥60% | 3 |
|
|
| 7 | ≥55% | 3- |
|
|
| 6 | ≥50% | 4+ |
|
|
| 5 | ≥45% | 4 |
|
|
| 4 | ≥40% | 4- |
|
|
| 3 | ≥33% | 5+ |
|
|
| 2 | ≥27% | 5 |
|
|
| 1 | ≥20% | 5- |
|
|
| 0 | <20% | 6 |
|
|
|
|
### Bewertungskriterien
|
|
|
|
| Kriterium | Gewicht | Beschreibung |
|
|
|-----------|---------|--------------|
|
|
| `rechtschreibung` | 15% | Orthografie |
|
|
| `grammatik` | 15% | Grammatik & Syntax |
|
|
| `inhalt` | 40% | Inhaltliche Qualität |
|
|
| `struktur` | 15% | Aufbau & Gliederung |
|
|
| `stil` | 15% | Ausdruck & Stil |
|
|
|
|
---
|
|
|
|
## Abitur-Docs API (Admin)
|
|
|
|
Verwaltung von Abitur-Dokumenten (NiBiS Niedersachsen) für RAG-System.
|
|
|
|
### GET /abitur-docs/documents
|
|
|
|
Listet alle Dokumente.
|
|
|
|
**Query Parameter:**
|
|
- `jahr` - Filter nach Jahr
|
|
- `fach` - Filter nach Fach
|
|
- `niveau` - Filter nach Niveau (eA/gA)
|
|
- `status` - Filter nach Status (pending/recognized/confirmed/indexed)
|
|
- `search` - Suche im Dateinamen
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"documents": [
|
|
{
|
|
"id": "uuid",
|
|
"filename": "2025_Deutsch_eA_I_EWH.pdf",
|
|
"status": "confirmed",
|
|
"metadata": {
|
|
"jahr": 2025,
|
|
"bundesland": "niedersachsen",
|
|
"fach": "deutsch",
|
|
"niveau": "eA",
|
|
"dokument_typ": "erwartungshorizont",
|
|
"aufgaben_nummer": "I"
|
|
},
|
|
"recognition_result": {
|
|
"confidence": 0.95,
|
|
"extracted": {...},
|
|
"method": "filename_pattern"
|
|
}
|
|
}
|
|
],
|
|
"total": 150
|
|
}
|
|
```
|
|
|
|
### GET /abitur-docs/documents/{id}
|
|
|
|
Ruft Dokument-Details ab.
|
|
|
|
### POST /abitur-docs/documents
|
|
|
|
Lädt einzelnes Dokument hoch.
|
|
|
|
**Request (multipart/form-data):**
|
|
- `file`: PDF Datei
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"document": {
|
|
"id": "uuid",
|
|
"filename": "...",
|
|
"status": "recognized",
|
|
"recognition_result": {...}
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /abitur-docs/import-zip
|
|
|
|
Importiert ZIP-Datei mit mehreren Dokumenten.
|
|
|
|
**Request (multipart/form-data):**
|
|
- `file`: ZIP Datei
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"imported_count": 45,
|
|
"skipped_count": 2,
|
|
"errors": ["file.xyz: Unbekanntes Format"]
|
|
}
|
|
```
|
|
|
|
### PUT /abitur-docs/documents/{id}/metadata
|
|
|
|
Aktualisiert Dokument-Metadaten.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"jahr": 2025,
|
|
"bundesland": "niedersachsen",
|
|
"fach": "deutsch",
|
|
"niveau": "eA",
|
|
"dokument_typ": "erwartungshorizont",
|
|
"aufgaben_nummer": "I"
|
|
}
|
|
```
|
|
|
|
### POST /abitur-docs/documents/{id}/index
|
|
|
|
Indexiert Dokument für RAG-System.
|
|
|
|
### DELETE /abitur-docs/documents/{id}
|
|
|
|
Löscht Dokument.
|
|
|
|
### GET /abitur-docs/documents/{id}/preview
|
|
|
|
Gibt PDF-Vorschau zurück.
|
|
|
|
**Response:** `application/pdf`
|
|
|
|
### GET /abitur-docs/enums
|
|
|
|
Listet verfügbare Enum-Werte für Dropdowns.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"bundeslaender": [
|
|
{"value": "niedersachsen", "label": "Niedersachsen"},
|
|
...
|
|
],
|
|
"faecher": [
|
|
{"value": "deutsch", "label": "Deutsch"},
|
|
...
|
|
],
|
|
"niveaus": [
|
|
{"value": "eA", "label": "eA - erhöhtes Anforderungsniveau"},
|
|
{"value": "gA", "label": "gA - grundlegendes Anforderungsniveau"}
|
|
],
|
|
"dokumenttypen": [
|
|
{"value": "aufgabe", "label": "Aufgabe"},
|
|
{"value": "erwartungshorizont", "label": "Erwartungshorizont"},
|
|
...
|
|
]
|
|
}
|
|
```
|
|
|
|
### GET /abitur-docs/search
|
|
|
|
Sucht Dokumente für Klausur-Korrektur.
|
|
|
|
**Query Parameter:**
|
|
- `fach` (required) - Fach
|
|
- `jahr` - Jahr
|
|
- `niveau` - Niveau
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"documents": [
|
|
{
|
|
"id": "uuid",
|
|
"filename": "...",
|
|
"metadata": {...}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Dokument-Status
|
|
|
|
| Status | Beschreibung |
|
|
|--------|--------------|
|
|
| `pending` | Hochgeladen, nicht erkannt |
|
|
| `recognized` | KI-Erkennung abgeschlossen |
|
|
| `confirmed` | Metadaten bestätigt |
|
|
| `indexed` | Im RAG-System indexiert |
|
|
| `error` | Fehler bei Verarbeitung |
|
|
|
|
### NiBiS Dateinamen-Muster
|
|
|
|
Automatische Erkennung von:
|
|
- `2025_Deutsch_eA_I.pdf` → Deutsch eA Aufgabe I
|
|
- `2025_Deutsch_eA_I_EWH.pdf` → Deutsch eA Erwartungshorizont I
|
|
- `2025_Englisch_gA_Hoerverstehen.pdf` → Englisch gA Hörverstehen
|
|
|
|
---
|
|
|
|
## Security API (DevSecOps Dashboard)
|
|
|
|
API fuer das Security Dashboard mit DevSecOps-Tools Integration.
|
|
|
|
### GET /v1/security/tools
|
|
|
|
Gibt Status aller DevSecOps-Tools zurueck.
|
|
|
|
**Response (200):**
|
|
```json
|
|
[
|
|
{
|
|
"name": "Gitleaks",
|
|
"installed": true,
|
|
"version": "v8.18.0",
|
|
"last_run": "09.01.2025 12:30",
|
|
"last_findings": 0
|
|
}
|
|
]
|
|
```
|
|
|
|
### GET /v1/security/findings
|
|
|
|
Gibt alle Security-Findings zurueck.
|
|
|
|
**Query Parameter:**
|
|
- `tool` (optional): Filter nach Tool (gitleaks, semgrep, bandit, trivy, grype)
|
|
- `severity` (optional): Filter nach Severity (CRITICAL, HIGH, MEDIUM, LOW, INFO)
|
|
- `limit` (optional): Max. Anzahl (default: 100)
|
|
|
|
**Response (200):**
|
|
```json
|
|
[
|
|
{
|
|
"id": "CVE-2023-12345",
|
|
"tool": "trivy",
|
|
"severity": "HIGH",
|
|
"title": "Critical vulnerability in package",
|
|
"message": "requests 2.28.0",
|
|
"file": "requirements.txt",
|
|
"line": null,
|
|
"found_at": "2025-01-09T12:30:00"
|
|
}
|
|
]
|
|
```
|
|
|
|
### GET /v1/security/summary
|
|
|
|
Gibt Severity-Zusammenfassung zurueck.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"critical": 0,
|
|
"high": 2,
|
|
"medium": 5,
|
|
"low": 12,
|
|
"info": 3,
|
|
"total": 22
|
|
}
|
|
```
|
|
|
|
### GET /v1/security/sbom
|
|
|
|
Gibt SBOM (Software Bill of Materials) zurueck.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"components": [
|
|
{
|
|
"name": "fastapi",
|
|
"version": "0.109.0",
|
|
"type": "python",
|
|
"licenses": [{"license": {"id": "MIT"}}]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"timestamp": "2025-01-09T12:30:00"
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /v1/security/history
|
|
|
|
Gibt Scan-Historie zurueck.
|
|
|
|
**Query Parameter:**
|
|
- `limit` (optional): Max. Anzahl (default: 20)
|
|
|
|
**Response (200):**
|
|
```json
|
|
[
|
|
{
|
|
"timestamp": "2025-01-09T12:30:00",
|
|
"title": "Gitleaks Scan",
|
|
"description": "Keine Findings",
|
|
"status": "success"
|
|
}
|
|
]
|
|
```
|
|
|
|
### GET /v1/security/reports/{tool}
|
|
|
|
Gibt vollstaendigen Report eines Tools zurueck.
|
|
|
|
**Path Parameter:**
|
|
- `tool`: Tool-Name (gitleaks, semgrep, bandit, trivy, grype)
|
|
|
|
**Response (200):** Rohes JSON des Tool-Reports
|
|
|
|
### POST /v1/security/scan/{type}
|
|
|
|
Startet einen Security-Scan.
|
|
|
|
**Path Parameter:**
|
|
- `type`: Scan-Typ (secrets, sast, deps, containers, sbom, all)
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"status": "started",
|
|
"scan_type": "all",
|
|
"timestamp": "20250109_123000",
|
|
"message": "Scan 'all' wurde gestartet"
|
|
}
|
|
```
|
|
|
|
### GET /v1/security/health
|
|
|
|
Health-Check fuer Security API.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"tools_installed": 5,
|
|
"tools_total": 6,
|
|
"reports_dir": "/app/security-reports",
|
|
"reports_exist": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Legal Templates API (Admin)
|
|
|
|
Verwaltung von rechtlichen Textbausteinen für den Dokumentengenerator. Die Templates werden aus Open-Source-Repositories (CC0, MIT, CC BY 4.0) ingestiert und für RAG-basierte Dokumentengenerierung verwendet.
|
|
|
|
### GET /api/v1/admin/templates/status
|
|
|
|
Gibt den aktuellen Ingestion-Status zurück.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"collection_exists": true,
|
|
"document_count": 1250,
|
|
"sources_count": 13,
|
|
"last_ingestion": "2026-02-08T10:30:00Z",
|
|
"ingestion_running": false
|
|
}
|
|
```
|
|
|
|
### GET /api/v1/admin/templates/sources
|
|
|
|
Listet alle konfigurierten Template-Quellen.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"sources": [
|
|
{
|
|
"name": "github-site-policy",
|
|
"repo_url": "https://github.com/github/site-policy",
|
|
"license_type": "cc0",
|
|
"license_name": "CC0 1.0 Universal",
|
|
"template_types": ["terms_of_service", "privacy_policy"],
|
|
"languages": ["en"],
|
|
"jurisdiction": "US",
|
|
"attribution_required": false,
|
|
"document_count": 45
|
|
}
|
|
],
|
|
"total_sources": 13
|
|
}
|
|
```
|
|
|
|
### GET /api/v1/admin/templates/licenses
|
|
|
|
Gibt Lizenz-Statistiken zurück.
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"licenses": {
|
|
"cc0": {
|
|
"count": 450,
|
|
"attribution_required": false,
|
|
"sources": ["github-site-policy", "opr-vc"]
|
|
},
|
|
"mit": {
|
|
"count": 380,
|
|
"attribution_required": true,
|
|
"sources": ["webflorist-privacy-policy"]
|
|
},
|
|
"cc_by_4": {
|
|
"count": 220,
|
|
"attribution_required": true,
|
|
"sources": ["common-paper"]
|
|
}
|
|
},
|
|
"total_documents": 1250
|
|
}
|
|
```
|
|
|
|
### POST /api/v1/admin/templates/ingest
|
|
|
|
Startet vollständige Ingestion aller Quellen im Hintergrund.
|
|
|
|
**Response (202):**
|
|
```json
|
|
{
|
|
"status": "started",
|
|
"message": "Ingestion für 13 Quellen gestartet",
|
|
"task_id": "uuid",
|
|
"sources_count": 13
|
|
}
|
|
```
|
|
|
|
### POST /api/v1/admin/templates/ingest-source
|
|
|
|
Ingestiert eine einzelne Quelle.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"source_name": "github-site-policy"
|
|
}
|
|
```
|
|
|
|
**Response (202):**
|
|
```json
|
|
{
|
|
"status": "started",
|
|
"message": "Ingestion für github-site-policy gestartet",
|
|
"source": "github-site-policy"
|
|
}
|
|
```
|
|
|
|
### POST /api/v1/admin/templates/search
|
|
|
|
Semantische Suche in Templates mit Lizenz-Filtern.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"query": "Datenschutzerklärung DSGVO konform",
|
|
"template_type": "privacy_policy",
|
|
"license_types": ["cc0", "mit"],
|
|
"language": "de",
|
|
"jurisdiction": "DE",
|
|
"attribution_required": false,
|
|
"limit": 10
|
|
}
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"results": [
|
|
{
|
|
"id": "uuid",
|
|
"text": "Diese Datenschutzerklärung informiert Sie...",
|
|
"score": 0.92,
|
|
"template_type": "privacy_policy",
|
|
"license_id": "cc0",
|
|
"license_name": "CC0 1.0 Universal",
|
|
"source_name": "opr-vc",
|
|
"source_url": "https://opr.vc/docs/dsgvo",
|
|
"language": "de",
|
|
"jurisdiction": "DE",
|
|
"attribution_required": false,
|
|
"attribution_text": null,
|
|
"placeholders": ["[FIRMENNAME]", "[ADRESSE]"]
|
|
}
|
|
],
|
|
"total": 45
|
|
}
|
|
```
|
|
|
|
### DELETE /api/v1/admin/templates/reset
|
|
|
|
Leert die gesamte Collection. **Vorsicht: Alle Templates werden gelöscht!**
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Collection bp_legal_templates geleert",
|
|
"deleted_count": 1250
|
|
}
|
|
```
|
|
|
|
### DELETE /api/v1/admin/templates/source/{source_name}
|
|
|
|
Löscht alle Dokumente einer bestimmten Quelle.
|
|
|
|
**Path Parameter:**
|
|
- `source_name`: Name der Quelle (z.B. "github-site-policy")
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "45 Dokumente von github-site-policy gelöscht",
|
|
"deleted_count": 45
|
|
}
|
|
```
|
|
|
|
### Lizenz-Typen
|
|
|
|
| Typ | Beschreibung | Attribution |
|
|
|-----|--------------|-------------|
|
|
| `public_domain` | Amtliche Werke (§5 UrhG) | Nein |
|
|
| `cc0` | CC0 1.0 Universal | Nein (empfohlen) |
|
|
| `unlicense` | Unlicense | Nein |
|
|
| `mit` | MIT License | Ja (im Footer) |
|
|
| `cc_by_4` | CC BY 4.0 | Ja + Änderungshinweis |
|
|
| `reuse_notice` | EDPB/EDPS Reuse Notice | Ja (keine Sinnentstellung) |
|
|
|
|
### Template-Typen
|
|
|
|
| Typ | Beschreibung |
|
|
|-----|--------------|
|
|
| `privacy_policy` | Datenschutzerklärung |
|
|
| `terms_of_service` | Nutzungsbedingungen |
|
|
| `agb` | Allgemeine Geschäftsbedingungen |
|
|
| `cookie_banner` | Cookie-Banner & Cookie-Policy |
|
|
| `impressum` | Impressum/Legal Notice |
|
|
| `widerruf` | Widerrufsbelehrung |
|
|
| `dpa` | Auftragsverarbeitungsvertrag |
|
|
| `sla` | Service Level Agreement |
|
|
| `nda` | Geheimhaltungsvereinbarung |
|
|
| `clause` | Einzelne Vertragsklausel |
|
|
|
|
---
|
|
|
|
## Fehler-Responses
|
|
|
|
### 400 Bad Request
|
|
```json
|
|
{
|
|
"detail": "Beschreibung des Fehlers"
|
|
}
|
|
```
|
|
|
|
### 401 Unauthorized
|
|
```json
|
|
{
|
|
"detail": "Not authenticated"
|
|
}
|
|
```
|
|
|
|
### 404 Not Found
|
|
```json
|
|
{
|
|
"detail": "Ressource nicht gefunden"
|
|
}
|
|
```
|
|
|
|
### 500 Internal Server Error
|
|
```json
|
|
{
|
|
"detail": "Interner Serverfehler"
|
|
}
|
|
```
|