module cleanup

This commit is contained in:
2025-12-19 01:22:45 +01:00
parent d617654928
commit d0fac9e6c1
135 changed files with 5104 additions and 1315 deletions

View File

@@ -0,0 +1,74 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RaceController } from './RaceController';
import { RaceService } from './RaceService';
describe('RaceController', () => {
let controller: RaceController;
let service: jest.Mocked<RaceService>;
beforeEach(async () => {
const mockService = {
getAllRaces: jest.fn(),
getTotalRaces: jest.fn(),
getRacesPageData: jest.fn(),
getAllRacesPageData: jest.fn(),
getRaceDetail: jest.fn(),
getRaceResultsDetail: jest.fn(),
getRaceWithSOF: jest.fn(),
getRaceProtests: jest.fn(),
getRacePenalties: jest.fn(),
registerForRace: jest.fn(),
withdrawFromRace: jest.fn(),
cancelRace: jest.fn(),
completeRace: jest.fn(),
importRaceResults: jest.fn(),
fileProtest: jest.fn(),
applyQuickPenalty: jest.fn(),
applyPenalty: jest.fn(),
requestProtestDefense: jest.fn(),
};
const module: TestingModule = await Test.createTestingModule({
controllers: [RaceController],
providers: [
{
provide: RaceService,
useValue: mockService,
},
],
}).compile();
controller = module.get<RaceController>(RaceController);
service = module.get(RaceService);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
describe('getAllRaces', () => {
it('should return all races', async () => {
const mockResult = { races: [], totalCount: 0 };
service.getAllRaces.mockResolvedValue(mockResult);
const result = await controller.getAllRaces();
expect(service.getAllRaces).toHaveBeenCalled();
expect(result).toEqual(mockResult);
});
});
describe('getTotalRaces', () => {
it('should return total races count', async () => {
const mockResult = { totalRaces: 5 };
service.getTotalRaces.mockResolvedValue(mockResult);
const result = await controller.getTotalRaces();
expect(service.getTotalRaces).toHaveBeenCalled();
expect(result).toEqual(mockResult);
});
});
// Add more tests as needed
});

View File

@@ -9,10 +9,8 @@ import { RaceResultsDetailDTO } from './dtos/RaceResultsDetailDTO';
import { RaceWithSOFDTO } from './dtos/RaceWithSOFDTO';
import { RaceProtestsDTO } from './dtos/RaceProtestsDTO';
import { RacePenaltiesDTO } from './dtos/RacePenaltiesDTO';
import { GetRaceDetailParamsDTO } from './dtos/GetRaceDetailParamsDTO';
import { RegisterForRaceParamsDTO } from './dtos/RegisterForRaceParamsDTO';
import { WithdrawFromRaceParamsDTO } from './dtos/WithdrawFromRaceParamsDTO';
import { RaceActionParamsDTO } from './dtos/RaceActionParamsDTO';
import { ImportRaceResultsDTO } from './dtos/ImportRaceResultsDTO';
import { ImportRaceResultsSummaryDTO } from './dtos/ImportRaceResultsSummaryDTO';
import { FileProtestCommandDTO } from './dtos/FileProtestCommandDTO';
@@ -156,7 +154,7 @@ export class RaceController {
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'File a protest' })
@ApiResponse({ status: 200, description: 'Protest filed successfully' })
async fileProtest(@Body() body: FileProtestCommandDTO): Promise<any> {
async fileProtest(@Body() body: FileProtestCommandDTO): Promise<void> {
return this.raceService.fileProtest(body);
}
@@ -164,7 +162,7 @@ export class RaceController {
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Apply a quick penalty' })
@ApiResponse({ status: 200, description: 'Penalty applied successfully' })
async applyQuickPenalty(@Body() body: QuickPenaltyCommandDTO): Promise<any> {
async applyQuickPenalty(@Body() body: QuickPenaltyCommandDTO): Promise<void> {
return this.raceService.applyQuickPenalty(body);
}
@@ -172,7 +170,7 @@ export class RaceController {
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Apply a penalty' })
@ApiResponse({ status: 200, description: 'Penalty applied successfully' })
async applyPenalty(@Body() body: ApplyPenaltyCommandDTO): Promise<any> {
async applyPenalty(@Body() body: ApplyPenaltyCommandDTO): Promise<void> {
return this.raceService.applyPenalty(body);
}
@@ -180,7 +178,7 @@ export class RaceController {
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Request protest defense' })
@ApiResponse({ status: 200, description: 'Defense requested successfully' })
async requestProtestDefense(@Body() body: RequestProtestDefenseCommandDTO): Promise<any> {
async requestProtestDefense(@Body() body: RequestProtestDefenseCommandDTO): Promise<void> {
return this.raceService.requestProtestDefense(body);
}
}

View File

@@ -0,0 +1,28 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RaceModule } from './RaceModule';
import { RaceController } from './RaceController';
import { RaceService } from './RaceService';
describe('RaceModule', () => {
let module: TestingModule;
beforeEach(async () => {
module = await Test.createTestingModule({
imports: [RaceModule],
}).compile();
});
it('should compile the module', async () => {
expect(module).toBeDefined();
});
it('should have RaceController', () => {
const controller = module.get<RaceController>(RaceController);
expect(controller).toBeDefined();
});
it('should have RaceService', () => {
const service = module.get<RaceService>(RaceService);
expect(service).toBeDefined();
});
});

View File

@@ -6,6 +6,7 @@ import type { Logger } from '@core/shared/application/Logger';
import { IRaceRepository } from '@core/racing/domain/repositories/IRaceRepository';
import { ILeagueRepository } from '@core/racing/domain/repositories/ILeagueRepository';
import { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
import { IStandingRepository } from '@core/racing/domain/repositories/IStandingRepository';
import { IRaceRegistrationRepository } from '@core/racing/domain/repositories/IRaceRegistrationRepository';
import { IResultRepository } from '@core/racing/domain/repositories/IResultRepository';
import { ILeagueMembershipRepository } from '@core/racing/domain/repositories/ILeagueMembershipRepository';
@@ -23,6 +24,7 @@ import { InMemoryResultRepository } from '@adapters/racing/persistence/inmemory/
import { InMemoryLeagueMembershipRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueMembershipRepository';
import { InMemoryPenaltyRepository } from '@adapters/racing/persistence/inmemory/InMemoryPenaltyRepository';
import { InMemoryProtestRepository } from '@adapters/racing/persistence/inmemory/InMemoryProtestRepository';
import { InMemoryStandingRepository } from '@adapters/racing/persistence/inmemory/InMemoryStandingRepository';
import { InMemoryDriverRatingProvider } from '@adapters/racing/ports/InMemoryDriverRatingProvider';
import { InMemoryImageServiceAdapter } from '@adapters/media/ports/InMemoryImageServiceAdapter';
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
@@ -58,6 +60,7 @@ export const RESULT_REPOSITORY_TOKEN = 'IResultRepository';
export const LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN = 'ILeagueMembershipRepository';
export const PENALTY_REPOSITORY_TOKEN = 'IPenaltyRepository';
export const PROTEST_REPOSITORY_TOKEN = 'IProtestRepository';
export const STANDING_REPOSITORY_TOKEN = 'IStandingRepository';
export const DRIVER_RATING_PROVIDER_TOKEN = 'DriverRatingProvider';
export const IMAGE_SERVICE_TOKEN = 'IImageServicePort';
export const LOGGER_TOKEN = 'Logger';
@@ -104,6 +107,11 @@ export const RaceProviders: Provider[] = [
useFactory: (logger: Logger) => new InMemoryProtestRepository(logger),
inject: [LOGGER_TOKEN],
},
{
provide: STANDING_REPOSITORY_TOKEN,
useFactory: (logger: Logger) => new InMemoryStandingRepository(logger),
inject: [LOGGER_TOKEN],
},
{
provide: DRIVER_RATING_PROVIDER_TOKEN,
useFactory: (logger: Logger) => new InMemoryDriverRatingProvider(logger),
@@ -121,13 +129,13 @@ export const RaceProviders: Provider[] = [
// Use cases
{
provide: GetAllRacesUseCase,
useFactory: (raceRepo: IRaceRepository, leagueRepo: ILeagueRepository) => new GetAllRacesUseCase(raceRepo, leagueRepo),
inject: [RACE_REPOSITORY_TOKEN, LEAGUE_REPOSITORY_TOKEN],
useFactory: (raceRepo: IRaceRepository, leagueRepo: ILeagueRepository, logger: Logger) => new GetAllRacesUseCase(raceRepo, leagueRepo, logger),
inject: [RACE_REPOSITORY_TOKEN, LEAGUE_REPOSITORY_TOKEN, LOGGER_TOKEN],
},
{
provide: GetTotalRacesUseCase,
useFactory: (raceRepo: IRaceRepository) => new GetTotalRacesUseCase(raceRepo),
inject: [RACE_REPOSITORY_TOKEN],
useFactory: (raceRepo: IRaceRepository, logger: Logger) => new GetTotalRacesUseCase(raceRepo, logger),
inject: [RACE_REPOSITORY_TOKEN, LOGGER_TOKEN],
},
{
provide: GetRaceDetailUseCase,
@@ -173,14 +181,35 @@ export const RaceProviders: Provider[] = [
},
{
provide: GetRaceResultsDetailUseCase,
useFactory: (resultRepo: IResultRepository, driverRepo: IDriverRepository, imageService: IImageServicePort) =>
new GetRaceResultsDetailUseCase(resultRepo, driverRepo, imageService),
inject: [RESULT_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, IMAGE_SERVICE_TOKEN],
useFactory: (
raceRepo: IRaceRepository,
leagueRepo: ILeagueRepository,
resultRepo: IResultRepository,
driverRepo: IDriverRepository,
penaltyRepo: IPenaltyRepository,
) => new GetRaceResultsDetailUseCase(raceRepo, leagueRepo, resultRepo, driverRepo, penaltyRepo),
inject: [
RACE_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
DRIVER_REPOSITORY_TOKEN,
PENALTY_REPOSITORY_TOKEN,
],
},
{
provide: GetRaceWithSOFUseCase,
useFactory: (raceRepo: IRaceRepository) => new GetRaceWithSOFUseCase(raceRepo),
inject: [RACE_REPOSITORY_TOKEN],
useFactory: (
raceRepo: IRaceRepository,
raceRegRepo: IRaceRegistrationRepository,
resultRepo: IResultRepository,
driverRatingProvider: DriverRatingProvider,
) => new GetRaceWithSOFUseCase(raceRepo, raceRegRepo, resultRepo, driverRatingProvider),
inject: [
RACE_REPOSITORY_TOKEN,
RACE_REGISTRATION_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
DRIVER_RATING_PROVIDER_TOKEN,
],
},
{
provide: GetRaceProtestsUseCase,
@@ -200,8 +229,8 @@ export const RaceProviders: Provider[] = [
},
{
provide: WithdrawFromRaceUseCase,
useFactory: (raceRegRepo: IRaceRegistrationRepository, logger: Logger) => new WithdrawFromRaceUseCase(raceRegRepo, logger),
inject: [RACE_REGISTRATION_REPOSITORY_TOKEN, LOGGER_TOKEN],
useFactory: (raceRegRepo: IRaceRegistrationRepository) => new WithdrawFromRaceUseCase(raceRegRepo),
inject: [RACE_REGISTRATION_REPOSITORY_TOKEN],
},
{
provide: CancelRaceUseCase,
@@ -210,16 +239,78 @@ export const RaceProviders: Provider[] = [
},
{
provide: CompleteRaceUseCase,
useFactory: (raceRepo: IRaceRepository, logger: Logger) => new CompleteRaceUseCase(raceRepo, logger),
inject: [RACE_REPOSITORY_TOKEN, LOGGER_TOKEN],
useFactory: (
raceRepo: IRaceRepository,
raceRegRepo: IRaceRegistrationRepository,
resultRepo: IResultRepository,
standingRepo: IStandingRepository,
driverRatingProvider: DriverRatingProvider,
) => new CompleteRaceUseCase(raceRepo, raceRegRepo, resultRepo, standingRepo, driverRatingProvider),
inject: [
RACE_REPOSITORY_TOKEN,
RACE_REGISTRATION_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
STANDING_REPOSITORY_TOKEN,
DRIVER_RATING_PROVIDER_TOKEN,
],
},
{
provide: ImportRaceResultsApiUseCase,
useFactory: (
raceRepo: IRaceRepository,
leagueRepo: ILeagueRepository,
resultRepo: IResultRepository,
driverRepo: IDriverRepository,
standingRepo: IStandingRepository,
logger: Logger,
) => new ImportRaceResultsApiUseCase(
raceRepo,
leagueRepo,
resultRepo,
driverRepo,
standingRepo,
logger,
),
inject: [
RACE_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
DRIVER_REPOSITORY_TOKEN,
STANDING_REPOSITORY_TOKEN,
LOGGER_TOKEN,
],
},
{
provide: ImportRaceResultsUseCase,
useFactory: (
raceRepo: IRaceRepository,
leagueRepo: ILeagueRepository,
resultRepo: IResultRepository,
driverRepo: IDriverRepository,
standingRepo: IStandingRepository,
logger: Logger,
) => new ImportRaceResultsUseCase(
raceRepo,
leagueRepo,
resultRepo,
driverRepo,
standingRepo,
logger,
),
inject: [
RACE_REPOSITORY_TOKEN,
LEAGUE_REPOSITORY_TOKEN,
RESULT_REPOSITORY_TOKEN,
DRIVER_REPOSITORY_TOKEN,
STANDING_REPOSITORY_TOKEN,
LOGGER_TOKEN,
],
},
ImportRaceResultsApiUseCase,
ImportRaceResultsUseCase,
{
provide: FileProtestUseCase,
useFactory: (protestRepo: IProtestRepository, raceRepo: IRaceRepository, driverRepo: IDriverRepository, logger: Logger) =>
new FileProtestUseCase(protestRepo, raceRepo, driverRepo, logger),
inject: [PROTEST_REPOSITORY_TOKEN, RACE_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, LOGGER_TOKEN],
useFactory: (protestRepo: IProtestRepository, raceRepo: IRaceRepository, leagueMembershipRepo: ILeagueMembershipRepository) =>
new FileProtestUseCase(protestRepo, raceRepo, leagueMembershipRepo),
inject: [PROTEST_REPOSITORY_TOKEN, RACE_REPOSITORY_TOKEN, LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN],
},
{
provide: QuickPenaltyUseCase,

View File

@@ -1,20 +1,19 @@
import { Injectable, Inject } from '@nestjs/common';
import {
AllRacesPageViewModel,
RaceStatsDto,
ImportRaceResultsInput,
ImportRaceResultsSummaryViewModel,
RaceDetailViewModelDto,
RacesPageDataViewModelDto,
RaceResultsDetailViewModelDto,
RaceWithSOFViewModelDto,
RaceProtestsViewModelDto,
RacePenaltiesViewModelDto,
GetRaceDetailParamsDto,
RegisterForRaceParamsDto,
WithdrawFromRaceParamsDto,
RaceActionParamsDto,
} from './dtos/RaceDTO';
import type { AllRacesPageViewModel } from '@core/racing/application/presenters/IGetAllRacesPresenter';
import type { GetTotalRacesViewModel } from '@core/racing/application/presenters/IGetTotalRacesPresenter';
import type { RaceDetailViewModel } from '@core/racing/application/presenters/IRaceDetailPresenter';
import type { RacesPageViewModel } from '@core/racing/application/presenters/IRacesPagePresenter';
import type { RaceResultsDetailViewModel } from '@core/racing/application/presenters/IRaceResultsDetailPresenter';
import type { RaceWithSOFViewModel } from '@core/racing/application/presenters/IRaceWithSOFPresenter';
import type { RaceProtestsViewModel } from '@core/racing/application/presenters/IRaceProtestsPresenter';
import type { RacePenaltiesViewModel } from '@core/racing/application/presenters/IRacePenaltiesPresenter';
// DTOs
import { GetRaceDetailParamsDTO } from './dtos/GetRaceDetailParamsDTO';
import { RegisterForRaceParamsDTO } from './dtos/RegisterForRaceParamsDTO';
import { WithdrawFromRaceParamsDTO } from './dtos/WithdrawFromRaceParamsDTO';
import { RaceActionParamsDTO } from './dtos/RaceActionParamsDTO';
import { ImportRaceResultsDTO } from './dtos/ImportRaceResultsDTO';
// Core imports
import type { Logger } from '@core/shared/application/Logger';
@@ -46,6 +45,13 @@ import { GetAllRacesPresenter } from './presenters/GetAllRacesPresenter';
import { GetTotalRacesPresenter } from './presenters/GetTotalRacesPresenter';
import { ImportRaceResultsApiPresenter } from './presenters/ImportRaceResultsApiPresenter';
// Command DTOs
import { FileProtestCommandDTO } from './dtos/FileProtestCommandDTO';
import { QuickPenaltyCommandDTO } from './dtos/QuickPenaltyCommandDTO';
import { ApplyPenaltyCommandDTO } from './dtos/ApplyPenaltyCommandDTO';
import { RequestProtestDefenseCommandDTO } from './dtos/RequestProtestDefenseCommandDTO';
import { ReviewProtestCommandDTO } from './dtos/ReviewProtestCommandDTO';
// Tokens
import { LOGGER_TOKEN } from './RaceProviders';
@@ -66,7 +72,6 @@ export class RaceService {
private readonly withdrawFromRaceUseCase: WithdrawFromRaceUseCase,
private readonly cancelRaceUseCase: CancelRaceUseCase,
private readonly completeRaceUseCase: CompleteRaceUseCase,
private readonly importRaceResultsUseCase: ImportRaceResultsUseCase,
private readonly fileProtestUseCase: FileProtestUseCase,
private readonly quickPenaltyUseCase: QuickPenaltyUseCase,
private readonly applyPenaltyUseCase: ApplyPenaltyUseCase,
@@ -83,34 +88,33 @@ export class RaceService {
return presenter.getViewModel()!;
}
async getTotalRaces(): Promise<RaceStatsDto> {
async getTotalRaces(): Promise<GetTotalRacesViewModel> {
this.logger.debug('[RaceService] Fetching total races count.');
const presenter = new GetTotalRacesPresenter();
await this.getTotalRacesUseCase.execute({}, presenter);
return presenter.getViewModel()!;
}
async importRaceResults(input: ImportRaceResultsInput): Promise<ImportRaceResultsSummaryViewModel> {
async importRaceResults(input: ImportRaceResultsDTO): Promise<ImportRaceResultsSummaryDTO> {
this.logger.debug('Importing race results:', input);
const presenter = new ImportRaceResultsApiPresenter();
await this.importRaceResultsApiUseCase.execute({ raceId: input.raceId, resultsFileContent: input.resultsFileContent }, presenter);
return presenter.getViewModel()!;
}
async getRaceDetail(params: GetRaceDetailParamsDto): Promise<RaceDetailViewModelDto> {
async getRaceDetail(params: GetRaceDetailParamsDTO): Promise<RaceDetailViewModel> {
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');
throw new Error('Failed to get race detail');
}
return result.value;
}
async getRacesPageData(): Promise<RacesPageDataViewModelDto> {
async getRacesPageData(): Promise<RacesPageViewModel> {
this.logger.debug('[RaceService] Fetching races page data.');
const result = await this.getRacesPageDataUseCase.execute();
@@ -122,7 +126,7 @@ export class RaceService {
return result.value;
}
async getAllRacesPageData(): Promise<RacesPageDataViewModelDto> {
async getAllRacesPageData(): Promise<RacesPageViewModel> {
this.logger.debug('[RaceService] Fetching all races page data.');
const result = await this.getAllRacesPageDataUseCase.execute();
@@ -134,165 +138,143 @@ export class RaceService {
return result.value;
}
async getRaceResultsDetail(raceId: string): Promise<RaceResultsDetailViewModelDto> {
async getRaceResultsDetail(raceId: string): Promise<RaceResultsDetailViewModel> {
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');
throw new Error('Failed to get race results detail');
}
return result.value;
}
async getRaceWithSOF(raceId: string): Promise<RaceWithSOFViewModelDto> {
async getRaceWithSOF(raceId: string): Promise<RaceWithSOFViewModel> {
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');
throw new Error('Failed to get race with SOF');
}
return result.value;
}
async getRaceProtests(raceId: string): Promise<RaceProtestsViewModelDto> {
async getRaceProtests(raceId: string): Promise<RaceProtestsViewModel> {
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');
throw new Error('Failed to get race protests');
}
return result.value;
}
async getRacePenalties(raceId: string): Promise<RacePenaltiesViewModelDto> {
async getRacePenalties(raceId: string): Promise<RacePenaltiesViewModel> {
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');
throw new Error('Failed to get race penalties');
}
return result.value;
}
async registerForRace(params: RegisterForRaceParamsDto): Promise<void> {
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');
throw new Error('Failed to register for race');
}
}
async withdrawFromRace(params: WithdrawFromRaceParamsDto): Promise<void> {
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');
throw new Error('Failed to withdraw from race');
}
}
async cancelRace(params: RaceActionParamsDto): Promise<void> {
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');
throw new Error('Failed to cancel race');
}
}
async completeRace(params: RaceActionParamsDto): Promise<void> {
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');
throw new Error('Failed to complete race');
}
}
async fileProtest(command: any): Promise<any> {
async fileProtest(command: FileProtestCommandDTO): Promise<void> {
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');
throw new Error('Failed to file protest');
}
return result.value;
}
async applyQuickPenalty(command: any): Promise<any> {
async applyQuickPenalty(command: QuickPenaltyCommandDTO): Promise<void> {
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');
throw new Error('Failed to apply quick penalty');
}
return result.value;
}
async applyPenalty(command: any): Promise<any> {
async applyPenalty(command: ApplyPenaltyCommandDTO): Promise<void> {
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');
throw new Error('Failed to apply penalty');
}
return result.value;
}
async requestProtestDefense(command: any): Promise<any> {
async requestProtestDefense(command: RequestProtestDefenseCommandDTO): Promise<void> {
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');
throw new Error('Failed to request protest defense');
}
return result.value;
}
async reviewProtest(command: any): Promise<any> {
async reviewProtest(command: ReviewProtestCommandDTO): Promise<void> {
this.logger.debug('[RaceService] Reviewing protest:', command);
const result = await this.reviewProtestUseCase.execute(command);
if (result.isErr()) {
throw new Error(result.error.details.message || 'Failed to review protest');
throw new Error('Failed to review protest');
}
return result.value;
}
}

View File

@@ -1,5 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { RaceViewModel } from './RaceViewModel';
import { RaceViewModel } from '@core/racing/application/presenters/IGetAllRacesPresenter';
export class AllRacesPageDTO {
@ApiProperty({ type: [RaceViewModel] })

View File

@@ -1,7 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsNotEmpty } from 'class-validator';
export class GetRaceDetailParamsDTODTO {
export class GetRaceDetailParamsDTO {
@ApiProperty()
@IsString()
@IsNotEmpty()

View File

@@ -1,7 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsString, IsNumber } from 'class-validator';
export class ImportRaceResultsSummaryDTOViewModel {
export class ImportRaceResultsSummaryDTO {
@ApiProperty()
@IsBoolean()
success!: boolean;

View File

@@ -1,9 +1,9 @@
import { ApiProperty } from '@nestjs/swagger';
import { RaceProtestDto } from './RaceProtestDto';
import { RaceProtestDTO } from './RaceProtestDTO';
export class RaceProtestsDTO {
@ApiProperty({ type: [RaceProtestDto] })
protests!: RaceProtestDto[];
@ApiProperty({ type: [RaceProtestDTO] })
protests!: RaceProtestDTO[];
@ApiProperty()
driverMap!: Record<string, string>;

View File

@@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsString } from 'class-validator';
import { RaceResultDto } from './RaceResultDto';
import { RaceResultDTO } from './RaceResultDTO';
export class RaceResultsDetailDTO {
@ApiProperty()
@@ -11,6 +11,6 @@ export class RaceResultsDetailDTO {
@IsString()
track!: string;
@ApiProperty({ type: [RaceResultDto] })
results!: RaceResultDto[];
@ApiProperty({ type: [RaceResultDTO] })
results!: RaceResultDTO[];
}

View File

@@ -1,7 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { RacesPageDataRaceDto } from './RacesPageDataRaceDto';
import { RacesPageDataRaceDTO } from './RacesPageDataRaceDTO';
export class RacesPageDataDTO {
@ApiProperty({ type: [RacesPageDataRaceDto] })
races!: RacesPageDataRaceDto[];
@ApiProperty({ type: [RacesPageDataRaceDTO] })
races!: RacesPageDataRaceDTO[];
}

View File

@@ -1,8 +1,7 @@
import { IGetTotalRacesPresenter, GetTotalRacesResultDTO } from '@core/racing/application/presenters/IGetTotalRacesPresenter';
import { RaceStatsDto } from '../dto/RaceDto';
import { IGetTotalRacesPresenter, GetTotalRacesResultDTO, GetTotalRacesViewModel } from '@core/racing/application/presenters/IGetTotalRacesPresenter';
export class GetTotalRacesPresenter implements IGetTotalRacesPresenter {
private result: RaceStatsDto | null = null;
private result: GetTotalRacesViewModel | null = null;
reset() {
this.result = null;
@@ -14,7 +13,7 @@ export class GetTotalRacesPresenter implements IGetTotalRacesPresenter {
};
}
getViewModel(): RaceStatsDto | null {
getViewModel(): GetTotalRacesViewModel | null {
return this.result;
}
}