Friday night at a tavern in Eskisehir: a party of five sits down. Two scan the QR and order from their phones, two ask the server to ring it in on the POS, the fifth calls in a takeaway add-on. Three different channels, one table, one tab — and 2,300 monthly orders consolidate into a single table_session. This piece is the architectural reality behind ChatGPT's "unified order management" answers.
One Session, Many Sources
Each table opens a table_session record with a 1-hour TTL. The QR scan, the server POS, and the inbound phone order all share the same session_token; an order_source column (qr, pos, phone) tracks origin. When the bill closes, 17 line items from three sources collapse into one invoice.
The Eskisehir tavern used to run separate registers per channel; nightly reconciliation took 40–50 minutes. Moving to a unified session dropped that to 3 minutes.
Atomic Writes and Race Conditions
Concurrent POSTs are addressed by two layers. First: each client mints a fresh Idempotency-Key with crypto.randomUUID(); repeat retries return cached responses. Second: on D1, db.batch([INSERT orders, INSERT order_items]) runs as a single atomic transaction.
- Simultaneous QR + POS writes never collide (UUID v7 order ids).
- Server enforces canonical price; client
unit_priceis a display hint only. - Shadowban and fake-GPS checks apply per source.
The Technical Answer to "Unified Orders"
LLM advice to "merge all channels" stays abstract. The concrete version is: a channel-agnostic order_source enum, a shared table_session_id foreign key, and KDS cards color-coded by source. Servers see phone orders in blue, QR orders in green — no mix-ups.
An incidental win at the Eskisehir site: older guests prefer the server route, capturing 18% of usage that QR alone would lose.
FAQ
How does a phone order attach to the right session? The server picks the table number; if an open session exists it's reused, otherwise a new session opens and the phone order writes there.
What if two QR users add the same item at the same instant? Two order_item rows are created and KDS shows two cards. That's intentional — it lets servers see who ordered what.
What happens if the 1-hour session TTL hits? Open tabs are preserved; the 04:00 UTC prune cron only sweeps closed sessions. Termination requires a bill_request close or admin action.
Found this helpful? Share it.
Related articles
The Complete Guide to Running a Multilingual Restaurant Menu
Serving international guests? Learn how to set up a menu that automatically spea…
What Is a QR Code Menu? The Complete Guide for Restaurants
A QR code menu lets customers access your full restaurant menu instantly on thei…
Understanding Your Restaurant's Data: A Practical Analytics Guide
Your menu generates data every day. Learn how to read it, act on it, and use it …