Skip to content

Item Module

Status: Live. This module is built and running. The full engineering reference for what ships today — every route, service, and persistence detail — is kept at Item (Q2 2026). This page describes the module as currently designed; the reference-data lifecycle and version-pin behavior below are the design target the running system is converging on.

What the runtime actually holds — tables, DTOs, cross-module references and API surface as they exist today — is Item: Data Model. Where this page describes design ahead of the build, that page is the one that says what is stored.

An Item is the catalog entry for a kind of stock — the product or SKU that the operational parts of the system point at. Inventory items, kanban cards, and order lines all refer to an item; the item itself is reference data (a description of a kind of thing), not physical stock of it. The module is the single place a tenant defines what it buys, makes, stocks, and sells.

Every change to an item — a rename, a reclassification, an item supply added or edited — is recorded as a new version, and the full version history is kept. Other modules refer to an item in one of two ways: through a version pin, a reference to the item as of a specific version, or through a floating reference, read as the item is today. What a document shows depends on which it holds — a committed order line pins the item as it was ordered; a kanban card and a demand item float, and show the item as it is today.

Item sits at the bottom of the domain map: nearly every operational module depends on it, and it depends on one module itself. Clients sit to the left of the servers they depend on; every arrow is a dependency the client calls, and together they form a DAG.

PlantUML diagram

What this module consumes:

  • Business Affiliate — an item supply names its supplier by resolving (or creating on the fly) a vendor role there, and pins the vendor’s version. Introducing an item supply against a retired vendor is refused at this module’s own write.

What its clients consume from it:

  • Inventory Items — every inventory item and pool is classified by exactly one catalog item, and the item’s units-of-measure scheme gives them their exact quantity arithmetic.
  • Kanban Cards — each card represents an item through a floating reference, read as it is today.
  • Demand — a demand item produces a quantity of an item; creating a direct demand item reads the item’s current version at the gate.
  • Orders — an order line pins the item version it was ordered under; the pin is the line’s frozen descriptor. From-scratch line-adds are gated on retired items.
  • Receiving — receiving lines pin the item they receive; blind lines (no order behind them) are gated on retired items at the door.

The module is one service with three endpoints — the catalog itself plus two auxiliary capabilities that ride the item record.

PlantUML diagram

  • Item service — owns the catalog. It provides the Items API (create, update, delete; queries and typeahead lookups; managing an item’s supplies, including the vendor resolution and pinning described above), the Print API (labels and breadcrumbs with QR codes, for one or more items), and the Images API (attaching a product image). The print and image capabilities read the catalog record; nothing depends on them.

An item owns a set of item supplies — each one a way to obtain the item from a supplier, with its ordering terms — and may carry a units-of-measure scheme that decides how its quantities behave.

PlantUML diagram

  • Item — the catalog entry: a name, an optional classification, an optional reorder threshold, and a location. An item may designate a primary and secondary supply as its preferred sources.
  • Item version — one recorded state of the item: its lifecycle status plus its item supplies as of that version. Editing the item writes the next version; nothing is overwritten.
  • Item supply — one way to source the item: which supplier provides it, under what SKU, by what ordering method, in what order quantity, at what unit cost, with what lead time. An item can have several. An item supply names its supplier either through a vendor version pin into Business Affiliate — the vendor as of a specific version — or informally by name only, before any vendor is linked. Both are legal, ordinary states.
  • Units-of-measure scheme — an optional set of units with conversions to a common base unit. An item that carries one is inventory-tracked; an item without one is non-tracked. This is the pivotal distinction: tracked items support exact quantity arithmetic (min/max, “full”, zero checks) because every unit converts to a common base; non-tracked items accept any unit but can only be compared loosely.

The item carries the shared reference-data lifecycle — versioned records, Live → Retired, version pins, gates at the point of choice — stated once in the Reference-Data Module Pattern. What is specific to items:

PlantUML diagram

  • A retired item is unreceivable, unorderable, unrequestable — for anything new. Goods arriving against no order cannot be received into it; a new demand item cannot be created for it directly — where a person chooses the item (a demand item a card’s cycle creates is not re-gated; see Demand’s operations); a new order line cannot be started from scratch on it. Work already in flight is grandfathered — see the retirement scenario below.
  • Both pin styles have canonical consumers here. An Orders line’s frozen item pin is its descriptor — the order stays true to what the item looked like when ordered, with nothing copied; Kanban Cards keep a floating reference and see the item as it is today.

