import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { WorkScheduleNotFoundError, InvalidEffectiveDateError, WorkScheduleAlreadyClosedError, } from "../lib/errors.generated"; export interface EndWorkScheduleInput { assignmentId: string; effectiveEnd: Date; } /** * Function: run * Description: Closes the current open 所定 (WorkSchedule) generation for an * Assignment (e.g. on assignment end or termination) by setting its * effectiveEnd. Does not create a replacement generation — that is * updateWorkSchedule's responsibility. */ export async function run(db: Transaction, input: EndWorkScheduleInput, _ctx: CommandContext) { const { assignmentId, effectiveEnd } = input; const current = await db .selectFrom("WorkSchedule") .selectAll() .where("assignmentId", "=", assignmentId) .orderBy("effectiveStart", "desc") .limit(1) .forUpdate() .executeTakeFirst(); if (!current) return err(new WorkScheduleNotFoundError(assignmentId)); if (current.effectiveEnd !== null) return err(new WorkScheduleAlreadyClosedError(assignmentId)); if (effectiveEnd < current.effectiveStart) { return err(new InvalidEffectiveDateError(assignmentId)); } const updated = await db .updateTable("WorkSchedule") .set({ effectiveEnd }) .where("id", "=", current.id) .returningAll() .executeTakeFirstOrThrow(); return ok({ workSchedule: updated }); }