FantasyDex
Full-PPR season rankings, waiver trends and player news in one Next.js app, fed by a Python pipeline that trains, evaluates and gates every projection before it ships.
- Next.js
- TypeScript
- PostgreSQL
- Drizzle
- Python
- scikit-learn
Source is private. The pipeline, evaluation reports and model card are available on request.
Problem
Most free fantasy rankings are a black box: you get an ordered list with no idea how it was built or how wrong it usually is. I wanted rankings where every number traces back to data, a model choice and a measured error.
My role
Solo project. I designed and built the data pipeline, the models, the evaluation process, the projection data contract, and the web app that serves the results.
Approach
- Collected 16 seasons (2010–2025) of nflverse player, team, roster and play-by-play data, plus college stats for rookies, with checksums and recorded provenance for every snapshot.
- Built a one-to-one player identity crosswalk across sources, and normalized points and games played by each team's schedule so seasons of different lengths compare fairly.
- Trained position-specific ridge and random-forest models under four training-window policies (all history, eight seasons, six seasons, recency-weighted), with separate heads for points and availability and a separate rookie pathway.
- Evaluated with rolling time-based folds: for each test season N, training ends at N−2 and N−1 is validation, so no future data leaks into a forecast.
- Converted projections into draft value (value over replacement) and positional tiers for a 12-team, two-flex league.
- Published results to the app through a versioned JSON contract that the importer validates before anything reaches the database, with one-command rollback.
Key decision: ship the model that passes, not the one that looks best
Before looking at the 2023–2025 review seasons, I wrote down what a learned model had to do to replace the simple baseline: beat it on point error, improve in at least two of three seasons, and not get worse for any subgroup such as rookies, players with limited history, or players coming off missed games.
The learned models cut average point error at five of six positions, by about 9% for wide receivers and 10% for quarterbacks. But each one failed at least one check (the gain was too small, one season got worse, or a subgroup like rookies regressed), so none passed. FantasyDex ships the calibrated baseline, and the learned models stay recorded as challengers for the next season. I didn't loosen the rules after seeing the results.
Engineering
- Next.js App Router, strict TypeScript, PostgreSQL with Drizzle migrations, least-privilege database roles.
- CI on every pull request: secret scan, dependency audit, typecheck, lint, migration drift check, unit tests, database integration tests, build and Playwright end-to-end tests.
- Player directory synced daily from the Sleeper API by an authenticated cron route; the trending adds/drops endpoint serves the last good result when Sleeper is down.
- Architecture decision records and a written lesson series explaining why each piece was built the way it was.
What's next
- Weekly projections, evaluated against the same pre-registered rules.
- Fantasy basketball (NBA) support.