← lab

TicketFlow

2025

0 double-bookings by design

The problem

Concurrent event-management & ticket-booking REST API in Go, Clean Architecture (domain / repository / service / handler), chi + pgx + go-redis, versioned migrations, zerolog, ~15MB multi-stage Docker image.

The constraint

The last-seat problem — simultaneous purchases of the final ticket. The booking flow is a 10-step sequence: Redis distributed lock → PostgreSQL SELECT FOR UPDATE → optimistic version check. Every write lands in an immutable JSONB audit log.

What the git log says

  • $ Redis distributed lock + SELECT FOR UPDATE + optimistic version check; cancellation restores inventory.
  • $ Immutable JSONB audit log — field-level diffs, actor ID, client IP.
  • $ Redis sliding-window Lua rate limiting (100 req/min/IP); batch creation of 50 events in one atomic round-trip via pgx Batch.
  • $ JWT HS256 RBAC — user reads/books, admin writes; passwords bcrypt-hashed.

What I learnt

Three overlapping concurrency controls aren't paranoia — each fails differently (lock TTL expiry vs. txn serialization vs. lost update). Audit trails are cheap to add early, impossible to retrofit honestly.

GoPostgreSQLRedisJWTDocker