import { type EmptyFields } from "@tailor-platform/erp-kit/core"; import { type TailorAnyDBField } from "@tailor-platform/sdk"; import type { TailorDBInsertable } from "@tailor-platform/sdk/kysely"; import type { ItemManagementModule } from "../item-management"; import type { PrimitivesModule } from "../primitives"; import { activateProduct } from "./command/activateProduct.generated"; import { assignAttributeValueToProduct } from "./command/assignAttributeValueToProduct.generated"; import { assignProductToCategory } from "./command/assignProductToCategory.generated"; import { createProduct } from "./command/createProduct.generated"; import { createProductAttribute } from "./command/createProductAttribute.generated"; import { createProductAttributeValue } from "./command/createProductAttributeValue.generated"; import { createProductCategory } from "./command/createProductCategory.generated"; import { deactivateProduct } from "./command/deactivateProduct.generated"; import { deleteProduct } from "./command/deleteProduct.generated"; import { deleteProductAttribute } from "./command/deleteProductAttribute.generated"; import { deleteProductAttributeValue } from "./command/deleteProductAttributeValue.generated"; import { deleteProductCategory } from "./command/deleteProductCategory.generated"; import { generateVariants } from "./command/generateVariants.generated"; import { moveProductCategory } from "./command/moveProductCategory.generated"; import { reactivateProduct } from "./command/reactivateProduct.generated"; import { removeAttributeValueFromProduct } from "./command/removeAttributeValueFromProduct.generated"; import { removeProductFromCategory } from "./command/removeProductFromCategory.generated"; import { updateProduct } from "./command/updateProduct.generated"; import { updateProductAttribute } from "./command/updateProductAttribute.generated"; import { updateProductAttributeValue } from "./command/updateProductAttributeValue.generated"; import { updateProductCategory } from "./command/updateProductCategory.generated"; import { createProductType, type CreateProductTypeParams } from "./db/product"; import { createProductAttributeType, type CreateProductAttributeTypeParams, } from "./db/productAttribute"; import { createProductAttributeAssignmentType, type CreateProductAttributeAssignmentTypeParams, } from "./db/productAttributeAssignment"; import { createProductAttributeValueType, type CreateProductAttributeValueTypeParams, } from "./db/productAttributeValue"; import { createProductCategoryType, type CreateProductCategoryTypeParams, } from "./db/productCategory"; import { createProductCategoryAssignmentType, type CreateProductCategoryAssignmentTypeParams, } from "./db/productCategoryAssignment"; import { createProductVariantType, type CreateProductVariantTypeParams } from "./db/productVariant"; import { calculateCategoryDepth } from "./query/calculateCategoryDepth.generated"; import { detectCategoryCircularReference } from "./query/detectCategoryCircularReference.generated"; import { getProduct } from "./query/getProduct.generated"; import { getProductAttribute } from "./query/getProductAttribute.generated"; import { getProductAttributeAssignment } from "./query/getProductAttributeAssignment.generated"; import { getProductAttributeValue } from "./query/getProductAttributeValue.generated"; import { getProductCategory } from "./query/getProductCategory.generated"; import { getProductCategoryAssignment } from "./query/getProductCategoryAssignment.generated"; import { getProductVariant } from "./query/getProductVariant.generated"; import { listAttributeAssignmentsByAttribute } from "./query/listAttributeAssignmentsByAttribute.generated"; import { listCategoryAssignmentsByProduct } from "./query/listCategoryAssignmentsByProduct.generated"; import { listProductAttributeAssignments } from "./query/listProductAttributeAssignments.generated"; import { listProductAttributeValues } from "./query/listProductAttributeValues.generated"; import { listProductCategoryAssignments } from "./query/listProductCategoryAssignments.generated"; import { listProductCategoryChildren } from "./query/listProductCategoryChildren.generated"; import { listProductVariants } from "./query/listProductVariants.generated"; type PrimitivesDB = PrimitivesModule["db"]; export type PrimitivesQueries = PrimitivesModule["queries"]; type ItemManagementDB = ItemManagementModule["db"]; export type ItemManagementCommands = ItemManagementModule["commands"]; export type SkuStrategy = ( productCode: string, axisValues: string[], currentVariantCount: number, axisLabels?: string[], ) => string; const DEFAULT_MAX_DEPTH = 10; const defaultSkuStrategy: SkuStrategy = (productCode, _axisValues, currentVariantCount) => { const seq = String(currentVariantCount + 1).padStart(3, "0"); return `${productCode}-${seq}`; }; export interface DefineModuleParams< PF extends Record, PAF extends Record, PAVF extends Record, PAAF extends Record, PCF extends Record, PCAF extends Record, PVF extends Record, > { product?: Omit, "unitType">; productAttribute?: CreateProductAttributeTypeParams; productAttributeValue?: CreateProductAttributeValueTypeParams; productAttributeAssignment?: CreateProductAttributeAssignmentTypeParams; productCategory?: CreateProductCategoryTypeParams; productCategoryAssignment?: CreateProductCategoryAssignmentTypeParams; productVariant?: Omit, "itemType">; categoryTree?: { maxDepth?: number }; skuStrategy?: SkuStrategy; primitives: { db: { unit: PrimitivesDB["unit"] }; queries: { getUnit: PrimitivesQueries["getUnit"] }; }; itemManagement: { db: { item: ItemManagementDB["item"] }; commands: { createItem: ItemManagementCommands["createItem"] }; }; } /* @__NO_SIDE_EFFECTS__ */ export const defineModule = < const PF extends Record = EmptyFields, const PAF extends Record = EmptyFields, const PAVF extends Record = EmptyFields, const PAAF extends Record = EmptyFields, const PCF extends Record = EmptyFields, const PCAF extends Record = EmptyFields, const PVF extends Record = EmptyFields, >( params: DefineModuleParams, ) => { const product = createProductType({ ...params.product, unitType: params.primitives.db.unit, }); const productAttributeDb = createProductAttributeType(params.productAttribute ?? {}); const productAttributeValueDb = createProductAttributeValueType( params.productAttributeValue ?? {}, ); const productAttributeAssignmentDb = createProductAttributeAssignmentType( params.productAttributeAssignment ?? {}, ); const productCategoryDb = createProductCategoryType(params.productCategory ?? {}); const productCategoryAssignmentDb = createProductCategoryAssignmentType( params.productCategoryAssignment ?? {}, ); const productVariantDb = createProductVariantType({ ...params.productVariant, itemType: params.itemManagement.db.item, }); const maxDepth = params.categoryTree?.maxDepth ?? DEFAULT_MAX_DEPTH; const skuStrategy = params.skuStrategy ?? defaultSkuStrategy; return { db: { product, productAttribute: productAttributeDb, productAttributeValue: productAttributeValueDb, productAttributeAssignment: productAttributeAssignmentDb, productCategory: productCategoryDb, productCategoryAssignment: productCategoryAssignmentDb, productVariant: productVariantDb, }, queries: { getProduct, getProductAttribute, getProductAttributeValue, getProductAttributeAssignment, getProductCategory, getProductCategoryAssignment, listProductAttributeAssignments, listAttributeAssignmentsByAttribute, listProductCategoryAssignments, listProductCategoryChildren, listProductVariants, getProductVariant, listCategoryAssignmentsByProduct, listProductAttributeValues, calculateCategoryDepth, detectCategoryCircularReference, }, commands: { createProduct: createProduct>(params.primitives.queries), updateProduct: updateProduct>(params.primitives.queries), activateProduct: activateProduct(), deactivateProduct: deactivateProduct(), reactivateProduct: reactivateProduct(), deleteProduct: deleteProduct(), createProductAttribute: createProductAttribute>(), updateProductAttribute: updateProductAttribute>(), deleteProductAttribute: deleteProductAttribute(), createProductAttributeValue: createProductAttributeValue(), updateProductAttributeValue: updateProductAttributeValue(), deleteProductAttributeValue: deleteProductAttributeValue(), createProductCategory: createProductCategory>({ maxDepth }), updateProductCategory: updateProductCategory>(), moveProductCategory: moveProductCategory({ maxDepth }), deleteProductCategory: deleteProductCategory(), assignProductToCategory: assignProductToCategory(), removeProductFromCategory: removeProductFromCategory(), assignAttributeValueToProduct: assignAttributeValueToProduct(), removeAttributeValueFromProduct: removeAttributeValueFromProduct(), generateVariants: generateVariants({ itemManagement: params.itemManagement.commands, skuStrategy, }), }, }; }; /** EmptyFields-instantiated alias — use instead of `ReturnType`, which widens field generics to their constraint. */ export type ProductManagementModule = ReturnType< typeof defineModule< EmptyFields, EmptyFields, EmptyFields, EmptyFields, EmptyFields, EmptyFields, EmptyFields > >;