move static data

This commit is contained in:
2025-12-26 00:20:53 +01:00
parent c977defd6a
commit b6cbb81388
63 changed files with 1482 additions and 418 deletions

View File

@@ -37,6 +37,7 @@ export class ListLeagueScoringPresetsUseCase {
sessionSummary: p.sessionSummary,
bonusSummary: p.bonusSummary,
dropPolicySummary: p.dropPolicySummary,
defaultTimings: p.defaultTimings,
}));
const result: ListLeagueScoringPresetsResult = { presets };

View File

@@ -11,7 +11,7 @@ import { PenaltyId } from './PenaltyId';
import { LeagueId } from '../LeagueId';
import { RaceId } from '../RaceId';
import { DriverId } from '../DriverId';
import { PenaltyType } from './PenaltyType';
import { PenaltyType, type PenaltyTypeValue } from './PenaltyType';
import { PenaltyValue } from './PenaltyValue';
import { PenaltyReason } from './PenaltyReason';
import { ProtestId } from '../ProtestId';
@@ -47,6 +47,19 @@ export interface PenaltyProps {
notes?: PenaltyNotes;
}
export const PENALTY_TYPES_REQUIRING_VALUE: PenaltyTypeValue[] = [
'time_penalty',
'grid_penalty',
'points_deduction',
'license_points',
'fine',
'race_ban',
];
export function penaltyTypeRequiresValue(type: PenaltyTypeValue): boolean {
return PENALTY_TYPES_REQUIRING_VALUE.includes(type);
}
export class Penalty implements IEntity<string> {
private constructor(private readonly props: PenaltyProps) {}
@@ -73,10 +86,12 @@ export class Penalty implements IEntity<string> {
if (!props.reason?.trim()) throw new RacingDomainValidationError('Penalty reason is required');
if (!props.issuedBy) throw new RacingDomainValidationError('Penalty must be issued by a steward');
const penaltyType = PenaltyType.create(props.type);
// Validate value based on type
if (['time_penalty', 'grid_penalty', 'points_deduction', 'license_points', 'fine', 'race_ban'].includes(props.type)) {
if (penaltyTypeRequiresValue(penaltyType.toString())) {
if (props.value === undefined || props.value <= 0) {
throw new RacingDomainValidationError(`${props.type} requires a positive value`);
throw new RacingDomainValidationError(`${penaltyType.toString()} requires a positive value`);
}
}
@@ -85,7 +100,7 @@ export class Penalty implements IEntity<string> {
leagueId: LeagueId.create(props.leagueId),
raceId: RaceId.create(props.raceId),
driverId: DriverId.create(props.driverId),
type: PenaltyType.create(props.type),
type: penaltyType,
reason: PenaltyReason.create(props.reason),
issuedBy: StewardId.create(props.issuedBy),
status: PenaltyStatus.create(props.status || 'pending'),

View File

@@ -11,23 +11,44 @@ export type PenaltyTypeValue =
| 'fine'
| 'race_ban';
export const PENALTY_TYPE_VALUES: PenaltyTypeValue[] = [
'time_penalty',
'grid_penalty',
'points_deduction',
'disqualification',
'warning',
'license_points',
'probation',
'fine',
'race_ban',
];
export type PenaltyValueKind = 'seconds' | 'grid_positions' | 'points' | 'races' | 'none';
export function getPenaltyValueKind(type: PenaltyTypeValue): PenaltyValueKind {
switch (type) {
case 'time_penalty':
return 'seconds';
case 'grid_penalty':
return 'grid_positions';
case 'points_deduction':
case 'license_points':
case 'fine':
return 'points';
case 'race_ban':
return 'races';
case 'disqualification':
case 'warning':
case 'probation':
return 'none';
}
}
export class PenaltyType {
private constructor(private readonly value: PenaltyTypeValue) {}
static create(value: string): PenaltyType {
const validTypes: PenaltyTypeValue[] = [
'time_penalty',
'grid_penalty',
'points_deduction',
'disqualification',
'warning',
'license_points',
'probation',
'fine',
'race_ban',
];
if (!validTypes.includes(value as PenaltyTypeValue)) {
if (!PENALTY_TYPE_VALUES.includes(value as PenaltyTypeValue)) {
throw new RacingDomainValidationError(`Invalid penalty type: ${value}`);
}

View File

@@ -10,6 +10,14 @@ export type LeagueScoringPresetPrimaryChampionshipType =
| 'nations'
| 'trophy';
export interface LeagueScoringPresetTimingDefaults {
practiceMinutes: number;
qualifyingMinutes: number;
sprintRaceMinutes: number;
mainRaceMinutes: number;
sessionCount: number;
}
export interface LeagueScoringPreset {
id: string;
name: string;
@@ -18,4 +26,5 @@ export interface LeagueScoringPreset {
dropPolicySummary: string;
sessionSummary: string;
bonusSummary: string;
defaultTimings: LeagueScoringPresetTimingDefaults;
}