Summary
Prevent partial pitching data from being presented as an MLB-wide pitching comparison.
The current pitching comparison path can accept a season when:
- the persisted league ingestion state is
COMPLETE; and
- at least some pitching rows exist.
That is not sufficient to establish league-wide pitching coverage.
A realistic failure mode is:
- a season was imported before pitching persistence existed;
- league ingestion state remains
COMPLETE;
- one team is re-imported later and now has pitching rows;
- the pitching comparison can treat that partial dataset as the MLB baseline.
This violates the project's rule that incomplete league data must never be labeled as a complete MLB-wide statistic.
Goal
Require demonstrable pitching coverage of the relevant stored league game identities before calculating or displaying an MLB-wide pitching baseline.
Scope
Update the pitching league-comparison path, including _load_league_pitching_comparison and any small repository/service helpers needed, so that COMPLETE league ingestion state alone is not treated as proof of pitching completeness.
The implementation should verify that persisted pitching rows cover the relevant league team-game identities used for the comparison.
Prefer a small explicit coverage check over introducing snapshot/versioning infrastructure.
Expected behavior
For a selected season:
- If league ingestion state is not
COMPLETE, preserve the existing unavailable behavior.
- If league ingestion is
COMPLETE but pitching coverage is partial, do not calculate or present an MLB-wide pitching baseline.
- If pitching coverage matches the required league game identities, allow the MLB-wide pitching comparison.
- Missing or legacy pitching rows must remain missing; do not fabricate data.
Regression case
Add a focused test for this sequence:
- Persist a league season with complete batting/league coverage.
- Persist pitching data for only one team.
- Leave the league ingestion state as
COMPLETE.
- Request the pitching comparison.
- Verify that an MLB-wide pitching baseline is refused/unavailable.
This should reproduce the mixed-state scenario found during the project audit.
Coverage semantics
The check should be based on relevant persisted identities, such as (team_id, game_pk), rather than:
- hardcoded team counts;
- hardcoded games-per-team;
- simply checking that pitching rows exist;
- merely checking for non-null pitching fields.
The exact implementation can use the smallest repository-level query or service helper that keeps route logic thin.
Preserve
- Existing team pitching analytics.
- Existing
COMPLETE league-ingestion semantics for batting/league workflows.
- DB-only browser rendering.
- Server-rendered FastAPI/Jinja architecture.
- Existing empty/missing-data behavior.
- Offline deterministic tests.
- SQLite.
Out of scope
- Redesigning the entire league completeness model.
- Snapshot/version IDs for imports.
- PostgreSQL.
- Background refresh infrastructure.
- Automatically re-importing missing pitching data.
- Refactoring unrelated analytics or routes.
Tests
Cover at minimum:
- complete league state + complete pitching coverage => MLB pitching baseline available;
- complete league state + partial pitching coverage => MLB pitching baseline unavailable;
- incomplete league state => existing unavailable behavior remains;
- no pitching rows => unavailable;
- no MLB API calls during browser rendering;
- existing team-only pitching analytics remain unaffected.
Completion criteria
- Partial pitching coverage can no longer be labeled or used as an MLB-wide pitching dataset.
- The mixed historical-import + one-team-backfill case is covered by regression tests.
- The implementation uses explicit persisted coverage rather than fixed MLB season counts.
- Existing tests continue to pass.
- Ruff lint and formatting remain clean.
Summary
Prevent partial pitching data from being presented as an MLB-wide pitching comparison.
The current pitching comparison path can accept a season when:
COMPLETE; andThat is not sufficient to establish league-wide pitching coverage.
A realistic failure mode is:
COMPLETE;This violates the project's rule that incomplete league data must never be labeled as a complete MLB-wide statistic.
Goal
Require demonstrable pitching coverage of the relevant stored league game identities before calculating or displaying an MLB-wide pitching baseline.
Scope
Update the pitching league-comparison path, including
_load_league_pitching_comparisonand any small repository/service helpers needed, so thatCOMPLETEleague ingestion state alone is not treated as proof of pitching completeness.The implementation should verify that persisted pitching rows cover the relevant league team-game identities used for the comparison.
Prefer a small explicit coverage check over introducing snapshot/versioning infrastructure.
Expected behavior
For a selected season:
COMPLETE, preserve the existing unavailable behavior.COMPLETEbut pitching coverage is partial, do not calculate or present an MLB-wide pitching baseline.Regression case
Add a focused test for this sequence:
COMPLETE.This should reproduce the mixed-state scenario found during the project audit.
Coverage semantics
The check should be based on relevant persisted identities, such as
(team_id, game_pk), rather than:The exact implementation can use the smallest repository-level query or service helper that keeps route logic thin.
Preserve
COMPLETEleague-ingestion semantics for batting/league workflows.Out of scope
Tests
Cover at minimum:
Completion criteria