import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import { workOrderLifecycle } from "../db/workOrder.lifecycle.generated"; import type { Transaction } from "../generated/kysely-tailordb"; import { WorkOrderNotFoundError, WorkOrderNotPausableError, PauseReasonRequiredError, } from "../lib/errors.generated"; export interface PauseWorkOrderInput { id: string; pauseReason: string; } /** * Function: pauseWorkOrder * * Temporarily halts an in-progress work order and records the reason for * the interruption. Preserves accumulated execution history so the work * order can later resume. */ export async function run(db: Transaction, input: PauseWorkOrderInput, _ctx: CommandContext) { const { id, pauseReason } = input; // 1. Validate pause reason is provided if (!pauseReason || pauseReason.trim() === "") { return err(new PauseReasonRequiredError(id)); } // 2. Fetch work order with lock const workOrder = await db .selectFrom("WorkOrder") .selectAll() .where("id", "=", id) .forUpdate() .executeTakeFirst(); if (!workOrder) { return err(new WorkOrderNotFoundError(id)); } // 3. Validate status is IN_PROGRESS const nextStatus = workOrderLifecycle.tryTransition(workOrder.status, "pause"); if (!nextStatus) { return err(new WorkOrderNotPausableError(id)); } // 4. Record pause event and set PAUSED const now = new Date(); const updatedWorkOrder = await db .updateTable("WorkOrder") .set({ status: nextStatus, pauseReason, }) .where("id", "=", id) .returningAll() .executeTakeFirstOrThrow(); // 5. Create PAUSED execution event await db .insertInto("WorkOrderExecutionEvent") .values({ workOrderId: id, eventType: "PAUSED", timestamp: now, quantity: null, timeValue: null, scrapValue: null, notes: pauseReason, }) .execute(); return ok({ workOrder: updatedWorkOrder }); }