Zuletzt aktualisiert:

Bericht: Kaufland-Bon-Import bekommt eine Vorschau (07.06.2026, abends)

Executive Summary

Der Kaufland-/Fremd-Bon-Import (ADR-52, vom selben Tag) bucht einen hochgeladenen Bon nicht mehr blind ein. Stattdessen liest die KI das PDF nur noch aus, das Frontend zeigt eine Vorschau mit allen erkannten Positionen, und erst auf „Importieren" landet etwas in der Datenbank. Damit kann ein verlesener oder kaputter Bon den Bestand nicht mehr im Vorbeigehen verändern — genau die Sorge, die Dennis geäußert hat („bevor mir ein Kassenzettel meine Datenbank zerschießt").

Der Code dieser Vorschau war in der Vorsession schon zu ~90 % gebaut worden, ging dort aber mitten im Verifizieren in den Cyber-Safeguard-Filter (das Playwright-Skript las den Internal-Token aus .env) und wurde nie committet — beim /clear war er weg. Diese Session hat ihn aus dem Session-Transcript rekonstruiert und sauber fertiggestellt; zugleich wurde ein verfrühter Fehlansatz (ein dry_run-API-Flag) wieder entfernt.

In einfachen Worten

Vorher: Bon-PDF hochladen → die KI bucht sofort alles ein, was sie zu erkennen glaubt. Wenn sie sich verliest, ist der Mist schon in Vorrat und Archiv.

Jetzt: Bon-PDF hochladen → die KI liest vor → du siehst eine Liste mit Markt, Datum, Endbetrag und allen Positionen. Du kannst pro Zeile entscheiden, ob sie in den Vorrat soll (Pfand nie), siehst eine Warnung, falls die Summen nicht passen, und tippst dann Importieren oder Verwerfen. Bis zu diesem Tippen ist die Datenbank unangetastet.

Architektur

📄 PDF → POST /api/receipts/import-pdf   (Raw-Body, %PDF-Check, 15 MB) → ai_job "receipt_pdf"
       → ai_jobs.job_receipt_pdf:  claude-CLI + Read liest PDF → Bon-JSON
                                   NUR EXTRAHIEREN, kein Import (JSON in Job-note)
       ↓ Frontend pollt den Job
📋 ReceiptPreview.svelte (Sheet + AiProgress-Ring):
     · Positionen/Preise/Rabatte/Pfand, Kontrollsummen-⚠️
     · je Food-Position eine Checkbox (Pfand fix aus)
     ├─ „Verwerfen"   → nichts passiert
     └─ „Importieren" → POST /api/receipts/import  (items[].to_inventory je Zeile)
                          → receipt_import.import_receipt_dict():
                              Bon IMMER komplett ins Archiv,
                              nur angehakte Positionen buchen Bestand

Der entscheidende Schnitt: Der Host-Worker importiert nicht mehr selbst, sondern liefert nur das extrahierte JSON zurück. Die Entscheidung „einbuchen ja/nein" liegt jetzt vollständig beim Menschen im Vorschau-Sheet.

Was diese Session konkret tat

Datei Änderung
app/ai_jobs.py job_receipt_pdf extrahiert nur noch (Bon-JSON → Job-note), kein Auto-Import mehr; urllib.parse-Import entfernt
app/frontend/src/components/ReceiptPreview.svelte neu — Vorschau-Sheet: pollt via AiProgress, listet Positionen, Per-Zeile-Checkbox, Kontrollsummen-Warnung, Importieren/Verwerfen
app/frontend/src/pages/Shopping.svelte „📄 Bon-PDF"-Upload öffnet das Vorschau-Sheet (previewJob) statt Fire-and-forget
app/backend/receipt_import.py receipt_items[].to_inventory (Default true) steuert das Einlagern je Position; Bon kommt immer komplett ins Archiv
app/backend/main.py verfrühtes dry_run-Flag wieder entfernt (toter Pfad)
app/tests/contract/test_bons_stats.py Contract-Test to_inventory=False → Position nicht im Vorrat, Bon trotzdem vollständig im Archiv

Hart erarbeitet / Fallen

Verifikation

Testplan

Gerätetest hinter Login: silverscale.dennisfisch.de/testplan/kaufland-pdf-vorschau (Quelle app/testplaene/kaufland-pdf-vorschau.html, ro-Mount, kein Rebuild). 17 Punkte über Upload+KI · Vorschau prüfen · Verwerfen schreibt nichts · Importieren bucht gezielt · Idempotenz/Fehlfälle. Funde direkt am Plan (🐞 + Notiz + ⌘V-Screenshot, ADR-50) → app/data/testplan-feedback/kaufland-pdf-vorschau/. Braucht ein echtes Kaufland-Bon-PDF aus der Card-App.

Nachtrag: erster Gerätetest deckte einen Worker-Bug auf (c02)

Dennis' erster echter Upload (ein Kaufland-Bon mit 57 Positionen) zeigte im Vorschau-Sheet nur den rohen Fehler „Expecting value: line 1 column 1 (char 0)". Systematische Diagnose (stderr der CLI war auf DEVNULL):

Offen / nächste Schritte


Bezug: Kaufland-PDF-Import · ADR-52 in app/ARCHITEKTUR.md · Commit 6c5c2ca