API contracts

JSON contract between the Python engine and the Next.js web app.

The Python engine emits stable JSON under data/output/api/. The web app consumes these files with snake_case on the wire; TypeScript types mirror the same shape.

Current-run files

Top-level copies of the latest run for fast page loads:

FilePurpose
latest.jsonMetadata pointer to the most recent stem
rankings.jsonFlat rankings for the latest run
field.jsonProjected CFP field for the latest run
bracket.jsonBracket payload for the latest run

These files update when a new run completes. They carry schema_version: 1.

Per-run files

Each completed run lives under data/output/api/runs/{stem}/:

FilePurpose
meta.jsonSeason, week, mode, weights, timestamps
rankings.jsonFull ranking table for that stem
field.jsonProjected field for that stem
bracket.jsonBracket structure and matchups
validation.jsonBacktest metrics when generated
audit.jsonSelection audit trail when exported

Scenario stems reuse the same layout with a distinct suffix so diffs stay traceable.

Run catalog files

FilePurpose
runs.jsonCatalog for the run switcher: all stems, labels, latest pointer

The web app reads runs.json once per session (shared catalog hook) and resolves per-run payloads by stem. There is no mapping layer between Python exports and TypeScript types.

Source of truth

Pydantic v2 models in src/api_contracts/models.py define the contract. Breaking changes require a schema version bump and coordinated web updates.

Note

The full contract includes TeamSlot shapes, audit payloads, sensitivity exports, and scenario stems. See the GitHub doc for complete JSONC examples.