root / work / restaurant-os
Active — Mobile · F&B SaaS

RestaurantOS

Multi-branch restaurant mobile app — menus, table booking, scheduling, and live brand presence in one experience

Started
2025
Repository Private / Internal

The Context

Most restaurant apps are either glorified PDFs or third-party aggregators that strip the brand identity entirely. A restaurant group with multiple branches has a different problem — each branch has its own menu variations, table layouts, peak hours, and booking capacity, but they all need to live under one unified brand experience. This app was built to give the restaurant full ownership: customers open one app, pick their branch, browse that branch's live menu, book a specific table at a specific time, and receive confirmations — while the operations team manages everything from a single backend that keeps each branch's data cleanly isolated.

Architecture & Execution

The API is organized around a branch-scoped context — every request carries a branch identifier, and the data layer enforces strict isolation so menus, tables, availability windows, and booking records never bleed across locations. Each branch maintains its own menu catalog with categories, items, pricing, and availability toggles that the ops team can update live. The table booking engine models each branch's floor layout as a set of bookable units with capacity and time-slot constraints. When a customer requests a reservation, the engine checks real-time availability from a Redis cache (refreshed on every booking mutation), confirms the slot, and writes the reservation to SQL Server. Firebase handles push notifications for booking confirmations, reminders, and cancellations. The advertisements and announcements layer is a lightweight CMS-style feed — branch managers publish offers and promotions that surface immediately in the app without a release cycle.

Post-Mortem Lessons

01

Multi-branch data isolation sounds like a schema decision until you're debugging why branch A's menu showed up in branch B's app. Enforcing branch context at the API middleware level — not just in queries — was the only way to make it airtight.

02

Table availability is a classic double-booking problem in disguise. Optimistic locking on reservation slots with a short Redis TTL on pending holds prevented race conditions during peak traffic without adding noticeable latency.

03

Live menu updates feel like a small feature until the ops team starts using them at 2pm on a Friday. Designing the cache invalidation strategy around menu mutations — not just TTL expiry — was what made instant updates actually instant.

Branch Architecture
Multi
Menu & Offers Feed
Live
Table Booking Engine
Full
Reservation Scheduling
Real-time
Core Technologies
Flutter .NET 9 ASP.NET Core SQL Server Redis Firebase Cloudflare
Customer App (Flutter)
          ↓
   ASP.NET Core API
    ↙      ↓       ↘
Branch   Menu     Booking
Context  Service  Engine
    ↓       ↓        ↓
  Tables  Live     Schedule
  & Caps  Offers   & Confirm
          ↓
  Firebase (push)
  Redis (availability cache)
  SQL Server (source of truth)