import type { ValueObject } from '@core/shared/domain/ValueObject'; import { RacingDomainValidationError } from '../errors/RacingDomainError'; import type { Weekday } from '../types/Weekday'; import { ALL_WEEKDAYS } from '../types/Weekday'; export interface MonthlyRecurrencePatternProps { ordinal: 1 | 2 | 3 | 4; weekday: Weekday; } export class MonthlyRecurrencePattern implements ValueObject { readonly ordinal: 1 | 2 | 3 | 4; readonly weekday: Weekday; private constructor(ordinal: 1 | 2 | 3 | 4, weekday: Weekday) { this.ordinal = ordinal; this.weekday = weekday; } static create(ordinal: 1 | 2 | 3 | 4, weekday: Weekday): MonthlyRecurrencePattern { if (!ordinal || ordinal < 1 || ordinal > 4) { throw new RacingDomainValidationError('MonthlyRecurrencePattern ordinal must be between 1 and 4'); } if (!weekday || !ALL_WEEKDAYS.includes(weekday)) { throw new RacingDomainValidationError('MonthlyRecurrencePattern weekday must be a valid weekday'); } return new MonthlyRecurrencePattern(ordinal, weekday); } /** * Get the ordinal suffix (1st, 2nd, 3rd, 4th) */ getOrdinalSuffix(): string { switch (this.ordinal) { case 1: return '1st'; case 2: return '2nd'; case 3: return '3rd'; case 4: return '4th'; } } /** * Get description of the pattern */ getDescription(): string { return `${this.getOrdinalSuffix()} ${this.weekday} of the month`; } get props(): MonthlyRecurrencePatternProps { return { ordinal: this.ordinal, weekday: this.weekday, }; } equals(other: ValueObject): boolean { const a = this.props; const b = other.props; return a.ordinal === b.ordinal && a.weekday === b.weekday; } }