37 lines
1.5 KiB
Markdown
37 lines
1.5 KiB
Markdown
# Provider Normalization Contract
|
|
|
|
HoopScout ingestion consumes provider data through a normalized, provider-agnostic contract defined in:
|
|
|
|
- `apps/providers/contracts.py`
|
|
- `apps/providers/interfaces.py`
|
|
|
|
## Contract scope
|
|
|
|
Adapters must return only normalized entities used by ingestion:
|
|
|
|
- `players`
|
|
- `competitions`
|
|
- `teams`
|
|
- `seasons`
|
|
- `player_stats`
|
|
- `player_careers`
|
|
- optional `cursor`
|
|
|
|
Raw provider response structures must remain inside `apps/providers` (client/adapter/mapping code).
|
|
`ExternalMapping.raw_payload` is used only for diagnostics and troubleshooting.
|
|
|
|
## Current balldontlie assumptions (MVP)
|
|
|
|
- Source scope is NBA-centric.
|
|
- Competition is normalized as a single NBA competition (`competition-nba`).
|
|
- Team country is not reliably available in source payloads and is normalized to `null`.
|
|
- Player nationality/birth/physical details are not available in player list payloads and are normalized to `null` (except fields explicitly present).
|
|
- Configured seasons are normalized from `PROVIDER_BALLDONTLIE_SEASONS`; the highest configured season is marked `is_current=true`.
|
|
- Advanced metrics (`usage_rate`, `true_shooting_pct`, `player_efficiency_rating`) are currently unavailable from this source path and normalized to `null`.
|
|
|
|
## Domain rules vs provider assumptions
|
|
|
|
- Domain rules live in ingestion/domain services and models.
|
|
- Provider assumptions live only in adapter/mapping modules.
|
|
- New providers must map to the same normalized contract and should not require ingestion logic changes.
|