# 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`): ```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, Crop - `ocr_pipeline_api.py` — Deskew, Dewarp - `ocr_pipeline_ocr_merge.py` — PaddleOCR + Tesseract Merge - `grid_editor_api.py` — Grid-Aufbau + Editor - `ocr_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 1. "Tesseract laeuft..." (Fortschrittsbalken) 2. "PaddleOCR laeuft..." (Fortschrittsbalken) 3. "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 |