Skip to content

Catalog Domain

The catalog domain provides product and category management for TypeScript backends. It handles product creation, publishing lifecycle, variant management with SKU validation, pricing, and category hierarchies.

Terminal window
npx @backcap/cli add catalog

The Product entity is the aggregate root. It owns its variants and enforces business rules (no duplicate SKUs, state machine transitions).

import { Product } from "./domains/catalog/domain/entities/product.entity";
const result = Product.create({
id: crypto.randomUUID(),
name: "Wireless Headphones",
description: "Premium wireless headphones with noise cancellation",
basePriceCents: 9999,
});
if (result.isOk()) {
const product = result.unwrap();
console.log(product.status.value); // "draft"
console.log(product.basePrice.cents); // 9999
}
FieldTypeDescription
idstringUnique identifier (UUID)
namestringProduct name
descriptionstringProduct description
statusProductStatusdraft, active, or archived
basePriceMoneyBase price in integer cents
categoryIdstring | nullOptional category reference
variantsProductVariant[]Product variants

Products follow a strict state machine:

  • draftactive via product.publish()
  • activearchived via product.archive()
  • No reverse transitions
import { ProductVariant } from "./domains/catalog/domain/entities/product-variant.entity";
const variant = ProductVariant.create({
id: crypto.randomUUID(),
productId: "prod-123",
sku: "WH-BLK-L",
priceCents: 10999,
attributes: { color: "black", size: "L" },
});

Categories support hierarchy via flat parentId references.

import { Category } from "./domains/catalog/domain/entities/category.entity";
const category = Category.create({
id: crypto.randomUUID(),
name: "Electronics",
slug: "electronics",
parentId: null, // root category
});
VODescription
SKUValidated alphanumeric format (3-50 chars), auto-uppercased
MoneyInteger cents with ISO 4217 currency, add(), subtract(), multiply()
ProductStatusEnum: draft, active, archived with state machine
Use CaseDescription
CreateProductCreate a new draft product
PublishProductTransition product from draft to active
AddVariantAdd a variant with SKU validation
UpdatePriceUpdate product base price
ListProductsList all products
GetProductGet a single product by ID
CreateCategoryCreate a category with unique slug
ListByCategoryList products in a category
import { createCatalogService } from "./domains/catalog/contracts";
import type { ICatalogService } from "./domains/catalog/contracts";
const catalog: ICatalogService = createCatalogService({
productRepository,
categoryRepository,
});
// Create a product
const result = await catalog.createProduct({
name: "Widget",
description: "A great widget",
basePriceCents: 1999,
});