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
- ~90 Tage endend am Bon-Datum (nicht am heutigen Tag → Schnitt zum Kaufzeitpunkt)
- Die aktuelle Position ist aus dem Schnitt ausgeschlossen (Anti-Bias Richtung neutral)
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
price_deltaist immer vorhanden (nieundefined), kann abernullsein- Client zeigt bei
nullkeinen Chip (zu wenig Daten, ehrlich) tone-Werte sind stabil; Text kommt vom Server — Client rendert direkt- Progressive: ältere Clients ohne
price_delta-Handling zeigen einfach nichts