Gastronomie-Betrieb
Eine PWA für Dienstplanung, Inventar und Lieferanten-Integrationen eines regionalen Restaurants mit mittlerem Volumen.
- 2025—
- live
- Architekt & Umsetzer
- React Native, Expo SDK 54, Supabase, TypeScript, Playwright
Ein Restaurant mit ~20 Mitarbeitenden organisierte Dienstplanung, Bestellung und Menü von Hand. Diese PWA vereint Dienstplanung, Inventar, Bestellung bei sechs Lieferanten und eine Live-Website in einem System.
- ~2 h WhatsApp-Hin-und-Her
- ~30 Min. in der App
- ~200 € pro Menü, ausgelagert
- Cent pro Lauf, LLM in der App
- Tage an systemübergreifenden Änderungen
- eine Aktion in der App
~2 h → ~30 Min.
~200 € → Cent
seit Dez. 2025
Die technische Aufschlüsselung
Das geschäftliche Problem
Ein regionales Restaurant mit mittlerem Volumen organisierte Dienstplanung, Bestellung und seine öffentliche Speisekarte von Hand. Die wöchentliche Personalplanung war etwa zwei Stunden WhatsApp-Hin-und-Her; Lieferantenbestellungen wurden vergessen; die öffentliche Website hinkte der echten Speisekarte hinterher, sodass Gäste mit veralteten Informationen ankamen; und handschriftliche Reservierungen gingen manchmal verloren. Und niemand konnte sehen, wie ein Service tatsächlich getaktet war — wie lange ein Tisch auf Getränke, dann auf Essen wartete — es gab also nichts Konkretes, woran man sich verbessern konnte.
Die Beteiligten: rund zwanzig Mitarbeitende und die Inhaber, die Schichten planen und Bestellungen aufgeben, die Gäste, die buchen und essen, und sechs B2B-Lieferanten, deren Kataloge und Preise sich ständig ändern — keiner davon mit einer brauchbaren API. Die Aufgabe war, all das in ein System zu bringen, dem alle gleichzeitig vertrauen können.
Die Architektur
Eine plattformübergreifende PWA — Web für die Inhaber, Telefone fürs Personal, eine Service-Ansicht — über einem einzigen verwalteten Postgres mit Row-Level Security und Realtime, dazu eine serverseitig gerenderte öffentliche Website, die dieselbe Datenbank nutzt.
Daten werden gestuft zwischengespeichert, je nachdem, wie oft sie sich tatsächlich ändern — Live-Service-Daten aktualisieren in Sekunden, Speisekarten in Tagen — hinter einem Adapter über Browser- und nativem Speicher. Die öffentliche Site rendert aus derselben Datenbank, die die Küche bearbeitet, und sowohl Web als auch App reagieren auf denselben row insert, sodass eine irgendwo eingetragene Reservierung genau eine Bestätigung auslöst.
Die Lieferanten-Schicht war der schwierigste Teil des Aufbaus. Keiner der sechs B2B-Lieferanten bot eine brauchbare API. Einer hatte einen Webshop, dessen Bestell-Endpunkte ich in einen programmatischen Bestellablauf reverse-engineert habe; ein anderer stellte einen halbstrukturierten JSON-Feed bereit; ein dritter hatte nichts außer einem Katalog, der mit Playwright gescrapt wurde. Über diese drei völlig verschiedenen Zugriffsmethoden liegt eine Normalisierungs-Pipeline, die dasselbe Produkt über alle sechs Lieferanten hinweg unscharf abgleicht — sodass ein Preisvergleich Gleiches mit Gleichem vergleicht und eine Bestellung an den jeweils günstigsten der Woche geleitet werden kann. Heterogene, undokumentierte Quellen dazu zu bringen, sich wie ein sauberer Katalog zu verhalten, war der Großteil der Ingenieursarbeit — und das macht aus „Bestellen" statt einer lästigen Pflicht eine Entscheidung.
| Lieferanten-Quelle | Integrationsmethode | Fragilität |
|---|---|---|
| Webshop, keine API | reverse-engineerte Bestell-Endpunkte | bricht bei einem Site-Redesign |
| Halbwegs strukturiert | halbstrukturierter JSON-Feed | bricht bei Schema-Drift |
| Nur Katalog | Playwright-gescrapt | bricht bei Markup-Änderung |
Eine Änderung, viele Ziele. Hier zahlt sich der Integrations-Bus aus. Eine einzelne Speisekarten-Änderung breitet sich von einer Stelle aus aus: Die öffentliche Website aktualisiert sofort, die hinterlegten Rezepte, die Portions- und Mengenberechnungen steuern, aktualisieren mit, und diese Mengen speisen die reverse-engineerte Lieferanten-Schicht, die die Bestellungen aufgibt. Der saisonale Speisekarten-Wechsel — drei Speisekarten pro Jahr — war früher tagelange manuelle systemübergreifende Bearbeitung; jetzt ist es eine Aktion in der App. Die Menü-Übersetzung läuft denselben Weg: ein LLM in der App übersetzt jede Speisekarte in die anderen Sprachen und ersetzt einen rund 200 € teuren professionellen Auftrag pro Menü durch einen Aufruf für Cent pro Lauf.
Live-Tischstatus über NFC. Das Personal setzt den Live-Zustand eines Tisches — Getränke serviert, Essen serviert, Tisch abgeräumt — durch Antippen eines NFC-Tags am Tisch. Jeder Tap ist ein mit Zeitstempel versehenes Ereignis, das in dasselbe Realtime-Postgres-Backbone geschrieben wird (ein weiterer row insert → notify-Produzent), sodass der Tischzustand sofort über Web-, Personal- und Service-Ansicht geteilt wird.
Die Datenbank ist der Integrations-Bus: Quelle der Wahrheit und Ereignis sind dieselbe Zeile.
Entscheidungen & Abwägungen
Cache-TTL pro Datentyp, nicht eine globale Konstante. Die Frische nach Volatilität zu bemessen, beseitigte sowohl die Veraltungs-Bugs als auch die unnötigen Roundtrips, die ein einzelnes TTL verursachte. Der Preis ist eine Invariante, die man überall halten muss: jeder Schreibvorgang invalidiert seinen Cache-Key.
Eine Website, immer synchron mit der Speisekarte. Die öffentliche Site liest aus derselben Datenbank, die die Küche bearbeitet, sodass eine Speisekarten-Änderung sofort live ist — kein zweites System zu pflegen, keine Verzögerung, über die Gäste stolpern. Die Abwägung: Die öffentliche Site erbt die Form der operativen Datenbank statt eines eigenen, sauberen Content-Modells.
Die Lieferanten reverse-engineeren und die Fragilität in Kauf nehmen. Gegen undokumentierte Webshop-Endpunkte und einen Scraper zu bauen, war der einzige Weg, an Preise zu kommen, die die Lieferanten schlicht nicht veröffentlichen — aber diese Integrationen brechen, sobald ein Lieferant seine Site neu gestaltet. Die Abwägung war explizit: eine brüchige Integration, die einen Live-Preisvergleich liefert, schlägt eine stabile, die es nicht gibt. Jede Quelle ist isoliert und unabhängig validiert, sodass sie, wenn eine bricht, allein degradiert, statt den ganzen Katalog mitzureißen.
NFC-Tap statt In-App-Navigation. Der Live-Status wird durch einen physischen Tap auf ein Tag am Tisch gesetzt, nicht durch das Durchsuchen von App-Bildschirmen. Während eines vollen Service navigiert das Personal nicht durch Menüs — ein reibungsloser Tap wird tatsächlich genutzt, und Akzeptanz, nicht das Datenmodell, ist die echte Grenze. Die Abwägung: NFC-Tags sind physische Infrastruktur, die platziert und gewartet werden muss, und die Daten sind immer nur so gut, wie das Personal daran denkt zu tippen.
Was gebrochen ist
Der übelste Bug war ein nur im Web auftretender Endlos-Spinner beim Fortsetzen (Resume). Der Browser serialisiert die Aktualisierung des Auth-Tokens über ein Lock, und beim Resume wartete ein Datenlesevorgang auf ein Lock, das nie zurückkehrte. Der erste Fix — ein 10-Sekunden-Timeout — ließ den Spinner sich beruhigen statt zu hängen, aber der nächste Lesevorgang scheiterte identisch, weil das Token weiterhin tot war. Der eigentliche Fix aktualisierte die Session vor dem Lese-Sturm nach dem Resume.
Ein Timeout erkauft eine überlebbare UX; nur die Frage „was scheitert beim nächsten Versuch?" führt zur Ursache.
Das Ergebnis
Seit Dezember 2025 im Produktivbetrieb, mit weiterhin neuen Funktionen — und die Erfolge bleiben bewusst getrennt, jeder auf genau das begrenzt, was er verändert hat, statt zu einer Zahl zusammengefasst.
Die Dienstplanung sank von ~2 Stunden WhatsApp-Koordination auf ~30 Minuten pro Woche in der App (diese Zahl betrifft allein die Dienstplanung). Inventar und Bestellerzeugung, früher ein paar Stunden der Woche des Inhabers, werden jetzt vom Personal direkt in der App erledigt — ein Zugewinn an Delegation und Fähigkeit, keine gemessene Zahl. Saisonale Speisekarten-Wechsel (drei Speisekarten pro Jahr) gingen von mehreren Tagen manueller systemübergreifender Arbeit — Website, hinterlegte Rezeptmengen und die Lieferanten-Verknüpfungen, die sie speisen — auf eine einzige Aktion in der App. Die Menü-Übersetzung wechselte von einem professionellen Auftrag zu rund 200 € pro Menü zu einer LLM-Übersetzung in der App für Cent. Reservierungen werden jetzt digital erfasst, sodass keine Buchungen mehr verloren gehen, und die damit verbundenen Gast-Kontaktdaten eröffneten eine Feedback-Schleife, die es auf Papier nicht gab.
Die NFC-Schicht eröffnet etwas, das das Restaurant nie hatte: Weil jeder Status-Tap einen Zeitstempel trägt, werden Service-Zeiten — Zeit bis zum Getränk, Zeit bis zum Essen, Tischwechsel — zum ersten Mal messbar. Es werden noch keine Zahlen behauptet; die Fähigkeit selbst ist das Ergebnis.
Geplant, nicht ausgeliefert: das Live-Signal „Tisch frei" wird die Echtzeit-Reservierungskapazität auf der öffentlichen Website speisen, sodass die Online-Buchung die tatsächliche Verfügbarkeit im Raum widerspiegelt. Die Daten fließen bereits über den Bus — sie in den öffentlichen Buchungsfluss einzubinden, ist der nächste Schritt.