← Work

Platform Engineering · Event Ticketing

Ticket Trove Africa

An East African event platform spanning public discovery, checkout-time ticket reservation, organizer operations, ticket issuance, transfer, and entry validation.

Role
Product / Platform Engineer
Frontend
Next.js 16 · React 19 · MUI 7
Backend
Fastify 5 · PostgreSQL · Redis
Delivery
Docker · GitHub Actions · BullMQ
Ticket Trove mobile event-discovery page inside the verified interactive preview
Captured from the live deployment on September 3, 2026.

Product surface

One product, two operating surfaces.

The attendee side needs fast event discovery and a dependable checkout and ticket experience. The organizer side needs control over events, inventory, promos, holds, and operational state. Both depend on the same transaction model underneath.

  • Attendeediscover · cart · checkout · tickets
  • Organizercreate · publish · tickets · promo · holds
  • Platformreservation · order · issuance · validation

Verified product evidence

Captured from the working deployment.

These screens document the live recruiter journey across discovery, checkout, ticket issuance, and organizer operations. They remain available when the free API is waking up.

Attendee journeyDiscovery → selection → simulated M-PESA → rotating QR ticket
Organizer journeyShared dashboard → event inventory and operations
Live Ticket Trove mobile event-detail page
Mobile event detail
Mobile Ticket Trove ticket-tier selection with an add-to-cart action
Mobile ticket selection
Mobile simulated M-PESA checkout with no-charge disclosure
Clearly disclosed simulated M-PESA
Mobile issued Ticket Trove pass with rotating QR code
Issued pass with rotating QR presentation
Mobile organizer events workspace showing seeded inventory and sales progress
Organizer inventory and event operations

Interactive demo

Explore the working demo.

Browse seeded Nairobi events, sign in with a shared attendee or organizer account, and complete a simulated checkout without leaving the case study.

tickets.larrymiami.com

Interactive demo

System model

Ticketing is a concurrency problem disguised as checkout.

The system has to preserve buyer intent without overselling organizer inventory. That means cart state, reservations, orders, issued tickets, and entry scans cannot be treated as unrelated screens or CRUD records.

Three connected lanes

Intent, inventory, and operations move together.

Each lane has different UX concerns, but the platform has to keep all three aligned around the same event and order state.

Attendee lane

From interest to a usable ticket

Browsing and cart state remain lightweight until checkout, when inventory becomes a transactional concern.

BrowseCartCheckoutTicket
Platform lane

Protect the authoritative sale state

Redis locks, PostgreSQL transactions, order state, and ticket validation boundaries protect the same inventory from races.

ReserveOrderIssueValidate
Organizer lane

Control the event after publish

Organizer tooling covers event lifecycle, ticket types, pricing, promotional rules, holds, and event-level operational metrics.

CreatePublishControlOperate

Checkout & inventory

Reserve late. Finalize once. Release safely.

The platform deliberately does not reserve inventory when a buyer adds a ticket to the cart. Reservation begins at checkout, where intent is strong enough to justify temporarily removing capacity from other buyers.

Order lifecycle

Checkout becomes a controlled state transition.

Redis locking and database transactions protect inventory and order state while the checkout flow moves toward completion or release.

01

Cart

Buyer intent only; inventory is not reserved yet.

02

Reserve

Checkout reserves ticket capacity for the pending order.

03

Order

Create the pending sale with customer and ticket context.

04

Finalize

Complete or cancel the order through one authoritative transition.

05

Issue

Create ticket records only after the order reaches the completed state.

06

Delivery

Queue ticket PDFs and buyer notifications after completion.

Expired / cancelled order → release inventory → return capacity to sale

Frontend architecture

The browser surface is built for regional product requirements.

The frontend uses Next.js 16 with localized routes, explicit server-state and client-state boundaries, strict form validation, performance work, and an installable PWA foundation.

Frontend stack

Product concerns have dedicated boundaries.

React Hook Form and Zod handle form contracts alongside these broader application boundaries.

Next.js 16

Application shell

App Router, localized routes, public product surfaces, protected organizer routes, and SEO.

next-intl

Regional language

English and Kiswahili routing are part of the application model rather than a later translation layer.

Query + Zustand

State separation

TanStack Query owns server state while Zustand handles focused client-side state.

Serwist

PWA readiness

