import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import { workCenterLifecycle } from "../db/workCenter.lifecycle.generated"; import type { Transaction } from "../generated/kysely-tailordb"; import { WorkCenterNotFoundError, WorkCenterNotDeactivatableError, WorkCenterInUseError, } from "../lib/errors.generated"; export interface DeactivateWorkCenterInput { id: string; } /** * Function: deactivateWorkCenter * * Removes a work center from future routing and release selection. * Preserves historical work-order and cost records while blocking * new execution use. */ export async function run(db: Transaction, input: DeactivateWorkCenterInput, _ctx: CommandContext) { const { id } = input; // 1. Fetch work center with lock const workCenter = await db .selectFrom("WorkCenter") .selectAll() .where("id", "=", id) .forUpdate() .executeTakeFirst(); if (!workCenter) { return err(new WorkCenterNotFoundError(id)); } // 2. Validate status is deactivatable const nextStatus = workCenterLifecycle.tryTransition(workCenter.status, "deactivate"); if (!nextStatus) { return err(new WorkCenterNotDeactivatableError(workCenter.code)); } // 3. Check for blocking dependencies — active routings that reference this work center const activeRoutingDependency = await db .selectFrom("RoutingOperation") .innerJoin("Routing", "Routing.id", "RoutingOperation.routingId") .select("RoutingOperation.id") .where("RoutingOperation.workCenterId", "=", id) .where("Routing.status", "=", "ACTIVE") .executeTakeFirst(); if (activeRoutingDependency) { return err(new WorkCenterInUseError(workCenter.code)); } // 4. Check for open work orders that still reference this work center const openWorkOrder = await db .selectFrom("WorkOrder") .select("WorkOrder.id") .where("WorkOrder.workCenterId", "=", id) .where("WorkOrder.status", "in", ["PENDING", "IN_PROGRESS", "PAUSED"]) .executeTakeFirst(); if (openWorkOrder) { return err(new WorkCenterInUseError(workCenter.code)); } // 5. Set status to INACTIVE const updatedWorkCenter = await db .updateTable("WorkCenter") .set({ status: nextStatus, }) .where("id", "=", id) .returningAll() .executeTakeFirstOrThrow(); return ok({ workCenter: updatedWorkCenter }); }