AG Menu
Full-stack restaurant platform, live in production
- Lines of TypeScript
- ~69,000
- app/ components/ lib/ hooks/ line count
- API route handlers
- 41
- app/api/**/route.ts
- Commits on main
- 263
- git rev-list --count HEAD
- Test & ops scripts
- 37
- scripts/
Problem
Restaurants need a public digital presence, a way to take reservations and orders, and a back office to run all of it — usually stitched together from four disconnected tools, none of which talk to their invoicing or to Google.
What I built
- Public restaurant pages, city directories and digital menus with structured data
- Merchant back office: menu, orders, reservations, waitlist, CRM, team, invoicing, analytics
- Authentication and four-role authorization enforced on the server and again in database rules
- Reservations exposed to Google Reserve, plus Google Business OAuth for the merchant
- Stripe billing with a webhook handler and InvoiceXpress issuing with SAF-T export
- Six in-product LLM endpoints for menu copy, chat, ads, analytics, room planning and waitlist
Architecture
- Next.js App Router — 34 page routes, 41 API route handlers
- Firebase client + Admin SDK; Firestore as the system of record
- Authorization resolved server-side, then re-enforced in 308 lines of security rules
- Third-party surface isolated behind dedicated route handlers (Stripe, Google, InvoiceXpress)
- Contract tests pinned to the boundaries that break silently
Stack
- Next.js 16
- React 19
- TypeScript
- Tailwind v4
- Firebase / Firestore
- firebase-admin
- Stripe
- Google APIs
- Gemini (@google/genai)
- Playwright
- Vercel
- Cloud Run
What it demonstrates
- Working inside a large codebase without rewriting it
- Multi-role product modelling, not just CRUD screens
- Third-party integration where failure is visible to a paying customer
- Shipping LLM features under real product constraints
Honest limit — The application repository is private, so the links point to the running product rather than to source.
