Files
gridpilot.gg/core/racing/domain/value-objects/MaxParticipants.ts
2026-01-16 16:46:57 +01:00

97 lines
2.4 KiB
TypeScript

/**
* Domain Value Object: MaxParticipants
*
* Represents the maximum number of participants allowed in a league or race.
* Enforces reasonable limits and constraints.
*/
import type { ValueObject } from '@core/shared/domain/ValueObject';
import { RacingDomainValidationError } from '../errors/RacingDomainError';
export interface MaxParticipantsProps {
value: number;
}
export class MaxParticipants implements ValueObject<MaxParticipantsProps> {
readonly value: number;
private constructor(value: number) {
this.value = value;
}
static create(value: number): MaxParticipants {
if (!Number.isInteger(value) || value <= 0) {
throw new RacingDomainValidationError('Max participants must be a positive integer');
}
// Enforce reasonable upper limit to prevent system abuse
if (value > 100) {
throw new RacingDomainValidationError('Max participants cannot exceed 100');
}
return new MaxParticipants(value);
}
/**
* Validate that max participants meets minimum requirements for ranked leagues
*/
validateForRankedLeague(): { valid: boolean; error?: string } {
if (this.value < 10) {
return {
valid: false,
error: 'Ranked leagues must allow at least 10 participants'
};
}
return { valid: true };
}
/**
* Validate that max participants meets minimum requirements for unranked leagues
*/
validateForUnrankedLeague(): { valid: boolean; error?: string } {
if (this.value < 2) {
return {
valid: false,
error: 'Unranked leagues must allow at least 2 participants'
};
}
return { valid: true };
}
/**
* Check if max participants is sufficient for the given participant count
*/
canAccommodate(participantCount: number): boolean {
return participantCount <= this.value;
}
/**
* Check if max participants is at least the given minimum
*/
isAtLeast(min: number): boolean {
return this.value >= min;
}
/**
* Check if max participants is exactly the given value
*/
isExactly(value: number): boolean {
return this.value === value;
}
get props(): MaxParticipantsProps {
return { value: this.value };
}
equals(other: ValueObject<MaxParticipantsProps>): boolean {
return this.value === other.props.value;
}
toString(): string {
return this.value.toString();
}
toNumber(): number {
return this.value;
}
}