OCR-Pipeline für Bild-/PDF-Anhänge, eigener Mail-OCR-Pfad unabhängig vom DMS-Board. Direkte Vorbedingung für SRC-10. - ocr.go: zustandsloses Paket (wie crypto/dedup), kennt weder Mandant noch Speicher. ExtractTextFromImage ruft tesseract (deu+eng) mit fester Argumentliste auf. HasTextLayer/ExtractTextFromPDF nutzen pdftotext zur Erkennung einer vorhandenen Textebene (direkt übernommen, kein unnötiges OCR) und rastern nur bei fehlender Textebene über pdftoppm (300dpi) jede Seite für Tesseract. - Bekannten Fehler vermieden (archivmail-Sprintf-WHERE-Muster): keine SQL-Klauselbildung, ausschließlich exec.CommandContext mit fester Argumentliste, keine Shell. - testpdf_test.go: Testfixtures (Vektor-Text-PDF, Bild-only-PDF mit eingebettetem JPEG) vollständig in Go erzeugt, keine externe Bibliothek, keine Testdateien im Repo. Prüfungen (alle real durchgeführt, siehe mail/docs/SRC-07-PRUEFPROTOKOLL.md): 1. TestExtractTextFromImage_KnownTextRecognized: reales gerastertes Bild, Text real korrekt erkannt. 2. TestExtractTextFromPDF_SkipsOCRWhenTextLayerPresent: echtes Vektor- Text-PDF, OCR real übersprungen. 3. TestExtractTextFromPDF_ThroughputIsAcceptable: 3,48s/Anhang real gemessen (Ziel 8s/Anhang). Zusätzlich TestExtractTextFromPDF_PerformsOCRWhenNoTextLayer für Akzeptanzkriterium 1 (gescannte PDFs) end-zu-Ende. Kein Umbau: search/dedup/indexworker/storage/crypto/encstorage/ savedsearch unverändert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
70 lines
3.8 KiB
Markdown
70 lines
3.8 KiB
Markdown
# 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.
|