Skip to content

PGA ITS

Next.js, Tech lead•2026

PGA ITS is the ITS Golf Alumni association's platform: a public site with live leaderboards and pairings, a tournament admin console, a member portal with performance history, and an on-course digital scorecard.

Scores used to live on handwritten paper cards, so a player's history didn't exist anywhere, and the replacement had to work where golf happens: on phones, mid-round, with bad signal, while spectators watch a leaderboard that should feel live without any realtime infrastructure.

PGA ITS: public landing page
Challenge

Paper scorecards, and no history at all.

Every tournament ran on handwritten paper cards: manual score collection and tabulation on event day, and nothing kept afterwards. The association's core ask was the record: players' historical performance, which meant the correctness of synced data mattered more than raw speed. Every scorecard feeds the member performance charts.

Score entry happens on the course, on players' phones, with unreliable signal; losing a hole's data mid-round is unacceptable. Leaderboards, pairings and admin views should feel live during a tournament. One app had to serve four audiences (public visitors, admins, members, and players scoring a round) on a small team with no budget for WebSocket infrastructure or a separate mobile app.

391
Digital scorecards, 4 tournaments
1,199
Users
39
Pages across 4 app areas
316/319
Commits mine, ~5.5 months
On mobile: landing, tournament details and the association's values
On mobile: landing, tournament details and the association's values
Tournament page: player flights grouped by handicap
Tournament page: player flights grouped by handicap
Approach

Local first, live enough.

  • A
    A local-first, offline-tolerant scorecard

    Hole-by-hole entry writes to local storage first; a debounced mutation syncs it three seconds later, and the payload is rebuilt from local storage at send time so it is never stale. Scores survive reloads and dead zones on the course. A server-first form was rejected; one bad-signal moment would lose a hole.

  • B
    Role-aware polling instead of WebSockets

    The public leaderboard, pairings and admin live-score pages poll every three seconds. On the scorecard, only non-captain players poll; the captain, the one typing, never gets local edits overwritten by a fetch. Near-live for the cost of zero realtime infrastructure; up to three seconds of staleness is fine for golf.

  • C
    A gateway with dual-audience cookies

    One catch-all route handler forwards to the backend and attaches headers server-side. Tokens live in httpOnly, secure, same-site-strict cookies split by audience (member and admin), so one app hosts both sessions. Dedicated streaming routes pass file uploads and downloads through without buffering.

  • D
    A generated API contract

    A script pulls the backend's OpenAPI spec and Kubb generates the types (99 files, around 15,000 lines) behind 11 typed service modules. No hand-written DTOs, and no drift when the backend engineer changes the contract.

  • E
    Keyless Cloud Run delivery

    A three-stage Bun Dockerfile (non-root, standalone output, build-cache mounts), built by GitHub Actions, which authenticates with workload identity federation instead of long-lived keys and pushes SHA-tagged images. Staging deploys on push; production is a manual dispatch gated to the main branch and a protected environment.

PGA ITS member profile with a Performance Snapshot of HCP index, rounds played, stroke average and best round charts
PGA ITS member profile with a Performance Snapshot of HCP index, rounds played, stroke average and best round charts
Details

Research done on the fairway.

  • Field research. I played in the client's tournament to watch manual scoring actually happen, then helped shape the scorecard flow with the designer.
  • Tournament ops console. QR camera check-in with camera settings, pairings, participants, sponsors and winners; tables with URL-synced filters; rich-text event descriptions.
  • The actual point. The member portal charts each player's performance over time: the historical dataset the association asked for, accumulating with every scorecard.
  • Standards set as lead. Build-time environment validation, pre-commit hooks with staged linting, import-order rules, and written UI and code conventions for the team.
Outcome

Paper replaced, history accumulating.

Four real tournaments have run on the platform, with 391 digital scorecards replacing paper and 1,199 users on the system. Players' history now accumulates into performance charts instead of disappearing with the cards.

The work shipped through sprints and five client UAT feedback rounds, on a staging and production pipeline that has run on Cloud Run with keyless CI since launch.

Delivered through Noosa, where the same team ships its own ticketing product.

  • Year2026
  • IndustryGolf · alumni community
  • ClientITS Golf Alumni · delivered through Noosa
  • RoleTech lead · sole frontend engineer · team of 5
  • Scope of work/ Frontend / Platform / Infrastructure / CI/CD
  • StackNext.js · React · TypeScript · Bun · Tailwind CSS · TanStack Query · Kubb · Recharts · Docker · GCP Cloud Run
Elian Richard