refactor
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
import type { RaceDetailOutputPort } from '@core/racing/application/ports/output/RaceDetailOutputPort';
|
||||
import type { Result } from '@core/shared/application/Result';
|
||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
||||
import type {
|
||||
GetRaceDetailResult,
|
||||
GetRaceDetailErrorCode,
|
||||
} from '@core/racing/application/use-cases/GetRaceDetailUseCase';
|
||||
import type { DriverRatingProvider } from '@core/racing/application/ports/DriverRatingProvider';
|
||||
import type { IImageServicePort } from '@core/racing/application/ports/IImageServicePort';
|
||||
import type { GetRaceDetailParamsDTO } from '../dtos/GetRaceDetailParamsDTO';
|
||||
@@ -9,44 +14,79 @@ import type { RaceDetailEntryDTO } from '../dtos/RaceDetailEntryDTO';
|
||||
import type { RaceDetailRegistrationDTO } from '../dtos/RaceDetailRegistrationDTO';
|
||||
import type { RaceDetailUserResultDTO } from '../dtos/RaceDetailUserResultDTO';
|
||||
|
||||
export type GetRaceDetailResponseModel = RaceDetailDTO;
|
||||
|
||||
export type GetRaceDetailApplicationError = ApplicationErrorCode<
|
||||
GetRaceDetailErrorCode,
|
||||
{ message: string }
|
||||
>;
|
||||
|
||||
export class RaceDetailPresenter {
|
||||
private result: RaceDetailDTO | null = null;
|
||||
private model: GetRaceDetailResponseModel | null = null;
|
||||
|
||||
constructor(
|
||||
private readonly driverRatingProvider: DriverRatingProvider,
|
||||
private readonly imageService: IImageServicePort,
|
||||
) {}
|
||||
|
||||
async present(outputPort: RaceDetailOutputPort, params: GetRaceDetailParamsDTO): Promise<void> {
|
||||
const raceDTO: RaceDetailRaceDTO | null = outputPort.race
|
||||
reset(): void {
|
||||
this.model = null;
|
||||
}
|
||||
|
||||
async present(
|
||||
result: Result<GetRaceDetailResult, GetRaceDetailApplicationError>,
|
||||
params: GetRaceDetailParamsDTO,
|
||||
): Promise<void> {
|
||||
if (result.isErr()) {
|
||||
const error = result.unwrapErr();
|
||||
if (error.code === 'RACE_NOT_FOUND') {
|
||||
this.model = {
|
||||
race: null,
|
||||
league: null,
|
||||
entryList: [],
|
||||
registration: {
|
||||
isUserRegistered: false,
|
||||
canRegister: false,
|
||||
},
|
||||
userResult: null,
|
||||
} as RaceDetailDTO;
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error(error.details?.message ?? 'Failed to get race detail');
|
||||
}
|
||||
|
||||
const output = result.unwrap();
|
||||
|
||||
const raceDTO: RaceDetailRaceDTO | null = output.race
|
||||
? {
|
||||
id: outputPort.race.id,
|
||||
leagueId: outputPort.race.leagueId,
|
||||
track: outputPort.race.track,
|
||||
car: outputPort.race.car,
|
||||
scheduledAt: outputPort.race.scheduledAt.toISOString(),
|
||||
sessionType: outputPort.race.sessionType,
|
||||
status: outputPort.race.status,
|
||||
strengthOfField: outputPort.race.strengthOfField ?? null,
|
||||
registeredCount: outputPort.race.registeredCount ?? undefined,
|
||||
maxParticipants: outputPort.race.maxParticipants ?? undefined,
|
||||
id: output.race.id,
|
||||
leagueId: output.race.leagueId,
|
||||
track: output.race.track,
|
||||
car: output.race.car,
|
||||
scheduledAt: output.race.scheduledAt.toISOString(),
|
||||
sessionType: output.race.sessionType,
|
||||
status: output.race.status,
|
||||
strengthOfField: output.race.strengthOfField ?? null,
|
||||
registeredCount: output.race.registeredCount ?? undefined,
|
||||
maxParticipants: output.race.maxParticipants ?? undefined,
|
||||
}
|
||||
: null;
|
||||
|
||||
const leagueDTO: RaceDetailLeagueDTO | null = outputPort.league
|
||||
const leagueDTO: RaceDetailLeagueDTO | null = output.league
|
||||
? {
|
||||
id: outputPort.league.id.toString(),
|
||||
name: outputPort.league.name.toString(),
|
||||
description: outputPort.league.description.toString(),
|
||||
id: output.league.id.toString(),
|
||||
name: output.league.name.toString(),
|
||||
description: output.league.description.toString(),
|
||||
settings: {
|
||||
maxDrivers: outputPort.league.settings.maxDrivers ?? undefined,
|
||||
qualifyingFormat: outputPort.league.settings.qualifyingFormat ?? undefined,
|
||||
maxDrivers: output.league.settings.maxDrivers ?? undefined,
|
||||
qualifyingFormat: output.league.settings.qualifyingFormat ?? undefined,
|
||||
},
|
||||
}
|
||||
: null;
|
||||
|
||||
const entryListDTO: RaceDetailEntryDTO[] = await Promise.all(
|
||||
outputPort.drivers.map(async driver => {
|
||||
output.drivers.map(async driver => {
|
||||
const ratingResult = await this.driverRatingProvider.getDriverRating({ driverId: driver.id });
|
||||
const avatarResult = await this.imageService.getDriverAvatar({ driverId: driver.id });
|
||||
return {
|
||||
@@ -61,24 +101,24 @@ export class RaceDetailPresenter {
|
||||
);
|
||||
|
||||
const registrationDTO: RaceDetailRegistrationDTO = {
|
||||
isUserRegistered: outputPort.isUserRegistered,
|
||||
canRegister: outputPort.canRegister,
|
||||
isUserRegistered: output.isUserRegistered,
|
||||
canRegister: output.canRegister,
|
||||
};
|
||||
|
||||
const userResultDTO: RaceDetailUserResultDTO | null = outputPort.userResult
|
||||
const userResultDTO: RaceDetailUserResultDTO | null = output.userResult
|
||||
? {
|
||||
position: outputPort.userResult.position.toNumber(),
|
||||
startPosition: outputPort.userResult.startPosition.toNumber(),
|
||||
incidents: outputPort.userResult.incidents.toNumber(),
|
||||
fastestLap: outputPort.userResult.fastestLap.toNumber(),
|
||||
positionChange: outputPort.userResult.getPositionChange(),
|
||||
isPodium: outputPort.userResult.isPodium(),
|
||||
isClean: outputPort.userResult.isClean(),
|
||||
ratingChange: this.calculateRatingChange(outputPort.userResult.position.toNumber()),
|
||||
position: output.userResult.position.toNumber(),
|
||||
startPosition: output.userResult.startPosition.toNumber(),
|
||||
incidents: output.userResult.incidents.toNumber(),
|
||||
fastestLap: output.userResult.fastestLap.toNumber(),
|
||||
positionChange: output.userResult.getPositionChange(),
|
||||
isPodium: output.userResult.isPodium(),
|
||||
isClean: output.userResult.isClean(),
|
||||
ratingChange: this.calculateRatingChange(output.userResult.position.toNumber()),
|
||||
}
|
||||
: null;
|
||||
|
||||
this.result = {
|
||||
this.model = {
|
||||
race: raceDTO,
|
||||
league: leagueDTO,
|
||||
entryList: entryListDTO,
|
||||
@@ -87,16 +127,16 @@ export class RaceDetailPresenter {
|
||||
} as RaceDetailDTO;
|
||||
}
|
||||
|
||||
getViewModel(): RaceDetailDTO | null {
|
||||
return this.result;
|
||||
getResponseModel(): GetRaceDetailResponseModel | null {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
get viewModel(): RaceDetailDTO {
|
||||
if (!this.result) {
|
||||
get responseModel(): GetRaceDetailResponseModel {
|
||||
if (!this.model) {
|
||||
throw new Error('Presenter not presented');
|
||||
}
|
||||
|
||||
return this.result;
|
||||
return this.model;
|
||||
}
|
||||
|
||||
private calculateRatingChange(position: number): number {
|
||||
|
||||
Reference in New Issue
Block a user