Skip to content
Nedim
Index01 / 05

Masadan Sipariş

A self-hosted QR ordering system built for a real restaurant, from the customer’s phone to the kitchen printer.

Placeholder cover art: stacked black waveform lines on off-white paper, one line in orange. A screenshot of the project will replace it.
Role
Solo developer — design, build, and deployment
Year
2026
Stack
TypeScript, Next.js 16 (App Router), React 19, Tailwind CSS 4, PostgreSQL, Prisma 6, Server-Sent Events, Zod, jose, bcryptjs, sharp, ESC/POS over TCP, Vitest, GitHub Actions

Problem

A restaurant (Heaven Restaurant, ~25–30 tables) needed guests to order from their own phones without installing an app or creating an account — and the orders had to reach the kitchen reliably, on existing hardware, without depending on a third-party cloud service.

What I did

I built a single self-hosted Next.js application that runs on the venue’s own network. Guests scan a signed table QR code, browse a bilingual (Turkish/English) menu, order, and follow status live over Server-Sent Events; staff manage tickets and table bills from a live desk.

The security model was a real design problem: QR codes carry an HMAC signature, table sessions expire and are capped per table, and an order-attempt ledger records abuse.

The hardest part was hardware. Accepted orders go into a PostgreSQL “outbox” that an on-premises bridge agent pulls and prints over TCP to an ESC/POS kitchen printer, with claims, acknowledgements, retries, and failed-delivery handling so a printer problem never silently loses a ticket.

Outcome

A complete end-to-end system — scan → order → staff acceptance → kitchen print — designed to run as a supervised service on one machine, with CI (lint, type-checks, Vitest) covering QR/session validation, auth, rate limits, order idempotency, billing, and the printer protocol.

It deliberately avoids Redis, hosted storage, and external schedulers so a small venue can actually run and maintain it.