Tighten provider normalization contract and fallback semantics
This commit is contained in:
36
docs/provider-normalization.md
Normal file
36
docs/provider-normalization.md
Normal file
@ -0,0 +1,36 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user