import { ok, err, type CommandContext } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { DuplicateCodeError, MissingRequiredFieldError, InvalidUomError, } from "../lib/errors.generated"; import type { PrimitivesQueries } from "../module"; export interface CreateProductInput { code: string; name: string; description?: string; unitId: string; } /** * Function: createProduct * * Creates a new product in DRAFT status with a unique code. */ export async function run>( db: Transaction, input: CreateProductInput & CF, ctx: CommandContext, primitivesQueries: Pick, ) { const { code, name, description, unitId, ...customFields } = input; // Validate required fields if (!code?.trim()) { return err(new MissingRequiredFieldError("code")); } if (!name?.trim()) { return err(new MissingRequiredFieldError("name")); } // Check code uniqueness const existingCode = await db .selectFrom("Product") .select("id") .where("code", "=", code) .forUpdate() .executeTakeFirst(); if (existingCode) { return err(new DuplicateCodeError(code)); } // Validate UoM const unitResult = await primitivesQueries.getUnit(db, { id: unitId }, ctx); if (!unitResult.ok) return err(new InvalidUomError(unitId)); if (unitResult.value.unit?.status !== "ACTIVE") { return err(new InvalidUomError(unitId)); } // Create product const product = await db .insertInto("Product") .values({ ...(customFields as Record), code, name, description: description ?? null, unitId, status: "DRAFT", }) .returningAll() .executeTakeFirstOrThrow(); return ok({ product }); }