← Back to game
Odds Graph Debug — 0042500103
DET @ ORL · 2026-04-25T17:00:00Z
·
price-history JSON ↗
·
alignment-debug JSON ↗
Summary
| game_row_found | True |
| playoff_row_found | True |
| game_time_utc | 2026-04-25T17:00:00Z |
| game_status_id | 3 |
| game_has_final_score | True |
| final_signal | scores_past_date |
| game_start_ms | 1777136400000 2026-04-25T17:00:00Z |
| window_start_ms | 1777132800000 2026-04-25T16:00:00Z |
| basketball_final_ms | 1777146686000 2026-04-25T19:51:26Z |
| window_end_ms | 1777147586000 2026-04-25T20:06:26Z |
| window_duration_min | 246 |
| pg_final_ms_fallback used | False |
| odds_start_fallback used | False |
game_time_utc Refetch Execution
| gtu_refetch_attempted | False ← refetch was NOT triggered on this request |
| gtu_refetch_trigger_reason | game_time_utc already set |
| game_time_utc_before | |
| game_date (used for ScoreboardV3 call) | NULL |
| source_1_scoreboard_attempted | |
| source_1_scoreboard_found_game | |
| source_1_scoreboard_gameTimeUTC | null |
| source_2_boxscore_attempted | |
| source_2_boxscore_gameTimeUTC | null |
| gtu_refetch_source_used | none |
| gtu_refetch_value | null |
| db_path | — |
| rows_affected (SQL UPDATE) | |
| gtu_refetch_update_applied | |
| game_time_utc_after (re-read same conn) | null |
Source Rows
A. games table
| game_id | 0042500103 |
| game_status_id | 3 |
| game_time_utc | 2026-04-25T17:00:00Z |
| home_abbr | ORL |
| visitor_abbr | DET |
| home_pts | 113 |
| visitor_pts | 105 |
B. playoff_games table
| game_start_ms | 1777136400000 |
| scheduled_start_ms | 1777136400000 |
| basketball_final_ms | 1777146686000 |
| basketball_final_source | espn_pbp_last_valid_event |
| basketball_final_event_text | End of Game |
| basketball_final_period | 4 |
| basketball_final_clock | 0.0 |
| basketball_final_raw_timestamp | 2026-04-25T19:51:26Z |
| home_team_abbr | ORL |
| away_team_abbr | DET |
| home_score | 113 |
| away_score | 105 |
| status | final |
C. playoff_game_pbp_events diagnostics
| row count | 513 |
Show last 5 PBP events ↓
[
{
"id": 11218,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414748",
"sequence": 748,
"timestamp_ms": 1777146686000,
"raw_timestamp": "2026-04-25T19:51:26Z",
"period": 4,
"clock": "0.0",
"event_type": "402",
"event_text": "End of Game",
"team_id": null,
"player_id": null,
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 748, \"period\": 4, \"clock\": \"0.0\", \"text\": \"End of Game\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
},
{
"id": 11217,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414747",
"sequence": 747,
"timestamp_ms": 1777146681000,
"raw_timestamp": "2026-04-25T19:51:21Z",
"period": 4,
"clock": "0.0",
"event_type": "412",
"event_text": "End of the 4th Quarter",
"team_id": null,
"player_id": null,
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 747, \"period\": 4, \"clock\": \"0.0\", \"text\": \"End of the 4th Quarter\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
},
{
"id": 11216,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414746",
"sequence": 746,
"timestamp_ms": 1777146669000,
"raw_timestamp": "2026-04-25T19:51:09Z",
"period": 4,
"clock": "7.8",
"event_type": "155",
"event_text": "Paolo Banchero defensive rebound",
"team_id": "19",
"player_id": "4432573",
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 746, \"period\": 4, \"clock\": \"7.8\", \"text\": \"Paolo Banchero defensive rebound\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
},
{
"id": 11215,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414745",
"sequence": 745,
"timestamp_ms": 1777146665000,
"raw_timestamp": "2026-04-25T19:51:05Z",
"period": 4,
"clock": "11.6",
"event_type": "131",
"event_text": "Duncan Robinson misses 27-foot three point pullup jump shot",
"team_id": "8",
"player_id": "3157465",
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 745, \"period\": 4, \"clock\": \"11.6\", \"text\": \"Duncan Robinson misses 27-foot three point pullup jump shot\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
},
{
"id": 11214,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414744",
"sequence": 744,
"timestamp_ms": 1777146648000,
"raw_timestamp": "2026-04-25T19:50:48Z",
"period": 4,
"clock": "19.5",
"event_type": "90",
"event_text": "Jalen Suggs out of bounds bad pass turnover",
"team_id": "19",
"player_id": "4432165",
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 744, \"period\": 4, \"clock\": \"19.5\", \"text\": \"Jalen Suggs out of bounds bad pass turnover\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
}
]
Games Row Provenance
Most Likely Write Source
confidence: High
fetch_and_store_games
game_time_utc is populated. This field is ONLY written by fetch_and_store_games() (ScoreboardV3). All other write paths omit it from their INSERT/UPDATE.
| this path writes game_time_utc | True |
| games.updated_at | — |
| games.game_time_utc (current) | 2026-04-25T17:00:00Z |
| games.game_status_id (current) | 3 |
| games.home_pts / visitor_pts | 113 / 105 |
Field-Level Write Coverage
| Field | Written by | NOT written by | Strategy / Risk |
|---|---|---|---|
| game_time_utc | fetch_and_store_games | sync_playoff_games, fetch_and_store_historical_game, copy_game_to_nba_db, boxscores_live_update, playoff_resolve_update |
COALESCE — set once on first non-null insert; never overwritten after that
Risk: High: only fetch_and_store_games writes it, and it only runs for today/yesterday |
| game_status_id | fetch_and_store_games, sync_playoff_games, fetch_and_store_historical_game, copy_game_to_nba_db, boxscores_live_update | playoff_resolve_update |
MAX(existing, new) in fetch_and_store_games; direct set in sync/historical/live
Risk: Low: all major paths write it |
| home_pts / visitor_pts | fetch_and_store_games, sync_playoff_games, fetch_and_store_historical_game, copy_game_to_nba_db, boxscores_live_update | playoff_resolve_update |
Varies: MAX for final (sync), COALESCE for live, direct for historical
Risk: Low: most paths populate scores |
| game_date | fetch_and_store_games, sync_playoff_games, fetch_and_store_historical_game, copy_game_to_nba_db | boxscores_live_update, playoff_resolve_update |
Set on INSERT; ON CONFLICT generally does not update it
Risk: Low: all INSERT paths include game_date |
All Candidate Write Paths
| Function | File | game_time_utc | can null gtu | old games | When / Note |
|---|---|---|---|---|---|
| fetch_and_store_games(game_date) likely | app/services/games.py | YES | Only if ScoreboardV3 returns gameTimeUTC=null (rare) | False |
Homepage load (today/yesterday), scheduler daily, startup warmup_games_db()
Warmup covers today+yesterday only. Games ≥2 days old are never re-fetched by this path.
|
| sync_playoff_games(season) | app/services/games.py | NO | True | True |
Rate-limited: called by playoff_analytics._sync_playoff_games_if_due() on bracket page fetch
LeagueGameFinder has no gameTimeUTC field. Creates complete rows (date, teams, final score) but leaves game_time_utc=NULL.
|
| fetch_and_store_historical_game(game_id) | app/services/historical.py | NO | True | True |
On-demand: /games/{game_id} visited and game not yet in DB
Bypassed if game already exists (sync_playoff_games may have created it). Does not populate game_time_utc.
|
| copy_game_to_nba_db(game_id) | app/services/playoff_history_db.py | NO | True | True |
Called first inside fetch_and_store_historical_game
Short-circuits the nba_api call if game is in the local history DB.
|
| fetch_and_store_live_boxscore() / store_live_period_scores() | app/services/boxscores.py | NO | False | False |
During live game polling (~every 5 s while game is live)
Never creates rows. Cannot set game_time_utc to NULL.
|
| _resolve_playoff_placeholders() | app/main.py | NO | False | False |
Homepage load when visitor/home team is still TBD
Only sets team identification fields. Cannot affect game_time_utc.
|
Execution Trace
| # | Step | Branch / Path | Output | Inputs & Fields | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Load games table row | found | found=True |
|
||||||||||||||||||||||||||||||||||||||||||
| 2 | Load playoff_games row | found | found=True |
|
||||||||||||||||||||||||||||||||||||||||||
| 3 | Load odds aggregate (playoff_game_odds_history) | has_data | cnt=832 min_ts=1776608450000 max_ts=1777158616000 |
|
||||||||||||||||||||||||||||||||||||||||||
| 4 | Derive scheduled_start_ms | games.game_time_utc | 1777136400000 (2026-04-25T17:00:00Z) |
|
||||||||||||||||||||||||||||||||||||||||||
| 5 | Derive game_start_ms | playoff_games.game_start_ms (actual) | 1777136400000 (2026-04-25T17:00:00Z) |
|
||||||||||||||||||||||||||||||||||||||||||
| 5b | Midnight-ET placeholder detection & start correction | not_midnight_et |
uncorrected → 1777136400000 (2026-04-25T17:00:00Z)
not midnight-ET
|
|
||||||||||||||||||||||||||||||||||||||||||
| 6 | Detect game_has_final_score | scores_past_date | game_has_final_score=True final_signal=scores_past_date |
|
||||||||||||||||||||||||||||||||||||||||||
| 7 | Derive basketball_final_ms | get_basketball_final_point → value | 1777146686000 (2026-04-25T19:51:26Z) |
|
||||||||||||||||||||||||||||||||||||||||||
| 8 | Derive window_start_ms (game_start − 1 h) | game_start_minus_1h | 1777132800000 (2026-04-25T16:00:00Z) |
|
||||||||||||||||||||||||||||||||||||||||||
| 9 | Derive window_end_ms (basketball_final + 15 min) | final_plus_15min | 1777147586000 (2026-04-25T20:06:26Z) |
|
Branch Decisions
scores_present
True
game_time_utc_present
True
past_date_in_et
True
status_id_is_3
True
pg_status_is_final
True
pg_status_is_in_progress
False
pg_has_basketball_final_ms
True
pg_bfm_suppressed_in_progress
False
scores_past_date_fired
True
scores_status3_sameday_fired
False
scores_status3_no_tip_fired
False
playoff_games_status_final_fired
False
playoff_games_has_final_ms_fired
False
midnight_et_start_detected
False
midnight_et_start_corrected
False
bfp_called
True
pg_final_ms_fallback_used
False
odds_start_fallback_used
False
Odds Filtering Breakdown
| odds source | — |
| raw rows total | 0 |
| rows before window_start_ms | 0 |
| rows in window (start → end) | 0 |
| rows after window_end_ms | 0 |
| earliest timestamp (epoch s) | — |
| latest timestamp (epoch s) | — |
| local odds history rows | 832 |
| window_start_ms applied | 1777132800000 2026-04-25T16:00:00Z |
| window_end_ms applied | 1777147586000 2026-04-25T20:06:26Z |
Enrichment Trace
A. Referees
| query | game_referee_assignments JOIN referees |
| game_referee_assignments rows | 4 |
| referees after JOIN | 4 |
| referee list |
#25 Tony Brothers (Crew Chief) #3 Nick Buchert (Referee) #27 Mitchell Ervin (Umpire) #30 John Butler (Alternate) |
B. Lineup Marker
| query | lineup_state WHERE game_id = ? |
| lineup_state row found | True |
| is_confirmed | 1 |
| telegram_first_detected_at | NULL |
| first_confirmed_at | 2026-04-25T23:18:20Z |
| chosen timestamp field | first_confirmed_at |
| final lineup_marker_ts | 2026-04-25T23:18:20Z 2026-04-25T23:18:20Z |
| lineup_confirmed | True |
Raw Debug JSON (machine-readable)
Show full debug payload ↓
{
"game_id": "0042500103",
"gtu_refetched": false,
"gtu_refetch_trace": {
"attempted": false,
"trigger_reason": "game_time_utc already set"
},
"games_raw": {
"game_id": "0042500103",
"game_status_id": 3,
"game_time_utc": "2026-04-25T17:00:00Z",
"home_abbr": "ORL",
"visitor_abbr": "DET",
"home_pts": 113,
"visitor_pts": 105
},
"playoff_games_raw": {
"game_start_ms": 1777136400000,
"scheduled_start_ms": 1777136400000,
"basketball_final_ms": 1777146686000,
"basketball_final_source": "espn_pbp_last_valid_event",
"basketball_final_event_text": "End of Game",
"basketball_final_period": 4,
"basketball_final_clock": "0.0",
"basketball_final_raw_timestamp": "2026-04-25T19:51:26Z",
"home_team_abbr": "ORL",
"away_team_abbr": "DET",
"home_score": 113,
"away_score": 105,
"status": "final"
},
"ph_agg": {
"cnt": 832,
"min_ts": 1776608450000,
"max_ts": 1777158616000
},
"bfp": {
"final_ms": 1777146686000,
"source": "stored_pbp_last_wallclock_at_zero",
"event_text": "End of Game",
"period": 4,
"clock": "0.0",
"raw_timestamp": null,
"warning": null
},
"bfp_called": true,
"bfp_error": null,
"final_branches": {
"scores_present": true,
"game_time_utc_present": true,
"past_date_in_et": true,
"status_id_is_3": true,
"pg_status_is_final": true,
"pg_status_is_in_progress": false,
"pg_has_basketball_final_ms": true,
"pg_bfm_suppressed_in_progress": false,
"scores_past_date_fired": true,
"scores_status3_sameday_fired": false,
"scores_status3_no_tip_fired": false,
"playoff_games_status_final_fired": false,
"playoff_games_has_final_ms_fired": false,
"midnight_et_start_detected": false,
"midnight_et_start_corrected": false
},
"window": {
"game_start_ms": 1777136400000,
"window_start_ms": 1777132800000,
"window_end_ms": 1777147586000,
"basketball_final_ms": 1777146686000,
"window_duration_min": 246
},
"odds_filter": {
"raw_count": 0,
"before_window": 0,
"in_window": 0,
"after_window": 0,
"uncategorized": 0
},
"referee_trace": {
"query": "game_referee_assignments JOIN referees",
"assignments_found": 4,
"referees_found": 4,
"error": null
},
"lineup_trace": {
"query": "lineup_state WHERE game_id = ?",
"row_found": true,
"is_confirmed": 1,
"telegram_first_detected_at": null,
"first_confirmed_at": "2026-04-25T23:18:20Z",
"chosen_field": "first_confirmed_at",
"error": null
},
"pbp_row_count": 513,
"pbp_last_events": [
{
"id": 11218,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414748",
"sequence": 748,
"timestamp_ms": 1777146686000,
"raw_timestamp": "2026-04-25T19:51:26Z",
"period": 4,
"clock": "0.0",
"event_type": "402",
"event_text": "End of Game",
"team_id": null,
"player_id": null,
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 748, \"period\": 4, \"clock\": \"0.0\", \"text\": \"End of Game\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
},
{
"id": 11217,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414747",
"sequence": 747,
"timestamp_ms": 1777146681000,
"raw_timestamp": "2026-04-25T19:51:21Z",
"period": 4,
"clock": "0.0",
"event_type": "412",
"event_text": "End of the 4th Quarter",
"team_id": null,
"player_id": null,
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 747, \"period\": 4, \"clock\": \"0.0\", \"text\": \"End of the 4th Quarter\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
},
{
"id": 11216,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414746",
"sequence": 746,
"timestamp_ms": 1777146669000,
"raw_timestamp": "2026-04-25T19:51:09Z",
"period": 4,
"clock": "7.8",
"event_type": "155",
"event_text": "Paolo Banchero defensive rebound",
"team_id": "19",
"player_id": "4432573",
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 746, \"period\": 4, \"clock\": \"7.8\", \"text\": \"Paolo Banchero defensive rebound\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
},
{
"id": 11215,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414745",
"sequence": 745,
"timestamp_ms": 1777146665000,
"raw_timestamp": "2026-04-25T19:51:05Z",
"period": 4,
"clock": "11.6",
"event_type": "131",
"event_text": "Duncan Robinson misses 27-foot three point pullup jump shot",
"team_id": "8",
"player_id": "3157465",
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 745, \"period\": 4, \"clock\": \"11.6\", \"text\": \"Duncan Robinson misses 27-foot three point pullup jump shot\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
},
{
"id": 11214,
"game_id": "0042500103",
"source": "espn",
"event_id": "401869414744",
"sequence": 744,
"timestamp_ms": 1777146648000,
"raw_timestamp": "2026-04-25T19:50:48Z",
"period": 4,
"clock": "19.5",
"event_type": "90",
"event_text": "Jalen Suggs out of bounds bad pass turnover",
"team_id": "19",
"player_id": "4432165",
"is_valid_in_game_event": 1,
"raw_json": "{\"seq\": 744, \"period\": 4, \"clock\": \"19.5\", \"text\": \"Jalen Suggs out of bounds bad pass turnover\"}",
"created_at": "2026-05-04T00:53:55Z",
"updated_at": "2026-05-04T00:53:55Z",
"home_score": null,
"away_score": null
}
],
"games_write_paths": [
{
"id": "fetch_and_store_games",
"file": "app/services/games.py",
"function": "fetch_and_store_games(game_date)",
"when": "Homepage load (today/yesterday), scheduler daily, startup warmup_games_db()",
"source_api": "ScoreboardV3 (nba_api)",
"writes_game_time_utc": true,
"game_time_utc_strategy": "COALESCE(existing, new) \u2014 fills if null, never overwrites non-null",
"can_create_null_gtu": "Only if ScoreboardV3 returns gameTimeUTC=null (rare)",
"covers_old_games": false,
"note": "Warmup covers today+yesterday only. Games \u22652 days old are never re-fetched by this path."
},
{
"id": "sync_playoff_games",
"file": "app/services/games.py",
"function": "sync_playoff_games(season)",
"when": "Rate-limited: called by playoff_analytics._sync_playoff_games_if_due() on bracket page fetch",
"source_api": "LeagueGameFinder (nba_api)",
"writes_game_time_utc": false,
"game_time_utc_strategy": "NOT in INSERT column list; NOT in ON CONFLICT SET \u2014 always NULL for new rows",
"can_create_null_gtu": true,
"covers_old_games": true,
"note": "LeagueGameFinder has no gameTimeUTC field. Creates complete rows (date, teams, final score) but leaves game_time_utc=NULL."
},
{
"id": "fetch_and_store_historical_game",
"file": "app/services/historical.py",
"function": "fetch_and_store_historical_game(game_id)",
"when": "On-demand: /games/{game_id} visited and game not yet in DB",
"source_api": "BoxScoreSummaryV3 (nba_api) / playoff_history_db",
"writes_game_time_utc": false,
"game_time_utc_strategy": "NOT in INSERT column list; NOT in ON CONFLICT SET",
"can_create_null_gtu": true,
"covers_old_games": true,
"note": "Bypassed if game already exists (sync_playoff_games may have created it). Does not populate game_time_utc."
},
{
"id": "copy_game_to_nba_db",
"file": "app/services/playoff_history_db.py",
"function": "copy_game_to_nba_db(game_id)",
"when": "Called first inside fetch_and_store_historical_game",
"source_api": "Local playoff_history.db SQLite file",
"writes_game_time_utc": false,
"game_time_utc_strategy": "NOT in INSERT column list; NOT in ON CONFLICT SET",
"can_create_null_gtu": true,
"covers_old_games": true,
"note": "Short-circuits the nba_api call if game is in the local history DB."
},
{
"id": "boxscores_live_update",
"file": "app/services/boxscores.py",
"function": "fetch_and_store_live_boxscore() / store_live_period_scores()",
"when": "During live game polling (~every 5 s while game is live)",
"source_api": "data.nba.com live BoxScore",
"writes_game_time_utc": false,
"game_time_utc_strategy": "UPDATE only: game_status_id, status_text, home_pts, visitor_pts",
"can_create_null_gtu": false,
"covers_old_games": false,
"note": "Never creates rows. Cannot set game_time_utc to NULL."
},
{
"id": "playoff_resolve_update",
"file": "app/main.py",
"function": "_resolve_playoff_placeholders()",
"when": "Homepage load when visitor/home team is still TBD",
"source_api": "postseason_state / standings (DB-only)",
"writes_game_time_utc": false,
"game_time_utc_strategy": "UPDATE only: visitor/home team abbr, name, team_id",
"can_create_null_gtu": false,
"covers_old_games": false,
"note": "Only sets team identification fields. Cannot affect game_time_utc."
}
],
"likely_games_write_source": {
"source": "fetch_and_store_games",
"reason": "game_time_utc is populated. This field is ONLY written by fetch_and_store_games() (ScoreboardV3). All other write paths omit it from their INSERT/UPDATE.",
"confidence": "High",
"writes_game_time_utc": true
},
"field_write_coverage": {
"game_time_utc": {
"written_by": [
"fetch_and_store_games"
],
"not_written_by": [
"sync_playoff_games",
"fetch_and_store_historical_game",
"copy_game_to_nba_db",
"boxscores_live_update",
"playoff_resolve_update"
],
"strategy": "COALESCE \u2014 set once on first non-null insert; never overwritten after that",
"null_risk": "High: only fetch_and_store_games writes it, and it only runs for today/yesterday"
},
"game_status_id": {
"written_by": [
"fetch_and_store_games",
"sync_playoff_games",
"fetch_and_store_historical_game",
"copy_game_to_nba_db",
"boxscores_live_update"
],
"not_written_by": [
"playoff_resolve_update"
],
"strategy": "MAX(existing, new) in fetch_and_store_games; direct set in sync/historical/live",
"null_risk": "Low: all major paths write it"
},
"home_pts / visitor_pts": {
"written_by": [
"fetch_and_store_games",
"sync_playoff_games",
"fetch_and_store_historical_game",
"copy_game_to_nba_db",
"boxscores_live_update"
],
"not_written_by": [
"playoff_resolve_update"
],
"strategy": "Varies: MAX for final (sync), COALESCE for live, direct for historical",
"null_risk": "Low: most paths populate scores"
},
"game_date": {
"written_by": [
"fetch_and_store_games",
"sync_playoff_games",
"fetch_and_store_historical_game",
"copy_game_to_nba_db"
],
"not_written_by": [
"boxscores_live_update",
"playoff_resolve_update"
],
"strategy": "Set on INSERT; ON CONFLICT generally does not update it",
"null_risk": "Low: all INSERT paths include game_date"
}
}
}