Skip to content

Orders: Data Model

The Orders module stores two tables — "order" and order_line — each an occurrence-carrying bitemporal table: every mutation appends a version row pairing what was attempted with the resulting state, rather than editing a row in place. Its subjects are the order (the header: status, priority, supplier, assignee) and its lines (item, quantity, confirmation, receiving progress). This page is the field-complete reference for both tables and their DTOs; for the module’s design and lifecycle, see Orders. See Data Models — Reading Guide for the shared envelope shapes referenced throughout.

order_line holds its parent order by a same-module order_ref column (no DB foreign key). Both the order’s supplier and a line’s item are floating references into other modules that freeze into version pins once the order is submitted; a line’s serviced demand items stay floating refs for the order’s whole life.

PlantUML diagram

"order" (quoted identifier — order is a reserved word)

Section titled “"order" (quoted identifier — order is a reserved word)”
ColumnTypeNullRole
idUUIDNOT NULL (PK)identity
tenant_idUUIDNOT NULLidentity
effective_as_oftimestamptzNOT NULLidentity
recorded_as_oftimestamptzNOT NULL, default now()identity
previousUUIDNULLidentity
eidUUIDNOT NULLidentity
retiredbooleanNOT NULL, default falsebookkeeping
bts_authorvarchar(255)NOT NULLbookkeeping
bts_author_subvarchar(255)NULLbookkeeping
bts_created_by_subvarchar(255)NULLbookkeeping
bts_notevarchar(512)NULLpayload
created_byvarchar(255)NOT NULL, default ‘system’bookkeeping
created_at_effectivetimestamptzNOT NULL, default now()bookkeeping
created_at_recordedtimestamptzNOT NULL, default now()bookkeeping
order_numbervarchar(64)NOT NULLpayload
kindvarchar(64)NOT NULLpayload
outcomevarchar(16)NOT NULLpayload
reasonvarchar(64)NULLpayload
notification_idUUIDNULLpayload — see Schema notes
statusvarchar(32)NOT NULLpayload
priorityvarchar(16)NOT NULLpayload
assigneevarchar(255)NULLpayload — plain text, not a reference; see Data Models — Reading Guide
notesvarchar(2048)NULLpayload
internal_notesJSONBNULLpayload
s_supplier_entity_idUUIDNULLpayload
s_supplier_affiliate_eidUUIDNULLpayload
s_supplier_namevarchar(255)NULLbookkeeping
s_supplier_record_idUUIDNULLbookkeeping
s_supplier_retiredbooleanNOT NULL, default falsebookkeeping
s_supplier_provenance_updated_byvarchar(255)NULLbookkeeping
s_supplier_provenance_updated_atbigintNULLbookkeeping
s_supplier_baseJSONBNULLpayload
s_supplier_overridesJSONBNULLpayload

Unique constraints: order_committed_previous — UNIQUE partial index on (previous) WHERE outcome = 'COMMITTED', the P2-H1 committed-successor fork guard (PDEV-1166). Turns “at most one committed successor per row” into a database invariant.

order_line (table renamed from procurement_order_line)

Section titled “order_line (table renamed from procurement_order_line)”
ColumnTypeNullRole
idUUIDNOT NULL (PK)identity
tenant_idUUIDNOT NULLidentity
effective_as_oftimestamptzNOT NULLidentity
recorded_as_oftimestamptzNOT NULL, default now()identity
previousUUIDNULLidentity
eidUUIDNOT NULLidentity
retiredbooleanNOT NULL, default falsebookkeeping
bts_authorvarchar(255)NOT NULLbookkeeping
bts_author_subvarchar(255)NULLbookkeeping
bts_created_by_subvarchar(255)NULLbookkeeping
bts_notevarchar(512)NULLpayload
created_byvarchar(255)NOT NULL, default ‘system’bookkeeping
created_at_effectivetimestamptzNOT NULL, default now()bookkeeping
created_at_recordedtimestamptzNOT NULL, default now()bookkeeping
order_refUUIDNOT NULLidentity
item_entity_idUUIDNULLpayload
item_item_namevarchar(255)NULLbookkeeping
item_record_idUUIDNULLbookkeeping
item_retiredbooleanNOT NULL, default falsebookkeeping
item_provenance_updated_byvarchar(255)NULLbookkeeping
item_provenance_updated_atbigintNULLbookkeeping
kindvarchar(64)NOT NULLpayload
outcomevarchar(16)NOT NULLpayload
reasonvarchar(64)NULLpayload
notification_idUUIDNULLpayload
s_line_statusvarchar(16)NOT NULLpayload
s_quantityJSONBNOT NULLpayload
s_receivedJSONBNOT NULLpayload
s_demandJSONBNOT NULLpayload
s_confirmationJSONBNULLpayload

Unique constraints: order_line_committed_previous — the same P2-H1 fork guard as "order", UNIQUE partial index on (previous) WHERE outcome = 'COMMITTED'.

OrderPayload (the payload of EntityRecord<OrderPayload, OrderMetadata>)

Section titled “OrderPayload (the payload of EntityRecord<OrderPayload, OrderMetadata>)”
FieldTypeStored or computedNotes
eIdEntityIdStored← eid
orderNumberStringStored
kindOrderOccurrenceKindStored
outcomeOrderOutcomeStored
reasonString?Stored
notificationIdUUID?Storedsee Schema notes
statusOrderStatusStored
supplierSupplierBinding?Storedthe s_supplier_* cluster, reference + base/override values
priorityOrderPriorityStored
assigneeString?Storedplain text
notesString?Stored
internalNotesList<String>StoredNULL stored as empty list

