Dhruv Kumar

Bunny’s Cafe

A real-time ordering system for the cafe behind my college, pitched and built solo. QR-code table entry, phone OTP auth, live order status, Razorpay checkout, and an admin dashboard the owner actually uses.

RolePitched, designed & built soloStackNext.js, Prisma, PostgreSQL, RazorpayLivebunnyscafe.in ↗
Bunny's Cafe admin dashboard: menu management with live order status

The problem

The cafe behind my college was jammed every lunch break: one counter, one queue, and forty minutes of class between orders. The bottleneck was not the kitchen, it was students standing in line to say what they wanted.

I pitched the owner on replacing the line with a phone in every student’s hand, then built and shipped the whole system myself: menu to kitchen to payment to handoff, with nothing bolted on from a third-party ordering platform.

How it works

01OrderA QR code on the table opens the menu in the browser, no app install. Items, variants, and add-ons are configured in an admin panel, with per-order price snapshots so a later menu change never rewrites a past receipt.
02VerifyFirebase phone OTP, rate-limited to 3 requests per phone-and-IP pair in a 5-minute window. A successful login sets a 7-day httpOnly JWT cookie so a regular does not re-verify every visit.
03PayRazorpay checkout or cash at the counter. Online payments are verified server-side by recomputing the HMAC-SHA256 signature before an order is ever written, so a forged client payload cannot mark itself paid.
04TrackThe order screen holds open a Server-Sent Events stream that polls the database every 1.5 seconds and only pushes a diff when the order actually changes state, with Web Push as a fallback so a closed tab still gets notified when the order is ready.

Behind the counter

The kitchen side got the same amount of attention as the ordering flow: a kanban board for incoming orders, a walk-in POS for the counter when a customer skips the QR code entirely, coupon codes with per-order minimums and usage caps, and a sales dashboard the owner can filter by day, week, or month to see cash versus online split.

Result

+35%Checkout completion after launch
1.5sOrder status refresh, diffed not polled blind
195Commits shipped solo, requirements to handoff

What I would change next

Order status updates by polling the database every 1.5 seconds and diffing the result before pushing. It works, and it is honest about what SSE on a serverless platform can do without a persistent backend, but a proper LISTEN/NOTIFY channel or a queue would replace the poll with an actual push and cut the delay further.