Files
gridpilot.gg/apps/website/lib/services/races/RaceService.ts
2025-12-19 21:58:03 +01:00

104 lines
2.8 KiB
TypeScript

import { RacesApiClient } from '../../api/races/RacesApiClient';
import { RaceDetailViewModel } from '../../view-models/RaceDetailViewModel';
import { RacesPageViewModel } from '../../view-models/RacesPageViewModel';
import { RaceStatsViewModel } from '../../view-models/RaceStatsViewModel';
// TODO: Move these types to apps/website/lib/types/generated when available
type RacesPageDataRaceDTO = {
id: string;
track: string;
car: string;
scheduledAt: string;
status: string;
leagueId: string;
leagueName: string;
};
type RacesPageDataDto = { races: RacesPageDataRaceDTO[] };
type RaceStatsDTO = { totalRaces: number };
/**
* Race Service
*
* Orchestrates race operations by coordinating API calls and view model creation.
* All dependencies are injected via constructor.
*/
export class RaceService {
constructor(
private readonly apiClient: RacesApiClient
) {}
/**
* Get race detail with view model transformation
*/
async getRaceDetail(
raceId: string,
driverId: string
): Promise<RaceDetailViewModel> {
const dto = await this.apiClient.getDetail(raceId, driverId);
return new RaceDetailViewModel(dto);
}
/**
* Get races page data with view model transformation
*/
async getRacesPageData(): Promise<RacesPageViewModel> {
const dto = await this.apiClient.getPageData();
return new RacesPageViewModel(dto);
}
/**
* Get all races page data with view model transformation
* Currently same as getRacesPageData, but can be extended for different filtering
*/
async getAllRacesPageData(): Promise<RacesPageViewModel> {
const dto = await this.apiClient.getPageData();
return new RacesPageViewModel(dto);
}
/**
* Get total races statistics with view model transformation
*/
async getRacesTotal(): Promise<RaceStatsViewModel> {
const dto: RaceStatsDTO = await this.apiClient.getTotal();
return new RaceStatsViewModel(dto);
}
/**
* Register for a race
*/
async registerForRace(raceId: string, leagueId: string, driverId: string): Promise<void> {
await this.apiClient.register(raceId, { leagueId, driverId });
}
/**
* Withdraw from a race
*/
async withdrawFromRace(raceId: string, driverId: string): Promise<void> {
await this.apiClient.withdraw(raceId, { driverId });
}
/**
* Cancel a race
*/
async cancelRace(raceId: string): Promise<void> {
await this.apiClient.cancel(raceId);
}
/**
* Complete a race
*/
async completeRace(raceId: string): Promise<void> {
await this.apiClient.complete(raceId);
}
/**
* Find races by league ID
*/
async findByLeagueId(leagueId: string): Promise<any[]> {
// Assuming the API has /races?leagueId=...
// TODO: Update when API is implemented
const dto = await this.apiClient.get('/races?leagueId=' + leagueId) as { races: any[] };
return dto.races;
}
}