# PDF-Scan Import (Handschriftliche Strichliste) - MVP Backlog

## Ziel

Gescanntes PDF einer handschriftlich ausgefuellten Strichliste hochladen,
Striche pro Mitglied automatisch erkennen und nach manueller Pruefung als
Buchungen verbuchen.

Wichtig: Im MVP wird niemals vollautomatisch ohne Review verbucht.

## Annahmen

- Das PDF-Layout ist stabil (gleiche Zeilen, gleiche Spalten).
- Namen stehen in festen Zeilen.
- Striche sind handschriftlich, aber in klaren Feldern.
- Tenant arbeitet mit bestehender Mitgliederliste aus `members`.

## MVP-Ergebnis

- Neuer Importtyp `PDF-Scan Strichliste` unter `/imports/`.
- Seite wird verarbeitet, erkannte Werte werden je Mitglied angezeigt.
- Admin korrigiert bei Bedarf und bestaetigt.
- Danach werden Buchungen ueber bestehende Buchungslogik erzeugt.
- Vollstaendige Nachvollziehbarkeit ueber Import-Job und Zeilenhistorie.

## Architektur (MVP)

1. Upload + Jobanlage
2. PDF zu Bild (300 DPI)
3. Raster-Template anwenden (Zeilen + Spaltenboxen)
4. Strichzaehlung je Box
5. Vorschau/Review
6. Verbuchen (bulk coffee)

## Paket 1 - Datenmodell und Upload (P0)

### Ticket OCR-001 - Migrationen fuer Scan-Import

Beschreibung:
- Tabellen fuer Jobs, Seiten und erkannte Zeilen anlegen.

Neue Migrationen:
- `database/migrations/2026_04_10_000001_create_scan_import_jobs_table.php`
- `database/migrations/2026_04_10_000002_create_scan_import_pages_table.php`
- `database/migrations/2026_04_10_000003_create_scan_import_rows_table.php`
- `database/migrations/2026_04_10_000004_create_scan_templates_table.php`

Tabellenkern:
- `scan_import_jobs`:
  `id, tenant_id, uploaded_by_user_id, source_filename, status, template_id, created_at, updated_at, processed_at`
- `scan_import_pages`:
  `id, job_id, page_number, image_path, image_width, image_height, processing_status`
- `scan_import_rows`:
  `id, job_id, page_id, row_index, member_id, member_name_raw, front_strokes_detected, back_strokes_detected, confidence, needs_review, corrected_front_strokes, corrected_back_strokes, created_at, updated_at`
- `scan_templates`:
  `id, tenant_id, name, page_width, page_height, anchor_json, grid_json, is_active`

Akzeptanzkriterien:
- Migrationen laufen ohne Fehler.
- Foreign Keys und Indexe fuer `tenant_id`, `job_id`, `member_id` vorhanden.
- Jobstatus mindestens: `uploaded, processing, review, approved, posted, failed`.

### Ticket OCR-002 - Upload-Endpunkt in Imports

Beschreibung:
- Formular und Handler fuer PDF-Upload integrieren.

Betroffene Dateien:
- [index.php](/config/workspace/kaffeeliste/saas-app/public/index.php)
- [imports/index.php](/config/workspace/kaffeeliste/saas-app/public/imports/index.php)
- [app-support.php](/config/workspace/kaffeeliste/saas-app/public/app-support.php)

Umfang:
- Neues Formular unter Imports:
  - Datei (`application/pdf`)
  - Template-Auswahl
  - Buchungszeitpunkt default jetzt
- Speichern in Upload-Verzeichnis (tenantbezogen).
- Job in `scan_import_jobs` anlegen.

Akzeptanzkriterien:
- PDF kann hochgeladen werden.
- Neuer Job erscheint in Import-Historie.
- Fehlerfaelle (kein PDF, zu gross, kein Template) geben klare Meldung.

## Paket 2 - Erkennung und Review (P0)

### Ticket OCR-003 - PDF Rendering und Vorverarbeitung

Beschreibung:
- PDF-Seiten in Bildseiten umwandeln und normalisieren.

Betroffene Dateien:
- [app-support.php](/config/workspace/kaffeeliste/saas-app/public/app-support.php)
- neuer Worker-Entry:
  `saas-app/public/scan-import/process.php` (oder synchroner Handler im MVP)

Umfang:
- Seite zu PNG 300 DPI rendern.
- Optional: Auto-Rotation, Kontrast, Binarisierung.
- Seite in `scan_import_pages` speichern.

Akzeptanzkriterien:
- Jede PDF-Seite erzeugt ein Bild.
- Fehlerhafte Seiten markieren Job als `failed`.

### Ticket OCR-004 - Template-Raster + Strichzaehlung

Beschreibung:
- Erkennung pro Zeile anhand fester Boxen fuer `front` und `back`.

Betroffene Dateien:
- [app-support.php](/config/workspace/kaffeeliste/saas-app/public/app-support.php)