OrderLinePayload (the payload of EntityRecord<OrderLinePayload, OrderLineMetadata>)

Section titled “OrderLinePayload (the payload of EntityRecord<OrderLinePayload, OrderLineMetadata>)”
FieldTypeStored or computedNotes
eIdEntityIdStored← eid
orderRefUUIDStored
itemItemReference.Value?Storedthe item_* cluster
kindOrderLineOccurrenceKindStored
outcomeOrderOutcomeStored
reasonString?Stored
notificationIdUUID?Stored
lineStatusLineStatusStored← s_line_status
quantityGeneralizedQuantityStored← s_quantity
receivedGeneralizedQuantityStored← s_received
demandSet<UUID>Stored← s_demand
confirmationConfirmation?Stored← s_confirmation

Note: the business-layer readings effectiveLineQty and openOf are computed over OrderLineState but are not projected onto any wire DTO.

OrderReadingsDto (GET .../order/{eId}/readings)

Section titled “OrderReadingsDto (GET .../order/{eId}/readings)”
FieldTypeStored or computedNotes
confirmedBooleanComputedevery live line has a non-null confirmation
receivingBooleanComputedsome live line has non-zero received
readingStringComputed"RECEIVING" if receiving, else "CONFIRMED" if confirmed, else "SUBMITTED"

OrderCommitResponse / OrderLineCommitResponse (mutation responses)

Section titled “OrderCommitResponse / OrderLineCommitResponse (mutation responses)”
FieldTypeNotes
occurrenceOccurrenceDtosee the shared envelope in Data Models — Reading Guide
recordEntityRecord<OrderPayload, OrderMetadata> (or the line equivalent)
ColumnTargetKindFreezes
s_supplier_entity_id, s_supplier_affiliate_eidBusiness Affiliate — BusinessRole (VENDOR)floatingat Submit
s_supplier_record_idBusiness Affiliate BusinessRole version rowversion-pinstamped by resolution while DRAFT, or by the retirement cascade
s_supplier_name, s_supplier_retired, s_supplier_provenance_*Business Affiliate BusinessRolevalue-snapshotrefreshed while DRAFT
item_entity_idItemfloatingat Submit
item_record_idItem version rowversion-pin
item_item_name, item_retired, item_provenance_*Itemvalue-snapshotthe denormalized effective Item (PDEV-1418)
s_demandDemand — DemandItemfloating (line-carried, no FK)never — membership checked live
notification_id (line)Demand ProductionDelivery, or null for manual repairfloatingstamped by the receipt listener
assigneenone — plain text, not a reference—never a reference at Phase 2; see Data Models — Reading Guide

order_line.order_ref is a same-module parent-child link (child holds the parent’s eid; no FK, no child table).

Orders is Designed — build pending. The routes below are the designed shape; the live /v1/order/... endpoints in the API Endpoint Catalog belong to the client-side purchase-order capability this module replaces, not to an earlier version of it.

Both subjects follow the request/response call-shape convention in The Orders v2 Call Shape.

MethodPathPurposeMain refusals
POSTorder/createCreate an order (DRAFT)
POSTorder/update-supplierChoose or override the supplier binding
POSTorder/reset-to-supplierDiscard per-order supplier overrides
POSTorder/update-detailsSet priority/assignee/notesDRAFT only
POSTorder/submitFreeze and transmit (DRAFT → SUBMITTED)needs ≥1 line, linked+unretired supplier
POSTorder/closeSUBMITTED → CLOSED
POSTorder/cancelDRAFT → CANCELED
POSTorder/deleteTombstone a terminal order
POSTorder/annotateSet internal notes
GETorder/{eId}?effectiveasof&recordedasofAn order as of a coordinatetombstoned = 404
GETorder/{eId}/log?page&sizeOccurrence log, most recent first
GETorder/{eId}/readings?effectiveasof&recordedasofThe CONFIRMED/RECEIVING reading
MethodPathPurposeMain refusals
POSTorder-line/add-lineAdd a line (from demand, from item, or free-form)
POSTorder-line/update-lineSet the requested quantity
POSTorder-line/attach-demand / detach-demandAdjust serviced demand items
POSTorder-line/remove-lineTombstone a line while composing
POSTorder-line/annotate-lineAppend a note occurrence
POSTorder-line/close-lineClose a line
POSTorder-line/record-receipt / reverse-receiptManual repair of received quantity
POSTorder-line/record-acknowledgmentRecord the vendor’s answer
GETorder-line/{eId}?effectiveasof&recordedasofA line as of a coordinateremoved = 404
GETorder-line/{eId}/log?page&sizeOccurrence log
GETorder-line/by-order/{orderId}?effectiveasof&recordedasofLive lines of an order

Listens for DemandNotification.ProductionRecorded/ProductionRevoked (reconciles received quantity), and for item/business-role change notifications (keeps the floating references current while DRAFT). Emits nothing of its own beyond two implementation-only occurrences (SYNC_ITEM, SYNC_SUPPLIER) that keep the denormalized snapshots in sync — they carry no model signature.

  • order.notification_id has no observed writer. No order-subject occurrence kind was found stamping a non-null value onto this column — it’s declared and read, but nothing in the current code path sets it.
  • OrderLineOccurrenceKind’s own KDoc disagrees with its enum body. The KDoc says “NINE” model line-subject kinds; the enum body declares 10 model kinds plus the implementation-only SYNC_ITEM, for 11 total.
  • assignee is plain text, not a version pin, despite the domain design describing it as one — see the Staff note in Data Models — Reading Guide. The model reserves the shape; nothing populates it at Phase 2.