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

5.4 KiB

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

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