Phase 1 — Make the week table real #407
Labels
No labels
Kestra
bug
enhancement
someday
subtask
☁️ api
🎛️ infrastructure
🐞 sentry
📆 2025 Season
📝 pages
allpicks
📝 pages
picks
📝 pages
standings
🚀 performance
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
#406 Resolve the technical debt issues that remain for the
week table issue
johnsturgeon/tgfp-web
Reference
johnsturgeon/tgfp-web#407
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 1 — Make the
weektable realParent: #___ · Tech debt: The
weektable exists but nothing fills itWhy
Weekshipped with its schema and no writer. Nothing creates rows, so thetable is empty in every environment and
Week.current()cannot answer from it.To keep the UI off the provider in the meantime,
Week.current()returns ahardcoded
WeekInfo(2026 preseason week 2). Every page renders against thatconstant. That is safe only while production holds no games — the picks page,
week picker, and standings all come back empty either way.
It stops being safe at regular-season week 1, when a hardcoded week means
players see the wrong week's games or none at all.
Nothing else in this epic can start until the table has rows.
Tasks
WeekInfointo its own module (app/models/week_info.py) tobreak the
week.py/model_helperscycle.model_helpers.pyis gone.Week.current()call sites —dependency.py,admin.pyx2,nag_players.py,scheduler.py,update_all_scores.py,game.py.active_weekanduq_week_activeplus a migration. SeeNo pointer column below. Confirm the revision drops the column, not
just the index.
app/jobs/sync_current_week.py. On an interval, derive thecurrent week from the games endpoint and get-or-create the
Weekrowfor it. Expose it on an admin route so it can be run by hand.
schedule_jobs.Week.current()and query for real.Remove the
# pylint: disable=unused-argumentwith it.Design decisions
Not from
getNFLCurrentInfo. That endpoint is not trusted — seegetNFLCurrentInfo?date=lies about the past in TECH_DEBT. The current weekis derived from game data instead.
No pointer column.
Week.current()is the most recent row, ordered by(season, season_type, week_no)descending. This works becauseSeasonTypevalues sort chronologically (1=pre, 2=reg, 3=post — see
season.py).It holds only while rows are created for weeks that have arrived.
Pre-seeding a whole season's calendar would silently break it — worth
remembering during the
week_idFK work, which tempts exactly that.Raises, does not return
None. Once the sync has run even once the tableis never empty, so an empty table means it has never run: a bootstrap failure,
not a state. Blank pages would be indistinguishable from the intended
between-seasons view. Raising also keeps the signature
-> WeekInfo, so nocaller grows a branch — and it is where the "at least one row" half of the
invariant lives, since Postgres can only express "at most one".
Returns
WeekInfo, not aWeekrow. SQLModel's__eq__compares everyfield,
idand timestamps included, so a row loaded from the database neverequals one built from
/allpicksquery parameters — the week picker'scurrent-week highlight would silently stop matching.
WeekInfois alsodetached-safe (
scheduler.pyuses the value after its session closes) andsafe to pickle into the APScheduler jobstore until Phase 4 removes that.
When Phase 3 needs
week.id, add a second accessor rather than changing whatcurrent()returns.Bootstrap
There is no seed step — the job is the bootstrap. First run on an empty
table creates one row; every run after finds it or adds the next.
The only gap is between deploy and first run, when
Week.current()raises.Running the job once at startup closes it.
On an empty table there is no prior row to anchor on, so the derivation
cannot be "previous week + 1". It has to resolve from a date. Confirm that
works cold before building the rest of the job around it.
Done when
Week.current()contains no hardcoded values and noactive_week.weektable has a row in dev, created by the job and not by hand.NoActiveWeekError, not blank pages.weektable issueweektable issueweektable issueweektable issue #406