# Plan: workflow_01_eingang_ocr.json für n8n

## Context
Erste Workflow-Datei der Buchhaltungs-Automatisierung (BuHa OptiMax Belegerkennung) nach Spec v1.0. Sprint 1+2 deckt den kompletten Eingangskanal ab: PDF-Upload → Normalisierung → Mistral OCR 3 (OCR + Extraktion in einem Schritt) → Validierung. Die fertige JSON-Datei soll direkt in n8n importierbar sein.

Ausgabepfad: `/home/uh888/buha-optimax-belegerkennung/workflow_01_eingang_ocr.json`

---

## Architektur-Entscheidungen

### HTTP Request Node für Mistral OCR (vom User bestätigt)
Die native Mistral Node gibt nur plain OCR-Text zurück. Wir verwenden stattdessen direkt die Mistral OCR API mit `document_annotation_format` + JSON-Schema → Mistral liefert sofort strukturiertes JSON, kein Regex-Parsing nötig.

- Credential: `Mistral OCR BuHa OptiMax Belegerkennung` (HTTP Header Auth, bereits in n8n gespeichert)
- Ein vorgelagerter Code Node bereitet den komplexen Request-Body vor

### Anthropic wird in Sprint 1+2 nicht gebraucht
Die Credential `Anthropic BuHa OptiMax Belegerkennung` gehört zu `workflow_02_kontierung.json` (Sprint 3) — hier nicht verwendet.

---

## Node-Struktur (9 Nodes)

```
[1] Webhook Trigger
      │
[2] Code: Normalisierung
      │
[3] Code: Mistral Request-Body aufbauen
      │
[4] HTTP Request: Mistral OCR API   ← Credential: "Mistral OCR BuHa OptiMax Belegerkennung"
      │
[5] Code: OCR Response parsen
      │
[6] Code: Validierung & Plausibilität
      │
[7] IF: Validierung OK?
      ├─ true  → [8] Respond to Webhook: Erfolg (200 + extrahierte Daten)
      └─ false → [9] Respond to Webhook: Fehler  (422 + Fehlerliste)
```

---

## Detaillierte Node-Beschreibung

### Node 1 — Webhook Trigger
- Type: `n8n-nodes-base.webhook`
- Path: `beleg-upload`
- Method: POST
- Response Mode: `responseNode` (Node 8/9 antworten)
- Options: `rawBody: true`, `binaryPropertyName: data`

### Node 2 — Code: Normalisierung
Exakt aus Spec Abschnitt 5.2 Node 2. Erkennt Quelle (webhook/email/drive), liefert:
`{ pdf_base64, original_dateiname, quelle, eingang_timestamp }`

Zusätzlich: **Test-Bypass-Klausel** — wenn der Body `testmodus: true` enthält, wird OCR übersprungen und die Testdaten direkt als OCR-Output weitergeleitet (für Tests ohne echte PDFs).

### Node 3 — Code: Mistral Request-Body aufbauen
Baut den vollständigen API-Body mit `document_annotation_format` + JSON-Schema (aus Spec Abschnitt 5.2 Node 3):
```js
return [{ json: { ...$input.first().json, mistral_body: JSON.stringify(body) } }];
```

### Node 4 — HTTP Request: Mistral OCR API
- URL: `https://api.mistral.ai/v1/ocr`
- Method: POST
- Authentication: Header Auth → `Mistral OCR BuHa OptiMax Belegerkennung`
- Content-Type: `application/json`
- Body: `={{ $json.mistral_body }}` (RAW)

### Node 5 — Code: OCR Response parsen
Extrahiert `pages[0].annotations[0]` aus Mistral-Response, ergänzt Defaults (EUR, DE), leitet Metadaten weiter.

### Node 6 — Code: Validierung
Exakt aus Spec Abschnitt 5.2 Node 4:
- Pflichtfelder: rechnungsdatum, lieferant_name, brutto > 0
- Plausibilität: netto + mwst ≈ brutto (±0,05 €)
- Netto-Berechnung wenn fehlend
- Datum-Sanity-Check (Zukunft / >2 Jahre alt)

### Node 7 — IF: Validierung OK?
- Condition: `{{ $json.validierung.valid }} === true`

### Node 8 — Respond to Webhook: Erfolg
- Status: 200
- Body: komplettes JSON mit Belegdaten + validierung

### Node 9 — Respond to Webhook: Fehler
- Status: 422
- Body: `{ fehler: $json.validierung.fehler, warnungen: $json.validierung.warnungen }`

---

## Test-Logik mit Section-12-Daten

**Problem:** Section 12 enthält strukturierte Testdaten (JSON), keine echten PDFs.

**Lösung:** Test-Bypass in Node 2 — POST mit `testmodus: true` überspringt OCR:

```json
{
  "testmodus": true,
  "lieferant_name": "Telekom Deutschland GmbH",
  "rechnungsnummer": "RE-TEST-001",
  "rechnungsdatum": "2024-03-01",
  "netto": 42.00,
  "mwst_betrag": 7.98,
  "brutto": 49.98,
  "mwst_satz": 19,
  "beschreibung": "Test"
}
```

Alle 3 Testbelege aus Section 12 können so direkt per curl/Postman getestet werden.

---

## Ausgabe

Valides n8n-Import-JSON mit:
- Zufälligen UUIDs für Node-IDs
- Credential-Referenzen nach Name (n8n matcht beim Import automatisch)
- Positionsgrid (200px Abstand zwischen Nodes)

**Beim Import in n8n:** Credential `Mistral OCR BuHa OptiMax Belegerkennung` beim HTTP Request Node einmalig bestätigen.
