/** * Domain Entity: League * * Represents a league in the GridPilot platform. * Immutable entity with factory methods and domain validation. */ export interface LeagueSettings { pointsSystem: 'f1-2024' | 'indycar' | 'custom'; sessionDuration?: number; qualifyingFormat?: 'single-lap' | 'open'; customPoints?: Record; } export class League { readonly id: string; readonly name: string; readonly description: string; readonly ownerId: string; readonly settings: LeagueSettings; readonly createdAt: Date; private constructor(props: { id: string; name: string; description: string; ownerId: string; settings: LeagueSettings; createdAt: Date; }) { this.id = props.id; this.name = props.name; this.description = props.description; this.ownerId = props.ownerId; this.settings = props.settings; this.createdAt = props.createdAt; } /** * Factory method to create a new League entity */ static create(props: { id: string; name: string; description: string; ownerId: string; settings?: Partial; createdAt?: Date; }): League { this.validate(props); const defaultSettings: LeagueSettings = { pointsSystem: 'f1-2024', sessionDuration: 60, qualifyingFormat: 'open', }; return new League({ id: props.id, name: props.name, description: props.description, ownerId: props.ownerId, settings: { ...defaultSettings, ...props.settings }, createdAt: props.createdAt ?? new Date(), }); } /** * Domain validation logic */ private static validate(props: { id: string; name: string; description: string; ownerId: string; }): void { if (!props.id || props.id.trim().length === 0) { throw new Error('League ID is required'); } if (!props.name || props.name.trim().length === 0) { throw new Error('League name is required'); } if (props.name.length > 100) { throw new Error('League name must be 100 characters or less'); } if (!props.description || props.description.trim().length === 0) { throw new Error('League description is required'); } if (!props.ownerId || props.ownerId.trim().length === 0) { throw new Error('League owner ID is required'); } } /** * Create a copy with updated properties */ update(props: Partial<{ name: string; description: string; settings: LeagueSettings; }>): League { return new League({ id: this.id, name: props.name ?? this.name, description: props.description ?? this.description, ownerId: this.ownerId, settings: props.settings ?? this.settings, createdAt: this.createdAt, }); } }