Spaces:
Running
Running
| # 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: | |
| ```tsx | |
| <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) | |
| ```json | |
| { | |
| "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. | |