import { ok, err } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { InvalidCodeError, InvalidNameError, CompanyNotFoundError, DuplicateCodeError, ParentNotFoundError, } from "../lib/errors.generated"; export interface CreateDepartmentInput { code: string; name: string; companyId: string; parentDepartmentId?: string; } /** * Function: createDepartment * * Creates a new department within a company, optionally nested under * an existing parent department in the same company. */ export async function run>( db: Transaction, input: CreateDepartmentInput & CF, ) { const { code, name, companyId, parentDepartmentId, ...customFields } = input; // 1. Validate code non-empty if (!code?.trim()) { return err(new InvalidCodeError(code)); } // 2. Validate name non-empty if (!name?.trim()) { return err(new InvalidNameError(name)); } // 3. Find company by companyId const company = await db .selectFrom("Company") .selectAll() .where("id", "=", companyId) .executeTakeFirst(); if (!company) { return err(new CompanyNotFoundError(companyId)); } // 4. Check code uniqueness in company const existingDepartment = await db .selectFrom("Department") .selectAll() .where("code", "=", code) .where("companyId", "=", companyId) .forUpdate() .executeTakeFirst(); if (existingDepartment) { return err(new DuplicateCodeError(code)); } // 5. If parentDepartmentId provided, validate parent if (parentDepartmentId) { const parent = await db .selectFrom("Department") .selectAll() .where("id", "=", parentDepartmentId) .executeTakeFirst(); if (!parent) { return err(new ParentNotFoundError(parentDepartmentId)); } if (parent.companyId !== companyId) { return err(new ParentNotFoundError(parentDepartmentId)); } } // 6. Insert with status ACTIVE const department = await db .insertInto("Department") .values({ ...(customFields as Record), code, name, companyId, parentDepartmentId: parentDepartmentId ?? null, status: "ACTIVE", }) .returningAll() .executeTakeFirstOrThrow(); return ok({ department }); }