import { ok, err } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { NodeHasAssignmentsError, NodeHasChildrenError, NodeNotFoundError, } from "../lib/errors.generated"; export interface DeleteTaxonomyNodeInput { id: string; } /** * Function: deleteTaxonomyNode * * Permanently removes a leaf taxonomy node with no item assignments. * The node's code becomes available for reuse. */ export async function run(db: Transaction, input: DeleteTaxonomyNodeInput) { const { id } = input; // 1. Check node exists (read-then-delete — lock) const node = await db .selectFrom("TaxonomyNode") .selectAll() .where("id", "=", id) .forUpdate() .executeTakeFirst(); if (!node) { return err(new NodeNotFoundError(id)); } // 2. Check no children (validation only — no lock) const children = await db .selectFrom("TaxonomyNode") .selectAll() .where("parentId", "=", id) .execute(); if (children.length > 0) { return err(new NodeHasChildrenError(id)); } // 3. Check no item assignments (validation only — no lock) const assignments = await db .selectFrom("ItemTaxonomyAssignment") .selectAll() .where("taxonomyNodeId", "=", id) .execute(); if (assignments.length > 0) { return err(new NodeHasAssignmentsError(id)); } // 4. Delete node await db.deleteFrom("TaxonomyNode").where("id", "=", id).execute(); return ok({ success: true as const }); }