Bookodi — Restaurant Operating System
A multi-tenant platform that runs a restaurant end to end — and the analytics and reservation views I built inside it.
- Role
- Frontend & data-visualisation engineer (contributor)
- Team
- XEOO product team
- Timeline
- May 2026 – Ongoing
- Organisation
- Bookodi (XEOO)
- Code
- Proprietary (employer)
- Reading time
- 5 min
Bookodi handles reservations, POS, kitchen display, menus, guest CRM, delivery, printing and billing for many restaurants from one Go API. Built by the XEOO team; I owned the analytics module, the reservation views and the dashboard home.
Overview
Bookodi is the XEOO team's restaurant platform: one Go API serves every tenant, and several front ends sit on top — the staff dashboard with POS and kitchen display, a guest PWA, a public booking site and an operator console.
I joined the product team in May 2026 and took ownership of the screens owners look at every day: analytics, the reservation views and the dashboard home. This case study covers the platform the team built, and my part of it.
The problem
Restaurants juggle a booking diary, a POS, kitchen tickets, a delivery queue and spreadsheets — with no single view of how the business is doing. Inside Bookodi itself, the analytics page had grown into a long list of disconnected charts: owners couldn't answer simple questions — are my regulars coming back? which dishes sell together? when do tables turn? — and several numbers were wrong.
Context & constraints
The platform is multi-tenant: every query is scoped to a restaurant, business hours and analytics follow each restaurant's own time zone (including daylight-saving changes), and the dashboard is used on desktops and on iPads at the host stand. New metrics had to be built from data the API already exposed.
Approach
The platform (team-built)
- Reservations engine — booking diary, table plan, walk-ins and waitlist; auto-assignment of a table or a group of nearby tables; row locks plus overlap and capacity checks against double booking; a no-show sweeper and risk scoring.
- Service — POS, an orders timeline, kitchen display, waiter board and a floor designer.
- Guests — menus, inventory, CRM profiles, reviews and conversations; a guest PWA installed from a table QR code for browsing, ordering and live order tracking.
- Delivery — service radius, geocoding, fees and minimum orders, driver dispatch and live tracking.
- Printing — tickets rendered on the server (ESC/POS, text or PDF) and delivered over raw TCP, IPP, LPD or USB through an on-site agent — now the desktop app.
- Billing — Stripe subscriptions with an explicit feature matrix per plan, checked separately from staff permissions.
My contributions
- Analytics, rebuilt around owners' questions — revenue & sales (median order value with range, share of orders above/below average, revenue per cover by party size), menu performance (a menu-engineering matrix, later replaced by frequently bought together pairs), customer insights (new vs returning guests, churn and retention), table & capacity, and staff & operations — under a KPI toolbar with date ranges and Excel export.
- A shared chart kit — KPI tiles, progress bars, heat cells, SVG area charts and spark bars, so every section looks and behaves the same.
- Reservation views — a 24-hour Gantt table plan with two-hour slots, a month calendar with bookings, guests and revenue per day, and a toolbar that collapses gracefully on iPad.
- Dashboard home — a reservation turn health panel (fill bar, 12-cell lunch/dinner heat strip, next-up list, seated / waiting / no-show counts) and a live turnover widget.
- The first guest booking widget — three themes (original, dark, black & white) against the public booking API, with a hold timer and nearby time-slot suggestions.
Key capabilities
- Multi-tenant reservations engine with automatic table assignment
- POS, kitchen display, waiter board and floor designer
- Guest PWA with QR install and live order tracking
- Server-rendered thermal printing through on-site agents
- Five-section analytics with Excel export (my work)
- 24-hour Gantt table plan and reservation turn-health panel (my work)
Architecture
Clients
Edge
Go API
Data & operations
One Go API for every tenant, several React front ends on top. My work lives in the staff dashboard. Select a component to trace its connections.
Key decisions
ADR-01Co-purchase pairs over a menu-engineering matrix
- Context
- The classic stars/plowhorses/puzzles/dogs matrix ranks dishes, but it doesn’t tell an owner what to do next.
- Decision
- Show item pairs that appear in the same order (seen at least twice, top five) — they point straight at combos and upsells.
- Trade-offs
- Less textbook, more actionable, and computable from data every restaurant already has.
ADR-02Fetch the calendar month separately
- Context
- The reservations list is paginated five rows at a time, but the calendar needs the whole month.
- Decision
- Load the month in its own request instead of deriving it from the paginated list.
- Trade-offs
- One extra request; the calendar is always complete and correct.
ADR-03Plans checked separately from permissions (team)
- Context
- What a restaurant has paid for and what a staff member may do are different questions.
- Decision
- An explicit feature matrix per plan, evaluated independently of role-based permissions.
- Trade-offs
- Two checks instead of one, but upgrades never change who can do what.
Challenges
A KPI that was always zero
Problem. The dashboard’s no-show count never moved.
Solution. The code compared the stored status `No_show` against the display label `No-show`. Comparing against the stored enum fixed it.
Charts that ignored the theme
Problem. Hard-coded colours broke dark mode.
Solution. Replaced 43 hard-coded colours with the theme’s colour tokens.
Popovers escaping their panels
Problem. Heatmap and day-view tooltips clipped at panel edges on smaller screens.
Solution. Popovers now stay inside their panel, flip at edges and close on Escape or an outside click.
Quality & delivery
Testing
Each pull request was reviewed by a senior developer and verified in the live environment after deployment. The platform's CI (built by the team) runs Go tests with the race detector, vulnerability checks, container builds with smoke runs, and front-end type-checks.
Deployment
Merging to main deploys after CI passes; the deploy script rebuilds only changed stacks, gates on readiness and rolls back automatically if health checks fail (pipeline built by the team).
Outcome
- Of the analytics module authored by me
- ~76%
- git blame at the June 2026 rebuild
- My commits in the June rebuild
- 49 / 125
- Top committer during that phase
- API routes in the Go backend
- 181
- Team platform
- Go test functions
- 222
- Team platform
The analytics module I rebuilt is the one running in the live product, and the work earned me a promotion from intern to permanent engineer in under two months. My later solo project, Bookodi Desktop, closed the platform's biggest operational gap: printing from the cloud to kitchen printers.
Lessons
- Metrics need the data people actually have, not the data a textbook assumes.
- Small shared chart primitives beat a charting library when every chart has to match the product.
- In a team product, the most valuable thing an intern can own is a whole surface, end to end.
Building something similar?
Tell me what you’re working on — I reply to every serious message.
Related work
Bookodi Desktop & Print Bridge
Native desktop app for the Bookodi restaurant platform with a built-in Print Bridge: it pairs with the cloud in one click, discovers printers on the local network and delivers server-rendered tickets over raw TCP, IPP, LPD, CUPS or the Windows spooler.
- TypeScript
- Vite
- Electron
- Node.js
- WebSockets
- GitHub Actions
- +3
Green Compare CRM
A FastAPI modular monolith with a React 19 front end, where Postgres row-level security backs every permission check. I started the repository, then shipped features across finance, telesales, renewals, dashboards and access control.
- TypeScript
- Python
- React
- Ant Design
- TanStack Query
- FastAPI
- +9