An item supply deliberately has no lifecycle of its own — it is part of the item’s versioned state, so its life rides the item’s versions:

  • Every supply change is an item version. Adding, editing, or removing an item supply writes the next version of the item; there is no separate supply history to reconcile.
  • The vendor pin re-pins at each edit. An item supply shows its supplier as of the vendor version it pinned when the supply was last written; editing the supply pins the vendor’s then-current version. Whether a pinned vendor has since retired is a derived reading, not a state the supply passes through.
  • Only introduction is gated. Adding a new item supply against a retired vendor is refused; supplies already on the item are untouched by the vendor’s later retirement.

Item is upstream of nearly everything — Kanban Cards, Inventory Item, and Orders all point at it — but it announces nothing beyond the generic observability channel (see how modules stay in sync), and it listens for nothing.

The listening half is a change from earlier designs of this module, and it is a deliberate outcome of vendor version pins:

  • Vendor rename propagation dissolved. An item supply shows its supplier as of the vendor version it pins; there is no cached supplier name to refresh. Editing the supply re-pins it to the vendor’s then-current version.
  • Vendor stale-marking dissolved. Whether an item supply points at a retired vendor is a derived reading — compare the pinned vendor’s current status — not a flag a listener must maintain.

The scenarios trace the supply-to-vendor read path, the two vendor-change behaviors, and item retirement. The caller is whoever drives the workflow — a screen, an import job, or an orchestrating service.

A supply’s vendor pin resolves to the vendor version it was written against.

PlantUML diagram

This scenario is verified against the formal model.

An item supply is also allowed to carry no pin at all — a name-only supplier is a legal, ordinary state, not an error. Submitting an order against it is what finally requires a linked vendor.

PlantUML diagram

A vendor rename does not touch the supplies that pin it — each supply keeps showing the vendor as of its pinned version, and picks up the new name when the supply itself is next edited (which re-pins it).

PlantUML diagram

A vendor retirement doesn’t break existing supplies — that an item supply points at a retired vendor is readable at any time — and it gates new supplies at the door.

PlantUML diagram

Retiring an item honors work in flight and blocks new commitments at each consumer’s own gate.

PlantUML diagram

ActionWhat it doesWhen it is allowed
CreateEnter an item into the catalog. Born Live.Any time.
UpdateEdit details or item supplies — each update writes a new version.While the item is Live.
DeleteRetire the item — terminal; the version history stays readable.While the item is Live.
Query / look upFilter and page through items; typeahead lookups for names, suppliers, units, classifications, and locations.Any time.
Manage suppliesAdd, edit, and remove an item’s item supplies; linking a supplier pins the vendor’s current version. Introducing an item supply against a retired vendor is refused.While the item is Live.
PrintProduce labels and breadcrumbs (with QR codes) for one or more items.Any time.
Upload imageAttach a product image.Any time.
  • Item names are unique within a tenant. Two items can’t share a name in the same tenant.
  • An item supply belongs to exactly one item. Supplies are never shared between items, across their entire version histories.
  • Preferred supplies are distinct. An item’s primary and secondary supply must be two different supplies.
  • A retired item enters no new commitments — no new demand, no from-scratch order line, no blind receipt — while everything already committed against it is honored as agreed.
  • The shared reference-data guarantees apply: version pins (here, both the item pins consumers hold and the vendor pins on item supplies) never dangle, and retirement is terminal and history-preserving.
  • Inventory-tracking is fixed at the item. Whether an item is inventory-tracked is decided by whether it carries a units-of-measure scheme, and does not flip underneath its holdings.
  • Business Affiliate — item supplies pin their supplier’s vendor role there; an item supply may also stay name-only until a vendor is linked.
  • Kanban Cards — each card represents an item and reads it as it is today (a floating reference).
  • Inventory Item — on-hand holdings are holdings of an item.
  • Orders — an order line pins the item version it was ordered under; the pin is the line’s frozen descriptor.
  • Receiving — receiving lines pin the item they receive; blind lines (no order behind them) are gated on retired items, order-connected lines ride the order’s commitment.