This commit is contained in:
2025-12-12 15:20:17 +01:00
parent 2cd3bfbb47
commit ddbd99b747
4 changed files with 16 additions and 7 deletions

View File

@@ -9,10 +9,11 @@ import { RacingDomainValidationError } from '../errors/RacingDomainError';
import type { IEntity } from '@gridpilot/shared/domain';
/**
* Stewarding decision mode for protests
*/
* Stewarding decision mode for protests
*/
export type StewardingDecisionMode =
| 'admin_only' // Only admins can decide
| 'steward_decides' // Single steward makes decision
| 'steward_vote' // X stewards must vote to uphold
| 'member_vote' // X members must vote to uphold
| 'steward_veto' // Upheld unless X stewards vote against

View File

@@ -72,7 +72,7 @@ export class Season implements IEntity<string> {
order?: number;
status?: SeasonStatus;
startDate?: Date;
endDate?: Date;
endDate?: Date | undefined;
schedule?: SeasonSchedule;
scoringConfig?: SeasonScoringConfig;
dropPolicy?: SeasonDropPolicy;

View File

@@ -4,7 +4,7 @@ import type { StewardingDecisionMode } from '../entities/League';
export interface SeasonStewardingConfigProps {
decisionMode: StewardingDecisionMode;
requiredVotes?: number;
requiredVotes?: number | undefined;
requireDefense: boolean;
defenseTimeLimit: number;
voteTimeLimit: number;
@@ -54,6 +54,17 @@ export class SeasonStewardingConfig
);
}
// For non-voting modes, requiredVotes should not be provided
if (props.decisionMode !== 'steward_vote' &&
props.decisionMode !== 'member_vote' &&
props.decisionMode !== 'steward_veto' &&
props.decisionMode !== 'member_veto' &&
props.requiredVotes !== undefined) {
throw new RacingDomainValidationError(
'SeasonStewardingConfig.requiredVotes should only be provided for voting/veto modes',
);
}
if (!Number.isInteger(props.defenseTimeLimit) || props.defenseTimeLimit < 0) {
throw new RacingDomainValidationError(
'SeasonStewardingConfig.defenseTimeLimit must be a non-negative integer (hours)',

View File

@@ -253,7 +253,6 @@ describe('SeasonScoringConfig', () => {
expect(
() =>
new SeasonScoringConfig({
// @ts-expect-error intentional invalid input
scoringPresetId: ' ',
}),
).toThrow(RacingDomainValidationError);
@@ -395,8 +394,6 @@ describe('SeasonStewardingConfig', () => {
() =>
new SeasonStewardingConfig({
decisionMode: mode,
// @ts-expect-error intentional invalid
requiredVotes: undefined,
requireDefense: true,
defenseTimeLimit: 24,
voteTimeLimit: 24,