Example: Inventory Tracker

Items, locations, movements, and low-stock alerts — a complete warehouse tracker where the ledger is always right.

Inventory is a ledger problem: current stock is a sum of movements, and every movement must be recorded once, in order. This example builds that ledger with alerts on top.

Data Model

  • items — sku, name, unit, reorder_level.
  • locations — warehouse/zone/bin.
  • movements — one append-only document per change:
Movement Document
{
  "_meta": {},
  "actor_guid": "b9ee6a631b24e78d1aa48aef0dc067fff7bfbacd24a56ef4ed1f08e537d48b6bd02",
  "item_name": "essential cotton t-shirt",
  "location": "wh-1/zone-a/bin-04",
  "note": "po-10482",
  "quantity": 24,
  "sku": "TSHIRT-BLK-M",
  "type": "receive"
}

Movement types: receive, ship, adjust, transfer (two linked movements: out + in). Never update movements — corrections are new adjust movements (the activity-log principle from Storage Examples).

Current Stock, Two Ways

  1. Ledger sum (exact) — aggregate movements per sku+location when you need the precise figure.
  2. Counter document (fast) — a stock storage with one doc per sku+location; every movement flow also applies mutations_increment_by_field to it via function_update_document (sequential, race-free — see mutations). Lists and alerts read only counters.

Audit job: a daily schedule_repeating_event recomputes the ledger sum against the counter and logs drift — you will catch a missed movement within a day, not at year-end.

The Flows

  • Receive — form or API → create movement → increment counter. Idempotent via a source reference (po-10482): re-receiving the same reference is skipped.
  • Ship — same, negative increment, with a guard when the counter would drop below zero (hold as backorder movement instead of going negative).
  • Transfer — one flow writes the out-movement and in-movement as two linked documents sharing a transfer guid; the counters move in the same flow.
  • Count check — an adjust movement with the counted quantity difference; the counter follows the same path as everything else.

Low-Stock Alerts

  1. After every counter change, compare against the item's reorder_level.
  2. Crossing the threshold (and only then — track previous state on the counter to avoid alert spam) creates an alert document and emails the buyer via the email pattern.
  3. Alert page: open alerts sorted by severity, closed with a status mutation once the receive lands.
  4. Next Steps

    E-Commerce Catalog Sell through this stock. Storage Examples The ledger and counter models in full. Repeating Events The daily drift-check scheduler.