Personal projectIn production
Fantasy Hockey
An eight-player league, from draft night to game day.

Live usage
Running in production, with live drafting, roster management, and NHL-based scoring in one shared league.
The short version
- The problem
- Commissioners need a fair draft and managers need a clear view of players, rosters, and standings. Underneath is one hard problem: keeping league state consistent when people act at the same time.
- What I built
- A fantasy hockey app covering setup, live drafting, roster management, NHL-based scoring, and season archives. The React interface connects to Firebase, and server-side workflows enforce draft turns, roster limits, and player ownership.

The production league overview brings season points, lineup alerts, current games, and standings together. Captured October 4, 2026; live points are provisional.
One draft, one set of rules
Snake-draft order, player search, active and reserve slots, queues, and server-controlled automatic drafting all depend on the same authoritative pick logic. A pick checks membership, team ownership, the current turn, roster capacity, season, and draft generation.
Two requests can compete for the same player, or a retry can arrive after a pick has already succeeded. Firestore transactions keep the player claim and draft state together. Repeating an accepted request can return its saved result instead of adding a second pick. Discord uses the same transaction, with signed requests and duplicate-delivery controls.
- ValidateMembership, turn and roster rules
- CommitPlayer claim and draft state together
- RecoverAccepted retries return the saved result

The production draft board shows all 176 selections completed across eight teams. Captured October 4, 2026.
Roster changes without rewriting history
The original draft and game-date roster history are retained separately. One-for-one free-agent replacements have exclusive reservations and a defined weekly effective time.
A replacement changes the intended future scoring period without changing who earned earlier points. The current roster and the historical scoring roster answer different questions, so the data model preserves both.
Follow the game behind the fantasy points
Game Centre brings the NHL scoreboard, player statistics, play-by-play, and an interactive shot map into the league. Managers can see which events involve their roster and inspect where attempts happened on the ice.
The interface distinguishes provisional live points from finalized season scoring. Shots without location data remain in the event list instead of disappearing from the game record.

The Rink view connects NHL shot locations to an event list and highlights the manager's players. Production capture, October 4, 2026; this game was in progress.
Correctness with a reference to check against
My scoring validation shows exact displayed-score agreement across 143 of 143 player-seasons using an independent reference dataset. One fully reconstructable team with no roster transactions also matched at 1,053.87 points.
This validates arithmetic for the reference statistics. Twelve of thirteen scoring rules were represented in real reference data; the goalie-goal rule was covered synthetically. It does not establish every live ingestion path or an entire production season.
Decisions & evidence
Interface & product decisions
Designed around a live draft
Responsive layouts, searchable player lists, clear turn ownership, and active/reserve distinctions help managers make picks with shared state visible.
Multiple interfaces, shared authority
Web and Discord picks use the same rules. The Discord deployment is configured for one league, server, and channel; it is not presented as a self-service integration for arbitrary leagues.
Useful states beyond the happy path
The interface distinguishes empty, loading, unavailable, and error states, with light and dark themes and team identities.
Evidence & scope
Scoring validation
The app is in production with eight players in its first official season, as of October 4, 2026. Separately, the repository's scoring parity report covers 143 player-seasons. That reference-data check does not establish a fully verified live season.
Usage reflects an owner-confirmed count of eight players as of October 4, 2026. Product screenshots were captured from the production app on October 4. Scoring validation uses an independent reference dataset; it is separate from live-season usage.
Let's
talk.
Looking for someone who can build the whole thing?
Software engineering, applied AI, and thoughtful product work. I'd like to hear what you're building.
