Case Study

Mix & Match Kain

A local food ordering system built for a real restaurant in Palawan. Deployed live. Survived a production outage. Sold out on its first run.

Type Full-Stack Web App
Stack Node.js · Express · WebSockets · Vanilla JS
Deployment Local network · LAN only
Status Completed · Live
Outcome Sold out First live run
Reliability 0 downtime During outage
Incidents 2 fixed live No shutdown
Architecture Local-first LAN-only deployment

What Was Actually Broken

The restaurant had no digital ordering system. Staff were taking orders manually, tracking stock by memory, and handling cash payments with no running total. During busy service, orders got confused, stock ran out without warning, and the payment process slowed everything down.

Three operational failures needed fixing: ordering speed, real-time stock visibility, and payment tracking. The solution had to work for non-technical staff and require no internet dependency — the system needed to run even if connectivity dropped.

What I Was Working With

Non-technical staff. The system had to work without any training. No logins, no app installs, no setup for customers.
No reliable internet guaranteed. The venue had WiFi but it couldn't be a dependency. A network drop couldn't take orders down.
I was the only developer. No team, no QA, no staging environment. Built, tested, and debugged solo.
Live debugging was the only fallback. No rollback plan. No second machine. If something broke during service, I fixed it on the spot.

How It Was Built

Both frontend and backend ran locally on the same machine during the event. Customers connected over the restaurant's WiFi and accessed the ordering interface directly from their own phones — no app install, no account required.

The decision to run everything on LAN was deliberate. It meant minimal latency on order submission, no dependency on external services, and the system continued operating when the internet dropped mid-event.

Customer phone Restaurant WiFi · own device Menu & cart Browse · add items · review order QR checkout Order encoded · QR generated Local machine · LAN only · no internet required Node.js / Express localhost:3000 · WebSockets Payments Order records Stock updates
Node.js Express WebSockets Vanilla JS HTML / CSS LAN deployment

System in Operation

Screenshots from the live deployment — customer ordering flow, QR checkout, and the admin order queue.

Customer ordering UI
QR checkout flow
Admin order queue
Live stock view

What Broke During Service

Three incidents occurred during the live event. All were resolved without taking the system offline.

QR codes not loading Incident
What happened: Under real load, QR generation was failing silently on some customer devices. Orders were being submitted but the QR was not rendering.
Root cause: The QR was being generated before the DOM element was ready — a timing issue that only surfaced under concurrent usage, not during local testing.
Fix: Patched live in approximately 30 minutes while service continued. No orders were lost.
Order totals drifting from actual values Incident
What happened: The running totals on the staff view were showing incorrect amounts — the numbers were drifting as more orders came in simultaneously.
Root cause: Concurrent order submissions were hitting the same total counter without sequencing. A state synchronization bug that didn't appear in single-user testing.
Fix: Fixed during active service. System remained operational throughout.
Internet outage mid-event No impact
What happened: The venue's internet connection dropped during service.
Impact: None. Both frontend and backend were running locally on the same machine. All customer ordering, stock updates, and payment recording continued without interruption.
Outcome: The local-first architecture allowed the system to continue operating when the internet dropped. Customers and staff did not notice.

What Was Sacrificed

Chose
LAN-only deployment — no external services, no cloud dependency, survives internet outage.
Gave up
Remote access — can't monitor or manage the system from outside the local network.
Chose
No login required — any customer on the WiFi can order immediately, no friction.
Gave up
Authentication — no user accounts, no order history, no per-customer tracking.
Chose
In-memory state — fast, simple, no database setup required for deployment.
Gave up
Data persistence — a server restart loses all orders. No post-event analytics.

What I'd Build Differently

01
Error logging before deployment Both production bugs were found by customers, not by the system. A proper error logging layer would have surfaced the QR timing issue and the total drift during load testing, not during live service.
02
Atomic order state updates The total calculation bug came from concurrent writes hitting the same counter without sequencing. An atomic update pattern or a simple queue would have prevented it entirely.
03
Persistent storage Running everything in memory meant a server restart wiped all orders. SQLite or a lightweight local database would have given the restaurant post-event records without adding cloud dependency.
04
Startup automation Pre-event setup was manual — start the server, confirm the LAN IP, check connections. A single startup script with environment validation would have reduced setup time and pre-event stress.

What Happened

The system was deployed during a live restaurant event. Order volume exceeded what was expected. Two bugs were found and fixed while service was running — neither required taking the system offline. The internet dropped mid-event and the system continued without interruption.

The kitchen ran out of food before the system ran out of capacity. That was the real test.

Known limitations remain: no persistent storage, no authentication, manual startup, no offline fallback if the local server crashes. Those are the next things to fix before the next deployment.