# SRC-07 – Prüfprotokoll: OCR für Anhänge Voraussetzung ARC-01, ARC-03 (beide Fertig). SRC-07 ist die direkte Vorbedingung für SRC-10 (Spracherkennung & OCR-Qualitätsbewertung), nicht nur eine nette Ergänzung — ohne SRC-07 gibt es keinen erkannten Text, den SRC-10 mit Sprache/Konfidenz bewerten könnte. ## Umsetzung - `mail/internal/ocr/ocr.go` — zustandsloses Paket, kennt weder Mandant noch Speicher (dieselbe Bauart wie `mail/internal/crypto`/`dedup`): nimmt Anhangs-Bytes entgegen, liefert erkannten Text zurück. Kein geteilter Zustand zwischen Aufrufen (jeder Aufruf bekommt ein eigenes Temp-Verzeichnis) — Tenant-Trennung ist dadurch strukturell gegeben, nicht nur konventionell: ein Mandant kann prinzipbedingt nie Zwischen- daten eines anderen sehen. Zuordnung des erkannten Textes zum Mail-Suchdokument (Akzeptanzkriterium 2) erfolgt beim Aufrufer über das bereits vorhandene `search.Document.AttachmentText`-Feld (SRC-01) — kein neues Feld nötig. - `ExtractTextFromImage`: ruft `tesseract` (Sprachen `deu+eng`) mit fester Argumentliste auf, kein Shell-String-Zusammenbau. - `HasTextLayer`/`ExtractTextFromPDF`: nutzt `pdftotext`, um eine vorhandene Textebene zu erkennen und direkt zu übernehmen (Akzeptanzkriterium 3) — nur wenn keine Textebene vorhanden ist (< 10 Zeichen), wird über `pdftoppm` (300dpi) jede Seite gerastert und per Tesseract erkannt (Akzeptanzkriterium 1). - Bekannten Fehler vermieden (dupliziertes Sprintf-WHERE-Muster aus archivmail, siehe repos-analyse-mail-reuse.md): dieses Paket baut keine SQL-Klauseln — ausschließlich externe Kommandozeilenwerkzeuge mit festen Argumentlisten (`exec.CommandContext`, keine Shell). - Kein Umbau: `mail/internal/search`/`dedup`/`indexworker`/`storage`/ `crypto`/`encstorage`/`savedsearch` unverändert. ## Prüfungen | # | Prüfung | Ergebnis | |---|---|---| | 1 | Test: Bildanhang mit bekanntem Text liefert erwartete Texterkennung | **bestanden** – `TestExtractTextFromImage_KnownTextRecognized`: reales, über `pdftoppm` gerastertes Bild mit dem Text "Rechnungsnummer 4711", `ExtractTextFromImage` erkennt real beide Wortbestandteile | | 2 | Test: PDF mit vorhandener Textebene wird korrekt übersprungen | **bestanden** – `TestExtractTextFromPDF_SkipsOCRWhenTextLayerPresent`: real erzeugtes Vektor-Text-PDF (echte PDF-Textebene, kein Bild), `ExtractTextFromPDF` liefert `OCRPerformed=false` und den Text direkt aus der Textebene | | 3 | Durchsatztest bestätigt akzeptable Verarbeitungszeit je Anhang | **bestanden** – `TestExtractTextFromPDF_ThroughputIsAcceptable`: 3 reale Anhänge (Rasterung 300dpi + OCR) in durchschnittlich 3,48s/Anhang (Ziel 8s/Anhang) | Zusätzlich (Akzeptanzkriterium 1, gescannte PDFs end-zu-Ende): `TestExtractTextFromPDF_PerformsOCRWhenNoTextLayer` — ein reales, ausschließlich rasterbildbasiertes PDF (kein Textelement, JPEG-Bild via `/DCTDecode` eingebettet) wird real per OCR erkannt, `OCRPerformed=true`. Testfixtures (`testpdf_test.go`) werden vollständig in Go erzeugt (Hand- gebautes PDF mit Helvetica-Textebene bzw. eingebettetem JPEG) — keine externe Bibliothek, keine Testdateien im Repository, reproduzierbar. ## Build/Test-Ergebnis (192.168.1.131) ``` go build ./... -> clean go vet ./... -> clean golangci-lint run ./... -> 0 issues go test ./internal/ocr/... -v -> 4/4 bestanden (14,99s gesamt) TEST_TENANT_DSN=... TEST_MANTICORE_URL=... go test ./... -p 1 -> alle Pakete bestanden, keine Regression ``` Werkzeugversionen auf 192.168.1.131: `tesseract 5.5.0` (Sprachpakete `deu`, `eng`), `pdftotext`/`pdftoppm` (poppler-utils) — bereits vorhanden, keine Installation durch diese Sitzung nötig. ## Gesamtergebnis **Bestanden.** Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt. Entsperrt SRC-10.