Files
gridpilot.gg/apps/website/lib/services/races/RaceService.ts

92 lines
2.7 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';
import type { RaceStatsDTO } from '../../types/generated/RaceStatsDTO';
/**
* 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
*
* The races API does not currently expose a league-filtered listing endpoint in this build,
* so this method deliberately signals that the operation is unavailable instead of making
* assumptions about URL structure.
*/
async findByLeagueId(_leagueId: string): Promise<never> {
throw new Error('Finding races by league ID is not supported in this build');
}
}