move static data
This commit is contained in:
@@ -33,6 +33,7 @@ import { GetLeagueWalletOutputDTO } from './dtos/GetLeagueWalletOutputDTO';
|
||||
import { TotalLeaguesDTO } from './dtos/TotalLeaguesDTO';
|
||||
import { WithdrawFromLeagueWalletInputDTO } from './dtos/WithdrawFromLeagueWalletInputDTO';
|
||||
import { WithdrawFromLeagueWalletOutputDTO } from './dtos/WithdrawFromLeagueWalletOutputDTO';
|
||||
import { LeagueScoringPresetsDTO } from './dtos/LeagueScoringPresetsDTO';
|
||||
|
||||
@ApiTags('leagues')
|
||||
@Controller('leagues')
|
||||
@@ -239,8 +240,8 @@ export class LeagueController {
|
||||
|
||||
@Get('scoring-presets')
|
||||
@ApiOperation({ summary: 'Get league scoring presets' })
|
||||
@ApiResponse({ status: 200, description: 'List of scoring presets' })
|
||||
async getLeagueScoringPresets() {
|
||||
@ApiResponse({ status: 200, description: 'List of scoring presets', type: LeagueScoringPresetsDTO })
|
||||
async getLeagueScoringPresets(): Promise<LeagueScoringPresetsDTO> {
|
||||
return this.leagueService.listLeagueScoringPresets();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsEnum } from 'class-validator';
|
||||
import { IsString, IsEnum, IsNumber, ValidateNested } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
|
||||
export class LeagueScoringPresetTimingDefaultsDTO {
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
practiceMinutes!: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
qualifyingMinutes!: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
sprintRaceMinutes!: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
mainRaceMinutes!: number;
|
||||
|
||||
@ApiProperty()
|
||||
@IsNumber()
|
||||
sessionCount!: number;
|
||||
}
|
||||
|
||||
export class LeagueScoringPresetDTO {
|
||||
@ApiProperty()
|
||||
@@ -29,4 +52,9 @@ export class LeagueScoringPresetDTO {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
dropPolicySummary!: string;
|
||||
|
||||
@ApiProperty({ type: LeagueScoringPresetTimingDefaultsDTO })
|
||||
@ValidateNested()
|
||||
@Type(() => LeagueScoringPresetTimingDefaultsDTO)
|
||||
defaultTimings!: LeagueScoringPresetTimingDefaultsDTO;
|
||||
}
|
||||
10
apps/api/src/domain/league/dtos/LeagueScoringPresetsDTO.ts
Normal file
10
apps/api/src/domain/league/dtos/LeagueScoringPresetsDTO.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { LeagueScoringPresetDTO } from './LeagueScoringPresetDTO';
|
||||
|
||||
export class LeagueScoringPresetsDTO {
|
||||
@ApiProperty({ type: [LeagueScoringPresetDTO] })
|
||||
presets!: LeagueScoringPresetDTO[];
|
||||
|
||||
@ApiProperty()
|
||||
totalCount!: number;
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||
import type { ListLeagueScoringPresetsResult, LeagueScoringPreset } from '@core/racing/application/use-cases/ListLeagueScoringPresetsUseCase';
|
||||
import type { LeagueScoringPresetsDTO } from '../dtos/LeagueScoringPresetsDTO';
|
||||
|
||||
export interface LeagueScoringPresetsViewModel {
|
||||
presets: LeagueScoringPreset[];
|
||||
totalCount: number;
|
||||
}
|
||||
export type LeagueScoringPresetsViewModel = LeagueScoringPresetsDTO;
|
||||
|
||||
export class LeagueScoringPresetsPresenter implements UseCaseOutputPort<ListLeagueScoringPresetsResult> {
|
||||
private viewModel: LeagueScoringPresetsViewModel | null = null;
|
||||
|
||||
@@ -17,6 +17,7 @@ import { FileProtestCommandDTO } from './dtos/FileProtestCommandDTO';
|
||||
import { QuickPenaltyCommandDTO } from './dtos/QuickPenaltyCommandDTO';
|
||||
import { ApplyPenaltyCommandDTO } from './dtos/ApplyPenaltyCommandDTO';
|
||||
import { RequestProtestDefenseCommandDTO } from './dtos/RequestProtestDefenseCommandDTO';
|
||||
import { PenaltyTypesReferenceDTO } from './dtos/PenaltyTypesReferenceDTO';
|
||||
|
||||
@ApiTags('races')
|
||||
@Controller('races')
|
||||
@@ -96,6 +97,13 @@ export class RaceController {
|
||||
return presenter.viewModel;
|
||||
}
|
||||
|
||||
@Get('reference/penalty-types')
|
||||
@ApiOperation({ summary: 'Get allowed penalty types and semantics' })
|
||||
@ApiResponse({ status: 200, description: 'Penalty types reference', type: PenaltyTypesReferenceDTO })
|
||||
getPenaltyTypesReference(): PenaltyTypesReferenceDTO {
|
||||
return this.raceService.getPenaltyTypesReference();
|
||||
}
|
||||
|
||||
@Get(':raceId/penalties')
|
||||
@ApiOperation({ summary: 'Get race penalties' })
|
||||
@ApiParam({ name: 'raceId', description: 'Race ID' })
|
||||
|
||||
@@ -50,6 +50,7 @@ import { FileProtestCommandDTO } from './dtos/FileProtestCommandDTO';
|
||||
import { QuickPenaltyCommandDTO } from './dtos/QuickPenaltyCommandDTO';
|
||||
import { RequestProtestDefenseCommandDTO } from './dtos/RequestProtestDefenseCommandDTO';
|
||||
import { ReviewProtestCommandDTO } from './dtos/ReviewProtestCommandDTO';
|
||||
import { PenaltyTypesReferenceDTO } from './dtos/PenaltyTypesReferenceDTO';
|
||||
|
||||
// Tokens
|
||||
import { ApplyPenaltyUseCase } from '@core/racing/application/use-cases/ApplyPenaltyUseCase';
|
||||
@@ -68,6 +69,13 @@ import {
|
||||
RACES_PAGE_DATA_PRESENTER_TOKEN
|
||||
} from './RaceTokens';
|
||||
|
||||
import {
|
||||
PENALTY_TYPE_VALUES,
|
||||
getPenaltyValueKind,
|
||||
type PenaltyTypeValue,
|
||||
} from '@core/racing/domain/entities/penalty/PenaltyType';
|
||||
import { penaltyTypeRequiresValue } from '@core/racing/domain/entities/penalty/Penalty';
|
||||
|
||||
@Injectable()
|
||||
export class RaceService {
|
||||
constructor(
|
||||
@@ -160,6 +168,22 @@ export class RaceService {
|
||||
return this.raceProtestsPresenter;
|
||||
}
|
||||
|
||||
getPenaltyTypesReference(): PenaltyTypesReferenceDTO {
|
||||
const items = PENALTY_TYPE_VALUES.map((type: PenaltyTypeValue) => ({
|
||||
type,
|
||||
requiresValue: penaltyTypeRequiresValue(type),
|
||||
valueKind: getPenaltyValueKind(type),
|
||||
}));
|
||||
|
||||
return {
|
||||
penaltyTypes: items,
|
||||
defaultReasons: {
|
||||
upheld: 'Protest upheld',
|
||||
dismissed: 'Protest dismissed',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async getRacePenalties(raceId: string): Promise<RacePenaltiesPresenter> {
|
||||
this.logger.debug('[RaceService] Fetching race penalties:', { raceId });
|
||||
await this.getRacePenaltiesUseCase.execute({ raceId });
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsNotEmpty, IsOptional, IsNumber, IsEnum } from 'class-validator';
|
||||
import { PENALTY_TYPE_VALUES } from '@core/racing/domain/entities/penalty/PenaltyType';
|
||||
|
||||
export class ApplyPenaltyCommandDTO {
|
||||
@ApiProperty()
|
||||
@@ -17,30 +18,8 @@ export class ApplyPenaltyCommandDTO {
|
||||
@IsNotEmpty()
|
||||
stewardId!: string;
|
||||
|
||||
@ApiProperty({
|
||||
enum: [
|
||||
'time_penalty',
|
||||
'grid_penalty',
|
||||
'points_deduction',
|
||||
'disqualification',
|
||||
'warning',
|
||||
'license_points',
|
||||
'probation',
|
||||
'fine',
|
||||
'race_ban',
|
||||
],
|
||||
})
|
||||
@IsEnum([
|
||||
'time_penalty',
|
||||
'grid_penalty',
|
||||
'points_deduction',
|
||||
'disqualification',
|
||||
'warning',
|
||||
'license_points',
|
||||
'probation',
|
||||
'fine',
|
||||
'race_ban',
|
||||
])
|
||||
@ApiProperty({ enum: PENALTY_TYPE_VALUES })
|
||||
@IsEnum(PENALTY_TYPE_VALUES)
|
||||
type!: string;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
|
||||
40
apps/api/src/domain/race/dtos/PenaltyTypesReferenceDTO.ts
Normal file
40
apps/api/src/domain/race/dtos/PenaltyTypesReferenceDTO.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsEnum, IsString } from 'class-validator';
|
||||
import {
|
||||
PENALTY_TYPE_VALUES,
|
||||
type PenaltyTypeValue,
|
||||
} from '@core/racing/domain/entities/penalty/PenaltyType';
|
||||
|
||||
export type PenaltyValueKindDTO = 'seconds' | 'grid_positions' | 'points' | 'races' | 'none';
|
||||
|
||||
export class PenaltyTypeReferenceDTO {
|
||||
@ApiProperty({ enum: PENALTY_TYPE_VALUES })
|
||||
@IsEnum(PENALTY_TYPE_VALUES)
|
||||
type!: PenaltyTypeValue;
|
||||
|
||||
@ApiProperty()
|
||||
@IsBoolean()
|
||||
requiresValue!: boolean;
|
||||
|
||||
@ApiProperty({ enum: ['seconds', 'grid_positions', 'points', 'races', 'none'] })
|
||||
@IsString()
|
||||
valueKind!: PenaltyValueKindDTO;
|
||||
}
|
||||
|
||||
export class PenaltyDefaultReasonsDTO {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
upheld!: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
dismissed!: string;
|
||||
}
|
||||
|
||||
export class PenaltyTypesReferenceDTO {
|
||||
@ApiProperty({ type: [PenaltyTypeReferenceDTO] })
|
||||
penaltyTypes!: PenaltyTypeReferenceDTO[];
|
||||
|
||||
@ApiProperty({ type: PenaltyDefaultReasonsDTO })
|
||||
defaultReasons!: PenaltyDefaultReasonsDTO;
|
||||
}
|
||||
Reference in New Issue
Block a user