Skip to main content
All projects
AI Restaurant Tech

Jubran

A 229-dish rooftop restaurant run from the table: guests scan a QR, order by tap or by chatting with an English and Arabic AI waiter, and staff see every table move live on the floor map.

Try it liveCodeWatch the run
Jubran
  • 229

    dishes across 27 categories

  • 63.45 JOD

    AI-taken order, priced to the fil

  • 1–4 s

    per AI waiter reply

  • 8 of 12

    tables live on the floor during the test service

Inside the product

See it working

Real screens and a recorded run, captured from the working product.

Jubran
Side by side: a guest on a phone orders a steak dinner through the AI waiter in English while the staff floor updates live; the order lands on table T1, staff start preparing and mark it ready, and the guest's tracker follows in real time.
Jubran
Open full size

Staff live floor: the new order lands on T1 among 8 busy tables, with KPIs and service queue.

01 / 07

My role

Sole engineer: product design, the FastAPI backend, the AI waiter and its server-side guards, the real-time layer, and the bilingual guest and staff apps.

The problem

A rooftop restaurant with a large, varied menu, from breakfast to steaks, desserts, drinks and shisha, is hard to browse on a phone and slow to order from at peak hours. Guests want recommendations and cooking preferences honoured, and staff need to see the whole floor at once. An AI waiter that can place orders also has to be impossible to trick into wrong prices or unconfirmed orders.

What I built

Each table's QR opens a guest app bound to that table: a photo menu across 27 categories with category chips and search, dish sheets with special instructions, a server-side basket that is re-priced and confirmed, live order tracking, one-tap table services, and edits to a sent order until it is ready.

The AI waiter talks in English, Arabic, Jordanian dialect or a mix. It answers from the restaurant's own menu, suggests pairings, adds dishes with cooking notes such as "medium-well", summarises the order with exact prices and sends it only after the guest confirms. Staff run the evening from a live floor map of the real dining room, an incoming-orders panel, a service queue, table visits with the running bill, full menu management for all 229 dishes, QR codes with printable PDFs, and AI settings with a 7-day usage and cost report.

Architecture

Next.js 16 guest and staff apps on a FastAPI backend with async SQLAlchemy, Alembic migrations and PostgreSQL with pgvector. The waiter uses Gemini tool calling, and every action is validated on the server. Menu search is built to combine dish-name matching with vector embeddings, and always keeps working through name matching when embeddings are unavailable. A transactional outbox feeds WebSocket updates to guests and staff. Providers and models are configured per purpose, with Gemini or OpenAI for chat, embeddings, transcription and live voice, and stored keys are encrypted.

Challenges

Making a large menu feel quick on a phone. Enforcing the waiter's rules in code: a dish has to be shown before it can be ordered, the order needs a fresh summary and an explicit "yes" in a later message, the table comes from the QR session, and prices are recomputed at submit. Carrying cooking notes through to the kitchen line by line, and keeping every screen in sync in real time.

Key engineering decisions

The model proposes and the server decides, so the guards hold whatever the guest types. A fresh summary is required before every confirmation, so a stale "send it" never places an outdated order. Name-matching fallback so search keeps working without embeddings. Security on by default: HttpOnly cookie sessions with hashed tokens, CSRF, WebSocket origin checks, rate limits, upload validation and strict security headers.

Results & impact

In a recorded run on Gemini 3.1 Flash Lite, the guest asked "What steaks do you have?" and got both steaks with their real descriptions and prices. One message then added a medium-well Rib-Eye, a Musakhan and two Mango Tropic; the waiter offered hummus to share, showed a priced summary and, after the guest's explicit yes, placed order JB-107 for 63.45 JOD with the cooking note on the steak line. When the guest first said "send it", the server insisted on a fresh summary before accepting. The order landed on table T1 on the staff map within a couple of seconds, and Start preparing and Ready moved the guest's tracker live. A scripted service through the real API filled 8 of 12 tables with orders in every state and open service requests.

Highlights

  • Bilingual AI waiter with pairings, cooking notes, priced summaries and explicit confirmation
  • Server-side guards on every AI action
  • 229 dishes in 27 categories with photo galleries, chips and search
  • Live floor map and order tracking over WebSockets
  • Admin with menu management, QR PDFs and a 7-day AI usage and cost report
  • Dictation and live speech-to-speech voice ordering
  • English and Arabic with full RTL, light and dark themes, phone-first guest app