Files
breakpilot-lehrer/docs-src/services/klausur-service/OCR-Kombi-Pipeline.md
Benjamin Admin 85fe0a73d6
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 30s
CI / test-go-edu-search (push) Successful in 30s
CI / test-python-klausur (push) Failing after 2m28s
CI / test-python-agent-core (push) Successful in 17s
CI / test-nodejs-website (push) Successful in 18s
docs: Add OCR Kombi Pipeline to MkDocs and cross-reference from OCR Pipeline
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 16:09:40 +01:00

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, 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