02 — System Diagram

🔍 Open the Interactive Diagram Viewer — pan, mouse-wheel zoom, fit-to-screen, full-screen, per-area tabs, the full ERD, and a focus mode that draws one model and its neighbours at a chosen depth. PurchaseRequirement is a hub table, so its links can be hidden to declutter the overview.

Regenerate the viewer after any DSL, menu_config.yaml or diagram_config.yaml change: python scripts/build_diagram_viewer.py psam.

The procurement spine

flowchart TD
  Sup[Supplier]
  Ctr[ContractRef]
  PR[PurchaseRequirement]
  SC[SourcingCase]
  Q[Quote]
  PO[PurchaseOrder]
  DM[DeliveryMilestone]
  ER[ExpeditingRecord]
  RR[ReceiptReference]
  SR[SupplyRisk]

  Sup --> Ctr
  PR --> SC
  Ctr --> SC
  Sup --> SC
  SC --> Q
  Sup --> Q
  PR --> PO
  Sup --> PO
  PO --> DM
  PO --> ER
  PO --> RR
  PR --> SR
  PO --> SR

(The two Integration models — ExternalRecordLink and EventOutbox — carry no local foreign keys; they link outward by canonical_ref strings and are omitted from the spine.)

How to read it

  • PurchaseRequirement is the hub. Almost every procurement record hangs off it; the diagram viewer lets you hide those hub edges to see the local structure of each area.
  • The procurement lifecycle runs left to right along the spine: a requirement (what is needed and why) → a sourcing case and the quotes within it (how it is bought, and from whom) → a purchase order (the commitment, under local or external-ERP authority) → delivery milestones, expediting records and a receipt reference (getting it here) — with a supply risk raised whenever the thread threatens the work it feeds.
  • Sourcing rests on masters. A SourcingCase points at the selected Supplier and, for a call-off, the ContractRef; each Quote names its Supplier. An order can be placed against a framework without a fresh quote.
  • Delivery is where assurance lives. Milestones flip to AT_RISK/DELAYED, expediting logs the chase, and the receipt closes the loop — so slippage is caught before the goods fail to arrive.

The cross-app golden thread

PSAM is the procurement node of the Work & Supply reference network; one thread crosses three apps:

  • Origin (msam → psam). A material shortage in msam (demand:wp-1001-brg for material:brg-6208) is routed by the orchestrator into PR-1001 (PurchaseRequirement.source_canonical_ref = demand:wp-1001-brg, source_type = MATERIAL_SHORTAGE).
  • Impact (psam → mwem). The SupplyRisk on PR-1001 carries impact_canonical_ref = workpkg:wp-1001 — a late bearing delivery is surfaced against the mwem work package it will block, not hidden inside the order.
  • Shared masters (psam ↔ scrm). supplier:* masters PSAM owns are read by scrm for shutdown/campaign mobilisation, so both apps name the same supplier.

See networks/work_supply_00/system.manifest.yaml for the routes and exposed entities.

Backing data (denormalised for display)

Each foreign key carries a denormalised <fk>_name display column so lists read in plain language (e.g. a PurchaseOrder row shows its supplier and requirement, a Quote shows its supplier) without a join at read time — the house style for these apps.