Skip to main content
Version: v1.0.0(int)

BOM

Bill of Materials — recipes linking input materials and/or input SKUs (with quantities) to an output SKU. One BOM per output SKU.

Tables owned

TablePurpose
org.bomsBOM header. One row per output SKU that has a recipe defined.
org.bom_itemsComposition lines. Polymorphic input (material_id XOR input_sku_id) with quantity.

Operations

Writes

  • createBom(conn, { outputSkuId })Bom. Creates the BOM header for a SKU. Items added separately.
  • deleteBom(conn, bomId)void. Cascades to items.
  • replaceBomItems(conn, bomId, items)BomItem[]. Replaces the full composition atomically (delete-then-insert in a single statement). items: Array<{ materialId?, inputSkuId?, quantity }>.
  • addBomItem(conn, bomId, item)BomItem. Single-line append (used by editor incremental adds).
  • updateBomItem(conn, bomItemId, patch)BomItem. Edits quantity (input identity stays fixed).
  • removeBomItem(conn, bomItemId)void.

Reads

  • listBoms(conn)Bom[]. One row per output SKU with a BOM.
  • getBomById(conn, bomId)Bom | null.
  • getBomForSku(conn, outputSkuId)Bom | null. The standard lookup.
  • listBomItems(conn, bomId)BomItem[]. Composition for one BOM.
  • getBomsForSkus(conn, outputSkuIds)Map<skuId, Bom>. Batch hydration (used by WO creation snapshot workflow in L3).
  • getBomItemsForBoms(conn, bomIds)Map<bomId, BomItem[]>. Batch hydration paired with above.

Notes

  • BOMs are read by WorkOrders (at WO creation, to populate work_order_inputs snapshot) — but reads go through L3, which calls BOM.getBomForSku and then WorkOrders.createWorkOrderInputs. No direct cross-component calls.
  • The material_id XOR input_sku_id invariant is a DB check constraint, restated here for clarity.