models:
- name: Item
collection: items
description: "Canonical product/service identity (referenced as item_id across the ERP)"
fields:
id:
type: uuid
attributes: ["@id", "@default(uuid)"]
description: "Unique item identifier"
item_code:
type: string
attributes: ["@required", "@max(60)"]
description: "Stock keeping unit / kode barang"
name:
type: string
attributes: ["@required", "@max(200)"]
description: "Item name"
description:
type: string?
attributes: ["@max(2000)"]
description: "Long-form description"
barcode:
type: string?
attributes: ["@max(60)"]
description: "Primary barcode / EAN (unique when present)"
brand_id:
type: uuid?
attributes: ["@foreign_key(Brand.id)"]
description: "Brand / merek"
item_group_id:
type: uuid
attributes: ["@required", "@foreign_key(ItemGroup.id)"]
description: "Category (classification)"
default_uom_id:
type: uuid
attributes: ["@required", "@foreign_key(Uom.id)"]
description: "Stocking / base unit of measure"
item_type:
type: ItemType
attributes: ["@default(physical_good)"]
description: "Commerce / fulfillment kind (sell anything: goods, digital, service, …)"
is_sales_item:
type: bool
attributes: ["@default(true)"]
description: "May be sold (projected as SellableProduct)"
is_purchase_item:
type: bool
attributes: ["@default(true)"]
description: "May be purchased (projected as PurchasableItem)"
is_stock_item:
type: bool
attributes: ["@default(true)"]
description: "Tracked in inventory (projected as StockItem)"
has_variants:
type: bool
attributes: ["@default(false)"]
description: "Item is sold per variant SKU (see ItemVariant)"
hsn_code:
type: string?
attributes: ["@max(20)"]
description: "HS / kode barang for customs & tax classification"
sni:
type: string?
attributes: ["@max(30)"]
description: "Standar Nasional Indonesia (SNI) certification number"
is_taxable:
type: bool
attributes: ["@default(true)"]
description: "Subject to PPN (rate/mechanics live in the tax overlay)"
weight_per_unit:
type: decimal?
attributes: ["@precision(18,4)"]
description: "Weight of one default_uom unit"
shelf_life_days:
type: int?
attributes: ["@non_negative"]
description: "Shelf life in days (perishables)"
standard_cost:
type: decimal?
attributes: ["@precision(18,6)", "@non_negative"]
description: "Standard unit cost for margin calculation (nullable = cost unknown; never negative; selling snapshots this at order-confirm time)"
tags:
type: json
attributes: ["@default('[]')"]
description: "Search tags (array of strings)"
data:
type: json
attributes: ["@default('{}')"]
description: "Type-specific config bag (e.g. {duration_minutes} for service, {license} for digital)"
status:
type: CatalogStatus
attributes: ["@default(active)"]
description: "Lifecycle status"
metadata:
type: Metadata
attributes: ["@audit_metadata"]
description: "Audit metadata (created_at, updated_at, deleted_at, created_by, updated_by, deleted_by)"
relations:
item_group:
type: ItemGroup
attributes: ["@one", "@foreign_key(item_group_id)"]
description: "Category"
inverse: items
brand:
type: Brand?
attributes: ["@one", "@foreign_key(brand_id)"]
description: "Brand"
inverse: items
default_uom:
type: Uom
attributes: ["@one", "@foreign_key(default_uom_id)"]
description: "Base unit"
inverse: items
variants:
type: ItemVariant[]
attributes: ["@one_to_many"]
description: "Sellable variant SKUs (when has_variants)"
inverse: item
indexes:
enums:
- name: ItemType
description: "What kind of thing is being sold (commerce / fulfillment kind)"
variants:
- name: physical_good
description: "Tangible, shippable, stockable good (default)"
default: true
- name: digital_good
description: "Downloadable / license / virtual (no shipping, not stockable)"
- name: service
description: "Service / jasa performed (not stockable)"
- name: subscription
description: "Recurring access / membership (not stockable)"
- name: bundle
description: "Composite of other items (kit)"
- name: gift_card
description: "Stored-value gift card / voucher (not stockable)"
- name: rental
description: "Time-based use of a physical good"