alami-vision-api / docs /PRODUCT_SCAN_UI_SPEC.md
alami-ci
Deploy from alami-eco/alami-trash-ai@aee69796b70947e95efdb9c7483fa52f8d3b4520
76838d6
|
Raw
History Blame Contribute Delete
9.26 kB

Produkt-Scan — UI-Spezifikation für den Mobile-Agenten

Von: Vision-Agent · Stand: 2026-07-07 · Founder-Go liegt vor. API ist fertig und live (GET /v1/product/{barcode}, v2.1.x auf https://alami-eco-alami-vision-api.hf.space). Dieses Dokument ist die vollständige Umsetzungs-Spec: Flow, Karten-Layout, Render-Regeln pro Feld, und die bewussten Grenzen, die wir mit dem Founder besprochen haben.


0. Produkt-Entscheidungen (Kontext, damit du weißt WARUM)

  1. Positionierung: Alami beantwortet „Was macht das Produkt mit der Welt — und wohin damit nach Gebrauch?" Das ist unser Alleinstellungsmerkmal (Yuka = Gesundheit, Oasis = Toxine — beide zeigen NICHT Entsorgung/Umwelt-Kreislauf).
  2. Gesundheits-Basics zeigen wir GRATIS mit (Nutri-Score, NOVA, Zusatzstoffe) — das holt preisbewusste Yuka-Nutzer ab. ABER: wir zeigen nur offizielle Schemata an, wir bewerten nie selbst (Haftung! Yuka wurde für eigene Risiko-Einstufungen verklagt). Also: keine Texte wie „gefährlich", „krebserregend", „schädlich" aus unserer Feder — nur amtliche Grades + Rohlisten.
  3. Kein Toxin-Scoring (PFAS/Mikroplastik/Schwermetalle à la Oasis) — dafür gibt es keine offenen Daten. Nicht andeuten, nicht simulieren.
  4. Kein TC/Economy-Bezug: Der Produkt-Scan ist reines Info-Feature. Kein ai_status, kein Submit-Pfad, keine Wallet-Berührung.
  5. UI-Vorbild: Oasis-Karten-Pattern (großer Score oben, aufklappbare Detail-Zeilen mit Ampel-Punkten darunter) — bewährt, Nutzer kennen es.

1. Einstieg & Scan-Flow

  • Modus-Toggle im bestehenden Kamera-Screen: 🗑️ Trash | 🛒 Product (App ist englisch → englische Labels, siehe §5 i18n).
  • Im Produkt-Modus: Stufe-A-Preview-Loop pausieren (keine parallelen /v1/analyze-Calls) und Barcode-Scanning aktivieren:
<CameraView
  barcodeScannerSettings={{ barcodeTypes: ['ean13', 'ean8', 'upc_a', 'upc_e'] }}
  onBarcodeScanned={({ data }) => onScan(data)}
/>
  • Debounce: gleiche Barcode-Nummer max. 1× pro ~3 s (onBarcodeScanned feuert mehrfach/Sekunde). Nach erfolgreichem Scan kurz haptisches Feedback + Scanning pausieren, bis die Karte geschlossen wird.
  • Call: GET {BASE_URL}/v1/product/{data} — gleicher x-api-key-Header wie künftig überall. Immer HTTP 200 (400 nur bei Nicht-Barcode-Strings); branchen ausschließlich auf response.status.

2. Die Produkt-Karte (Bottom-Sheet, wie euer Tag-Sheet)

Reihenfolge von oben nach unten — bewusst: Umwelt zuerst (unsere Marke), Gesundheit als Zusatz, Entsorgung als Alami-Unikat prominent:

┌──────────────────────────────────────────┐
│  [Bild]  Coca-Cola                       │  ← product.name + brand + image_url
│          Coca-Cola · 33 cl               │  ← quantity
│                                          │
│  ENVIRONMENT                             │
│  ◯ Eco-Score:  C  (ampel-farbig)         │  ← sustainability.ecoscore_grade
│  🏷 made-in-the-eu · triman              │  ← sustainability.labels (Chips, max ~5)
│                                          │
│  DISPOSAL — the Alami special            │
│  ▢ Metal · drink can                     │  ← packaging[]: Chip in .color, label_en
│    ♻️ Metal/packaging recycling.         │  ← disposal_hint_en
│    Deposit cans: return to store.        │
│    ~15 g if littered                     │  ← litter_weight_estimate_g (optional)
│                                          │
│  HEALTH BASICS (official schemes)        │
│  ◯ Nutri-Score: E  (ampel-farbig)        │  ← health.nutriscore_grade
│  ▸ Processing: NOVA 4 — ultra-processed  │  ← health.nova_group (Mapping §3.3)
│  ▸ Additives: 2  (e150d, e338)           │  ← health.additives_count + Liste aufklappbar
│  ▸ vegan? maybe · palm-oil-free ✓        │  ← health.ingredients_analysis
│                                          │
│  Data: Open Food Facts — ODbL   [link]   │  ← attribution — PFLICHT, immer sichtbar
└──────────────────────────────────────────┘

3. Render-Regeln pro Feld

3.1 Eco-Score & Nutri-Score (beide als Ampel-Kreis)

Grade Farbe
a #1fa363 dunkelgrün
b #8bc34a hellgrün
c #f9a825 gelb
d #ef6c00 orange
e #d32f2f rot
null / "not-applicable" / "unknown" grauer Kreis + Text "No data" — ehrlich zeigen, nie verstecken, nie raten

3.2 Verpackung (packaging[])

  • Pro Eintrag ein Chip in color (unsere Materialfarben, identisch zu den Kamera-Overlays!) mit label_en, optional shape (bereinigt: en:-Präfix strippen, Bindestriche → Leerzeichen).
  • Darunter disposal_hint_en als Fließtext.
  • litter_weight_estimate_g: optional als „~15 g if littered" — kleine, aber einzigartige Alami-Note.
  • packaging == [] → Zeile „No packaging data yet".

3.3 Health-Block — NUR anzeigen, nie werten

  • Nutri-Score: Ampel wie §3.1. Untertitel exakt: "Nutri-Score (official EU scheme)" — macht klar, dass es nicht unsere Bewertung ist.
  • NOVA (health.nova_group), neutrales Wording:
    • 1 → "unprocessed / minimally processed"
    • 2 → "processed culinary ingredients"
    • 3 → "processed food"
    • 4 → "ultra-processed"
    • null → Zeile weglassen
  • Zusatzstoffe: Additives: {additives_count} + aufklappbare Liste der E-Nummern (health.additives). Keine eigenen Risiko-Farben/-Urteile — neutral grau. Optional pro E-Nummer ein Link auf https://world.openfoodfacts.org/additive/{code} (externe Quelle urteilt, nicht wir).
  • ingredients_analysis: Chips; Werte können maybe-vegan etc. sein → als "vegan?" mit Fragezeichen rendern, *-free/bestätigte als ✓.

3.4 Status-UX (response.status)

status UI
found Karte wie oben
not_found "Product not in the database yet." + Button "Add it on Open Food Facts" (Link https://world.openfoodfacts.org/) — Goodwill + die DB wächst
unavailable "Service temporarily unreachable." + Retry-Button. Niemals blockieren/crashen

3.5 Attribution — nicht optional

attribution.text + attribution.url immer sichtbar auf der Karte (Fußzeile reicht). Das ist ODbL-Lizenzpflicht, kein Nice-to-have.

4. Latenz & Verhalten

  • Erster Lookup ~0,5–1,5 s (Upstream) → Skeleton/Spinner in der Karte.
  • Danach 24 h serverseitig gecacht → Wiederholungs-Scans schnell.
  • Ihr müsst nichts loggen — Server schreibt anonyme Scan-Statistik (Barcode+Status, bewusst ohne user_id). Keine User-Daten mitschicken.

5. i18n

Alle Anzeige-Felder kommen doppelt: label_en/label_de, disposal_hint_en/disposal_hint_de. App ist englisch → *_en verwenden. Deutsch liegt für die Mehrsprachigkeit bereit (per Geräte-Locale wählen); weitere Sprachen kommen später als zusätzliche *_<lang>-Felder (additiv). Statische UI-Texte dieses Features (Section-Header, Status-Meldungen) bitte gleich in euer i18n-System, nicht hardcoden.

6. Beispiel-Response (echt, live getestet: Coca-Cola 5449000000996)

{
  "status": "found", "found": true, "barcode": "5449000000996",
  "source": "openfoodfacts",
  "product": { "name": "coca-cola", "brand": "Coca-Cola", "quantity": "33 cl",
               "image_url": "https://images.openfoodfacts.org/…/front_en.1035.200.jpg" },
  "sustainability": { "ecoscore_grade": "not-applicable", "ecoscore_score": null,
                      "labels": ["made-in-the-eu", "fr:triman"] },
  "health": { "nutriscore_grade": "e", "nova_group": 4,
              "additives_count": 2, "additives": ["e150d", "e338"],
              "ingredients_analysis": ["palm-oil-free", "maybe-vegan", "maybe-vegetarian"] },
  "packaging": [
    { "raw": "en:aluminium", "shape": "en:drink-can",
      "bucket": "metal", "label_en": "Metal", "label_de": "Metall", "color": "#64748b",
      "disposal_hint_en": "Metal/packaging recycling. Deposit cans: return to store.",
      "disposal_hint_de": "Gelber Sack / Gelbe Tonne. Pfanddosen: Rückgabe im Handel.",
      "litter_weight_estimate_g": 15.0 }
  ],
  "attribution": { "text": "Daten: Open Food Facts — Open Database License (ODbL)",
                   "url": "https://world.openfoodfacts.org" }
}

7. Explizit NICHT bauen (besprochen & entschieden)

  • ❌ eigene Gesundheits-/Risiko-Scores oder Warntexte („harmful", „toxic", …)
  • ❌ Toxin-/PFAS-/Mikroplastik-Anzeigen (keine Datenbasis)
  • ❌ Kopplung an TC/Economy/Submit-Pfad
  • ❌ Attribution weglassen oder verstecken

8. Später (nur Ausblick, nichts bauen)

  • P3: „Found in real cleanups: n×" pro Marke (Brand Radar, geparkt)
  • P4: kombinierter Alami-Score + Premium/B2B
  • Regionale Entsorgungsregeln (Region-Tabelle serverseitig)

Fragen → an den Vision-Agenten. Referenzen: docs/api.md, docs/PRODUCT_SCAN_VISION.md (Konzept/Strategie), docs/MOBILE_AGENT_HANDOFF.md §4d.