export interface LeagueScheduleDTO { leagueId: string; seasonId: string; races: Array<{ id: string; name: string; scheduledTime: Date; trackId: string; status: string; }>; } export interface LeagueSchedulePreviewDTO { leagueId: string; preview: Array<{ id: string; name: string; scheduledTime: Date; trackId: string; }>; } export type SeasonScheduleConfigDTO = { seasonStartDate: string; recurrenceStrategy: 'weekly' | 'everyNWeeks' | 'monthlyNthWeekday'; weekdays?: string[]; raceStartTime: string; timezoneId: string; plannedRounds: number; intervalWeeks?: number; monthlyOrdinal?: 1 | 2 | 3 | 4; monthlyWeekday?: string; }; import { SeasonSchedule } from '../../domain/value-objects/SeasonSchedule'; import { RaceTimeOfDay } from '../../domain/value-objects/RaceTimeOfDay'; import { LeagueTimezone } from '../../domain/value-objects/LeagueTimezone'; import { RecurrenceStrategyFactory } from '../../domain/value-objects/RecurrenceStrategy'; import { WeekdaySet } from '../../domain/value-objects/WeekdaySet'; import { MonthlyRecurrencePattern } from '../../domain/value-objects/MonthlyRecurrencePattern'; import { ALL_WEEKDAYS, type Weekday } from '../../domain/types/Weekday'; function toWeekdaySet(values: string[] | undefined): WeekdaySet { const weekdays = (values ?? []).filter((v): v is Weekday => ALL_WEEKDAYS.includes(v as Weekday), ); return WeekdaySet.fromArray(weekdays.length > 0 ? weekdays : ['Mon']); } export function scheduleDTOToSeasonSchedule(dto: SeasonScheduleConfigDTO): SeasonSchedule { const startDate = new Date(dto.seasonStartDate); const timeOfDay = RaceTimeOfDay.fromString(dto.raceStartTime); const timezone = LeagueTimezone.create(dto.timezoneId); const recurrence = (() => { switch (dto.recurrenceStrategy) { case 'everyNWeeks': return RecurrenceStrategyFactory.everyNWeeks( dto.intervalWeeks ?? 2, toWeekdaySet(dto.weekdays), ); case 'monthlyNthWeekday': { const pattern = MonthlyRecurrencePattern.create( dto.monthlyOrdinal ?? 1, ((dto.monthlyWeekday ?? 'Mon') as Weekday), ); return RecurrenceStrategyFactory.monthlyNthWeekday(pattern); } case 'weekly': default: return RecurrenceStrategyFactory.weekly(toWeekdaySet(dto.weekdays)); } })(); return new SeasonSchedule({ startDate, timeOfDay, timezone, recurrence, plannedRounds: dto.plannedRounds, }); }