Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10 KiB
OCR Kombi Pipeline - Modulare 11-Schritt-Architektur
Version: 1.0.0 Status: Phase 1 implementiert (Grundgeruest + DB) URL: https://macmini:3002/ai/ocr-kombi
Uebersicht
Die OCR Kombi Pipeline ist der Nachfolger des OCR-Overlay-Monolithen (/ai/ocr-overlay).
Sie zerlegt den OCR-Prozess in 11 modulare Schritte mit je einer eigenen Komponente
pro Frontend- und Backend-Datei. Ziel: schnelles Debugging, klare Verantwortlichkeiten,
Multi-Page-Dokument-Unterstuetzung.
Primaerer Modus: Kombi (PaddleOCR + Tesseract) — der einzige Modus, den der User nutzt.
Warum ein Refactor?
| Problem (alt) | Loesung (neu) |
|---|---|
page.tsx = 751-Zeilen-Monolith mit 3 Modi |
page.tsx = ~140-Zeilen-Orchestrator, je 1 Datei pro Step |
| Upload, Orientierung und Page-Split in einem Step | 3 separate Steps mit eigener Logik |
| Keine Multi-Page-Dokument-Unterstuetzung | document_group_id + page_number auf DB-Ebene |
| OCR intransparent (eine Blackbox) | 3-Phasen-Fortschritt + Engine-Attribution pro Wort (geplant) |
grid_editor_api.py = 1801 Zeilen |
4 Module + Orchestrator (geplant) |
Pipeline-Schritte
| # | Step | Frontend | Backend | Beschreibung |
|---|---|---|---|---|
| 1 | Upload | StepUpload.tsx |
step_upload.py |
Bild/PDF hochladen, Titel, Kategorie. Multi-Page-PDF → N Sessions |
| 2 | Orientierung | StepOrientation.tsx |
(shared) | Rotation 90/180/270 erkennen + korrigieren |
| 3 | Seitentrennung | StepPageSplit.tsx |
(shared) | Doppelseiten erkennen + splitten |
| 4 | Begradigung | StepDeskew.tsx |
(shared) | Hough Lines + Word Alignment |
| 5 | Entzerrung | StepDewarp.tsx |
(shared) | Shear-Korrektur (Vertikalkanten-Drift) |
| 6 | Zuschneiden | StepContentCrop.tsx |
(shared) | Scanner-Raender entfernen (nach Begradigung!) |
| 7 | OCR | StepOcr.tsx |
(shared) | Tesseract + PaddleOCR + Merge |
| 8 | Strukturerkennung | StepStructure.tsx |
(shared) | Boxen, Zonen, Farben, Grafiken |
| 9 | Grid-Aufbau | StepGridBuild.tsx |
(shared) | Strukturiertes Grid aus OCR + Struktur |
| 10 | Grid-Review | StepGridReview.tsx |
(shared) | Excel-Editor, IPA, Silben, Korrekturen |
| 11 | Ground Truth | StepGroundTruth.tsx |
(shared) | Validierung + GT-Markierung |
!!! note "Crop nach Dewarp" Seitentrennung (Step 3) passiert vor Begradigung — richtig, weil jede Haelfte unabhaengig begradigt wird. Der Content-Crop (Step 6) bleibt nach Dewarp, weil content-basierter Crop auf geradem Bild besser funktioniert.
Multi-Page-Dokument-Gruppierung
Problem
Ein Lehrer scannt 10 Vokabelseiten als eine PDF-Datei. Im Endnutzer-Frontend soll das ein zusammenhaengendes Dokument sein. Alle Seiten muessen spaeter zu gemeinsamen Lern-Units verarbeitet werden koennen.
Loesung: document_group_id + page_number
Zwei neue Felder auf ocr_pipeline_sessions (Migration 009_add_document_group.sql):
ALTER TABLE ocr_pipeline_sessions
ADD COLUMN IF NOT EXISTS document_group_id UUID,
ADD COLUMN IF NOT EXISTS page_number INT;
| Upload-Typ | document_group_id | page_number |
|---|---|---|
| Einzelbild | neues UUID | 1 |
| Multi-Page-PDF (10 Seiten) | gleiches UUID fuer alle 10 | 1..10 |
| Doppelseiten-Split von S. 3 | gleiches UUID | neue S. 3 + S. 4, Rest umkontiert |
Benennung
Upload-Titel "Vokabeln Unit 3" erzeugt:
- "Vokabeln Unit 3 — S. 1"
- "Vokabeln Unit 3 — S. 2"
- ...
- "Vokabeln Unit 3 — S. 10"
Session-Liste im Admin
Gruppierte Anzeige: Ein Dokument-Header ("Vokabeln Unit 3, 10 Seiten") mit aufklappbaren Einzel-Sessions darunter. Jede Session hat eigenen Pipeline-Status.
API-Endpoints
Neue Endpoints (OCR Kombi)
| Methode | Pfad | Beschreibung |
|---|---|---|
| POST | /api/v1/ocr-kombi/upload |
Upload: Einzelbild oder Multi-Page-PDF |
| GET | /api/v1/ocr-kombi/documents/{group_id} |
Alle Sessions einer Dokumentgruppe |
Bestehende Endpoints (wiederverwendet)
Die Kombi-Pipeline nutzt alle bestehenden Endpoints aus /api/v1/ocr-pipeline/:
| Methode | Pfad | Step |
|---|---|---|
| POST | /sessions |
Upload (Legacy, Einzelbild) |
| POST | /sessions/{id}/orientation |
Orientierung |
| POST | /sessions/{id}/page-split |
Seitentrennung |
| POST | /sessions/{id}/deskew |
Begradigung |
| POST | /sessions/{id}/dewarp |
Entzerrung |
| POST | /sessions/{id}/crop |
Zuschneiden |
| POST | /sessions/{id}/paddle-kombi |
OCR (Kombi) |
| POST | /sessions/{id}/detect-structure |
Strukturerkennung |
| POST | /sessions/{id}/build-grid |
Grid-Aufbau |
| POST | /sessions/{id}/save-grid |
Grid speichern |
| GET | /sessions/{id}/grid-editor |
Grid laden |
| POST | /sessions/{id}/mark-ground-truth |
GT markieren |
Dateistruktur
Frontend
admin-lehrer/app/(admin)/ai/ocr-kombi/
├── page.tsx # ~140 Zeilen, Orchestrator mit Suspense-Boundary
├── types.ts # KOMBI_V2_STEPS (11 Steps), DocumentGroup-Types, OCR-Transparenz-Types
└── useKombiPipeline.ts # Hook: Session-State, Step-Navigation, Dokument-Gruppierung
admin-lehrer/components/ocr-kombi/
├── KombiStepper.tsx # 11-Step-Indikator (kompakt, scrollbar)
├── SessionList.tsx # Gruppierte Session-Liste (Dokumentgruppen aufklappbar)
├── SessionHeader.tsx # Aktive Session: Name + Kategorie + GT-Badge
├── StepUpload.tsx # Drag-Drop + Titel + Kategorie-Auswahl
├── StepOrientation.tsx # Wrapper → shared StepOrientation
├── StepPageSplit.tsx # Doppelseiten-Erkennung + Auto-Advance
├── StepDeskew.tsx # Wrapper → shared StepDeskew
├── StepDewarp.tsx # Wrapper → shared StepDewarp
├── StepContentCrop.tsx # Wrapper → shared StepCrop
├── StepOcr.tsx # Wrapper → PaddleDirectStep (kombi endpoint)
├── StepStructure.tsx # Wrapper → shared StepStructureDetection
├── StepGridBuild.tsx # Auto-Trigger build-grid + Ergebnis-Anzeige
├── StepGridReview.tsx # Wrapper → shared StepGridReview (mit saveRef)
└── StepGroundTruth.tsx # GT-Markierung mit Auto-Save
Backend
klausur-service/backend/ocr_kombi/
├── __init__.py
├── router.py # Composite Router (/api/v1/ocr-kombi)
└── step_upload.py # Multi-Page-PDF → N Sessions + document_group_id
Shared (wiederverwendet)
Die Kombi-Pipeline nutzt alle bestehenden Backend-Module:
orientation_crop_api.py— Orientierung, Page-Split, Cropocr_pipeline_api.py— Deskew, Dewarpocr_pipeline_ocr_merge.py— PaddleOCR + Tesseract Mergegrid_editor_api.py— Grid-Aufbau + Editorocr_pipeline_session_store.py— DB-Layer (erweitert um document_group_id)- Alle
cv_*.py— CV-Algorithmen
Migration
migrations/009_add_document_group.sql # document_group_id UUID + page_number INT + Index
Implementierungsphasen
| Phase | Status | Beschreibung |
|---|---|---|
| 1: Grundgeruest + DB | Implementiert | DB-Migration, Types, Hook, Stepper, SessionList, page.tsx, Navigation, Backend-Router |
| 2: Vorverarbeitungs-Steps | Geplant | Multi-Page-PDF-Upload, Orientierung ohne Upload, Seitentrennung mit document_group_id |
| 3: OCR-Transparenz | Geplant | 3-Phasen-Fortschritt, Engine-Attribution pro Wort, Farbkodierung |
| 4: Grid-Pipeline aufteilen | Geplant | grid_editor_api.py → 4 Module + Orchestrator |
| 5: Restliche Steps | Geplant | Structure, GridBuild, GridReview, GroundTruth voll integriert |
| 6: Features migrieren | Spaeter | LLM-Review-Streaming, Labeling-Mode, Bild-Generierung |
| 7: Aufraeumen | Spaeter | /ai/ocr-overlay und /ai/ocr-pipeline loeschen |
OCR-Transparenz (Phase 3, geplant)
3-Phasen-Fortschritt in Step 7
- "Tesseract laeuft..." (Fortschrittsbalken)
- "PaddleOCR laeuft..." (Fortschrittsbalken)
- "Merge laeuft..." (Fortschrittsbalken)
Engine-Attribution pro Wort
Vergleichsansicht mit Farbkodierung:
| Farbe | Bedeutung |
|---|---|
| Gruen | Beide Engines einig |
| Blau | Nur PaddleOCR |
| Orange | Nur Tesseract |
| Gelb | Konflikt, PaddleOCR gewaehlt |
| Rot | Konflikt, Tesseract gewaehlt |
Geplanter Endpoint
POST /sessions/{id}/ocr-kombi-transparent
→ { raw_tesseract, raw_paddle, merged, engine_source_per_word }
Grid-Pipeline-Aufteilung (Phase 4, geplant)
grid_editor_api.py (1801 Zeilen) wird aufgeteilt in:
| Modul | Inhalt | ~Zeilen |
|---|---|---|
grid_build_filters.py |
Margin, Footer, Header, Exclude, Grafik-Filter | ~200 |
grid_build_zones.py |
Box-Detect, Page-Zones, Vert-Dividers | ~250 |
grid_build_columns.py |
Spalten-Clustering + Union-Merge + Zone-Grids | ~300 |
grid_build_postprocess.py |
Row/Cell-Postprocessing, IPA, Farben, Dictionary | ~500 |
grid_editor_api.py wird zum schlanken Orchestrator.
Verhaeltnis zu bestehenden Pipelines
| Pipeline | Route | Status | Beschreibung |
|---|---|---|---|
| OCR Kombi | /ai/ocr-kombi |
Aktiv (neu) | Modulare 11-Schritt-Pipeline |
| OCR Overlay | /ai/ocr-overlay |
Legacy | 751-Zeilen-Monolith, 3 Modi |
| OCR Pipeline | /ai/ocr-pipeline |
Legacy | Volle Pipeline mit Spalten |
| OCR Compare | /ai/ocr-compare |
Eigenstaendig | Methoden-Vergleich |
Die alte OCR Overlay (/ai/ocr-overlay) bleibt waehrend des gesamten Umbaus parallel nutzbar
fuer A/B-Tests. Sobald die Kombi-Pipeline feature-complete ist, werden die alten Pipelines
in Phase 7 entfernt.
Aenderungshistorie
| Datum | Version | Aenderung |
|---|---|---|
| 2026-03-26 | 1.0.0 | Phase 1: Grundgeruest mit 11-Step-Architektur, DB-Migration (document_group_id, page_number), Backend-Router mit Multi-Page-Upload, Frontend mit SessionList (gruppiert), KombiStepper, 13 Step-Komponenten, useKombiPipeline Hook, Navigation |