# 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