Manifest and service-worker tooling establish an installable, offline-aware browser foundation.

Backend architecture

A modular monolith with explicit transactional boundaries.

The Fastify backend is intentionally a single deployable application, but domain modules keep authentication, event management, organizations, ticketing, and background jobs from collapsing into one undifferentiated service layer.

01

Authentication

JWT access/refresh flows, verification paths, permission rules, rate limiting, and security-oriented Fastify plugins.

02

Events

Event lifecycle, public discovery, organizer editing, ticket types, pricing, promo codes, holds, and event-level metrics.

03

Organizations

Organizer ownership and membership boundaries keep operational access scoped to the correct organization.

04

Ticketing

Cart, checkout reservation, orders, inventory, ticket records, dynamic QR validation, entry OTPs, scan logs, and transfers.

05

Delivery & jobs

BullMQ-backed work queues separate ticket PDF generation and buyer notifications from synchronous request handling.

Ticket integrity

The ticket stays stateful after purchase.

Issuing a QR image is not the end of the security model. Entry validation combines short-lived QR data, a separate entry factor, concurrency protection, and scan history so the system can distinguish a valid ticket from an expired, duplicated, or wrong-event attempt.

Entry controls

Validation is treated as another transactional boundary.

The same ticket can also move between people through an explicit transfer lifecycle rather than silently editing ownership data.

Dynamic QR

30-second TOTP window

Ticket UUID, short-lived TOTP data, and timestamp rotate the scannable payload.

Entry OTP

Separate expiring factor

A hashed entry OTP has its own expiry and must validate alongside the ticket QR state.

Scan control

Duplicate-aware validation

Rate limits, Redis locking, ticket state checks, and scan logs protect concurrent entry attempts.

Transfer lifecycle

Ownership changes are explicit

Claim tokens, transfer limits, cancellation, history, and guest/authenticated claiming preserve provenance.

Delivery & operations

Deployment is part of the system design.

The portfolio deployment is treated as a real operating mode: CI verifies database migrations and repeatable seed data, the API remains container portable, and the Next.js frontend uses a same-origin proxy so recruiters never depend on a retired product domain.

Delivery path

Build, verify, migrate, deploy, observe.

Portfolio mode disables real payments, background workers, uploads, cron jobs, and outbound notifications while preserving the product's transactional checkout and ticket-issuance path.

API CI

Verify the real data path

PostGIS and Redis service containers run lint, types, tests, migrations, and the idempotent portfolio seed twice.

Container

Keep the API portable

The production Docker build is checked on every pull request and can run on a free container host.

Next.js

Proxy through one origin

The public frontend rewrites API calls server-side, avoiding brittle browser CORS and exposing one memorable URL.

Safe demo

Preserve flows, suppress side effects

Simulated payments issue real demo tickets while money movement, messages, uploads, workers, and cron stay off.

Engineering evidence

The implementation boundary is explicit.

The implementation repositories are private. This case study connects verified implementation evidence to the architecture, transaction model, security boundaries, delivery controls, and live product experience.

Frontend

Product application

Next.js 16 App Router, English/Kiswahili routes, public event/cart/ checkout/ticket surfaces, organizer dashboard routes, PWA tooling, and the live Ticket Trove product.

Backend

Transactional ticketing code

Fastify modules, checkout-time reservation, Redis locks, atomic order completion/cancellation, ticket validation, transfer workflows, background jobs, and PostgreSQL migrations.

Delivery

CI/CD and operational controls

PostGIS and Redis test dependencies, Docker verification, migrations, repeatable demo seeding, frontend lint and type checks, production builds, health checks, and Sentry integration are represented in code.

Evidence boundary

Implemented code is not the same as every roadmap target being achieved.

The case study intentionally avoids presenting planning targets or incomplete surfaces as shipped proof.

  • The dedicated organizer analytics tab is still marked “Coming Soon”; event-level metrics already exist elsewhere in the dashboard.
  • Roadmap load and scale targets are goals, not claimed benchmark results.
  • The gate-scanning operational interface remains a product boundary; the API validation, locking, and scan-log architecture is implemented.
  • The public demo uses shared seeded accounts and simulated payments, so it is evidence of product flow rather than a commercial transaction environment.

Ticket Trove Africa

Regional product requirements shape platform design.

Inventory concurrency, mobile entry, language, connectivity, and organizer operations all influence the architecture.