Added week_id to game model as a foreign key #418
No reviewers
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
johnsturgeon/tgfp-web!418
Loading…
Reference in a new issue
No description provided.
Delete branch "phase-3-game-week-id-foreign-key-409"
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?
Add Game.week_id as a NOT NULL FK plus migration. One revision,
no backfill, while the tables are still empty.
create_the_picks sets week_id via get-or-create on Week, the
same way it already resolves teams.
Switch Game.games_for_week and Game.get_first_game_of_the_week
to filter on week_id.
Switch PlayerGamePick.find_picks_for_week and
upsert_award_with_args to the FK. Keep this separate from the task
above — different tables, different blast radius.
Resolves #409
gamemodel as a foreign keyI have enough to write the review.
Summary
This PR introduces a
week_idFK onGame, migrates the week-scoped queries from the denormalized(season, season_type, week_no)triple to the FK, and replaces the Wednesday-croncreate_picksjob with an hourlysync_games_for_current_weekupsert job. The model and query changes are coherent and the None-guards added aroundplayer.id/game.idare a real improvement, but there are a few gaps: an unmonitored set of jobs, a missing startup one-shot for the new sync job, and no test coverage for the new job orWeekquery methods.Blocking
gametable is empty in every environment this migrates.alembic/versions/1cfb85d793c6_...py:26addsweek_idasNOT NULLwith no server default and no backfill. UnlikeWeek.game_state(which got aserver_defaultprecisely becauseweekalready held rows — seeapp/models/week.py:34-41), this column will fail the migration with an integrity error if anygamerow exists. The PR description asserts the tables are still empty; that assumption is the whole safety of this migration, so it needs to be verified against prod before merge, not assumed.Worth fixing
Awards, team-records, and
schedule_jobslost their monitoring with no replacement. The@monitor(...)decorators were removed fromscheduled_update_all_awards(app/jobs/award_update_all.py),sync_the_team_records(app/jobs/sync_team_records.py), andschedule_jobs(app/jobs/scheduler.py), and theSENTRY_CRON_MONITOR_*config was deleted (app/config/config.py,config/op.env). Only the newsync_games_for_current_weekgot a Kuma monitor. So three previously-monitored recurring jobs now run with zero check-in coverage. If the intent is a Sentry→Kuma migration, the awards and team-records jobs need Kuma monitors too; otherwise a silent failure of the weekly award/records jobs is now invisible. Please confirm this is intentional.No startup one-shot for
sync_games_for_current_week.schedule_sync_games_for_current_week()(app/jobs/scheduler.py:167) registers only anIntervalTrigger(hours=1), whose first fire is ~1 hour out.sync_current_weekdeliberately pairs its interval with arun_date=now()startup job (app/main.py:136-143) precisely to populate an empty table immediately — the comment atapp/main.py:124-128spells this out. On a fresh-season database the picks page will show no games for up to an hour after boot. Consider adding the same one-shot date-trigger for the games sync.No test coverage for the new job or the new
Weekmethods.sync_games_for_current_week(including its create-vs-update branch atapp/jobs/sync_games_for_current_week.py:81-95),Week.all_weeks_for_current_season, andWeek.find_by_infoare all untested. The upsert branch in particular carries the core behavior change of this PR and deserves a test (new game inserted with correctweek_id; existing game updated in place).PR description overstates the pick/award change. The description says it switches
PlayerGamePick.find_picks_for_weekandupsert_award_with_argsto the FK, butapp/models/player_game_pick.py:117-127still filters on the denormalizedweek_no/season/season_type, and callers still passweek.info. That's fine as-is, but the description doesn't match the code — worth correcting so a future reader doesn't assumefind_picks_for_weekis FK-based.Nits
sync_games_for_current_weekmatches existing games byexternal_game_idalone (app/jobs/sync_games_for_current_week.py:78), while the documented/enforced key is(data_source, external_game_id)(seeuq_game_data_source_external_game_idinapp/models/game.py:18-24). Harmless with a single provider today, but inconsistent with the model's key; adding.where(Game.data_source == DataSource.TANK01)would keep it honest. The trailing.limit(1)is also redundant given that unique constraint.The update branch never refreshes
week_id(app/jobs/sync_games_for_current_week.py:82-87), so a game whose week association is ever wrong won't self-correct on the next sync. Low-risk since a game's week doesn't change, but worth a comment if intentional.Misleading log line:
sync_games_for_current_weeklogs"Creating weekly picks page for ..."(app/jobs/sync_games_for_current_week.py:65-67) — copied from the deletedcreate_the_picks; it's now a game sync, not a picks-page creation.Stale comment:
app/jobs/scheduler.py:28still references "the gap beforecreate_the_picksfires Wednesday 6am PT," but that job was deleted in this PR.