TicketHub

Multi-tenant ticketing · Founder

Year
2026
Scope
Seven surfaces on one backend
Stack
NestJS · Prisma · PostgreSQL · TanStack Start · Expo · Electron
Shown here
24 screens, on seeded demo data
Live product
tickethub.cloud
The Expo customer app — discover, map browse, and an event page
  • React
  • TanStack Start
  • Tailwind
  • GSAP

Buyer Web

Browse, events and community

The public front door: event and bookings catalogue, event pages for both general-admission and seat-mapped shows, public organizer profiles, and an in-app community feed with organizer posts, polls and stories.

Server-rendered on TanStack Start with TanStack Query over a NestJS API. Auth is JWT in httpOnly cookies with CSRF double-submit.

Open the live product

Landing page, with the scroll-driven feature rows
Catalogue: sixteen live events, filtered by category
Event page for a seat-mapped show
  • Prisma
  • PostgreSQL
  • HMAC
  • Zod

Seated Checkout & Wallet

Venue seat picker on a hold timer

The seated flow: pick a date, drill into a section of the venue map, then choose exact seats against live availability and pay before the hold expires. Seat geometry is a shared package used by both the merchant editor and this buyer picker, so zones, rows and seats have one definition.

Checkout, commission and inventory all land in a single Prisma transaction — validate stock, increment sold, mint tickets, mark paid, emit commission, append a wallet ledger row with the balance after. Emails fire only after commit. Money is integer cents end to end, wire to database to UI, with one formatter on the way out.

Tickets live in an account wallet, transfer between customers on an accept basis, and present at the door as a signed pass. The QR is an HMAC payload verified with a constant-time compare, and the database stays the source of truth for status, so a replayed code returns ALREADY_USED instead of admitting twice.

Section overview, drilling into a zone of the venue
Seat picker working against live availability
The customer ticket wallet
The signed QR pass presented at the door
Voting module, tallied live over WebSockets
  • React
  • TanStack Query
  • Prisma
  • PostgreSQL

Merchant Back-office

Venue builder and event workspace

Where an organizer runs the business: a drag-and-drop seat-map editor, a tabbed workspace per event, order fulfilment with affiliate attribution, the sales wallet, and per-reseller commission.

The editor builds a venue out of zones, rows, tables, booths and decor — the arena here is 2,661 live seats across 130 priced layers. Its geometry is a shared package, so the buyer’s seat picker reads the same definition instead of a copy of it.

The wallet is an append-only ledger carrying the balance after every row, and reseller commission is overridable per tier, attributed back through the same orders the merchant sees.

Seat-map editor: 2,661 seats across 130 priced layers
The per-event workspace, on its sales tab
Orders, with the affiliate credited on each one
A reseller’s funnel and commission by state
Sales wallet — an append-only ledger, balance after each row
  • React
  • TanStack Query
  • Prisma

Reseller Portal

Tracked links, commission and payouts

The fourth audience. Resellers take tracked links to market, earn per-tier commission, pass KYC before any payout clears, and withdraw from their own wallet.

Attribution runs through the same order pipeline the merchant reads, so a commission row and the order that produced it can never disagree — and every commission carries a state, earned through paid, pending or void.

Lifetime earnings, conversion rate, and which links convert
  • NestJS
  • TanStack Query
  • Recharts

Platform Admin

GMV, KYC and automated payouts

Operations for the whole marketplace: merchant and affiliate approval, KYC review over encrypted documents behind signed URLs, GMV and order-mix reporting, payouts, and community moderation.

Automatic merchant disbursements run every decision — caps, hold windows, cooling-off and the dual-control threshold — through one pure planning function, so the money rules are unit-testable with no clock and no database. The wallet behind them is an append-only ledger rather than a balance column.

GMV, order mix and what is waiting for approval
Automatic merchant disbursements under dual control
  • Expo
  • React Native
  • MapLibre
  • Skia

Mobile App

Expo app with map discovery

The customer app on Expo: event and booking discovery, a MapLibre map with clustered pins and a result sheet, event pages with date and tier selection, an offline-capable ticket wallet, the signed QR pass, and the community tab.

Passwordless email-code auth, NativeWind for styling and Skia for the pass rendering. Deep links drive navigation, which is also how these screens were captured.

Discover feed
Map browse, pins clustered by city
Event page with date picker and tiers
Offline-capable ticket wallet
The signed QR pass
Booking page
  • Electron
  • SQLite
  • Offline outbox

Door Check-in

Offline-first Electron station

An Electron station for the door. Staff sign in once, name the station and set a PIN; the station then unlocks by PIN all night without exposing an account.

It holds the roster locally and queues scans in an outbox, so it keeps admitting guests when the venue’s internet drops and syncs when it returns. The door screen shows a live checked-in count and per-ticket-type progress, takes the camera scanner, a USB scanner gun anywhere on screen, or a typed name, reference, email or phone.

Door Check-in
The door screen: live count, scanner and search
Door Check-in
Station settings, sync state and queued scans