Betriebs-App Gastronomie
Eine App, die Dienstplan, Lager und die Bestellung bei sechs Lieferanten in einem Restaurantbetrieb zusammenführt.
- seit 2025
- live
- Architekt & Umsetzer
- React Native, Expo SDK 54, Supabase, TypeScript, Playwright
Das Problem
Ein Restaurant plante Dienste, bestellte Ware und pflegte seine Speisekarte von Hand. Der Dienstplan kostete jede Woche rund zwei Stunden Abstimmung per WhatsApp, Bestellungen bei Lieferanten gingen unter, und weil die öffentliche Website der echten Karte hinterherhinkte, kamen Gäste mit veralteten Angaben an. Reservierungen standen auf Zetteln, von denen gelegentlich einer verschwand.
Dazu kam eine blinde Stelle: Wie ein Service tatsächlich lief, konnte niemand sehen. Wie lange ein Tisch auf die Getränke wartete und wie lange aufs Essen, wusste keiner, und damit fehlte auch jeder Ansatzpunkt, um daran etwas zu verbessern.
Beteiligt waren rund zwanzig Mitarbeitende und die Inhaber, die Gäste, die buchen und essen, und sechs Großhändler mit ständig wechselnden Katalogen und Preisen, von denen keiner eine brauchbare Schnittstelle anbot. Zu bauen war ein System, dem alle gleichzeitig vertrauen.
Die Lösung
Eine App für Inhaber, Personal und Service, darunter eine einzige gemeinsame Datenbank. Dienstplan, Lager, die Bestellung bei sechs Lieferanten und die öffentliche Website lesen und schreiben dieselben Daten, sodass eine geänderte Karte oder eine Reservierung überall zugleich ankommt. NFC-Tags an den Tischen halten jeden Schritt im Service mit Zeitstempel fest.
- ~2 h Hin und Her per WhatsApp
- ~10 Min. in der App
- handschriftliche Notizen, gingen teils verloren
- eine Live-Übersicht für das ganze Team
- Chefsache, Bestellungen gingen unter
- das Team pflegt es in der App, Bestellungen entstehen automatisch
- im Service nicht sichtbar
- pro Tisch erfasst: Zeit bis zum Getränk, Zeit bis zum Essen
- auf Papier gab es keinen Kanal
- Rückmeldung über den Reservierungskontakt
- Nachfrage in der Küche mitten im Service
- steht im Service in der App
- ~200 € pro Karte, extern vergeben
- Cent pro Lauf, Sprachmodell in der App
- tagelange Änderungen in mehreren Systemen
- eine Aktion in der App
~2 h → ~10 Min.
~200 € → Cent
seit Dez. 2025
Das Ergebnis
Im Einsatz ist das System seit Dezember 2025, und es kommen weiter Funktionen dazu. Die Ergebnisse stehen bewusst einzeln und bleiben auf das begrenzt, was sie tatsächlich verändert haben, statt zu einer Zahl verrechnet zu werden.
Der Dienstplan kostet statt rund zwei Stunden Abstimmung noch etwa zehn Minuten pro Woche in der App. Lager und Bestellung waren früher ein paar Stunden aus der Woche des Inhabers und liegen heute beim Personal, das sie direkt in der App führt, was ein Zugewinn an Delegation ist und keine gemessene Zahl.
Der saisonale Kartenwechsel, dreimal im Jahr, brauchte Tage an Änderungen in Website, Rezeptmengen und Lieferantenverknüpfungen und ist heute eine einzige Aktion. Die Übersetzung der Karte kostet Cent statt rund 200 € pro Karte. Reservierungen laufen digital und gehen nicht mehr verloren, und über die hinterlegten Kontaktdaten gibt es erstmals eine Rückmeldung von Gästen.
Die NFC-Schicht eröffnet etwas, das der Betrieb nie hatte: Weil jeder Tap einen Zeitstempel trägt, sind die Zeiten im Service erstmals messbar, bis zum Getränk, bis zum Essen, bis der Tisch wieder frei ist. Zahlen behaupte ich hier noch keine, die Messbarkeit selbst ist das Ergebnis.
Geplant, noch nicht ausgeliefert: Das Signal „Tisch ist frei" soll die Reservierungskapazität auf der Website speisen, damit die Online-Buchung zeigt, was im Raum wirklich verfügbar ist. Die Daten laufen schon über den Bus, es fehlt die Anbindung an die öffentliche Buchung.
Die Technik dahinter
Die Architektur
Oben steht eine plattformübergreifende App: im Browser für die Inhaber, auf dem Telefon für das Personal, dazu eine eigene Ansicht für den Service. Darunter liegt eine einzige verwaltete Postgres-Datenbank mit Row-Level Security und Realtime, aus der auch die öffentliche Website liest, die serverseitig gerendert wird.
Zwischengespeichert wird nach Änderungsrate, wobei ein Adapter Browser- und Gerätespeicher kapselt: Live-Daten aus dem Service laufen im Sekundentakt nach, Speisekarten in Tagen. Weil Website und App auf denselben row insert reagieren, löst eine Reservierung genau eine Bestätigung aus, egal wo sie eingetragen wurde.
Die Lieferanten waren der schwierigste Teil. Keiner der sechs bot eine Schnittstelle an, weshalb ich bei einem die Bestellendpunkte des Webshops so lange rückentwickelt habe, bis sich darüber programmatisch bestellen ließ; ein zweiter lieferte immerhin einen halbstrukturierten JSON-Feed, und beim dritten blieb nur der Katalog, ausgelesen mit Playwright.
Über diesen drei Zugängen liegt eine Normalisierung, die dasselbe Produkt bei allen sechs Händlern wiedererkennt, auch wenn jeder es anders benennt und anders verpackt. Erst dadurch vergleicht der Preisvergleich Gleiches mit Gleichem, und erst dadurch kann eine Bestellung an den günstigsten Anbieter der Woche gehen. Diese Vereinheitlichung war der Großteil der Arbeit, und sie macht aus dem Bestellen eine Entscheidung statt einer Pflichtübung.
| Lieferantenquelle | Zugang | Was sie brechen lässt |
|---|---|---|
| Webshop ohne API | rückentwickelte Bestellendpunkte | ein Relaunch der Website |
| Teilweise strukturiert | halbstrukturierter JSON-Feed | eine Änderung am Schema |
| Nur Katalog | mit Playwright ausgelesen | eine Änderung am Markup |
Eine Änderung, viele Ziele. Hier zahlt sich die gemeinsame Datenbank aus, weil eine Änderung an der Karte von einer Stelle aus in alle Richtungen wirkt: Die Website zeigt sie sofort, die hinterlegten Rezepte rechnen Portionen und Mengen neu, und diese Mengen gehen in die Lieferantenschicht, die die Bestellung auslöst.
Der saisonale Kartenwechsel, dreimal im Jahr, kostete früher Tage an Handarbeit in mehreren Systemen und ist heute eine einzige Aktion in der App. Die Übersetzung der Karte läuft denselben Weg: Ein Sprachmodell in der App übersetzt in die übrigen Sprachen, für Cent statt für rund 200 € pro Karte beim Dienstleister.
Tischstatus per NFC. Das Personal setzt den Status eines Tisches, indem es ein NFC-Tag am Tisch antippt: Getränke serviert, Essen serviert, Tisch abgeräumt. Jeder Tap ist ein Ereignis mit Zeitstempel und geht in dieselbe Realtime-Datenbank, sodass der Status sofort in allen Ansichten steht.
Die Datenbank ist der Integrations-Bus: der führende Datensatz und das Ereignis sind dieselbe Zeile.
Entscheidungen und Abwägungen
Cache-Dauer pro Datenart, nicht eine globale Konstante. Ein einziger Wert für alles erzeugte beides, veraltete Anzeigen und überflüssige Abfragen; sobald sich die Frische nach der Änderungsrate richtet, fällt beides weg. Bezahlt wird das mit einer Regel, die dann überall gelten muss: Jeder Schreibvorgang macht seinen Cache-Eintrag ungültig.
Eine Website, die nie hinterherhinkt. Sie liest aus derselben Datenbank, die die Küche pflegt, also ist eine Kartenänderung sofort öffentlich, und es gibt kein zweites System zu pflegen. Erkauft ist das damit, dass die öffentliche Seite die Struktur der Betriebsdatenbank erbt statt eines eigenen, sauberen Inhaltsmodells.
Die Lieferanten rückentwickeln und die Brüchigkeit hinnehmen. Gegen undokumentierte Endpunkte und einen Scraper zu bauen war der einzige Weg an Preise, die diese Händler nicht veröffentlichen, und solche Integrationen brechen, sobald ein Lieferant seine Seite umbaut. Die Abwägung war bewusst: Eine brüchige Anbindung, die den Preisvergleich liefert, ist mehr wert als eine stabile, die es nicht gibt. Jede Quelle ist gekapselt und wird einzeln validiert, damit ein Ausfall nicht den ganzen Katalog mitreißt.
Antippen statt durch die App navigieren. Im vollen Service sucht niemand einen Bildschirm, während ein Tap auf das Tag am Tisch nichts kostet und deshalb tatsächlich benutzt wird. Die Grenze eines solchen Systems ist die Akzeptanz und nicht das Datenmodell. Dafür sind NFC-Tags physische Infrastruktur, die angebracht und ersetzt werden muss, und die Daten sind nur so gut, wie das Personal ans Antippen denkt.
Was schiefging
Der hartnäckigste Fehler trat nur im Browser auf: Nach dem Aufwecken eines Geräts drehte sich der Ladekreis endlos. Die Erneuerung des Auth-Tokens serialisiert der Browser über ein Lock, und beim Aufwachen wartete eine Datenabfrage auf genau dieses Lock, das nie zurückkam.
Der erste Versuch war ein Timeout nach zehn Sekunden, womit die Oberfläche zwar nicht mehr hing, die nächste Abfrage aber genauso scheiterte, weil das Token weiterhin tot war. Die eigentliche Lösung erneuert die Session, bevor nach dem Aufwachen die Welle von Abfragen losläuft.
Ein Timeout erkauft eine erträgliche Oberfläche. Zur Ursache führt erst die Frage, was beim nächsten Versuch passiert.
Ein ähnliches Problem im eigenen Betrieb?
Was ich für Unternehmen macheSie besetzen eine Rolle in angewandter KI oder Solutions-Architektur?
Der vollständige Werdegang