league service
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
import type { Race } from '@gridpilot/racing/domain/entities/Race';
|
||||
import {
|
||||
getRaceRepository,
|
||||
getIsDriverRegisteredForRaceQuery,
|
||||
getRegisterForRaceUseCase,
|
||||
getWithdrawFromRaceUseCase,
|
||||
} from '@/lib/di-container';
|
||||
import type { IRaceRepository } from '@gridpilot/racing/application/ports/IRaceRepository';
|
||||
import type { IIsDriverRegisteredForRaceQuery } from '@gridpilot/racing/application/queries/IIsDriverRegisteredForRaceQuery';
|
||||
import type { IRegisterForRaceUseCase } from '@gridpilot/racing/application/use-cases/IRegisterForRaceUseCase';
|
||||
import type { IWithdrawFromRaceUseCase } from '@gridpilot/racing/application/use-cases/IWithdrawFromRaceUseCase';
|
||||
|
||||
export interface LeagueScheduleRaceItemViewModel {
|
||||
id: string;
|
||||
@@ -23,85 +21,95 @@ export interface LeagueScheduleViewModel {
|
||||
races: LeagueScheduleRaceItemViewModel[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load league schedule with registration status for a given driver.
|
||||
*/
|
||||
export async function loadLeagueSchedule(
|
||||
leagueId: string,
|
||||
driverId: string,
|
||||
): Promise<LeagueScheduleViewModel> {
|
||||
const raceRepo = getRaceRepository();
|
||||
const isRegisteredQuery = getIsDriverRegisteredForRaceQuery();
|
||||
export interface ILeagueSchedulePresenter {
|
||||
loadLeagueSchedule(leagueId: string, driverId: string): Promise<LeagueScheduleViewModel>;
|
||||
registerForRace(raceId: string, leagueId: string, driverId: string): Promise<void>;
|
||||
withdrawFromRace(raceId: string, driverId: string): Promise<void>;
|
||||
}
|
||||
|
||||
const allRaces = await raceRepo.findAll();
|
||||
const leagueRaces = allRaces
|
||||
.filter((race) => race.leagueId === leagueId)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime(),
|
||||
export class LeagueSchedulePresenter implements ILeagueSchedulePresenter {
|
||||
constructor(
|
||||
private raceRepository: IRaceRepository,
|
||||
private isDriverRegisteredForRaceQuery: IIsDriverRegisteredForRaceQuery,
|
||||
private registerForRaceUseCase: IRegisterForRaceUseCase,
|
||||
private withdrawFromRaceUseCase: IWithdrawFromRaceUseCase,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Load league schedule with registration status for a given driver.
|
||||
*/
|
||||
async loadLeagueSchedule(
|
||||
leagueId: string,
|
||||
driverId: string,
|
||||
): Promise<LeagueScheduleViewModel> {
|
||||
const allRaces = await this.raceRepository.findAll();
|
||||
const leagueRaces = allRaces
|
||||
.filter((race) => race.leagueId === leagueId)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime(),
|
||||
);
|
||||
|
||||
const now = new Date();
|
||||
|
||||
const registrationStates: Record<string, boolean> = {};
|
||||
await Promise.all(
|
||||
leagueRaces.map(async (race) => {
|
||||
const registered = await this.isDriverRegisteredForRaceQuery.execute({
|
||||
raceId: race.id,
|
||||
driverId,
|
||||
});
|
||||
registrationStates[race.id] = registered;
|
||||
}),
|
||||
);
|
||||
|
||||
const now = new Date();
|
||||
const races: LeagueScheduleRaceItemViewModel[] = leagueRaces.map((race) => {
|
||||
const raceDate = new Date(race.scheduledAt);
|
||||
const isPast = race.status === 'completed' || raceDate <= now;
|
||||
const isUpcoming = race.status === 'scheduled' && raceDate > now;
|
||||
|
||||
const registrationStates: Record<string, boolean> = {};
|
||||
await Promise.all(
|
||||
leagueRaces.map(async (race) => {
|
||||
const registered = await isRegisteredQuery.execute({
|
||||
raceId: race.id,
|
||||
driverId,
|
||||
});
|
||||
registrationStates[race.id] = registered;
|
||||
}),
|
||||
);
|
||||
return {
|
||||
id: race.id,
|
||||
leagueId: race.leagueId,
|
||||
track: race.track,
|
||||
car: race.car,
|
||||
sessionType: race.sessionType,
|
||||
scheduledAt: raceDate,
|
||||
status: race.status,
|
||||
isUpcoming,
|
||||
isPast,
|
||||
isRegistered: registrationStates[race.id] ?? false,
|
||||
};
|
||||
});
|
||||
|
||||
const races: LeagueScheduleRaceItemViewModel[] = leagueRaces.map((race) => {
|
||||
const raceDate = new Date(race.scheduledAt);
|
||||
const isPast = race.status === 'completed' || raceDate <= now;
|
||||
const isUpcoming = race.status === 'scheduled' && raceDate > now;
|
||||
return { races };
|
||||
}
|
||||
|
||||
return {
|
||||
id: race.id,
|
||||
leagueId: race.leagueId,
|
||||
track: race.track,
|
||||
car: race.car,
|
||||
sessionType: race.sessionType,
|
||||
scheduledAt: raceDate,
|
||||
status: race.status,
|
||||
isUpcoming,
|
||||
isPast,
|
||||
isRegistered: registrationStates[race.id] ?? false,
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Register the driver for a race.
|
||||
*/
|
||||
async registerForRace(
|
||||
raceId: string,
|
||||
leagueId: string,
|
||||
driverId: string,
|
||||
): Promise<void> {
|
||||
await this.registerForRaceUseCase.execute({
|
||||
raceId,
|
||||
leagueId,
|
||||
driverId,
|
||||
});
|
||||
}
|
||||
|
||||
return { races };
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the driver for a race.
|
||||
*/
|
||||
export async function registerForRace(
|
||||
raceId: string,
|
||||
leagueId: string,
|
||||
driverId: string,
|
||||
): Promise<void> {
|
||||
const useCase = getRegisterForRaceUseCase();
|
||||
await useCase.execute({
|
||||
raceId,
|
||||
leagueId,
|
||||
driverId,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdraw the driver from a race.
|
||||
*/
|
||||
export async function withdrawFromRace(
|
||||
raceId: string,
|
||||
driverId: string,
|
||||
): Promise<void> {
|
||||
const useCase = getWithdrawFromRaceUseCase();
|
||||
await useCase.execute({
|
||||
raceId,
|
||||
driverId,
|
||||
});
|
||||
/**
|
||||
* Withdraw the driver from a race.
|
||||
*/
|
||||
async withdrawFromRace(
|
||||
raceId: string,
|
||||
driverId: string,
|
||||
): Promise<void> {
|
||||
await this.withdrawFromRaceUseCase.execute({
|
||||
raceId,
|
||||
driverId,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user