Sean Orgaz

Work

White-Label Restaurant Platform

Restaurants that want their own ordering app usually can't afford one, so they rent a slot in someone else's marketplace and give up the customer relationship. This platform gives each restaurant its own branded iOS app, web ordering, and staff dashboard from one shared codebase and one backend. A new restaurant is a row in the database and a config file, not a fork.

Type
Software · Product · iOS
Surfaces
Customer iOS app · Web ordering · Staff dashboard · Operator console
Stack
TypeScript · Fastify · Postgres (Drizzle, row-level security) · Next.js · SwiftUI · Stripe Connect · Docker · Railway
The staff dashboard, recorded against the demo tenant. Demo data.

01The problem

A branded app is out of reach for one restaurant, so they rent a slot in someone else's.

Custom apps cost more than most independent restaurants make in a year, so they end up on third-party marketplaces: high commissions, no customer data, and a menu that looks like everyone else's. The alternative, forking a template app per client, is how white-label vendors drown in maintenance.

I wanted to know if one codebase and one backend could serve many restaurants, each with a genuinely separate app under their own name, without copying code for every new client.

02The approach

Clone by configuration, never by copying code.

Every restaurant is a tenant: a row in the database plus a brand file with its name, colors, icon, and feature flags. The customer apps, the dashboard, and the API are each one codebase serving every tenant. Shipping a fix to all restaurants is one commit. Onboarding a new one is a config file and a build, not a new project.

  • Customer iOS app: native SwiftUI, one codebase, one branded build per restaurant under the restaurant's own App Store account
  • Web ordering: the same experience in a browser, tenant resolved from the URL, no install
  • Staff dashboard: live orders, kitchen board, menu, customers, reservations, rewards, marketing, analytics
  • Operator console: where new restaurants get created, branded, and built

03For the restaurant

Orders come in, tickets move, and the owner sees the whole business in one place.

The dashboard is where a restaurant lives during service. New orders land on a live board and move through accepted, preparing, and ready; the kitchen screen shows the same tickets by station with a timer on each. Around that sit the menu editor, customer records, reservations, rewards, marketing, reviews, and analytics.

Live orders board with new, accepted, preparing, and ready columns
Live orders board. Demo data.
Kitchen display with tickets by station and timers
Kitchen board. Demo data.
Menu editor with categories, items, and prices
Menu editor. Demo data.
Owner overview with a morning briefing and today's numbers
Owner overview. Demo data.
Analytics with revenue, top items, peak hours, and sales by channel
Analytics. Demo data.
Customer list with visit counts and loyalty tiers
Customers. Demo data.

04For the guest

Their restaurant's app, with their restaurant's name on it.

A guest downloads the restaurant's own app or opens its web ordering page. Menu, ordering, pickup or delivery, rewards, gift cards, reservations, and messages, all themed to that restaurant from the brand file the app fetches at launch. Sign-in is a phone number and a code, because nobody remembers a password for a pizza place.

Web ordering page for a demo restaurant with hero image, offers, and menu
Web ordering. Demo restaurant.
iOS app home screen with tonight's special and menu categories
The iOS app, signed in. Demo data.
iOS app menu browse with offers and gift cards
Menu and offers.
iOS reservations screen with party size, dates, and times
Reservations.
iOS rewards screen with a membership card and points
Rewards.
iOS account screen with favorites, order history, wallet, and settings
Account.
Web rewards sign-in
Rewards on the web.
Web reservation booking with party size, date, and available times
Reservations on the web.

05How it works

One API, one database, and rules that make a cross-tenant bug impossible to write.

Every tenant-owned table carries a tenant id, and Postgres row-level security enforces it, so a request can only ever see its own restaurant's rows. Tenant identity comes from the signed-in token or the app's API key, never from a request parameter. Money is integer cents everywhere and order totals are always computed on the server.

Payments run through Stripe Connect, so each restaurant is paid into its own account and the platform never holds funds or touches card data. An order is written before payment and only becomes placed when Stripe's webhook confirms it, handled idempotently so a retry can't create a second order. Push goes out over APNs for app users and falls back to SMS for web guests.

The iOS build pipeline is the part most white-label products get wrong. Here the Xcode project is generated from a config file per tenant, built and submitted with fastlane under the client's own developer account, and only the app name, icon, bundle id, and API key are baked in. Theme and feature flags come from the API at launch, so most changes never need an App Store release.

  • Fastify REST API under /v1, one instance serves every tenant
  • Postgres with a migrator role and an app role that cannot bypass row-level security
  • Order status flow: pending payment → placed → accepted → preparing → ready → completed
  • Unacknowledged-order alerts so a paid order can never sit unseen
  • Typecheck, lint, unit, and end-to-end tests in CI; API and web clients ship as Docker images

06My role

Solo, end to end.

System design and the written architecture document, the data model and migrations, the API, both Next.js apps, the native iOS app, the per-tenant build pipeline, payments, notifications, the operator tooling, tests, and the deployment runbook. Built with AI assistance as a deliberate part of the workflow, which is how one person ships this much surface area.

07Where it stands

Built end to end, demoed with fictional restaurants, not yet launched with a paying one.

Everything on this page is real software running against seeded demo tenants. Ember & Oak and Urban Greens are invented, and so are their customers and orders. The next step is the same one every product faces: a first restaurant.

08What I learned

Multi-tenancy is a discipline, not a feature.

Catalyst Art taught me to build for one client. This taught me to build for many at once without building for any of them. Every table, every query, every screen had to be designed so that the second, tenth, and fiftieth restaurant cost nothing extra. Getting the security model into the database itself, rather than trusting application code to remember, was the single decision that made the rest possible.

It also made me respect the boring choices: one API, one database, integer cents, and a payment flow that refuses to believe the client. Those are what let a solo developer sleep.