/** * Domain Value Object: MaxParticipants * * Represents the maximum number of participants allowed in a league or race. * Enforces reasonable limits and constraints. */ import type { IValueObject } from '@core/shared/domain'; import { RacingDomainValidationError } from '../errors/RacingDomainError'; export interface MaxParticipantsProps { value: number; } export class MaxParticipants implements IValueObject { 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: IValueObject): boolean { return this.value === other.props.value; } toString(): string { return this.value.toString(); } toNumber(): number { return this.value; } }