import { ok, err } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { ValueNotFoundError, ValueInUseError, AttributeNotFoundError, } from "../lib/errors.generated"; export interface DeleteProductAttributeValueInput { id: string; } /** * Function: deleteProductAttributeValue * * Deletes a value from an attribute if not in use on ACTIVE products. */ export async function run(db: Transaction, input: DeleteProductAttributeValueInput) { const { id } = input; const value = await db .selectFrom("ProductAttributeValue") .selectAll() .where("id", "=", id) .forUpdate() .executeTakeFirst(); if (!value) { return err(new ValueNotFoundError(id)); } // Data integrity check: verify parent attribute exists const attribute = await db .selectFrom("ProductAttribute") .select("id") .where("id", "=", value.attributeId) .executeTakeFirst(); if (!attribute) { return err(new AttributeNotFoundError(value.attributeId)); } // Check if value is in use on ACTIVE products // Find variants that include this value ID in their axisValueKey const activeVariantUsage = await db .selectFrom("ProductVariant") .innerJoin("Product", "Product.id", "ProductVariant.productId") .select("ProductVariant.id") .where("Product.status", "=", "ACTIVE") .where("ProductVariant.axisValueKey", "like", `%${id}%`) .executeTakeFirst(); if (activeVariantUsage) { return err(new ValueInUseError(id)); } // Remove attribute assignment references on DRAFT products const draftProducts = await db .selectFrom("Product") .select("id") .where("status", "=", "DRAFT") .execute(); const draftProductIds = draftProducts.map((p) => p.id); if (draftProductIds.length > 0) { await db .deleteFrom("ProductAttributeAssignment") .where("valueId", "=", id) .where("productId", "in", draftProductIds) .execute(); } // Delete the value await db.deleteFrom("ProductAttributeValue").where("id", "=", id).execute(); return ok({ id }); }