/** * Schedule-X calendar configuration factory. * * Week-start-day translation: * Project convention: WEEK_START_DAY = 0 (Sunday, JS/date-fns convention) * Schedule-X v4: firstDayOfWeek = 7 (Sunday, Temporal convention) * * Passing 0 to Schedule-X silently defaults to Monday. The constant * WEEK_START_DAY === 0 ? 7 translation below encodes this as the source of * truth so the pitfall cannot recur. * * calendarId routing contract (must align with hydrateEvents.ts): * Shared-family calendar → key 'shared' * Per-member calendars → key String(userId) (NOT String(db calendarId)) * * Source: https://schedule-x.dev/docs/calendar/configuration * Source: https://schedule-x.dev/docs/calendar/calendars */ import { deriveScheduleXColors } from './colorUtils.js' /** Week start day in JS/date-fns convention: 0 = Sunday. */ export const WEEK_START_DAY = 0 /** * firstDayOfWeek in Schedule-X/Temporal convention: 7 = Sunday, 1 = Monday. * * Translation: WEEK_START_DAY === 0 (JS Sunday) → 7 (Temporal Sunday). * Hard-code to the project convention; one edit here when the user wants Monday. */ export const SX_FIRST_DAY_OF_WEEK: number = WEEK_START_DAY === 0 ? 7 : WEEK_START_DAY /** * Per-member calendar config entry passed to buildCalendarConfig. * * id = String(users.id) — the Schedule-X calendars config key * name = users.displayName * color = users.color hex */ export interface MemberCalendarConfig { id: string // String(users.id) name: string // users.displayName color: string // hex from users.color } export interface ScheduleXCalendarEntry { colorName: string lightColors: { main: string container: string onContainer: string } } export interface CalendarConfig { firstDayOfWeek: number calendars: Record } /** * Build the Schedule-X calendars configuration object. * * Always includes a 'shared' entry (rose #F25C7A). * Adds one entry per member, keyed by String(userId). * * The keys here are the routing contract: hydrateEvents() must produce * calendarId values that exactly match these keys: * isShared:true → 'shared' * isShared:false → String(ownerUserId) (NOT String(db calendarId)) */ export function buildCalendarConfig(members: MemberCalendarConfig[]): CalendarConfig { const calendars: Record = {} // Shared-family calendar: reserved rose color, confirmed by user calendars['shared'] = { colorName: 'shared', lightColors: deriveScheduleXColors('#F25C7A'), } // Per-member calendars keyed by String(userId) for (const m of members) { calendars[m.id] = { colorName: `member-${m.id}`, lightColors: deriveScheduleXColors(m.color), } } return { firstDayOfWeek: SX_FIRST_DAY_OF_WEEK, // 7 = Sunday in Temporal convention calendars, } }