import { ProtestsApiClient } from '../../api/protests/ProtestsApiClient'; import { ProtestViewModel } from '../../view-models/ProtestViewModel'; import type { LeagueAdminProtestsDTO, ApplyPenaltyCommandDTO, RequestProtestDefenseCommandDTO, DriverSummaryDTO } from '../../types'; /** * Protest Service * * Orchestrates protest operations by coordinating API calls and view model creation. * All dependencies are injected via constructor. */ export class ProtestService { constructor( private readonly apiClient: ProtestsApiClient ) {} /** * Get protests for a league with view model transformation */ async getLeagueProtests(leagueId: string): Promise<{ protests: ProtestViewModel[]; racesById: LeagueAdminProtestsDTO['racesById']; driversById: LeagueAdminProtestsDTO['driversById']; }> { const dto = await this.apiClient.getLeagueProtests(leagueId); return { protests: dto.protests.map(protest => new ProtestViewModel(protest)), racesById: dto.racesById, driversById: dto.driversById, }; } /** * Get a single protest by ID from league protests */ async getProtestById(leagueId: string, protestId: string): Promise<{ protest: ProtestViewModel; race: LeagueAdminProtestsDTO['racesById'][string]; protestingDriver: DriverSummaryDTO; accusedDriver: DriverSummaryDTO; } | null> { const dto = await this.apiClient.getLeagueProtest(leagueId, protestId); const protest = dto.protests[0]; if (!protest) return null; const race = Object.values(dto.racesById)[0]; const protestingDriver = dto.driversById[protest.protestingDriverId]; const accusedDriver = dto.driversById[protest.accusedDriverId]; return { protest: new ProtestViewModel(protest), race, protestingDriver, accusedDriver, }; } /** * Apply a penalty */ async applyPenalty(input: ApplyPenaltyCommandDTO): Promise { await this.apiClient.applyPenalty(input); } /** * Request protest defense */ async requestDefense(input: RequestProtestDefenseCommandDTO): Promise { await this.apiClient.requestDefense(input); } }