import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { DuplicateHolidayDateError, InvalidHolidayKindError } from "../lib/errors.generated"; const HOLIDAY_KINDS = ["STATUTORY", "PRESCRIBED"] as const; export interface CreateCompanyHolidayInput { calendarId: string; holidayDate: Date; holidayKind: string; name: string; } /** * Function: createCompanyHoliday * Description: Registers a new dated holiday fact — a calendar, a date, its * holidayKind, and a name — in a HolidayCalendar. This is the data-driven * replacement for the legacy hardcoded holiday list. holidayDate is unique * per calendar, so the same date can be a holiday in one calendar and a * working day in another. */ export async function run(db: Transaction, input: CreateCompanyHolidayInput, _ctx: CommandContext) { const existing = await db .selectFrom("CompanyHoliday") .selectAll() .where("calendarId", "=", input.calendarId) .where("holidayDate", "=", input.holidayDate) .forUpdate() .executeTakeFirst(); if (existing) { return err( new DuplicateHolidayDateError(`${input.calendarId}:${input.holidayDate.toISOString()}`), ); } if (!(HOLIDAY_KINDS as readonly string[]).includes(input.holidayKind)) { return err(new InvalidHolidayKindError(input.holidayKind)); } const companyHoliday = await db .insertInto("CompanyHoliday") .values({ calendarId: input.calendarId, holidayDate: input.holidayDate, holidayKind: input.holidayKind as (typeof HOLIDAY_KINDS)[number], name: input.name, }) .returningAll() .executeTakeFirstOrThrow(); return ok({ companyHoliday }); }