Files
gridpilot.gg/apps/api/src/domain/race/presenters/RaceResultsDetailPresenter.ts
2025-12-22 19:17:33 +01:00

73 lines
2.4 KiB
TypeScript

import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type {
GetRaceResultsDetailResult,
GetRaceResultsDetailErrorCode,
} from '@core/racing/application/use-cases/GetRaceResultsDetailUseCase';
import type { IImageServicePort } from '@core/racing/application/ports/IImageServicePort';
import type { RaceResultsDetailDTO } from '../dtos/RaceResultsDetailDTO';
import type { RaceResultDTO } from '../dtos/RaceResultDTO';
export type GetRaceResultsDetailResponseModel = RaceResultsDetailDTO;
export type GetRaceResultsDetailApplicationError = ApplicationErrorCode<
GetRaceResultsDetailErrorCode,
{ message: string }
>;
export class RaceResultsDetailPresenter {
private result: GetRaceResultsDetailResult | null = null;
constructor(private readonly imageService: IImageServicePort) {}
present(result: GetRaceResultsDetailResult): void {
this.result = result;
}
async getResponseModel(): Promise<GetRaceResultsDetailResponseModel | null> {
if (!this.result) {
return null;
}
const output = this.result;
const driverMap = new Map(output.drivers.map(driver => [driver.id, driver]));
const results: RaceResultDTO[] = await Promise.all(
output.results.map(async singleResult => {
const driver = driverMap.get(singleResult.driverId.toString());
if (!driver) {
throw new Error(`Driver not found for result: ${singleResult.driverId}`);
}
const avatarUrl = this.imageService.getDriverAvatar(driver.id);
return {
driverId: singleResult.driverId.toString(),
driverName: driver.name.toString(),
avatarUrl,
position: singleResult.position.toNumber(),
startPosition: singleResult.startPosition.toNumber(),
incidents: singleResult.incidents.toNumber(),
fastestLap: singleResult.fastestLap.toNumber(),
positionChange: singleResult.getPositionChange(),
isPodium: singleResult.isPodium(),
isClean: singleResult.isClean(),
} as RaceResultDTO;
}),
);
return {
raceId: output.race.id,
track: output.race.track,
results,
} as RaceResultsDetailDTO;
}
get viewModel(): Promise<GetRaceResultsDetailResponseModel> {
return this.getResponseModel().then(model => {
if (!model) throw new Error('Presenter not presented');
return model;
});
}
}