43 lines
1.7 KiB
TypeScript
43 lines
1.7 KiB
TypeScript
import type { IStandingRepository } from '../../domain/repositories/IStandingRepository';
|
|
import type { IDriverRepository } from '../../domain/repositories/IDriverRepository';
|
|
import type { LeagueStandingsViewModel } from '../presenters/ILeagueStandingsPresenter';
|
|
import { Result } from '@core/shared/application/Result';
|
|
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
|
|
|
export interface GetLeagueStandingsUseCaseParams {
|
|
leagueId: string;
|
|
}
|
|
|
|
/**
|
|
* Use Case for retrieving league standings.
|
|
*/
|
|
export class GetLeagueStandingsUseCase {
|
|
constructor(
|
|
private readonly standingRepository: IStandingRepository,
|
|
private readonly driverRepository: IDriverRepository,
|
|
) {}
|
|
|
|
async execute(
|
|
params: GetLeagueStandingsUseCaseParams,
|
|
): Promise<Result<LeagueStandingsViewModel, ApplicationErrorCode<'REPOSITORY_ERROR'>>> {
|
|
try {
|
|
const standings = await this.standingRepository.findByLeagueId(params.leagueId);
|
|
const driverIds = [...new Set(standings.map(s => s.driverId))];
|
|
const driverPromises = driverIds.map(id => this.driverRepository.findById(id));
|
|
const driverResults = await Promise.all(driverPromises);
|
|
const drivers = driverResults.filter((d): d is NonNullable<typeof d> => d !== null);
|
|
const driverMap = new Map(drivers.map(d => [d.id, { id: d.id, name: d.name }]));
|
|
const viewModel: LeagueStandingsViewModel = {
|
|
standings: standings.map(s => ({
|
|
driverId: s.driverId,
|
|
driver: driverMap.get(s.driverId)!,
|
|
points: s.points,
|
|
rank: s.position,
|
|
})),
|
|
};
|
|
return Result.ok(viewModel);
|
|
} catch {
|
|
return Result.err({ code: 'REPOSITORY_ERROR', message: 'Failed to fetch league standings' });
|
|
}
|
|
}
|
|
} |