Dokument-Import (Phase 0-1)
Ziel
Ein Dokument wird kontrolliert übernommen, eindeutig identifiziert und unverändert archiviert. Der extrahierte Inhalt wird vollständig und reproduzierbar in der SQL-Datenbank als Single Source of Truth gespeichert.
Eingangskanäle
- Dateiupload über Content Pipeline UI
- Ablage in beobachtetem Import-Verzeichnis
- Übergabe über interne Schnittstelle
Akzeptierte Formate
- PDF (via pdfplumber)
- Markdown
- Plain Text
Identität und Versionierung
| Konzept | Beschreibung |
|---|---|
| Content Hash | Primäre Dublettenerkennung über SHA256 der Originaldatei |
| Dokumenten-ID | Stabile, systemgenerierte ID über gesamten Lebenszyklus |
| Versionierung | Neue Version bei geändertem Inhalt, referenziert Original-ID |
Archivierung
Die Originaldatei wird unverändert archiviert und dient als Quelle für Reprocessing:
- Binärartefakt
- Content Hash
- Dateigröße
- Erfassungszeit
Textgewinnung
- Formatabhängige, deterministische Extraktion
- Linearer Textstrom ohne Layoutlogik
- Keine Inhalte entfernt, zusammengefasst oder interpretiert
Normalisierung
- Vereinheitlichung von Zeilenumbrüchen
- Unicode-Normalisierung
- Entfernung technischer Steuerzeichen
Beteiligte Komponenten
| Komponente | Pfad | Funktion |
|---|---|---|
| Content Pipeline | /content-pipeline | Web-UI für Imports |
| import_pdf() | pipeline/import_pipeline.py | PDF-Extraktion |
| documents-Tabelle | ki_content.documents | Dokument-Metadaten |
| document_pages | ki_content.document_pages | Seitenweise Extraktion |
Datenbank-Schema
documents: id, filename, source_path, file_size, content_hash, page_count, status, version, created_at document_pages: id, document_id, page_number, content, metadata, created_at
Prüfbedingungen für Supervision
- Für jede Dokumenten-ID existiert mindestens eine unveränderte Originaldatei
- Jede spätere Verarbeitung referenziert exakt diese Dokumenten-ID und Version
- Reprocessing mit derselben Originaldatei ergibt identische Content Hash Werte
- Der gespeicherte Text ist vollständig aus der Originaldatei rekonstruierbar
PDF-Rotationserkennung
Status: Implementiert
Task #442 - Abgeschlossen am 27.12.2025
Problem
PDF-Dokumente können Seiten enthalten, die um 90°, 180° oder 270° gedreht sind. Ohne Korrektur führt dies zu:
- Fehlerhafter OCR: Text wird nicht oder falsch erkannt
- Unlesbaren Vision-Analysen: LLM kann Inhalt nicht interpretieren
- Korrupten Embeddings: Semantisch falscher Inhalt wird gespeichert
Lösung: Mehrstufige Orientierungserkennung
┌─────────────────────────────────────────────────────────┐
│ Stufe 1: PDF-Metadaten (/Rotate Flag) │
│ → Schnell, kostenlos, 0ms │
└─────────────────────┬───────────────────────────────────┘
│ Falls rotation == 0
▼
┌─────────────────────────────────────────────────────────┐
│ Stufe 2: Tesseract OSD │
│ → Erkennt 0°/90°/180°/270° │
│ → ~50-100ms pro Seite │
└─────────────────────┬───────────────────────────────────┘
│ Falls Confidence < 2.0
▼
┌─────────────────────────────────────────────────────────┐
│ Stufe 3: Vision-LLM Fallback │
│ → Für Bilder ohne Text (optional) │
└─────────────────────────────────────────────────────────┘
Implementierte Dateien
| Datei | Funktion | Status |
|---|---|---|
orientation.py | Orientierungslogik (NEU) | ✓ |
extract.py | Rotation vor OCR | ✓ |
vision.py | Bilder rotieren | ✓ |
config.py | Konfigurationswerte | ✓ |
Konfiguration
# config.py
ROTATION_DETECTION_ENABLED = True
ROTATION_OSD_CONFIDENCE_THRESHOLD = 2.0
ROTATION_USE_VISION_FALLBACK = False
Abhängigkeiten
| Komponente | Status |
|---|---|
| tesseract-ocr 5.5.0 | ✓ Installiert |
| tesseract-ocr-deu | ✓ Installiert |
| tesseract-ocr-osd | ✓ Installiert |
| PyMuPDF | ✓ Vorhanden |
| pytesseract | ✓ Vorhanden |
| Pillow | ✓ Vorhanden |
API
detect_orientation(image_bytes) -> dict
Erkennt Orientierung eines Bildes mittels Tesseract OSD.
Returns:
{
'rotation': 90, # 0, 90, 180, 270
'confidence': 3.5, # OSD Confidence
'script': 'Latin', # Erkanntes Skript
'method': 'osd' # 'osd', 'fallback' oder 'disabled'
}
get_page_rotation(page) -> int
Kombiniert PDF-Metadaten und OSD-Erkennung.
Returns: int (0, 90, 180, 270)
rotate_image(image_bytes, rotation) -> bytes
Rotiert Bild um angegebene Grad.
correct_page_orientation(page, target_dpi) -> tuple[bytes, int]
Convenience-Funktion für korrekt orientiertes Bild.
Referenz
- Task #442: Implementierung
- PyMuPDF Docs: https://pymupdf.readthedocs.io/
- Tesseract OSD: https://tesseract-ocr.github.io/