Files
gridpilot.gg/docs/standings-issues-summary.md
2026-01-21 16:52:43 +01:00

162 lines
5.4 KiB
Markdown

# League Standings Issues Summary
## Quick Overview
The leagues feature's standings calculation has **7 critical issues** that prevent accurate season-specific standings.
## Issues Found
### 1. ❌ InMemoryStandingRepository.recalculate() Doesn't Consider Seasons
**File:** `adapters/racing/persistence/inmemory/InMemoryStandingRepository.ts:169-270`
**Problem:** Calculates standings from ALL completed races in a league, not just races from a specific season.
**Impact:** Standings mix results from all seasons, making them inaccurate for any specific season.
---
### 2. ❌ CompleteRaceUseCase Uses Hardcoded Points System
**File:** `core/racing/application/use-cases/CompleteRaceUseCase.ts:200-203`
**Problem:** Uses hardcoded F1 points system instead of league's configured points system.
**Impact:** All leagues use same points system regardless of configuration (F1, IndyCar, custom).
---
### 3. ❌ ImportRaceResultsUseCase Recalculates All League Standings
**File:** `core/racing/application/use-cases/ImportRaceResultsUseCase.ts:156`
**Problem:** Recalculates ALL standings for the league when importing one race.
**Impact:** Performance issue + includes results from all seasons.
---
### 4. ❌ Standing Entity Doesn't Track Season Association
**File:** `core/racing/domain/entities/Standing.ts`
**Problem:** Standing entity only tracks `leagueId` and `driverId`, no `seasonId`.
**Impact:** Can't distinguish between standings from different seasons.
---
### 5. ❌ GetLeagueStandingsUseCase Retrieves League-Level Standings
**File:** `core/racing/application/use-cases/GetLeagueStandingsUseCase.ts:39`
**Problem:** Retrieves standings that include results from all seasons.
**Impact:** Returns inaccurate standings for any specific season.
---
### 6. ❌ LeagueStandingsRepository Not Connected to Standing Calculation
**File:** `adapters/racing/persistence/inmemory/InMemoryLeagueStandingsRepository.ts`
**Problem:** Repository exists but not used by standing calculation logic.
**Impact:** No clear connection between standing calculation and this repository.
---
### 7. ❌ LeagueStandingsPresenter Hardcodes Metrics
**File:** `apps/api/src/domain/league/presenters/LeagueStandingsPresenter.ts:24-30`
**Problem:** Hardcodes wins, podiums, and races to 0.
**Impact:** API always returns 0 for these metrics.
---
## Root Cause
**Design Inconsistency:** Two parallel standings systems that don't align:
1. **League-level standings** (`Standing` entity):
- Updated immediately when races complete
- Used by `GetLeagueStandingsUseCase`
- Don't support season-specific features
2. **Season-level standings** (`ChampionshipStanding` entity):
- Calculated using `RecalculateChampionshipStandingsUseCase`
- Support drop score policies per season
- Not used by main standings API
---
## Recommended Fixes
### Short-term (Quick Wins)
1. ✅ Fix CompleteRaceUseCase to use league's points system
2. ✅ Fix ImportRaceResultsUseCase to recalculate only relevant standings
3. ✅ Add seasonId to Standing entity
4. ✅ Fix GetLeagueStandingsUseCase to accept seasonId parameter
### Long-term (Refactoring)
1. ✅ Consolidate standings into single system (use ChampionshipStanding)
2. ✅ Update CompleteRaceUseCase to use RecalculateChampionshipStandingsUseCase
3. ✅ Update ImportRaceResultsUseCase to use RecalculateChampionshipStandingsUseCase
4. ✅ Update GetLeagueStandingsUseCase to retrieve ChampionshipStanding
5. ✅ Remove LeagueStandingsRepository
6. ✅ Fix LeagueStandingsPresenter to return actual metrics
---
## Testing Strategy
### Unit Tests
- Test CompleteRaceUseCase with different points systems
- Test ImportRaceResultsUseCase with season-specific recalculation
- Test GetLeagueStandingsUseCase with seasonId parameter
- Test Standing entity with seasonId field
### Integration Tests
- Test complete race flow with season-specific standings
- Test import race results flow with season-specific standings
- Test standings recalculation for specific season
- Test API endpoints with season-specific standings
### End-to-End Tests
- Test league standings API with season parameter
- Test standings calculation across multiple seasons
- Test drop score policy application per season
---
## Files to Modify
### Core Domain
- `core/racing/domain/entities/Standing.ts` - Add seasonId field
- `core/racing/domain/repositories/StandingRepository.ts` - Update interface
### Application Layer
- `core/racing/application/use-cases/CompleteRaceUseCase.ts` - Use league points system
- `core/racing/application/use-cases/ImportRaceResultsUseCase.ts` - Season-specific recalculation
- `core/racing/application/use-cases/GetLeagueStandingsUseCase.ts` - Accept seasonId parameter
### Persistence Layer
- `adapters/racing/persistence/inmemory/InMemoryStandingRepository.ts` - Update recalculate method
- `adapters/racing/persistence/inmemory/InMemoryLeagueStandingsRepository.ts` - Remove or refactor
### API Layer
- `apps/api/src/domain/league/presenters/LeagueStandingsPresenter.ts` - Return actual metrics
---
## Priority
**HIGH:** Issues 1, 2, 4, 5 (affect accuracy of standings)
**MEDIUM:** Issues 3, 6 (affect performance and architecture)
**LOW:** Issue 7 (affects API response quality)
---
## Next Steps
1. Create implementation plan for short-term fixes
2. Design long-term refactoring strategy
3. Update tests to cover season-specific scenarios
4. Implement fixes incrementally
5. Verify standings accuracy after each fix