The problem
A cinema needs to sell tickets online without two people buying the same seat, control access at the door, and make sure each role (customer, employee, administrator) only sees what it should.
What I built
- Real-time seat selection with double-booking control.
- Registered or guest checkout, candy bar and combos, points, credit and coupons.
- Single-use QR tickets and PDFs, validated by camera from the employee profile.
- Admin panel: movies, showtimes with automatic theater assignment, pricing, and PDF and Excel reports.
- PWA with push notifications for new releases.
Technical decisions
Security lives in the database
Each role's permissions are defined with Postgres Row Level Security. Angular guards only organize navigation: even if someone bypasses them, the database won't return data that isn't theirs.
Seats synced with Realtime
Each customer sees, live, the seats other people are taking, using Supabase Realtime.
Documented requirements and decisions
42 requirements and 14 technical decisions written in the repo, each one with the alternatives evaluated.
Stack
Angular 22 TypeScript Signals Supabase Auth Postgres + RLS Realtime Storage Edge Functions PWA Vitest Vercel
What I'd do differently
- I'd test the layout on phones from day one: today, on narrow screens, the listings get cut off on the right.
- I'd make the demo keep itself up to date, with a scheduled job in the database that creates future showtimes. Showtimes loaded by hand expire, and then the purchase flow can't be tried.

