Case study · Dispense
Dispense · Banquets Bar Sales Tracker
A POS-style sales tracker running live at a 5-star Sydney hotel's banquet bars.
The problem
Banquet bar sales were tallied by hand. At the end of every function, the bar total had to be reconciled against the EFTPOS terminal's settlement printout and re-keyed into the hotel's MICROS POS. Slow, error-prone, and done at the end of a long shift.
The solution
An iPad-first web app (PWA) shaped around how a banquet bar shift actually runs: set up the night's bar before doors ("Mise en Place"), ring sales through service with a two-tap flow built for speed in the dark, then close with an end-of-day screen that reconciles card totals against the EFTPOS settlement and produces a MICROS-ready report. One tap to copy, no mental arithmetic at midnight.
Interactive
This is not a portfolio mock-up. It is the tracker the bar actually runs on.
Technical breakdown
-
Offline-first PWA
Installs to the iPad home screen and keeps working with no network. Every mutation persists to localStorage, and a service worker caches the app shell so a dropped connection mid-service costs nothing.
-
Cloud sync with row-level security
State syncs to a Supabase (Postgres) backend keyed by venue and terminal, so a replaced iPad resumes exactly where the old one stopped. The client ships only a publishable key, and row-level security policies scope it to a single table, so the browser can touch nothing else.
-
Tested core logic
Report maths, preset resolution and the item×payment matrix live in a pure, DOM-free module exercised by a Node test suite. The numbers the hotel reconciles against are covered by tests.
-
Iterated in production
Version 1 shipped and ran live; feedback from real shifts drove a ground-up redesign (Dispense): cleaner service flow, EFTPOS reconciliation, and the MICROS hand-off that removed the shift's most error-prone step.
-
Honest scale
One venue, a handful of terminals, real users every function. Built, deployed and maintained solo alongside study and the job itself.