162 lines
5.4 KiB
Markdown
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
|