Zuletzt aktualisiert:

title: Bon-Position Preis-Verdikt — Vertrag (SILV-296) category: dev date: 2026-06-17


Bon-Position Preis-Verdikt

Additives Feld price_delta je Position in GET /api/receipts/{rid} (seit SILV-296).

Feld-Struktur

"price_delta": {
  "tone":     "guenstig" | "teuer" | "normal",
  "text":     "Günstiger als üblich: 0,49 € (Ø 0,55 €)",
  "unit":     0.49,
  "avg90":    0.55,
  "deltaPct": -10.9,
  "count":    7
}

Oder null, wenn keine ausreichende Datenbasis (s. u.).

Feld Typ Bedeutung
tone string Günstigkeits-Klasse (Server ownt das — Client textet/schwellt NICHTS)
text string Lesbare Erklärung für den Chip-Label
unit float Grundpreis dieser Position (ohne Rabatt), €/Einheit
avg90 float Ø unit_price im 90-Tage-Fenster (gerundet auf 4 Stellen)
deltaPct float Abweichung in Prozent: (unit − avg90) / avg90 × 100
count integer Stützstellen im Fenster (ohne aktuelle Position)

Wann ist price_delta nicht null?

Alle drei Bedingungen müssen erfüllt sein: - food_id ist gesetzt - unit_price > 0 - is_deposit = 0 - Mindestens 3 Stützstellen im Fenster (sonst null → Client zeigt keinen Chip)

Fenster & Ausschluss

Schwellen (Server-seitig, anti-drift)

Bedingung tone
unit ≤ avg90 × 0.95 guenstig
unit ≥ avg90 × 1.05 teuer
sonst normal

neutral wird hier nicht vergeben — null drückt „keine Datenbasis" aus.

Abgrenzung zu _price_level

_price_level (Einkaufslistenpreis-Verdikt) nutzt den Effektivpreis (total + discount) / qty über alle Bons all-time — richtig für die Artikel-Preishistorie im Stammdatensteckbrief. SILV-296 braucht dagegen den Grundpreis unit_price im 90-Tage-Fenster — das ist die ehrliche Achse für „war dieser Einkauf günstig?".

Client-Vertrag