ByteBite Product & Domain Requirements v1
ByteBite product and domain requirements v1, plus the storefront data backlog.
Stand
Diese Seite ist die Produktliste v1 und der Backlog für die noch fehlenden Storefront-Daten. Gebaut heißt: Tabelle und öffentlicher oder Dashboard-Pfad existieren. Phase N heißt: eigener späterer Slice, in diesem Durchgang ohne Migration und ohne API-Code.
GET /storefront/restaurant bleibt die öffentliche Restaurant-Antwort. Neue Felder kommen additiv dazu und sind leer, solange die Zeile fehlt. Der Warenkorb bleibt der gemeinsame Ablauf.
Ordering
- Abholung und Lieferung. Gebaut. Ohne
fulfillmentTypeentsteht eine Abholung. Lieferung ist die explizite zweite Art. - Gast-Checkout. Gebaut. Der Kundenaccount bleibt eine eigene, schon beschlossene Anforderung und wird hier nicht neu geschnitten.
- Bestellnotizen. Gebaut.
- Gutscheine. Phase 6.
- Mindestbestellwert und Liefergebühr. Gebaut pro Lieferzone. Freigrenze und die Bezugsgröße des Mindestwerts sind Phase 4.
- Restaurant muss jede Bestellung aktiv annehmen. Gebaut.
- Maximal 10 Minuten Annahmezeit. Gebaut.
- ETA bei Annahme: 15, 30, 45 oder 60 Minuten, gespeichert auf der Bestellung. Gebaut. Die Schätzung vor dem Abschluss ist Phase 3.
- Live-Bestellstatus für Kunden. Gebaut.
Payment Methods
cash— gebaut. Der Checkout schreibtcash/unpaid.card_at_door— pro Restaurant optional, im Backlog je Bestellart. Konfiguration ist Phase 7.bitepay— entschieden in ADR-007. Die Anbindung ist der Folge-Slice nach Phase 7.
BitePay v1, sobald der Folge-Slice gebaut ist:
- Kredit-/Debitkarte
- Apple Pay
Orders
Order-Status, gebaut:
pendingacceptedpreparingreadycompletedcancelled
Delivery
Hierarchische Delivery Rules, gebaut (Delivery, ADR-017):
- Straße
- Ortsteil
- PLZ + Ort
- Ort
Die spezifischste aktive Regel gewinnt. Pro Regel sind Mindestbestellwert, Liefergebühr und Aktivstatus gespeichert. Das Land ist DE. Der übergeordnete Ort steht auf jeder Regel.
Freigrenze und min_order_basis sind Phase 4. Eine Alias-Tabelle für doppelte Ortsnamen gibt es nicht. Mapbox und die bestehende Normalisierung (trim, NFC, kleingeschrieben) bleiben die geografische Wahrheit.
Restaurant
- Ein Standort pro Restaurant im MVP. Die Adresse hängt am Profil. Gebaut (Restaurant profile). Es gibt keine zweite Standorttabelle.
- Ein Menü pro Restaurant. Gebaut.
- Menü enthält Kategorien. Gebaut.
- Kategorien und Gerichte: Name, Beschreibung, Preis in Cent, Bild-URL, aktiv/inaktiv, Sortierung. Gebaut. Größen mit eigenem Absolutpreis sind gebaut (Menu sizes). Pflichtoptionen, Extras, Allergene und Zusatzstoffe sind Phase 5.
- Wochenöffnungszeiten mit mehreren Fenstern pro Tag. Gebaut (Opening hours). Dieselbe Liste gilt für Anzeige, Abholung und Lieferung.
- Geschlossene Tage über eine Woche ohne Fenster. Gebaut.
- Sonderöffnungszeiten und Feiertage. Phase 3.
- Urlaub. Phase 3.
- Temporär geschlossen / Bestellpause (
restaurants.orders_paused). Gebaut. Der Schalter gilt für Abholung und Lieferung gemeinsam. Getrennte Schalter sind Phase 3.
Products
- Größen/Varianten. Gebaut. Ist mindestens eine Größe aktiv, ist die Wahl Pflicht, und der Zeilenpreis ist der Preis dieser Größe.
- Pflichtoptionen. Phase 5.
- Optionale Extras. Phase 5.
- Mehrfachauswahl. Phase 5.
- Preisaufschläge. Phase 5.
- Extra-Preise können je Größe variieren. Phase 5.
- Allergene. Phase 5.
- Zusatzstoffe. Phase 5.
- Kein spezielles Entfernen-Optionsmodell. Das bleibt außerhalb dieses Backlogs.
White Label
Pro Restaurant konfigurierbar und gebaut:
- Logo (
restaurants.logo_url) - Primär- und Sekundärfarbe
- Kategorie-Bilder und Gerichtbilder (
image_url)
Der Upload liegt im Dashboard (Object storage). Seeds legen keine Dateien an. Hero, zweites Logo, Alternativtexte und SEO-Overrides sind Phase 2.
Einheitlich über alle Restaurants:
- Layout/UX
- Font
Domains
restaurant_domains: Hostname, Typ (BYTEBITE_SUBDOMAINoderCUSTOM_DOMAIN), primäre Domain,verified_at. Gebaut.- Standardmäßig Restaurant-Subdomain unter
getbytebite.co(<slug>.getbytebite.co, in Staging<slug>.staging.getbytebite.co). - Die Marketing-Landingpage liegt auf dem Apex: Staging
staging.getbytebite.co, Produktiongetbytebite.coundwww.getbytebite.co(ADR-022).apps/landingzeigt vorerstComing Soon, StagingoderComing Soon, Production. Der Apex ist kein Restaurant und wird nicht inrestaurant_domainseingetragen. - Eigene Domain optional. Custom-Domain-Setup im MVP manuell.
- Verifizierung und produktives TLS für Custom Domains bleiben die offenen Punkte in Known gaps.
- Kein Deployment pro Restaurant.
Die Domain steht in der Tenant-Auflösung über den Host. Sie ist kein Anzeigefeld im öffentlichen Restaurant-Payload.
Dashboard
- Tablet/PWA als primärer Use Case.
- Akustische Benachrichtigung bei neuer Bestellung.
- Deutliche visuelle neue-Bestellung-Ansicht.
- Rollen v1:
RESTAURANT,ADMIN. - Internes ByteBite-Admin-Dashboard.
Notifications
- E-Mail: AWS SES.
- SMS: Twilio.
- SMS-Sender:
ByteBite.
SMS bei Annahme, Ablehnung, Timeout und Küche „fertig“ ist gebaut. E-Mail-Versand hat noch keine customer_email auf der Bestellung.
Storage & Monitoring
- Production Object Storage: Backblaze B2. Medien in Staging und Produktion sind offen (Known gaps).
- Development Object Storage: MinIO. Gebaut für Logo-, Kategorie- und Gerichtbilder.
- Error Monitoring: Sentry.
- Zusätzliches Uptime Monitoring.
Development
- macOS als primäre lokale Entwicklungsumgebung.
- Vollständig Docker-basiert mit Hot Reload.
- Lokale
.testDomains analog zur Produktion. - Dev-Seeds für Demo-Restaurants Luigi und Mario, Nutzer, Menü, Öffnungszeiten, Profil und eine Lieferzone. Seeds legen keine Bestellungen und keine Bilddateien an.
Speichergrenzen
Neue Felder kommen in eigene 1:1-Tabellen an restaurants.id. restaurants bleibt Identität (id, name, slug, status), Logo-URL und die beiden Farben. orders_paused bleibt auf restaurants, bis ein eigener Aufräum-Slice es in den Betriebsstatus zieht.
- Profil: stabile Angaben. Kurztext, Adresse, Kontakt.
- Darstellung: Hero, Alternativtexte, SEO-Overrides, Küchenarten.
- Rechtliches: Betreiber, Impressum, Datenschutz, Bestellbedingungen.
- Betrieb: Live-Schalter und Schätzwerte vor dem Abschluss. Die Wochenfenster und
orders.eta_minutesbleiben eigene Daten.
GET /storefront/restaurant setzt das öffentliche Objekt aus diesen Quellen zusammen. Das Payload-Schema in packages/schemas/src/storefront.ts wird in jeder Phase additiv erweitert. Leere 1:1-Zeilen liefern leere Felder.
Phase 1 — Profil
Gebaut. Siehe Restaurant profile.
Tabelle restaurant_profiles, genau eine Zeile pro Restaurant:
- Kurzbeschreibung
- Straße, Hausnummer, PLZ, Ort
- Land, im MVP
DE - Telefon, E-Mail
- Optional Breitengrad, Längengrad, Karten-URL
API: das Profil liegt verschachtelt in GET /storefront/restaurant. Schreiben im Dashboard auf der bestehenden Restaurantseite, Tenant ist die Pfad-restaurantId wie bei den anderen Dashboard-Routen.
Die Abholadresse späterer Phasen ist diese Adresse.
Seeds für Luigi und Mario füllen Adresse und Kontakt.
Phase 2 — Darstellung, Bilder, Rechtliches
restaurant_presentation, eine Zeile pro Restaurant:
- Hero-URL und Alternativtext
- Optionale zweite Logo-URL
- Alternativtext zum bestehenden Logo
- SEO-Titel, SEO-Beschreibung, Social-Bild-URL
- Küchenarten als Textliste dieses Restaurants
Leere SEO-Felder erzeugt der Storefront aus Name und Kurzbeschreibung. Gesetzte Felder überschreiben das.
restaurant_legal, eine Zeile pro Restaurant:
- Betreibername, Rechtsform
- Impressumstext, Datenschutztext, Bestellbedingungen
Öffentliche Rechtsseiten lesen nur diese Zeile.
Alternativtexte an bestehenden Bildern: image_alt auf menu_categories und menu_items. Die Upload-Ziele Logo, Kategoriebild und Gerichtbild bleiben. Hero und zweites Logo werden weitere Upload-Ziele unter restaurants/:restaurantId/.
Phase 3 — Zeiten und Live-Betrieb
restaurant_opening_windows bekommt service: hours (Anzeige), pickup, delivery. Bestehende Zeilen werden hours. Leere Abhol- oder Lieferfenster fallen auf hours zurück. Der Checkout prüft das Fenster der gewählten Art.
Neue Tabellen:
restaurant_hour_exceptions: Datum, ganztägig geschlossen oder abweichende Uhrzeit, optional jeservice. Das sind Feiertage und Sonderzeiten.restaurant_closures: Von-bis für Betriebsferien. Blockiert beide Arten.restaurant_operations:pickup_enabled,delivery_enabled,pickup_eta_minutes,delivery_eta_minutes,preorder_enabled. Dazu ein Text für abweichende Abholbedingungen.
orders_paused bleibt der gemeinsame Pause-Schalter und gewinnt gegen die beiden Enabled-Flags. deliveryAvailable bleibt „mindestens eine aktive Zone“ und wird zusammen mit delivery_enabled und dem Lieferfenster gelesen.
Vorbestellung speichert in dieser Phase das Flag und die erlaubten Fenster. Eine Bestellung auf ein späteres Zeitfenster zu legen ist ein Folge-Slice, weil dafür Bestellzeitpunkt und Küchenlast dazukommen.
Die Schätzung vor dem Abschluss ist pickup_eta_minutes / delivery_eta_minutes. orders.eta_minutes bleibt die ETA, die das Personal bei der Annahme setzt.
Der Abholhinweis ist ein optionales Textfeld auf restaurant_profiles.
Phase 4 — Lieferzonen
Additive Spalten auf delivery_rules:
free_delivery_subtotal_cents.nullheißt keine Freigrenze.min_order_basis. v1 nurSUBTOTAL: die Gerichtesumme ohne Liefergebühr.
Quote und Checkout geben die Freigrenze mit aus. Die Gebühr wird 0, wenn die Zwischensumme die Grenze erreicht. Der Mindestwert bleibt auf der Zwischensumme.
Keine Alias-Tabelle.
Phase 5 — Karte
Neue Tabellen, Preise in Cent:
menu_option_groups: Gericht, Name, Pflicht, Mindest- und Maximalanzahl, Sortierung.menu_options: Gruppe, Name, Aufpreis, aktiv, Sortierung.menu_option_variant_prices: optionaler Aufpreis einer Option für eine Größe. Ohne Zeile gilt der Aufpreis der Option.
Warenkorb und Bestellzeile speichern die gewählte Auswahl als Snapshot, analog zu variant_name. Dieselbe Größe bleibt eine Zeile. Unterschiedliche Extras werden getrennte Zeilen.
Allergene und Zusatzstoffe: Katalogtabellen plus Zuordnung zum Gericht.
Auf menu_items, nullable: vegetarian, vegan, spicy. null heißt unbestätigt und wird öffentlich nicht behauptet. sku ist optional.
unavailable_until optional auf Gericht und Größe: der Eintrag bleibt sichtbar und ist bis zu diesem Zeitpunkt nicht bestellbar. is_active bleibt „nicht auf der Karte“.
menu_item_windows: optionale Zeitfenster pro Gericht. Leer heißt immer verfügbar.
Gerichtbilder und Kategoriebilder bleiben die bestehenden URL-Spalten.
Phase 6 — Weitere Preisbestandteile
Die Bestellung bekommt aufgeschlüsselte Cent-Beträge neben der bestehenden Summe. Die Prüfung total = subtotal + delivery_fee wird um diese Bestandteile erweitert. Jede Bestellung speichert die angewandten Beträge als Snapshot.
Restaurant-Regeln, v1 klein:
- Verpackung: Centbetrag, optional je Bestellart.
- Pfand: Centbetrag an der Option oder am Gericht, mal Menge.
- Zuschlag: benannter Centbetrag, optional je Bestellart.
- Gutschein: Code, Cent oder Prozent, ein Code pro Bestellung. Das ist die Gutschein-Zeile aus Ordering.
Phase 7 — Zahlungsarten, danach BitePay
Zuerst die Konfiguration: restaurant_payment_methods mit Methode, Bestellart und enabled. Der Checkout lässt cash und card_at_door zu, wenn die Zeile für die gewählte Art aktiv ist.
BitePay bleibt der darauffolgende Slice nach ADR-007. Eine Zeile bitepay ohne Stripe-Anbindung lehnt der Checkout ab. Autorisieren, Capture bei Annahme und Aufheben bei Ablehnung oder Timeout werden dort gebaut.
Phase 8 — Storefront liest die Overrides
Kein neues Schema. Startseite und Layout setzen Titel, Beschreibung und Social-Bild aus Phase 2. Fehlt ein Override, gelten Name und Kurzbeschreibung.
Strukturierte Daten für Restaurant, Adresse, Öffnungszeiten und Speisekarte entstehen aus Profil, Zeiten und Karte.
Reihenfolge
Phase 0 ist diese Seite. Danach Phase 1. Phase 2 und Phase 5 können danach unabhängig voneinander folgen. Phase 3 folgt auf Phase 1. Phase 4 kann jederzeit nach Phase 0 folgen. Phase 6 folgt auf Phase 5 und Phase 4. Phase 7 folgt auf Phase 3. Phase 8 folgt auf Phase 2.
Außerhalb dieses Backlogs
- Bewertungen.
- Analyse-Konfiguration pro Restaurant. Sentry bleibt die Plattform-Überwachung.
- Ein Optionsmodell zum Entfernen von Zutaten.
- Eine Alias-Tabelle für Ortsnamen.
- Kundenaccounts. Die Anforderung bleibt bestehen und bekommt hier keinen neuen Schnitt.
- Custom-Domain-Verifizierung und Medien auf Backblaze B2 in Staging und Produktion. Beides bleibt in Known gaps.