One system from QR code to profit report
A complete restaurant operating system: customers order by scanning, staff bill in under fifteen seconds, cooks work a live ticket board, and the owner sees profit for any date range.
- Client
- Pizza Theory
- Industry
- Restaurants & Food Service

What was the problem?
Order entry slow enough to build a queue during a rush, a kitchen that started cooking before payment confirmed and absorbed every mistake as wasted food, and customers interrupting staff to ask where their order was. Stock and expenses were reconstructed after closing rather than captured during service.
What made it hard
Commercially
- Replacing a paper workflow without asking staff to learn complex software
- Delivering POS capability without per-terminal licensing or dedicated hardware
- Giving the owner profit rather than just sales
Technically
- Invoice numbers that cannot collide when two cashiers and a QR customer confirm in the same millisecond
- Four distinct user experiences over one shared data model
- Real-time propagation across every open device with no refresh button
- Keeping read performance constant as years of order history accumulate
- Bridging a staff credential system to database-level security rules
Operationally
- Billing fast enough to survive a rush
- Cooks needing a screen with no prices and no customer data
- Owner needing to add and remove staff without a developer or the Firebase console
At scale
- A ledger that stays as fast in its third year as on day one
Security
- Money fields must become immutable once an order is paid
- A cook must not be able to reach billing or customer data by typing a URL
- No database credentials may be exposed to a public, unauthenticated ordering page
What we built
A full-stack POS built end to end: sub-10-second order booking, a payment-gated kitchen flow so orders reach the kitchen only after payment, real-time customer notifications through placed, preparing and ready for pickup, automated invoicing, inventory, expense tracking, reports, role-based user management, custom menus and a kitchen module.
What it does
QR-code customer ordering with no login or app
Live kitchen queue position for the customer
Returning-customer recognition by phone number
Sub-15-second counter billing
Quick row of five most-ordered items from real history
Audio-haptic bill confirmation
Kitchen board with role-scoped ticket view
Eight-tile owner dashboard with live profit
Repeat-customer table with lifetime spend
Searchable invoice ledger with CSV export
Audit-trailed invoice editing with money lock on payment
Menu, add-on, inventory and expense management
Owner-managed staff accounts and roles
Branded A4 PDF and thermal invoicing
Star ratings tied to specific invoices
Command palette search across orders, menu and inventory
Installable PWA with platform-aware install flow
Engineering decisions
Choices that could have gone another way, and what each one bought.
Invoice numbers that cannot collide
Bill numbering is implemented as an atomic Firestore transaction — the counter read, the increment and the order write happen as a single indivisible operation, on the client for counter billing and through the Admin SDK for public QR orders, sharing one identical path scheme.
Why it matters. Two cashiers and a QR-code customer can hit confirm in the same millisecond and still get PT-0041, PT-0042 and PT-0043. It also costs one round trip instead of two, so billing feels instant. Bill numbering is the one thing a restaurant cannot get wrong.
A financial-integrity rule built into the workflow
Money fields lock the moment an order is marked paid. Only the customer name and phone stay editable afterwards, and every edit is stamped with an author and a timestamp, displayed alongside the invoice number.
Why it matters. That is the difference between a billing app and an app an accountant will accept.
A date-partitioned ledger designed for year five
Orders are stored on a hierarchical path — business, year, month, date, orders — so a single day's business can be read without touching a record from any other day, while collection-group indexes still allow instant search across all time.
Why it matters. The app is intended to stay exactly as fast in its third year as on day one, rather than degrading as history accumulates.
Two authentication systems, bridged invisibly
Staff sign in with email and password against a bcrypt-hashed directory through NextAuth. That session is exchanged server-side for a short-lived Firebase custom token, which is what actually authorises database reads and writes.
Why it matters. One login for the user, proper database-level security rules underneath, and an owner who can add and remove staff without ever touching the Firebase console.
A service worker written for a financial app, not a blog
Only content-hashed static assets are cached — never an API response, never a page, never anything user-specific — and the worker is versioned so a new deployment cleanly invalidates the old cache.
Why it matters. A POS that serves a stale order total is worse than a POS that is offline.
Role-based access enforced in three layers
A central route-to-role map drives navigation gating, client routing guards and server-side API checks, with Firestore rules scoping every read and write to the owning business. Typing a URL you are not allowed to reach redirects you to your own home screen.
Why it matters. A cook sees the kitchen board and nothing else — no prices, no customer data, no billing — enforced at every layer rather than hidden in the interface.
Designed for the counter, not the desk
Fifteen-second billing flows, thumb-reachable controls, a Quick row computed from real order history, a command palette searching orders, menu and inventory at once, and audio-haptic confirmation — a three-note chime plus vibration — so staff know a bill saved without looking at the screen.
Why it matters. During a rush, staff are not looking at the screen. The system has to confirm through sound and touch.
Technical detail
Collapsed by default. Open whichever part you are evaluating.
- Frontend
- Next.js 15 App Router with React Server Components
- TypeScript end-to-end
- Tailwind CSS with shadcn/ui on Radix primitives
- Approximately 45 components
- Responsive to small phones with safe-area handling
- Backend
- Next.js API route handlers
- Firebase Admin SDK for server-only public endpoints
- Database
- Cloud Firestore
- Date-partitioned document paths: business → year → month → date → orders
- Three purpose-built composite indexes for collection-group search by business, invoice and phone
- Storage
- Firebase-hosted menu imagery, compressed in the browser before upload
- Authentication
- NextAuth v5 credentials provider
- bcrypt password hashing
- JWT sessions with 30-day lifetime
- Server-minted Firebase custom tokens bridging the staff session to database auth
- Authorization
- Central route-to-role map
- Navigation-level gating
- Client-side routing guards
- Server-side API checks
- Firestore security rules scoping every read and write to the owning business
- Caching
- Custom service worker caching only content-hashed static assets — never an API response, page or user-specific content
- Versioned worker so a deployment cleanly invalidates the previous cache
- Messaging
- SMS templates and provider configuration for invoice dispatch
- Deployment
- Vercel with environment-driven configuration
- Monitoring
- Install-prompt analytics tracking intent, dismissals and completions
- Frontend
- Next.js 15
- React Server Components
- TypeScript
- Tailwind CSS
- shadcn/ui
- Radix UI
- Backend
- Next.js API routes
- Firebase Admin SDK
- NextAuth v5
- Database
- Cloud Firestore
- Cloud
- Vercel
- Firebase
- Integrations
- SMS provider (configurable)
- Tools
- ESLint 9
- Vitest
- React Testing Library
- Authentication
- bcrypt-hashed staff credentials
- JWT sessions with a 30-day lifetime
- Staff session exchanged server-side for a short-lived Firebase custom token
- Authorization
- Three roles — Super Admin, Reception/Cashier and Cook
- Enforced in navigation, in client routing, and at the API layer
- Staff management endpoints reject non-admin sessions outright
- A cook signing in lands on the kitchen board and can reach nothing else
- Data protection
- Firestore security rules scope every read and write to the owning business
- Public ordering endpoints run server-side through the Admin SDK so no credentials reach the browser
- The kitchen surface exposes no prices and no customer data
- Auditability
- Every invoice edit stamped with author and timestamp
- Editor attribution displayed alongside the invoice number
- Privacy
- Customer records keyed by phone number; no account or password required of customers
Mechanisms
- Atomic transactional invoice numbering
- Real-time Firestore onSnapshot listeners across all surfaces
- Service worker that never caches API responses or user-specific content
- Graceful error states throughout
Failure scenarios handled
- Concurrent billing from two terminals and a QR customer simultaneously
- Missing Firestore index — surfaced with a direct link to create it
- Stale cache after deployment — prevented by worker versioning
Idempotency. Invoice issuance is transactional, so a number is consumed exactly once regardless of concurrency.
Before and after
Before
- A billing book, a calculator, a phone for order calls and a notebook for expenses
- Customers repeatedly asking counter staff whether their order was ready
- Sales and expenses tracked separately, so profit was never visible in one place
- Off-the-shelf POS priced per terminal per month and locked to specific hardware
After
- One record moving from QR-code order to kitchen ticket to paid invoice to profit line
- Customers watching their own position in the kitchen queue
- Live profit for any date range, with expenses folded in
- A system running on the devices the restaurant already owned, with no licence fees
The build, by the numbers
What was built, at what scale. These describe the system's size, not its business results.
- role-specific surfaces
- 4role-specific surfacesCustomer, reception, kitchen and owner — one shared live data model
- enforcement layers for access control
- 3enforcement layers for access controlNavigation, client routing and server-side API checks
- live dashboard tiles
- 8live dashboard tilesIncluding profit computed live from sales less expenses
- per-terminal licence cost
- 0per-terminal licence costRuns in a browser on devices the restaurant already owns
What changed as a result?
Orders booked in under 10 seconds. The payment-first kitchen queue eliminates unpaid and incorrect orders, and customers stay informed in real time until pickup — a fully automated shop-floor system.
- Order booked to invoice in under 10 seconds
- Kitchen queue gated on payment, so unpaid orders cannot reach the line
- Customers notified automatically at each stage, removing status interruptions
What we can evidence
Orders booked in under 10 seconds
Why does this matter in restaurants & food service?
Restaurant software is the system that takes an order, bills it, tells the kitchen and records what it cost you — and it is judged at the counter during a rush, not in a demo. If booking an order takes thirty seconds, the queue builds and staff work around the system instead of through it. We built the Pizza Theory POS end to end.
Order entry slow enough to build a queue
Every extra second per order compounds across a dinner rush. The Pizza Theory POS books an order in under ten seconds, which is the difference between the system helping and the system being bypassed.
Unpaid and incorrect orders reaching the kitchen
A kitchen that starts cooking before payment confirms absorbs every mistake as wasted food. A payment-gated queue means an order only reaches the kitchen once it is paid for.
Customers asking staff where their order is
Every status question interrupts someone working. Real-time notifications through placed, preparing and ready-for-pickup remove almost all of those interruptions.
Stock and expenses reconciled after closing
Counting stock and totting up expenses at the end of a shift is where margin quietly disappears. Inventory and expense tracking inside the POS make the numbers a by-product of service.
See it running
pizza-theory.vercel.app(opens in a new tab)Need something like this for restaurants & food service?
Tell us what is slowing the business down and we will tell you whether software is the right fix. If it is not, we will say so.
Free 30 minutes · no obligation
Related work
- Education / Internal SaaS
Little Lumos School Management Portal
Custom-built school management SaaS that automates end-to-end school operations
- AI Workflow Platform
Little Lumos — AI Monthly Progress Reports
A preschool was hand-writing 70+ monthly progress reports, costing 3–4 working days every month. Softivum built the full workflow: teachers speak, AI drafts, admins approve, and branded letters reach both parents with per-recipient delivery tracking.
- Marketplace Platform
Helpora — Hyperlocal Neighbour-Help Marketplace
A marketplace where neighbours pay neighbours for everyday help. Softivum built the consumer app, the marketplace engine, the operations console and the brand site — verifying identity against government records, holding every payment in escrow until the job is done, and tracking helpers live on a map.