Umfang:
- Template aus `scan_templates.grid_json` laden.
- Zeile -> Mitglied mappen (primar ueber Reihenfolge/Namenvergleich).
- In jeder Box Striche zaehlen:
  - verbundene Komponenten
  - minimale Laenge/Neigung als Filter
- Confidence pro Feld berechnen.

Akzeptanzkriterien:
- Je Zeile entstehen `front_strokes_detected` und `back_strokes_detected`.
- Werte landen in `scan_import_rows`.
- Zeilen mit geringer Sicherheit setzen `needs_review = 1`.

### Ticket OCR-005 - Review-UI

Beschreibung:
- UI zur Pruefung und Korrektur vor Verbuchung.

Betroffene Dateien:
- [index.php](/config/workspace/kaffeeliste/saas-app/public/index.php)
- optional neue Route:
  `saas-app/public/imports/review/index.php`

Umfang:
- Liste aller erkannten Zeilen:
  `Mitglied | front erkannt | back erkannt | confidence | korrigierbar`
- Bildausschnitt pro Zeile einblendbar.
- Aktionen:
  - `Alle ohne Konflikt uebernehmen`
  - `Korrekturen speichern`
  - `Verbuchung starten`

Akzeptanzkriterien:
- Admin kann jeden Wert manuell korrigieren.
- Ohne bestaetigte Review keine Verbuchung moeglich.

## Paket 3 - Verbuchung, Audit, Betrieb (P1)

### Ticket OCR-006 - Verbuchung in bestehende Finanzlogik

Beschreibung:
- Freigegebene Scan-Zeilen als Buchungen erzeugen.

Betroffene Dateien:
- [app-support.php](/config/workspace/kaffeeliste/saas-app/public/app-support.php)

Umfang:
- Pro Zeile `total = front + back`.
- Nur `total > 0` verbuchen.
- Nutzung bestehender Buchungsfunktion
  (`app_create_coffee_booking` mit `source = scan_import`).
- Jobstatus auf `posted` setzen.

Akzeptanzkriterien:
- Ledger-Eintraege korrekt erzeugt.
- Doppelte Verbuchung fuer denselben Job wird verhindert.
- Import kann nicht zweimal gepostet werden.

### Ticket OCR-007 - Fehlerbehandlung und Monitoring

Beschreibung:
- Robustheit fuer Produktivbetrieb.

Betroffene Dateien:
- [app-support.php](/config/workspace/kaffeeliste/saas-app/public/app-support.php)
- optional neue Tabelle `scan_import_logs`

Umfang:
- Klare Fehlermeldungen je Schritt (Upload, Render, Erkennung, Posting).
- Retry fuer `processing` bei transienten Fehlern.
- Zeitmessung pro Seite, Trefferquote pro Job.

Akzeptanzkriterien:
- Fehler sind in UI sichtbar.
- Job bleibt bei Fehler reproduzierbar im Zustand `failed`.

### Ticket OCR-008 - Rechte und Feature-Flag

Beschreibung:
- Zugriff auf Scan-Import rollen- und lizenzgesteuert.

Betroffene Dateien:
- [app-support.php](/config/workspace/kaffeeliste/saas-app/public/app-support.php)
- [index.php](/config/workspace/kaffeeliste/saas-app/public/index.php)

Umfang:
- Nur `tenant_admin` und `finance_admin`.
- Lizenzfeature `scan_import` (tenantweit schaltbar).

Akzeptanzkriterien:
- Unberechtigte Rollen sehen Bereich nicht.
- Direkter URL-Zugriff wird abgefangen.

## Definition of Done (MVP)

- Upload bis Verbuchung funktioniert fuer 1-3 seitige Standard-PDFs.
- Review vor Verbuchung ist verpflichtend.
- `all/front/back` Sicht in Buchungen bleibt konsistent.
- Mindestens 85 Prozent korrekte Erst-Erkennung bei Referenz-Scans.
- Restliche Fehler koennen in der Review-Maske schnell korrigiert werden.

## Testplan

### Fachliche Tests

- Drei bekannte Test-PDFs mit Referenzwerten importieren.
- Vergleich `erkannt` vs `korrigiert` vs `verbucht`.
- Doppelt-Posting verhindern.

### Technische Tests

- Migrationen, Upload-Validation, Rechtepruefung.
- Jobstatuswechsel in allen Pfaden.
- Regression fuer bestehende CSV-Importe.

### UX-Tests

- Review-Seite auf Desktop und Mobile nutzbar.
- Korrektur pro Zeile in unter 3 Klicks.

## Reihenfolge fuer Start der Umsetzung

1. OCR-001 + OCR-002
2. OCR-003 + OCR-004
3. OCR-005
4. OCR-006
5. OCR-007 + OCR-008

## Aufwand (grobe Schaetzung)

- Paket 1: 1-2 Tage
- Paket 2: 3-5 Tage
- Paket 3: 2-3 Tage
- Gesamt MVP: 6-10 Arbeitstage

