This commit is contained in:
2025-12-17 14:04:11 +01:00
parent 1ea9c9649f
commit daa4bb6576
238 changed files with 4263 additions and 1752 deletions

View File

@@ -1,5 +1,20 @@
import { Injectable, Inject } from '@nestjs/common';
import { AllRacesPageViewModel, RaceStatsDto, ImportRaceResultsInput, ImportRaceResultsSummaryViewModel } from './dto/RaceDto';
import {
AllRacesPageViewModel,
RaceStatsDto,
ImportRaceResultsInput,
ImportRaceResultsSummaryViewModel,
RaceDetailViewModelDto,
RacesPageDataViewModelDto,
RaceResultsDetailViewModelDto,
RaceWithSOFViewModelDto,
RaceProtestsViewModelDto,
RacePenaltiesViewModelDto,
GetRaceDetailParamsDto,
RegisterForRaceParamsDto,
WithdrawFromRaceParamsDto,
RaceActionParamsDto,
} from './dtos/RaceDTO';
// Core imports
import type { Logger } from '@core/shared/application/Logger';
@@ -8,6 +23,23 @@ import type { Logger } from '@core/shared/application/Logger';
import { GetAllRacesUseCase } from '@core/racing/application/use-cases/GetAllRacesUseCase';
import { GetTotalRacesUseCase } from '@core/racing/application/use-cases/GetTotalRacesUseCase';
import { ImportRaceResultsApiUseCase } from '@core/racing/application/use-cases/ImportRaceResultsApiUseCase';
import { GetRaceDetailUseCase } from '@core/racing/application/use-cases/GetRaceDetailUseCase';
import { GetRacesPageDataUseCase } from '@core/racing/application/use-cases/GetRacesPageDataUseCase';
import { GetAllRacesPageDataUseCase } from '@core/racing/application/use-cases/GetAllRacesPageDataUseCase';
import { GetRaceResultsDetailUseCase } from '@core/racing/application/use-cases/GetRaceResultsDetailUseCase';
import { GetRaceWithSOFUseCase } from '@core/racing/application/use-cases/GetRaceWithSOFUseCase';
import { GetRaceProtestsUseCase } from '@core/racing/application/use-cases/GetRaceProtestsUseCase';
import { GetRacePenaltiesUseCase } from '@core/racing/application/use-cases/GetRacePenaltiesUseCase';
import { RegisterForRaceUseCase } from '@core/racing/application/use-cases/RegisterForRaceUseCase';
import { WithdrawFromRaceUseCase } from '@core/racing/application/use-cases/WithdrawFromRaceUseCase';
import { CancelRaceUseCase } from '@core/racing/application/use-cases/CancelRaceUseCase';
import { CompleteRaceUseCase } from '@core/racing/application/use-cases/CompleteRaceUseCase';
import { ImportRaceResultsUseCase } from '@core/racing/application/use-cases/ImportRaceResultsUseCase';
import { DashboardOverviewUseCase } from '@core/racing/application/use-cases/DashboardOverviewUseCase';
import { FileProtestUseCase } from '@core/racing/application/use-cases/FileProtestUseCase';
import { QuickPenaltyUseCase } from '@core/racing/application/use-cases/QuickPenaltyUseCase';
import { ApplyPenaltyUseCase } from '@core/racing/application/use-cases/ApplyPenaltyUseCase';
import { RequestProtestDefenseUseCase } from '@core/racing/application/use-cases/RequestProtestDefenseUseCase';
// Presenters
import { GetAllRacesPresenter } from './presenters/GetAllRacesPresenter';
@@ -23,6 +55,23 @@ export class RaceService {
private readonly getAllRacesUseCase: GetAllRacesUseCase,
private readonly getTotalRacesUseCase: GetTotalRacesUseCase,
private readonly importRaceResultsApiUseCase: ImportRaceResultsApiUseCase,
private readonly getRaceDetailUseCase: GetRaceDetailUseCase,
private readonly getRacesPageDataUseCase: GetRacesPageDataUseCase,
private readonly getAllRacesPageDataUseCase: GetAllRacesPageDataUseCase,
private readonly getRaceResultsDetailUseCase: GetRaceResultsDetailUseCase,
private readonly getRaceWithSOFUseCase: GetRaceWithSOFUseCase,
private readonly getRaceProtestsUseCase: GetRaceProtestsUseCase,
private readonly getRacePenaltiesUseCase: GetRacePenaltiesUseCase,
private readonly registerForRaceUseCase: RegisterForRaceUseCase,
private readonly withdrawFromRaceUseCase: WithdrawFromRaceUseCase,
private readonly cancelRaceUseCase: CancelRaceUseCase,
private readonly completeRaceUseCase: CompleteRaceUseCase,
private readonly importRaceResultsUseCase: ImportRaceResultsUseCase,
private readonly dashboardOverviewUseCase: DashboardOverviewUseCase,
private readonly fileProtestUseCase: FileProtestUseCase,
private readonly quickPenaltyUseCase: QuickPenaltyUseCase,
private readonly applyPenaltyUseCase: ApplyPenaltyUseCase,
private readonly requestProtestDefenseUseCase: RequestProtestDefenseUseCase,
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
) {}
@@ -47,4 +96,202 @@ export class RaceService {
await this.importRaceResultsApiUseCase.execute({ raceId: input.raceId, resultsFileContent: input.resultsFileContent }, presenter);
return presenter.getViewModel()!;
}
async getRaceDetail(params: GetRaceDetailParamsDto): Promise<RaceDetailViewModelDto> {
this.logger.debug('[RaceService] Fetching race detail:', params);
const presenter = new RaceDetailPresenter();
const result = await this.getRaceDetailUseCase.execute(params);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to get race detail');
}
return result.value;
}
async getRacesPageData(): Promise<RacesPageDataViewModelDto> {
this.logger.debug('[RaceService] Fetching races page data.');
const result = await this.getRacesPageDataUseCase.execute();
if (result.isErr()) {
throw new Error('Failed to get races page data');
}
return result.value;
}
async getAllRacesPageData(): Promise<RacesPageDataViewModelDto> {
this.logger.debug('[RaceService] Fetching all races page data.');
const result = await this.getAllRacesPageDataUseCase.execute();
if (result.isErr()) {
throw new Error('Failed to get all races page data');
}
return result.value;
}
async getRaceResultsDetail(raceId: string): Promise<RaceResultsDetailViewModelDto> {
this.logger.debug('[RaceService] Fetching race results detail:', { raceId });
const result = await this.getRaceResultsDetailUseCase.execute({ raceId });
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to get race results detail');
}
return result.value;
}
async getRaceWithSOF(raceId: string): Promise<RaceWithSOFViewModelDto> {
this.logger.debug('[RaceService] Fetching race with SOF:', { raceId });
const result = await this.getRaceWithSOFUseCase.execute({ raceId });
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to get race with SOF');
}
return result.value;
}
async getRaceProtests(raceId: string): Promise<RaceProtestsViewModelDto> {
this.logger.debug('[RaceService] Fetching race protests:', { raceId });
const result = await this.getRaceProtestsUseCase.execute({ raceId });
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to get race protests');
}
return result.value;
}
async getRacePenalties(raceId: string): Promise<RacePenaltiesViewModelDto> {
this.logger.debug('[RaceService] Fetching race penalties:', { raceId });
const result = await this.getRacePenaltiesUseCase.execute({ raceId });
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to get race penalties');
}
return result.value;
}
async registerForRace(params: RegisterForRaceParamsDto): Promise<void> {
this.logger.debug('[RaceService] Registering for race:', params);
const result = await this.registerForRaceUseCase.execute(params);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to register for race');
}
}
async withdrawFromRace(params: WithdrawFromRaceParamsDto): Promise<void> {
this.logger.debug('[RaceService] Withdrawing from race:', params);
const result = await this.withdrawFromRaceUseCase.execute(params);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to withdraw from race');
}
}
async cancelRace(params: RaceActionParamsDto): Promise<void> {
this.logger.debug('[RaceService] Cancelling race:', params);
const result = await this.cancelRaceUseCase.execute({ raceId: params.raceId });
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to cancel race');
}
}
async completeRace(params: RaceActionParamsDto): Promise<void> {
this.logger.debug('[RaceService] Completing race:', params);
const result = await this.completeRaceUseCase.execute({ raceId: params.raceId });
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to complete race');
}
}
async importRaceResultsAlt(params: { raceId: string; resultsFileContent: string }): Promise<void> {
this.logger.debug('[RaceService] Importing race results (alt):', params);
const result = await this.importRaceResultsUseCase.execute({
raceId: params.raceId,
resultsFileContent: params.resultsFileContent,
});
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to import race results');
}
}
async getDashboardOverview(driverId: string): Promise<any> {
this.logger.debug('[RaceService] Getting dashboard overview:', { driverId });
const result = await this.dashboardOverviewUseCase.execute({ driverId });
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to get dashboard overview');
}
return result.value;
}
async fileProtest(command: any): Promise<any> {
this.logger.debug('[RaceService] Filing protest:', command);
const result = await this.fileProtestUseCase.execute(command);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to file protest');
}
return result.value;
}
async applyQuickPenalty(command: any): Promise<any> {
this.logger.debug('[RaceService] Applying quick penalty:', command);
const result = await this.quickPenaltyUseCase.execute(command);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to apply quick penalty');
}
return result.value;
}
async applyPenalty(command: any): Promise<any> {
this.logger.debug('[RaceService] Applying penalty:', command);
const result = await this.applyPenaltyUseCase.execute(command);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to apply penalty');
}
return result.value;
}
async requestProtestDefense(command: any): Promise<any> {
this.logger.debug('[RaceService] Requesting protest defense:', command);
const result = await this.requestProtestDefenseUseCase.execute(command);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to request protest defense');
}
return result.value;
}
}