import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { AccrualPlanNotFoundError, PlanAlreadyRetiredError } from "../lib/errors.generated"; export interface RetireAccrualPlanInput { id: string; /** Retirement date set as effectiveEnd on the current open generation; defaults to today. */ effectiveEnd?: Date; } /** * Function: retireAccrualPlan * Description: Closes the current open generation of an AccrualPlan when * the plan is discontinued, preserving all prior generations so that past * grants remain historically explainable. */ export async function run(db: Transaction, input: RetireAccrualPlanInput, _ctx: CommandContext) { const { id } = input; const current = await db .selectFrom("AccrualPlan") .selectAll() .where("id", "=", id) .forUpdate() .executeTakeFirst(); if (!current) { return err(new AccrualPlanNotFoundError(id)); } if (current.effectiveEnd !== null) { return err(new PlanAlreadyRetiredError(id)); } const effectiveEnd = input.effectiveEnd ?? new Date(); const accrualPlan = await db .updateTable("AccrualPlan") .set({ effectiveEnd }) .where("id", "=", id) .returningAll() .executeTakeFirstOrThrow(); return ok({ accrualPlan }); }