iOS: Kassenzettel scannen -> Lebensmittel erkennen & einlagern

Neuer Flow (Kachel im Listen-Tab): Foto aufnehmen/waehlen, Artikelbereich per
Rechteck markieren, on-device OCR (Vision, deutsch; Bild bleibt auf dem Geraet),
Zeilen an /products/match schicken. Pruefen-Liste je Zeile: Artikel-Picker
(Auto-Treffer ueber Schwellwert + eigene Lebensmittel-Suche), Menge (aus Zeile
geparst, korrigierbar), Lagerort-Dropdown + QR-Scan. Einlagern per checkInBatch,
unbekannte Zeilen werden uebersprungen; keine Neuanlage.

Backend: MatchCandidate traegt package_size/base_unit mit, damit die App die
Einheit ohne Extra-Abruf kennt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-30 18:40:10 +02:00
parent 9cc3e325bb
commit 648b8294b8
6 changed files with 488 additions and 1 deletions

View File

@@ -301,6 +301,13 @@ actor APIClient {
return try await send(request, as: StockResponse.self)
}
/// Kassenzettel-Zeilen (OCR) den aehnlichsten Lebensmitteln zuordnen.
func matchReceipt(_ lines: [String], threshold: Int? = nil) async throws -> [MatchLine] {
var request = try makeRequest("/products/match", method: "POST")
try jsonBody(&request, MatchRequest(lines: lines, threshold: threshold))
return try await send(request, as: [MatchLine].self)
}
func checkOut(_ payload: CheckOutRequest) async throws -> StockResponse {
var request = try makeRequest("/stock/checkout", method: "POST")
try jsonBody(&request, payload)