export type SeasonStatus = 'planned' | 'active' | 'completed'; import { RacingDomainValidationError } from '../errors/RacingDomainError'; import type { IEntity } from '@gridpilot/shared/domain'; export class Season implements IEntity { readonly id: string; readonly leagueId: string; readonly gameId: string; readonly name: string; readonly year?: number; readonly order?: number; readonly status: SeasonStatus; readonly startDate?: Date; readonly endDate?: Date; private constructor(props: { id: string; leagueId: string; gameId: string; name: string; year?: number; order?: number; status: SeasonStatus; startDate?: Date; endDate?: Date; }) { this.id = props.id; this.leagueId = props.leagueId; this.gameId = props.gameId; this.name = props.name; this.year = props.year; this.order = props.order; this.status = props.status; this.startDate = props.startDate; this.endDate = props.endDate; } static create(props: { id: string; leagueId: string; gameId: string; name: string; year?: number; order?: number; status?: SeasonStatus; startDate?: Date; endDate?: Date; }): Season { if (!props.id || props.id.trim().length === 0) { throw new RacingDomainValidationError('Season ID is required'); } if (!props.leagueId || props.leagueId.trim().length === 0) { throw new RacingDomainValidationError('Season leagueId is required'); } if (!props.gameId || props.gameId.trim().length === 0) { throw new RacingDomainValidationError('Season gameId is required'); } if (!props.name || props.name.trim().length === 0) { throw new RacingDomainValidationError('Season name is required'); } const status: SeasonStatus = props.status ?? 'planned'; return new Season({ id: props.id, leagueId: props.leagueId, gameId: props.gameId, name: props.name, ...(props.year !== undefined ? { year: props.year } : {}), ...(props.order !== undefined ? { order: props.order } : {}), status, ...(props.startDate !== undefined ? { startDate: props.startDate } : {}), ...(props.endDate !== undefined ? { endDate: props.endDate } : {}), }); } /** * Domain rule: Wallet withdrawals are only allowed when season is completed */ canWithdrawFromWallet(): boolean { return this.status === 'completed'; } /** * Check if season is active */ isActive(): boolean { return this.status === 'active'; } /** * Check if season is completed */ isCompleted(): boolean { return this.status === 'completed'; } }