Spaces:
Paused
Paused
Download sql/nfl_report_room_schema.sql from AIBRUH/big-proppa: direct link, hf CLI and curl.
- Browser
- Download file 9.8 kB
-
https://huggingface.co/spaces/AIBRUH/big-proppa/resolve/main/sql/nfl_report_room_schema.sql
- Command line
-
hf download hf://spaces/AIBRUH/big-proppa/sql/nfl_report_room_schema.sql
-
curl -L -o nfl_report_room_schema.sql https://huggingface.co/spaces/AIBRUH/big-proppa/resolve/main/sql/nfl_report_room_schema.sql
9.8 kB
| -- ============================================================================= | |
| -- frontal-lobe2 : NFL sports report room | |
| -- ============================================================================= | |
| -- Purpose: give a beat writer everything needed to write a matchup preview from | |
| -- the lake alone -- injuries, inactives-track, current news, transactions -- no | |
| -- browser tab open. This is the data layer only; narrative generation (an agent | |
| -- reading this and writing the article) is a later phase, per the user. | |
| -- | |
| -- Sources, both confirmed live with real 2026 data on 2026-09-25: | |
| -- 1. nflverse injuries_2026.csv -- OFFICIAL weekly injury report (practice | |
| -- status, game status, injury type). This is the closest thing to a | |
| -- league-mandated inactives signal available pre-gameday. See caveat in | |
| -- docs/REPORT_ROOM.md: the FINAL inactives list is only released ~90 min | |
| -- before kickoff and is not covered here -- this is the last official | |
| -- report before that point (usually Fri "Questionable/Doubtful/Out"). | |
| -- 2. ESPN (site.web.api.espn.com -- confirmed reachable; the more commonly | |
| -- documented site.api.espn.com returned HTTP 403 in this environment). | |
| -- Same "unofficial/undocumented, can change without notice" risk profile | |
| -- already flagged for ESPN elsewhere in this project -- just a different, | |
| -- currently-reachable host. Three endpoints used: | |
| -- /injuries -- narrative injury context per player (why it | |
| -- matters, who benefits if they sit) | |
| -- /news, /news?team=<abbr> -- headlines + summary, tagged with | |
| -- structured athleteId/teamId categories (no fuzzy | |
| -- text matching needed to link a story to a player) | |
| -- /transactions -- roster moves (signings, releases, IR moves) | |
| -- | |
| -- Engine: DuckDB. | |
| -- ============================================================================= | |
| CREATE SCHEMA IF NOT EXISTS silver; | |
| CREATE SCHEMA IF NOT EXISTS gold; | |
| -- ============================================================================ | |
| -- Official weekly injury report (nflverse). One row per player per week. | |
| -- ============================================================================ | |
| CREATE TABLE IF NOT EXISTS silver.nfl_injury_report ( | |
| season INTEGER NOT NULL, | |
| week INTEGER NOT NULL, | |
| season_type VARCHAR, | |
| game_type VARCHAR, | |
| team VARCHAR NOT NULL, | |
| gsis_id VARCHAR, -- nflverse player id, joins to nfl_player | |
| position VARCHAR, | |
| full_name VARCHAR, | |
| report_primary_injury VARCHAR, | |
| report_secondary_injury VARCHAR, | |
| report_status VARCHAR, -- Questionable | Doubtful | Out | |
| practice_primary_injury VARCHAR, | |
| practice_secondary_injury VARCHAR, | |
| practice_status VARCHAR, -- Did Not Participate | Limited | Full | |
| ingest_run_id VARCHAR NOT NULL, | |
| PRIMARY KEY (season, week, team, gsis_id, full_name) | |
| ); | |
| CREATE INDEX IF NOT EXISTS ix_injury_team_week | |
| ON silver.nfl_injury_report (season, week, team); | |
| -- ============================================================================ | |
| -- ESPN narrative injury context. One row per player, current snapshot | |
| -- (ESPN's injuries endpoint is "current state", not a per-week history -- | |
| -- snapshot it repeatedly if a history is wanted later). | |
| -- ============================================================================ | |
| CREATE TABLE IF NOT EXISTS silver.nfl_injury_narrative ( | |
| espn_athlete_id VARCHAR NOT NULL, | |
| player_name VARCHAR, | |
| team VARCHAR, | |
| status VARCHAR, -- Questionable | Doubtful | Out | IR | |
| injury_type VARCHAR, -- e.g. 'Toe', 'Achilles' | |
| injury_location VARCHAR, -- e.g. 'Leg' | |
| injury_side VARCHAR, -- Left | Right | |
| return_date DATE, | |
| short_comment VARCHAR, -- one-line practice-report style note | |
| long_comment VARCHAR, -- full narrative paragraph, matchup context | |
| reported_at TIMESTAMP, | |
| fetched_at_utc TIMESTAMP NOT NULL, | |
| source_name VARCHAR NOT NULL DEFAULT 'espn', | |
| PRIMARY KEY (espn_athlete_id, fetched_at_utc) | |
| ); | |
| CREATE INDEX IF NOT EXISTS ix_injury_narr_team | |
| ON silver.nfl_injury_narrative (team, fetched_at_utc); | |
| -- ============================================================================ | |
| -- News articles. League-wide + team-scoped pulls land here; category tags | |
| -- (below) are what actually link a story to a specific player/team. | |
| -- ============================================================================ | |
| CREATE TABLE IF NOT EXISTS silver.nfl_news_article ( | |
| espn_article_id VARCHAR PRIMARY KEY, | |
| headline VARCHAR, | |
| description VARCHAR, -- ESPN's own summary, not just a title | |
| article_type VARCHAR, -- e.g. 'Media', 'HeadlineNews', 'Story' | |
| published_at TIMESTAMP, | |
| last_modified_at TIMESTAMP, | |
| is_premium BOOLEAN, -- ESPN+ gated; still has headline/description | |
| fetched_at_utc TIMESTAMP NOT NULL, | |
| source_name VARCHAR NOT NULL DEFAULT 'espn' | |
| ); | |
| CREATE INDEX IF NOT EXISTS ix_news_published | |
| ON silver.nfl_news_article (published_at); | |
| -- Many-to-many: one article can tag multiple players/teams (a trade story tags | |
| -- two teams and the player involved, for instance). | |
| -- No composite PK here on purpose: espn_athlete_id/team are legitimately NULL | |
| -- for non-athlete/non-team tags (e.g. a 'league' tag has neither), and DuckDB | |
| -- (like most SQL engines) rejects NULL in a PRIMARY KEY column. A tag_id | |
| -- surrogate key keeps this table de-duplicable without that constraint. | |
| CREATE TABLE IF NOT EXISTS silver.nfl_news_article_tag ( | |
| tag_id VARCHAR PRIMARY KEY, -- article_id + tag_type + subject, hashed | |
| espn_article_id VARCHAR NOT NULL, | |
| tag_type VARCHAR NOT NULL, -- 'athlete' | 'team' | 'league' | |
| espn_athlete_id VARCHAR, | |
| team VARCHAR, -- abbreviation, when tag_type='team' | |
| tag_description VARCHAR -- display name as ESPN tagged it | |
| ); | |
| CREATE INDEX IF NOT EXISTS ix_newstag_athlete | |
| ON silver.nfl_news_article_tag (espn_athlete_id); | |
| CREATE INDEX IF NOT EXISTS ix_newstag_team | |
| ON silver.nfl_news_article_tag (team); | |
| -- ============================================================================ | |
| -- Transactions (signings, releases, IR moves, trades). | |
| -- ============================================================================ | |
| CREATE TABLE IF NOT EXISTS silver.nfl_transaction ( | |
| transaction_id VARCHAR NOT NULL, | |
| team VARCHAR, | |
| description VARCHAR NOT NULL, -- ESPN's own transaction text | |
| transaction_date DATE, | |
| fetched_at_utc TIMESTAMP NOT NULL, | |
| source_name VARCHAR NOT NULL DEFAULT 'espn', | |
| PRIMARY KEY (transaction_id, fetched_at_utc) | |
| ); | |
| CREATE INDEX IF NOT EXISTS ix_txn_team_date | |
| ON silver.nfl_transaction (team, transaction_date); | |
| -- ============================================================================ | |
| -- GOLD: espn_athlete_id <-> nflverse gsis_id bridge. ESPN and nflverse use | |
| -- different player id schemes; name-matched as a best effort (case-insensitive, | |
| -- suffix-stripped). Anything unresolved stays NULL rather than a wrong guess -- | |
| -- check gold.v_nfl_player_id_bridge_unmatched before trusting a join silently. | |
| -- ============================================================================ | |
| CREATE TABLE IF NOT EXISTS gold.nfl_player_id_bridge ( | |
| gsis_id VARCHAR, | |
| espn_athlete_id VARCHAR, | |
| match_method VARCHAR NOT NULL, -- 'exact_name' | 'normalized_name' | 'manual' | |
| PRIMARY KEY (gsis_id, espn_athlete_id) | |
| ); | |
| -- ============================================================================ | |
| -- GOLD: the matchup bundle. Parameterized by two team abbreviations -- run as | |
| -- a query template (see scripts/matchup_report.py), not a static materialized | |
| -- view, since "which two teams" changes every call. | |
| -- | |
| -- This view returns injuries + news + transactions for ONE team; the report | |
| -- script calls it twice (once per side) and stitches the bundle together, so | |
| -- the underlying SQL stays simple and reusable rather than a single giant | |
| -- cross-joined query. | |
| -- ============================================================================ | |
| CREATE OR REPLACE VIEW gold.v_nfl_team_report_card AS | |
| SELECT 'injury_official' AS section, r.team, r.full_name AS subject, r.report_status AS headline, | |
| r.report_primary_injury AS detail, NULL AS narrative, | |
| NULL::TIMESTAMP AS occurred_at | |
| FROM silver.nfl_injury_report r | |
| JOIN (SELECT max(season) AS season, max(week) AS week FROM silver.nfl_injury_report) latest | |
| ON r.season = latest.season AND r.week = latest.week | |
| UNION ALL | |
| SELECT 'injury_narrative', team, player_name, status, | |
| injury_type || COALESCE(' (' || injury_location || ')', ''), long_comment, | |
| reported_at | |
| FROM silver.nfl_injury_narrative | |
| WHERE fetched_at_utc = (SELECT max(fetched_at_utc) FROM silver.nfl_injury_narrative) | |
| UNION ALL | |
| SELECT 'news', t.team, a.headline, a.description, NULL, a.description, a.published_at | |
| FROM silver.nfl_news_article a | |
| JOIN silver.nfl_news_article_tag t ON t.espn_article_id = a.espn_article_id | |
| WHERE t.tag_type = 'team' | |
| UNION ALL | |
| SELECT 'transaction', team, description, NULL, NULL, NULL, transaction_date::TIMESTAMP | |
| FROM silver.nfl_transaction; | |
| CREATE INDEX IF NOT EXISTS ix_bridge_gsis ON gold.nfl_player_id_bridge (gsis_id); | |