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 { DriversLeaderboardResultDTO } from '../presenters/IDriversLeaderboardPresenter'; import type { AsyncUseCase, Logger } from '@core/shared/application'; import { Result } from '@core/shared/result/Result'; import { RacingDomainValidationError } from '../../domain/errors/RacingDomainError'; /** * Use Case for retrieving driver leaderboard data. * Orchestrates domain logic and returns result. */ export class GetDriversLeaderboardUseCase implements AsyncUseCase> { constructor( private readonly driverRepository: IDriverRepository, private readonly rankingService: IRankingService, private readonly driverStatsService: IDriverStatsService, private readonly imageService: IImageServicePort, private readonly logger: Logger, ) {} async execute(): Promise> { this.logger.debug('Executing GetDriversLeaderboardUseCase'); try { 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, }; this.logger.debug('Successfully retrieved drivers leaderboard.'); return Result.ok(dto); } catch (error) { this.logger.error('Error executing GetDriversLeaderboardUseCase', error instanceof Error ? error : new Error(String(error))); return Result.err(new RacingDomainValidationError(error instanceof Error ? error.message : 'Unknown error occurred')); } } }