The client came to us before opening — planning a five-brand ghost kitchen running out of one prep line, and looking for a system that could carry it from launch. The brief was clear: every brand had to feel like its own shop to the customer, but the kitchen, the admin and the books needed to behave like one operation. We built the whole stack to that brief, ready on opening day.
Each brand gets its own catalog page, its own colour, its own status tracker, its own Instagram-style feed. To the customer it reads as a focused shop. Behind the curtain it's one database, one kitchen dashboard and one finance log — tagged by brand at every row, so the math will be honest from the very first month-end.
Instagram-feed style menu per brand — carousel posts, double-tap love, add-to-cart stepper, catatan field. Each brand has its own URL, palette and tone of voice. Customer taps the brand's Instagram or TikTok bio link, lands on its storefront and sees one shop, not five.
Live geolocation calculates delivery fee against the kitchen pin before the customer commits. Pays via tunai / QRIS / transfer. Order lands in the kitchen the moment the QRIS hits.
One screen on the prep line. Every order in queue, colour-bordered by brand. Stations swipe through queued → cooking → ready. Live counts at the top. No paper tickets, no lost orders.
Five phases — placed, paid, cooking, out for delivery, arrived. Customer sees the brand they ordered from, not "ghost kitchen." Auto-updated from kitchen dashboard taps. The status URL stays in their browser so they can re-open it instead of calling.
Owner's dashboard. Filter by brand, by phase, by date. See active orders, today's count, history, brand-by-brand revenue split. One view to manage all five brands — no switching apps.
Per-brand revenue tracking with shared-cost allocation (rent, staff, gas, packaging). Monthly P&L per brand auto-computed. Marketing budget tracker so we know cost-per-customer per brand — the only number that decides what we launch next.
Five brands, one prep line. Two live on opening day; three pre-wired in the database.
The client wanted to launch with two brands and have three more pre-wired in the database for later. Each brand had its own positioning, palette and audience — a customer ordering a Korean rice bowl should never know the same kitchen also ships geprek. The customer surface had to read as a single, focused brand from the first tap.
But repeating the build five times was off the table. We needed one shell that wore five faces — clean to launch a new brand in a day, not a sprint.
A single PWA shell renders the storefront. A brand slug in the URL pulls the right colour tokens, type, products and copy at boot — same code, different shop. Customer taps a brand's Instagram or TikTok bio link, lands on its focused storefront, never sees the others.
Spinning up a new brand for the client is now a row in a database, a colour and a product list. Geprek 28 and Sego Sambel shipped in week 2; Bap Bowl, Nasgor Mas and Tumis Bunda are pre-wired for whenever the client decides to flip them on.
The risk the founders flagged early: with one prep team handling five brands, brand context disappears between order and plate. A "nasi + sambal + ayam" ticket could belong to Geprek 28, Sego Sambel or Nasgor Mas — and a wrong-brand box landing at a customer's door on launch week would be very public, very fast.
The kitchen surface had to make the brand impossible to miss, even at peak service, even on the first shift the team ever ran.
Every ticket on the kitchen screen carries a coloured left-bar — one colour per brand. The brand name sits on top in bold mono. There's no scenario where the cook is reading a ticket without knowing whose order it is.
Tap to advance: antri → masak → siap. The customer's status tracker updates instantly. The admin's brand-queue chip ticks down by one. One tablet, three swipes, no second screen to keep in sync — ready for the staff to learn in an afternoon.
Shared kitchen, shared staff, shared gas, shared packaging supplier. Per-brand revenue is trivial — sum the receipts. Per-brand profit is the harder number. The founders wanted that visible from month one, not after a year of guessing.
The point: the "do we launch the fourth brand?" call should be made on a number, not a feeling. That meant building shared-cost allocation into the system before the first order ever landed.
Every order, ticket, status row and ledger entry carries the brand id from the moment it's written. Shared costs (rent, gas, base staff) auto-allocate by each brand's share of orders that month. Brand-specific costs (packaging SKUs, ingredients tagged to a brand) hit the right ledger directly.
Marketing spend is attached to a brand and a campaign — cost-per-customer computes itself from the order log. The brand-aware admin gives the owner one screen to read all six.
We didn't start with the database. We started with a mocked catalog page for one of the launch brands, on a phone, and put it in front of the founders — would a customer believe this was a real shop? Once that landed, we worked backwards into the kitchen and the admin.
This is what the founders walk into on opening day. Live-ops numbers (CAC, per-brand margin, throughput) come once the kitchen is running — we'll publish them when there's real data behind them.
The customer storefront is a single PWA. A brand slug in the URL pulls the brand's theme tokens (colours, typography, copy), product list and order destination at boot. New brand = new row in the brands table, new product list, ship.
Hosted on the same XAMPP setup the owner already runs for the rest of the operation. No build step, no Docker, no reinvention. Cousin-can-read-it on purpose — the kitchen screen has to keep working when the developer is asleep.
Every order, ticket, status row and ledger entry carries the brand_id. Kitchen filters by it, admin filters by it, finance allocates by it. There is no place in the system where a row exists without knowing which brand it belongs to.
Customer arrives from the brand's Instagram or TikTok bio link, opens a PWA, orders, pays QRIS, watches the status URL. No app store, no login. The brand's social does the marketing job; the storefront just has to convert.
A wall-mounted Android tablet on the prep line. Tickets stream in, colour-bordered. Tap to advance through three states. Live counts at the top so the cook knows the queue depth without opening anything.
Rent, gas and base staff cost get split each month by each brand's share of total orders. Brand-specific costs (packaging SKUs, ingredients tagged to a single brand) hit the right ledger directly. Owner-readable formula visible per row.
Free scope-out call. We've done it for ourselves — we know what bites at month two.