Case study · № 092026Team of 4

Cafe POS

A full-stack restaurant point-of-sale covering table and floor management, fast billing, multi-method payments (cash, Razorpay, UPI QR), a real-time Socket.io kitchen display, and customer self-ordering by scanning a table QR. Role-based access spans admin, staff, kitchen, and customer.

Team4 people
My roleFront end
RealtimeSocket.io
PaymentsRazorpay · UPI
cafe pos · order flow
ClientsAPIServicesDataPOS terminalReactCustomer QRself-orderKitchen displaylive boardExpress APIRESTSocket.ioroom broadcastOrders / TablessessionsPaymentsRazorpay · UPI QRPostgreSQLPrismaticketspay
Fig. 1 · Restaurant POS — a Socket.io kitchen display (New → Preparing → Ready), QR self-ordering, and Razorpay/UPI over Prisma·Postgres. (I owned the front end.)
01

Context

A small cafe juggles table service, order-taking, kitchen coordination, and payments across disconnected tools. Cafe POS folds them into one: front-of-house takes orders on a terminal, orders stream live to a kitchen display, customers can self-order by scanning a table QR, and payments settle by cash, card, or UPI in the same flow.

A four-person team sprint. I was the front-end developer.

floor · tables
02

The real-time kitchen

The kitchen display is the piece that has to feel instant, and it runs on Socket.io with room-based broadcasting — clients join restaurant, kitchen, table, and order rooms, and events like order:new and order:statusChanged push a ticket across New → Preparing → Ready columns without a refresh.

On the client side that’s my useWebSocket hook feeding the kitchen and customer layouts, so a status change on the floor and a new order from a QR scan both light up the same board in real time.

kitchen display
03

My role, honestly

I owned the front-end foundation. My first commit scaffolded the whole client — a Radix-based UI component library, the shared layouts, the custom hooks (including the WebSocket one above), and the service/state wiring with Zustand. From there I built out the customer- and kitchen-facing pages: real-time table-status indicators on the floor plan, drag-and-drop category reordering, and the kitchen display shell. The backend, payments, and data model were largely teammates’ work; I consumed those APIs from the client.

04

Payments, three ways

Because a cafe takes money however the customer has it, checkout supports three paths: cash with denomination buttons and change calculation, card/UPI through Razorpay with server-side signature verification, and a generated UPI QR for scan-to-pay. The front end switches cleanly between them; the verification and the cash session bookkeeping live on the server.

05

What I would change

The socket client reconnects but doesn’t reconcile — if the kitchen display drops for thirty seconds it can miss a ticket rather than replaying missed events on reconnect. I’d add a short server-side event buffer keyed per room so a reconnecting board catches up, which matters more in a real kitchen than in a demo.

Built with
React 19ViteZustandRadix UITailwindSocket.ioRazorpayqrcodeNodeExpressPrismaPostgreSQL
← PreviousKidnexNext →RMC ERP
You found the trick.
Thanks for
looking closely.
↑ ↑ ↓ ↓ ← → ← → B A · konami