Data model
Where every number on the site actually comes from — the JSON snapshot, the indexed accessors, and the aggregation passes that produce careers, records, H2H, and rivalry intensity.
Pipeline
- 1Sleeper API → sleeper_raw.jsontools/refresh-data.mjs walks previous_league_id back through every season, dumps the raw league/users/rosters/matchups/brackets/drafts/transactions/traded_picks per year.
- 2Raw + CBS bridge → normalized.jsontools/refresh-data.mjs + tools/build-cbs-2020.mjs join Sleeper with cbs_2020.json (pre-Sleeper history), fold rosters → SeasonManager rows, collapse transactions → TradeEvent rows, compute the Career[] table once, and capture expansions + champion finishes.
- 3Build-time JSON import → lib/data.tsPages and analytics import normalized.json + sleeper_raw.json statically; lib/data.ts builds Maps (byUserId, matchupsByYear, rosterToUserByYear, draftPickByPosition…) once per server boot.
- 4Per-page aggregation → lib/analytics/*H2H, records, rivalries, lineup efficiency, trade hindsight, trends — each is a pure function over the same in-memory snapshot.
Refresh cadence: cron hits /api/cron/refresh nightly; the static JSON is what every page reads.
Entities
click any row to inspect a real sampleUser14lib/types → User▸
Manager identity. user_id is the only stable key — display_name and team_name change.
user_iddisplay_nameteam_nameavatarView sample row
{
"user_id": "682694793616236544",
"display_name": "bloodyrichard",
"team_name": "USPS Allstars ⭐️📦✅",
"avatar": "f0edbf4278f53f9425db175073df6584"
}Career12data.careers (precomputed)▸
One row per manager, summed across every Sleeper + CBS season. Reconciled against data.champions at module load so championships / runner_ups / thirds reflect playoff results.
seasonswins/losses/tiesfpts / fpts_againstchampionships / runner_ups / thirds / lastsbest_finish / worst_finishwin_pctavg_fpts_per_seasonView sample row
{
"user_id": "682694793616236544",
"display_name": "bloodyrichard",
"team_name": "USPS Allstars ⭐️📦✅",
"seasons": 7,
"wins": 51,
"losses": 32,
"ties": 0,
"fpts": 11441.759999999998,
"fpts_against": 10451.54,
"championships": 2,
"runner_ups": 0,
"thirds": 2,
"lasts": 0,
"best_finish": 1,
"worst_finish": 3,
"first_year": 2020,
"last_year": 2026,
"win_pct": 0.614,
"avg_fpts_per_season": 1634.54
}Season7data.seasons[]▸
Per-year league snapshot. previous_league_id is the chain pointer; settings/scoring_settings power Trends.
yearleague_idprevious_league_idsettingsscoring_settingsroster_positionsmanagers[]View sample row
{
"year": 2026,
"league_id": "1326430722143027200",
"name": "United Dynasty Fantasy Football League",
"status": "pre_draft",
"total_rosters": 12,
"previous_league_id": "1194779081882595328",
"season_type": "regular",
"settings": {
"best_ball": 0,
"waiver_budget": 750,
"disable_adds": 0,
"divisions": 0,
"capacity_override": 0,
"waiver_bid_min": 0,
"taxi_deadline": 4,
"draft_rounds": 5,
"reserve_allow_na": 0,
"start_week": 1,
"playoff_seed_type": 0,
"playoff_teams": 7,
"veto_votes_needed": 5,
"squads": 1,
"num_teams": 12,
"daily_waivers_hour": 9,
"playoff_type": 0,
"taxi_slots": 8,
"sub_start_time_eligibility": 0,
"daily_waivers_days": 5461,
"sub_lock_if_starter_active": 0,
"playoff_week_start": 15,
"waiver_clear_days": 1,
"reserve_allow_doubtful": 0,
"commissioner_direct_invite": 0,
"veto_auto_poll": 0,
"reserve_allow_dnr": 0,
"taxi_allow_vets": 1,
"waiver_day_of_week": 2,
"playoff_round_type": 0,
"reserve_allow_out": 1,
"reserve_allow_sus": 1,
"veto_show_votes": 0,
"trade_deadline": 10,
"taxi_years": 2,
"daily_waivers": 1,
"faab_suggestions": 0,
"disable_trades": 0,
"pick_trading": 1,
"type": 2,
"max_keepers": 1,
"waiver_type": 2,
"max_subs": 0,
"league_average_match": 0,
"trade_review_days": 0,
"bench_lock": 0,
"offseason_adds": 1,
"leg": 1,
"daily_waivers_base": 4,
"reserve_slots": 2,
"reserve_allow_cov": 1,
"daily_waivers_last_ran": 5
},
"scoring_settings": {
"sack": 0,
"fgm_40_49": 0,
"pass_int": -2,
"pts_allow_0": 0,
"bonus_pass_yd_400": 2,
"pass_2pt": 2,
"st_td": 6,
"rec_30_39": 0.75,
"fgm_yds_over_30": 0.1,
"rec_td": 6,
"rec_20_29": 0.5,
"idp_blk_kick": 2,
"fgm_30_39": 0,
"idp_fum_ret_yd": 0.1,
"xpmiss": -1,
"rush_td": 6,
"idp_tkl": 0,
"pass_td_40p": 0,
"fgm": 3,
"idp_sack_yd": 0.04,
"rec_2pt": 2,
"idp_tkl_loss": 0,
"pass_int_td": -4,
"idp_tkl_solo": 0.5,
"st_fum_rec": 2,
"fgmiss": -1,
"ff": 0,
"idp_int": 2,
"rec": 1,
"idp_int_ret_yd": 0.1,
"idp_safe": 3,
"pts_allow_14_20": 0,
"fgm_0_19": 0,
"idp_def_td": 6,
"int": 0,
"def_st_fum_rec": 0,
"fum_lost": -2,
"pts_allow_1_6": 0,
"kr_yd": 0.04,
"idp_sack": 2,
"fgm_20_29": 0,
"pts_allow_21_27": 0,
"bonus_pass_yd_300": 1,
"xpm": 1,
"rec_40p": 1,
"rush_2pt": 2,
"fum_rec": 0,
"idp_pass_def": 1,
"def_st_td": 0,
"pass_cmp_40p": 1,
"fgm_50p": 0,
"def_td": 0,
"idp_fum_rec": 2,
"rec_td_40p": 1.5,
"safe": 0,
"pass_yd": 0.04,
"blk_kick": 0,
"pass_td": 4,
"idp_qb_hit": 0,
"rush_yd": 0.1,
"rush_40p": 2,
"pr_yd": 0.04,
"fum": 0,
"pts_allow_28_34": 0,
"pts_allow_35p": 0,
"fum_rec_td": 6,
"rec_yd": 0.1,
"rush_td_40p": 0,
"def_st_ff": 0,
"pts_allow_7_13": 0,
"idp_ff": 3,
"st_ff": 1,
"idp_tkl_ast": 0.25
},
"roster_positions": [
"QB",
"RB",
"RB",
"WR",
"WR",
"TE",
"FLEX",
"K",
"DL",
"DB",
"IDP_FLEX",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN",
"BN"
],
"draft_id": "1326430722159816704",
"avatar": "e7666f3276fce37438e1e566a76f00eb",
"source": "sleeper",
"managers": [
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 1,
"user_id": "474788159146684416",
"display_name": "McPeake1",
"team_name": "The McCafrican Americans",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 436,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 2,
"user_id": "682694793616236544",
"display_name": "bloodyrichard",
"team_name": "USPS Allstars ⭐️📦✅",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 484,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 3,
"user_id": "683165664151670784",
"display_name": "verbbb",
"team_name": "verbbb",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 263,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 4,
"user_id": "682704177654198272",
"display_name": "Patek007",
"team_name": "Cursed team",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 445,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 5,
"user_id": "682684750502096896",
"display_name": "mattkieser",
"team_name": "Mike Vick’s Puppies🐶",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 380,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 6,
"user_id": "682657697815961600",
"display_name": "Marble221",
"team_name": "Kirko Chainz Gang",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 544,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 7,
"user_id": "682658309609697280",
"display_name": "Purshdaddy",
"team_name": "Glock Purdy 🔫",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 542,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 8,
"user_id": "632483874114478080",
"display_name": "PsychJawn",
"team_name": "Shipping DeJawn",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 400,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 9,
"user_id": "682991018118832128",
"display_name": "BrettRV",
"team_name": "Njigbas with Attitude ",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 256,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 10,
"user_id": "682658216940728320",
"display_name": "andyarm",
"team_name": "First Down Syndrome ",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 614,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 11,
"user_id": "609107523265437696",
"display_name": "TheEnglishman43",
"team_name": "Nick top Bobby bottom ",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 553,
"total_moves": 0,
"final_rank": null
},
{
"year": 2026,
"league_id": "1326430722143027200",
"roster_id": 12,
"user_id": "918211486294814720",
"display_name": "WillGaul314",
"team_name": "Golden Branch in Pants ",
"wins": 0,
"losses": 0,
"ties": 0,
"fpts": 0,
"fpts_against": 0,
"waiver_budget_used": 250,
"total_moves": 0,
"final_rank": null
}
]
}Champion7data.champions[]▸
Final finish per season. source='cbs' for pre-Sleeper years; 'sleeper' rows include the championship game row.
yearchampion_user_idrunner_up_user_idthird_user_idlast_user_idchampionship_gamesourceView sample row
{
"year": 2026,
"league_id": "1326430722143027200",
"league_name": "United Dynasty Fantasy Football League",
"total_rosters": 12,
"status": "pre_draft",
"champion_user_id": null,
"champion_roster_id": null,
"runner_up_user_id": null,
"runner_up_roster_id": null,
"third_user_id": null,
"third_roster_id": null,
"last_user_id": null,
"last_roster_id": null,
"championship_game": {
"p": 1,
"m": 7,
"r": 3,
"l": null,
"w": null,
"t1": null,
"t2": null,
"t2_from": {
"w": 5
},
"t1_from": {
"w": 4
}
},
"source": "sleeper"
}TradeEvent183data.trade_events[]▸
Flat transactions: adds, drops, traded picks, waiver-budget moves. Drives /trades, hindsight, trade trees.
yearweektransaction_idroster_ids[]adds{}drops{}draft_picks[]waiver_budget[]View sample row
{
"year": 2026,
"week": 1,
"transaction_id": "1353923413617434624",
"created": 1777163005789,
"roster_ids": [
7,
11
],
"draft_picks": [
{
"round": 2,
"season": "2027",
"league_id": null,
"roster_id": 2,
"owner_id": 7,
"previous_owner_id": 11
},
{
"round": 2,
"season": "2026",
"league_id": null,
"roster_id": 8,
"owner_id": 11,
"previous_owner_id": 7
}
],
"adds": {},
"drops": {},
"waiver_budget": []
}MatchupTeam1,168sleeper_raw[year].matchups[week][] (1168 rows total)▸
One row per team per week. Two rows sharing a matchup_id = one game. starters_points + players_points feed records, H2H, and lineup efficiency.
roster_idmatchup_idpointsstarters[]starters_points[]players[]players_points{}View sample row
— no sample —
BracketGame83sleeper_raw[year].winners_bracket / losers_bracket▸
Sleeper's compact bracket node. p=1 is the final, w/l are roster_ids, t1_from/t2_from chain the bracket.
mrt1t2wlpt1_fromt2_fromView sample row
{
"m": 1,
"r": 1,
"l": null,
"w": null,
"t1": 8,
"t2": 2
}DraftPick530lib/data.ts → draftPickByPosition▸
Every draft slot across every year, keyed `${year}-${round}-${slot}`. Combined with allTradedPicks to render the rookie/start-up board.
draft_idrounddraft_slotpick_noplayer_idroster_idpicked_byView sample row
{
"year": 2020,
"pick": {
"draft_id": "cbs-2020-draft",
"draft_slot": 1,
"is_keeper": null,
"metadata": {
"first_name": "Christian",
"last_name": "McCaffrey",
"position": "RB"
},
"pick_no": 1,
"picked_by": "474788159146684416",
"player_id": "4034",
"roster_id": 1,
"round": 1
},
"user_id": "474788159146684416"
}Aggregations
Career row
view →- Group every SeasonManager by user_id (joined via roster_id → owner_id per year).
- Σ wins/losses/ties/fpts/fpts_against across all seasons.
- Read final_rank per season → tally championships (rank=1), runner_ups (rank=2), thirds (rank=3), lasts (rank=N).
- win_pct = wins / (wins+losses+ties); avg_fpts_per_season = fpts / seasons.
H2H matrix
view →- Walk every (year, week) in matchupsByYear.
- Group rows by matchup_id — pairs of length 2 are valid games.
- Resolve each roster_id → user_id via rosterToUserByYear[year].
- For each pair, increment cell[i][j] and cell[j][i] symmetrically: games, wins/losses/ties, pf, pa.
- Final cell = total record between user i and user j across the whole archive.
Records (highs, streaks, blowouts)
view →- Flatten every matchup pair into one game-row per team (allGames).
- Sort by pts ↓ for single_game_high, ↑ for single_game_low.
- margin = pts − opp_pts → max(margin) is biggest_blowout, min(margin>0) is closest_win.
- Per uid chronological feed → bestStreak scans for longest 'W' or 'L' run.
- Σ pts per (year, uid) → season_pf_high / season_pf_low.
Rivalry intensity
view →- Start from H2H allPairs() (every pair with ≥2 games).
- Annotate each pair by re-walking matchups: close_games (|margin| ≤ 7), blowouts (|margin| ≥ 25), playoff_meetings (week ≥ 15).
- Composite score = 0.35·balance + 0.25·close% + 0.15·blowout% + 0.15·playoff + 0.10·volume.
- balance = 1 − |a_wins − b_wins| / games; scaled ×100 → 0–100 intensity.
Lineup efficiency
view →- For each (year, week), read row.players + row.players_points.
- Build optimal lineup greedily: walk roster_positions, strict slots first (QB/RB/WR/TE/K/DEF), then FLEX/SUPER_FLEX. Pick max-points eligible unused player per slot.
- actual_pts = Σ starters_points; optimal_pts = Σ greedy lineup pts.
- left_on_bench = max(0, optimal_pts − actual_pts); efficiency = actual / optimal.
- Career roll-up: Σ actual, Σ optimal, Σ left across every week per uid.
Trends
view →- scoring_inflation: Σ row.points across every week of a year ÷ matchup-team count → league_avg per season.
- trade_volume: count trade_events filtered by year.
- faab_usage: Σ waiver_budget.amount per year across trade_events.
- scoring_changes: diff scoring_settings between consecutive seasonByYear entries.