GoodBirdies
A tournament-internal stock market for amateur golf outings — golfers become tradeable "stocks" that participants IPO and trade, with payouts settling from the tournament's final results.
GoodBirdies wraps a stock market around a golf tournament. Every golfer in an outing becomes a tradeable “stock” — participants are both players and investors, buying into one another during the IPO, trading shares while the tournament runs, and cashing out based on who they hold when results come in. Strong finishes pay their shareholders; the market is the game wrapped around the game.
Two tournament formats run side by side:
- Standard — golfers invest in each other during the IPO, and each golfer’s market cap emerges from those investments.
- Calcutta — the admin runs a live verbal auction and records winning bids, with an optional 50% buyback for golfers bidding on themselves.
Share prices are fixed per tournament with no volatility — the strategy is in who you hold and how many shares, not in price swings. A tournament moves through a guarded lifecycle (setup → ipo → trading → results → closed), with phase transitions protected by compare-and-set guards to prevent double-advance on a lost race.
Key highlights include:
- Atomic money movement: Every investment, trade, and auction settlement runs through atomic primitives with canonical-order row locking to avoid deadlocks. No path mutates holdings directly, and every financial operation is recorded as a reversible, audited transaction.
- Live updates without polling: Server-Sent Events stream per-tournament and per-user events, fanned out across replicas via Postgres
LISTEN/NOTIFY, and mapped to TanStack Query cache invalidations so the UI stays live. - Security-first auth: JWT access/refresh tokens in httpOnly cookies (never in response bodies), double-submit CSRF protection, per-request CSP nonces, and rate limiting.
The stack pairs a Next.js 16 / React 19 frontend (Tailwind v4, shadcn/ui, Recharts) with a FastAPI + SQLAlchemy 2.0 backend on Python 3.13, backed by Postgres in production and deployed to Railway.