Sync services and execution order
Canonical sync processing is split into coordinated backend services:- Fetch/parse canonical source data
- Upsert league records and metadata
- Sync team records and logos
- Link teams to leagues
- Ensure team leaderboard parity where required
League linking and leaderboard parity
- Team rows are linked to league rows through normalized identifiers and mapping logic.
- Team sync paths also ensure team leaderboard rows exist for consistent ranking surfaces.
- Public
GET /api/config/sportsis derived fromLeague.sport. Teamsportis never null ("other"when unknown). - Leaderboard join (
/api/teams/{id}/join) is a separate write from socialTeamFollow. - HQ stars (
app/api/me/starred-teams) are a third write. They do not createTeamFollowor a leaderboard entry.GET /api/teams/{id}(app/api/teams/[id]/route.ts) is the public id-or-slug read. - Public
GET /api/teams/{id}/rosterreadsPlayerrows (isActive: true) and maps position to sport-awarerole/duty. Editorial snapshots live inleagues/teams/rosters.json.
Team logo propagation
- Canonical logo paths are fetched from source data and uploaded to storage.
- Backend updates team logo fields after successful upload.
- Clients consume resulting logo URLs from API payloads.
Idempotency and safety
- Sync routes are designed to be repeatable.
- Non-destructive update behavior is preferred over hard deletes.
- Partial failures should log recoverable errors and preserve existing valid data.
