DATA PLATFORM · INSPECTABLE BY DESIGN

Question → grain → transformation → test → football product.

Python produces predictions and evaluation artifacts. dbt separately turns their file families and statistics into tested player-week facts and versioned decision marts; FastAPI serves both provenance paths without pretending dbt trains the model.

COMPACT ARCHITECTURE
  1. 01nflverse statistics + Python model artifacts
  2. 02bronze file families → silver quality contracts
  3. 03gold player-week facts + evaluation/policy marts
  4. 04Parquet exports → /marts/*; artifacts → /performance
  5. 05Predictions, Evaluation, Decisions, Player history

The pre-scoring silver gate and the post-scoring warehouse build are distinct execution stages.

02

TRACE A METRIC

What share of scored predictions landed within three points?

The trace keeps evaluation window, season, model version, candidate and cohort aligned. It never pools ALL with positional cohorts.

1 · INPUT GRAIN

fct_player_week

player_id × season × week × model_version × candidate. Prediction rows without actuals remain visible but do not qualify.

2 · TRANSFORMATION

fct_weekly_eval

Rows with actual is not null are aggregated by eval_window × season × week × model_version × candidate × cohort. within_3 is inclusive.

3 · PROOF + PRODUCT

independent paths

A singular test reconciles n exactly and MAE/within rates to 0.0001 against evaluation artifacts. /performance serves artifacts; /marts/* serves exports.

UNIT-TEST EXAMPLE · NOT MEASURED PERFORMANCE

Inclusive tolerance math

Open fixture
|error| 1within 3: true · within 5: true
|error| 3within 3: true · within 5: true
|error| 4.5within 3: false · within 5: true
|error| 6within 3: false · within 5: false

The fifth fixture row has no actual and is excluded. Result: n=4, MAE=3.625, within-3=2/4 and within-5=3/4. This defined unit test is not a claim about its most recent execution.

03

DECISIONS BEHIND THE MODELS

Tradeoffs remain attached to the implementation.

corrections

Handle corrections without rebuilding every transformation

Problem. Published statistics can be restated after a game.

Chosen approach. Incremental delete+insert at player × season × week reprocesses the newest four distinct loaded periods plus new periods.

Tradeoff / limit. A correction outside that conservative, uncalibrated window waits for a full refresh. The fixture tests use a two-period window; they do not prove universal equivalence.

Downstream effect. Recent corrected scores flow downstream; fct_player_week stays a full table because its causal baseline depends on earlier observations.

history

Preserve captured history without inventing the past

Problem. Latest-seen player attributes cannot truthfully describe every earlier scoring period.

Chosen approach. snp_player checks name, position and team; the as-of view uses a capture when period > start and period ≤ next capture.

Tradeoff / limit. History begins at first capture. Earlier periods fall back to current attributes with is_exact_asof=false; this is warehouse knowledge, not a transaction ledger.

Downstream effect. The snapshot-backed views are not exported, and the current player API still reads latest-seen dim_player.

versioning

Evolve a mart without breaking its consumer

Problem. New interval metrics should not silently change an existing API contract.

Chosen approach. v1 retains alias fct_decision_policy; latest v2 exports as fct_decision_policy_v2 and adds within-3 rate and interval coverage.

Tradeoff / limit. An unversioned dbt ref resolves to latest, while /marts/decisions deliberately pins v1. Exported does not mean served.

Downstream effect. The response now reports mart_version from the serving constant; it remains a backwards-compatible v1 API.

rollups

Keep metrics stable across sources and rollups

Problem. Overlapping prediction families and incomplete outcomes can distort a headline rate.

Chosen approach. Weekly predictions win deterministic source precedence; model version and candidate stay in the key, and unplayed outcomes remain null.

Tradeoff / limit. Rates require their actual denominators. A narrowed population with a higher hit rate is not automatically a better policy.

Downstream effect. Evaluation artifacts and exported marts remain independent provenance paths that are reconciled under aligned scope.

Loading model inspector…
05

VALIDATE + PUBLISH

State reuse is not a claim that every test ran.

Main builds the full development project. Pull requests may select state:modified+ and defer unchanged nodes to cached main development DuckDB relations; if the cache is unavailable, CI falls back to a full dev build. This is never production deferral. Full-history checks can also be conditional on vars, so a successful workflow is not interchangeable with full-data proof.