← Projects

SeatFlow

A movie-ticket booking platform: browse movies, pick a showtime, choose seats on a live seat map, pay, and get a QR ticket. The focus is the part that is easy to get wrong. No seat is ever sold twice, even when a thousand people go for the same seats at once, payments arrive late or twice, or the database drops connections mid-booking.

SeatFlow seat map

Highlights

  • Correct under contention. 1,000 concurrent clients compete for 50 seats, and the database is checked after every run: no seat has two owners, and every multi-seat hold is all or nothing. This runs in CI.
  • Payments that can’t lose money or double-sell. Signed webhooks with deduplication, one transaction from event to ticket, reconciliation for lost webhooks, and automatic refunds through a transactional outbox when a late payment finds its seats gone.
  • Live seat map. Seat changes are pushed over WebSockets from a Postgres trigger that fires only on commit. Clients merge by per-seat version, so late or reordered messages can’t show stale state.
  • Measured optimization. A lock-free fast path for seats that are plainly taken gave +66% throughput and −44% p95 latency on the hottest seats (k6 against a production build).
  • Survives failures. Fault tests kill database connections in the middle of a booking storm. Data stays consistent and the API recovers on its own.
  • Accessible. The seat map works fully from the keyboard and with screen readers, and is checked against WCAG 2.2 AA with axe.

Architecture

A modular monolith: a booking is one Postgres transaction, which microservices would turn into a distributed problem. A Next.js web app proxies to a NestJS API that owns all booking logic, and a worker expires stale holds, reconciles payments, and drains the outbox.

Stack

Next.js · React · NestJS · Prisma with raw SQL for locking · PostgreSQL · Jest, Playwright, k6 · Docker Compose · GitHub Actions