import type { IDriverRepository } from '../../domain/repositories/IDriverRepository'; import type { IRankingService } from '../../domain/services/IRankingService'; import type { IDriverStatsService } from '../../domain/services/IDriverStatsService'; import type { IImageServicePort } from '../ports/IImageServicePort'; import type { IDriversLeaderboardPresenter, DriversLeaderboardResultDTO, DriversLeaderboardViewModel, } from '../presenters/IDriversLeaderboardPresenter'; import type { UseCase } from '@gridpilot/shared/application/UseCase'; /** * Use Case for retrieving driver leaderboard data. * Orchestrates domain logic and delegates presentation to the presenter. */ export class GetDriversLeaderboardUseCase implements UseCase { constructor( private readonly driverRepository: IDriverRepository, private readonly rankingService: IRankingService, private readonly driverStatsService: IDriverStatsService, private readonly imageService: IImageServicePort, ) {} async execute(_input: void, presenter: IDriversLeaderboardPresenter): Promise { presenter.reset(); const drivers = await this.driverRepository.findAll(); const rankings = this.rankingService.getAllDriverRankings(); const stats: DriversLeaderboardResultDTO['stats'] = {}; const avatarUrls: DriversLeaderboardResultDTO['avatarUrls'] = {}; for (const driver of drivers) { const driverStats = this.driverStatsService.getDriverStats(driver.id); if (driverStats) { stats[driver.id] = driverStats; } avatarUrls[driver.id] = this.imageService.getDriverAvatar(driver.id); } const dto: DriversLeaderboardResultDTO = { drivers, rankings, stats, avatarUrls, }; presenter.present(dto); } }