@izumisy-tailor/omakase-modules 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -28
- package/docs/generated/README.md +35 -0
- package/docs/generated/_media/creating-modules.md +471 -0
- package/docs/{tutorials → generated/_media}/using-modules.md +69 -20
- package/docs/generated/builder/README.md +25 -0
- package/docs/generated/builder/functions/defineModule.md +60 -0
- package/docs/generated/builder/functions/withModuleConfiguration.md +68 -0
- package/docs/generated/builder/type-aliases/AnyDefinedModule.md +57 -0
- package/docs/generated/builder/type-aliases/ConfiguredDependencies.md +44 -0
- package/docs/generated/builder/type-aliases/ConfiguredModule.md +60 -0
- package/docs/generated/builder/type-aliases/DefinedModule.md +93 -0
- package/docs/generated/builder/type-aliases/DependencyModules.md +29 -0
- package/docs/generated/builder/type-aliases/EmptyDependencies.md +34 -0
- package/docs/generated/builder/type-aliases/ModuleBuilder.md +124 -0
- package/docs/generated/builder/type-aliases/ModuleBuilderProps.md +42 -0
- package/docs/generated/builder/type-aliases/ModuleFactoryContext.md +40 -0
- package/docs/generated/builder/type-aliases/TablesFromNames.md +28 -0
- package/docs/generated/config/README.md +19 -0
- package/docs/generated/config/classes/ModuleLoader.md +128 -0
- package/docs/generated/config/functions/loadModules.md +79 -0
- package/docs/generated/config/sdk/README.md +16 -0
- package/docs/generated/config/sdk/functions/getModulesReference.md +81 -0
- package/docs/generated/config/sdk/functions/loadModuleForDev.md +53 -0
- package/docs/generated/config/sdk/type-aliases/GetModulesReferenceOptions.md +60 -0
- package/docs/generated/config/type-aliases/LoadedModules.md +162 -0
- package/docs/generated/modules.md +11 -0
- package/package.json +17 -18
- package/src/builder/helpers.ts +388 -28
- package/src/builder/index.ts +8 -1
- package/src/builder/register.ts +38 -25
- package/src/config/module-loader.ts +251 -21
- package/src/config/sdk/dev-context.ts +82 -0
- package/src/config/sdk/index.ts +2 -1
- package/src/config/sdk/paths.ts +124 -13
- package/src/config/sdk/wrapper/base.ts +185 -0
- package/src/config/sdk/wrapper/generator.ts +89 -0
- package/src/config/sdk/wrapper/strategies.ts +121 -0
- package/docs/examples/data-models/core/inventory-module.md +0 -230
- package/docs/examples/data-models/core/order-module.md +0 -132
- package/docs/examples/data-models/scenarios/inventory-reservation-scenario.md +0 -73
- package/docs/examples/data-models/scenarios/multi-storefront-order-scenario.md +0 -99
- package/docs/examples/data-models/scenarios/order-payment-status-scenario.md +0 -92
- package/docs/examples/data-models/scenarios/procurement-order-scenario.md +0 -95
- package/docs/tutorials/creating-modules.md +0 -256
- package/src/config/module-registry.ts +0 -22
- package/src/stub-loader/index.ts +0 -3
- package/src/stub-loader/interface.ts +0 -40
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# Order Module Core Contract
|
|
2
|
-
|
|
3
|
-
## Goal
|
|
4
|
-
Maintain the order module as a clean, channel-neutral core that accepts standardised intents, persists canonical orders, and exposes status history for downstream consumers without leaking external system concerns.
|
|
5
|
-
|
|
6
|
-
## Module Boundary
|
|
7
|
-
- Own canonical order identifiers, customer references, and pricing snapshots required by internal workflows.
|
|
8
|
-
- Publish contracts that upstream systems write to (`order.orderIntent`) and downstream systems read (`order.order`, `orderStatusHistory`).
|
|
9
|
-
- Avoid dependencies on channel integrations, inventory logic, billing specifics, or storefront payload schemas.
|
|
10
|
-
- Surface read models through TailorDB views or projections instead of embedding module-specific fields in `order.order`.
|
|
11
|
-
|
|
12
|
-
## Published Contracts
|
|
13
|
-
|
|
14
|
-
All tables implicitly include an auto-generated `id` primary key; only domain-specific columns are listed below.
|
|
15
|
-
|
|
16
|
-
### `order.orderIntent`
|
|
17
|
-
| Field | Description |
|
|
18
|
-
| --- | --- |
|
|
19
|
-
| `orderIntentId` | Stable identifier generated by the caller; dedupe key combined with `sourceSystem`.
|
|
20
|
-
| `sourceSystem` | Logical system identifier (e.g., `channel.shopify`, `crm.salesforce`).
|
|
21
|
-
| `externalOrderId` | Optional reference for tracing back to the originating system.
|
|
22
|
-
| `customerRef` | Customer identity reference understood by commerce core/CRM.
|
|
23
|
-
| `lineItems` | Array of SKU identifiers, quantities, and pricing snapshots already mapped to internal product IDs.
|
|
24
|
-
| `totals` | Order-level monetary snapshot (currency, subtotal, tax, shipping, discounts).
|
|
25
|
-
| `submittedAt` | Timestamp from the originating system; used for sequencing when backfilling.
|
|
26
|
-
| `payloadHash` | Optional trace hash to support replay verification.
|
|
27
|
-
|
|
28
|
-
**Responsibilities**
|
|
29
|
-
- Callers (channel integration, CRM, manual tools) must write intents via the published contract and handle idempotency using `orderIntentId` + `sourceSystem`.
|
|
30
|
-
- Intents remain mutable only until acknowledged by the order module; mutations must create new intents.
|
|
31
|
-
|
|
32
|
-
### `order.order`
|
|
33
|
-
| Field | Description |
|
|
34
|
-
| --- | --- |
|
|
35
|
-
| `customerRef` | Carried over from the intent; never rewritten by downstream modules.
|
|
36
|
-
| `lineItems` | Snapshot derived from the accepted intent; includes SKU, quantity, unit price, totals.
|
|
37
|
-
| `currency` | ISO currency code resolved via commerce core metadata.
|
|
38
|
-
| `createdAt` / `updatedAt` | Managed by the order module; reflect canonical lifecycle timestamps.
|
|
39
|
-
| `intentRef` | Foreign key back to `order.orderIntent` for traceability.
|
|
40
|
-
**Responsibilities**
|
|
41
|
-
- Remains immutable for line items and monetary values once created; adjustments require follow-up intents or dedicated adjustment commands.
|
|
42
|
-
- Exposes only generic fields; module-specific state must live in projections or status history.
|
|
43
|
-
|
|
44
|
-
### `orderStatusHistory`
|
|
45
|
-
| Field | Description |
|
|
46
|
-
| --- | --- |
|
|
47
|
-
| `orderId` | Order identifier referencing `order.order`.
|
|
48
|
-
| `module` | Namespace-qualified module writing the status (e.g., `channel`, `inventory`, `billing`).
|
|
49
|
-
| `statusCode` | Module-defined status code (e.g., `channel:captured`, `procurement:po_confirmed`).
|
|
50
|
-
| `category` | Optional grouping such as `fulfillment`, `payment`, `support`.
|
|
51
|
-
| `severity` | Optional flag (`info`, `warning`, `blocking`) signalling operational impact.
|
|
52
|
-
| `payload` | JSON payload for contextual metadata (tracking number, reason codes, ETA).
|
|
53
|
-
| `recordedAt` | Timestamp supplied by the writer; used for chronological rendering.
|
|
54
|
-
| `writtenBy` | Executor/actor responsible for the entry.
|
|
55
|
-
| `closedAt` | Optional timestamp when the status is superseded/resolved.
|
|
56
|
-
|
|
57
|
-
**Responsibilities**
|
|
58
|
-
- Writers append-only; updates occur by inserting new entries instead of mutating existing ones.
|
|
59
|
-
- Downstream projections (latest status, blocking status, timeline views) are derived from this table.
|
|
60
|
-
- Status vocabularies are documented per module to avoid collisions; the order module provides write APIs but does not interpret module-specific semantics.
|
|
61
|
-
|
|
62
|
-
## Status Model Principles
|
|
63
|
-
- Clean core: `order.order` keeps only canonical attributes; module-specific lifecycle stays in history/projections.
|
|
64
|
-
- History over flags: statuses are append-only rows, not columns on `order.order`.
|
|
65
|
-
- Module ownership: each module writes its own statuses; order core supplies infrastructure only.
|
|
66
|
-
- Read-only projections: UIs read history + module projections; modules never mutate others' tables.
|
|
67
|
-
- Optional composition: modules can be added/removed without schema migrations to `order.order`.
|
|
68
|
-
|
|
69
|
-
### Order Status Vocabulary
|
|
70
|
-
|
|
71
|
-
| Label | Writer | Trigger timing | Notes |
|
|
72
|
-
| --- | --- | --- | --- |
|
|
73
|
-
| `order:submitted` | Order module | Immediately after an `orderIntent` is accepted and converted into `order.order`. | Establishes the baseline timeline entry for all downstream consumers. |
|
|
74
|
-
| `order:manually_adjusted` | Order module / Operator | Whenever an operator edits the order after creation (e.g., address correction, line adjustment). | Signals other modules to reconcile manual updates or rerun validation. |
|
|
75
|
-
| `order:cancelled` | Order module / Operator | When the order is cancelled or voided. | Downstream modules should unwind reservations, authorizations, and tasks. |
|
|
76
|
-
|
|
77
|
-
Modules must introduce additional statuses using their own namespace prefix (e.g., `inventory:*`, `billing:*`). Shared dashboards consume this vocabulary to build customer-facing timelines.
|
|
78
|
-
|
|
79
|
-
## Projections & Queries
|
|
80
|
-
- Latest status per module: windowed view picking the newest entry per `(orderId, module)`.
|
|
81
|
-
- Blocking status detection: filter where `severity = 'blocking'` and `closedAt IS NULL` to pause fulfilment/billing.
|
|
82
|
-
- Timelines: list all history entries ordered by `recordedAt` for customer communications.
|
|
83
|
-
- Aggregations: dashboards (e.g., counts of `procurement:delayed`) without touching `order.order` schema.
|
|
84
|
-
|
|
85
|
-
## Integration Patterns
|
|
86
|
-
- Inventory/Procurement: executors write `procurement:po_*`, `inventory:reservation_*`; projections decide release timing.
|
|
87
|
-
- Billing/Payments: append `billing:invoice_posted`, `billing:payment_failed`; UIs read history for payment lifecycle.
|
|
88
|
-
- Multi-entity: log `entity:*` milestones (policy snapshots, settlements) without adding entity fields to orders.
|
|
89
|
-
- CRM/Customer success: `crm:*` entries (case opened, loyalty awarded) live in history, not in `order.order`.
|
|
90
|
-
- Manual operations: operators insert `manual:*` notes for auditability.
|
|
91
|
-
|
|
92
|
-
## Design Guidelines
|
|
93
|
-
1. Naming discipline: use `module:status` to avoid collisions and simplify filtering.
|
|
94
|
-
2. Idempotent writes: guard against duplicates (check last status per module where needed).
|
|
95
|
-
3. Retention: define history retention/partitioning; plan for high-volume modules.
|
|
96
|
-
4. Access control: modules insert/update only their own statuses; apply RBAC for manual tools.
|
|
97
|
-
5. Testing: integration tests should assert history entries for key flows and respect blocking statuses.
|
|
98
|
-
6. Documentation: each module documents its vocabulary and payload expectations.
|
|
99
|
-
|
|
100
|
-
## Migration Strategy
|
|
101
|
-
1. Create `orderStatusHistory` and backfill from legacy order columns if present.
|
|
102
|
-
2. Update executors/modules to append history instead of mutating `order.order` columns.
|
|
103
|
-
3. Deprecate legacy status columns once consumers pivot to history-driven projections.
|
|
104
|
-
4. Provide transitional views so downstream systems can adopt the model gradually.
|
|
105
|
-
|
|
106
|
-
## Ingestion Pattern
|
|
107
|
-
1. External systems transform their payloads into the `order.orderIntent` schema.
|
|
108
|
-
2. The order module validates intents (schema, dedupe, referenced entities), persists them, and emits a CDC event.
|
|
109
|
-
3. `orderIntentIngestor` consumes the CDC stream, creates the canonical `order.order`, and records the originating mapping.
|
|
110
|
-
4. Success results in a `channel:captured` (or equivalent) entry appended to `orderStatusHistory`.
|
|
111
|
-
5. Failure scenarios raise rejection events so the caller can diagnose issues without introducing direct dependencies on order internals.
|
|
112
|
-
|
|
113
|
-
## Downstream Consumption
|
|
114
|
-
- Inventory, procurement, billing, and CRM modules listen to `order.order` CDC events to start their workflows.
|
|
115
|
-
- Status dashboards query projections derived from `orderStatusHistory` to display customer timelines and operational alerts.
|
|
116
|
-
- Channel-specific projections (e.g., `channel.statusProjection`) remain within the owning module and reference `orderId` and `orderStatusHistory` data as needed.
|
|
117
|
-
|
|
118
|
-
## Dependency Guidelines
|
|
119
|
-
- Order depends only on shared infrastructure modules (e.g., commerce core for product metadata).
|
|
120
|
-
- Upstream modules must depend on the order contract to write intents; downstream modules may depend on the order module for CDC schemas and read models.
|
|
121
|
-
- Bidirectional dependencies are avoided by using shared tables (`order.orderIntent`, `orderStatusHistory`) as integration boundaries.
|
|
122
|
-
|
|
123
|
-
## Versioning & Change Management
|
|
124
|
-
- Introduce new fields in `order.orderIntent` as optional with defaults; communicate schema revisions through versioned documentation.
|
|
125
|
-
- Provide a deprecation window before enforcing mandatory fields so channel connectors can adopt changes.
|
|
126
|
-
- For breaking changes, publish a new contract version (e.g., `order.orderIntent.v2`) and run both in parallel until migration completes.
|
|
127
|
-
|
|
128
|
-
## Operational Considerations
|
|
129
|
-
- Implement replay tooling to rebuild orders from intents for audit scenarios.
|
|
130
|
-
- Monitor dedupe metrics to detect misconfigured source systems.
|
|
131
|
-
- Enforce payload size limits and validation rules to prevent unbounded data ingestion.
|
|
132
|
-
- Retain intents for the retention period required by compliance/audit and purge only after downstream reconciliation.
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# Inventory Reservation Scenario
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
This document captures a flow where the order module remains independent while an optional inventory module automates stock reservations. Back-office teams can maintain inventory manually (for example via spreadsheets or direct TailorDB edits), and when the inventory module is enabled it reacts to order events, applies reservation logic, and publishes stock projections without imposing reverse dependencies on the order module. The order contract referenced here is defined in [Order Module Core Contract](../order-module-core-contract.md).
|
|
5
|
-
|
|
6
|
-
## Module Dependencies
|
|
7
|
-
|
|
8
|
-
| Module (package path) | Declared dependencies | Purpose |
|
|
9
|
-
| --- | --- | --- |
|
|
10
|
-
| Commerce core (`packages/commerce-core-module`) | — | Owns product and customer master data; exposes immutable definitions consumed by downstream modules. |
|
|
11
|
-
| Order (`packages/order-module`) | — | Publishes the `order.orderIntent` contract, stores canonical orders, and exposes status history for downstream projections. |
|
|
12
|
-
| Inventory (`packages/inventory-module`) | Order, Commerce core | Listens to order events to automate reservations and uses commerce metadata to resolve SKU attributes. |
|
|
13
|
-
|
|
14
|
-
## TailorDB Tables and Views
|
|
15
|
-
- Uses core tables `inventory.reservation` and `inventory.stockLedger` as defined in `core/inventory-module.md`; not redefined here.
|
|
16
|
-
- `inventory.remainingStock`: Derived view exposing per-SKU on-hand quantities for read-only consumers (scenario-local read model).
|
|
17
|
-
|
|
18
|
-
## Order Status
|
|
19
|
-
|
|
20
|
-
Baseline `order:*` statuses are defined in [Order Module Core Contract](../order-module-core-contract.md#order-status-vocabulary). This scenario appends the following inventory-originated statuses into `orderStatusHistory` so order consumers can see reservation outcomes without querying inventory tables directly:
|
|
21
|
-
|
|
22
|
-
| Label | Writer | Trigger timing | Notes |
|
|
23
|
-
| --- | --- | --- | --- |
|
|
24
|
-
| `inventory:reservation_created` | Inventory module | When `inventoryReservationIntake` begins reserving stock for an order. | Optional; useful for long-running reservation processes. |
|
|
25
|
-
| `inventory:reservation_confirmed` | Inventory module | After stock is successfully reserved. | Indicates inventory has secured the requested quantities. |
|
|
26
|
-
| `inventory:reservation_backordered` | Inventory module | When inventory cannot fully reserve quantities. | Marks the order as waiting on replenishment. |
|
|
27
|
-
| `inventory:reservation_cancelled` | Inventory module | When a reservation is released due to order change or cancellation. | Ensures support teams understand why stock was freed. |
|
|
28
|
-
|
|
29
|
-
## Inventory Status (scenario-specific)
|
|
30
|
-
|
|
31
|
-
This scenario does not introduce additional inventory status codes beyond the core vocabulary. It emits the core `inventory:reservation_*` statuses above; other core statuses (for example `inventory:stock_adjusted`, `inventory:fulfillment_task_created`) remain available but are not invoked in this flow.
|
|
32
|
-
|
|
33
|
-
## Executor Triggers
|
|
34
|
-
|
|
35
|
-
| Trigger table (module) | Writers (modules) | Activation timing | Target executor (module) | Responsibility |
|
|
36
|
-
| --- | --- | --- | --- | --- |
|
|
37
|
-
| `order.order` (order) | Order (owner), operators | Record creation or update (CDC) | `inventoryReservationIntake` (inventory) | Decide whether to create/update `inventory.reservation` entries based on order status; can be disabled for manual-only workflows. |
|
|
38
|
-
| `inventory.reservation` (inventory) | Inventory (owner), operators | Record creation or update (CDC) | `inventoryReservationProjector` (inventory) | Maintain `inventory.remainingStock` snapshots and ensure reservations propagate to the ledger when required. |
|
|
39
|
-
| `inventory.stockLedger` (inventory) | Inventory (owner), operators | Record creation (CDC) | `inventoryStockMetricsUpdater` (inventory) | Update analytical projections and audit views after any stock movement (manual or automated). |
|
|
40
|
-
|
|
41
|
-
## Flow
|
|
42
|
-
1. An operator or integration submits `order.orderIntent`; the order module validates and ingests it into `order.order`, emitting a CDC event. Manual edits can still be applied directly to `order.order` when policy permits.
|
|
43
|
-
2. If the inventory module is enabled, `inventoryReservationIntake` reacts to the order CDC event and records reservation rows in `inventory.reservation` (and, when relevant, appends movements to `inventory.stockLedger`). If automation is disabled, operators can insert reservations or ledger entries manually without involving the executor.
|
|
44
|
-
3. Inventory appends reservation outcomes (`inventory:reservation_confirmed`, `inventory:reservation_backordered`) to `orderStatusHistory` so order consumers can see automation progress without depending directly on inventory tables.
|
|
45
|
-
4. CDC events on `inventory.reservation` and `inventory.stockLedger` trigger inventory-side projectors that refresh `inventory.remainingStock` and other read models.
|
|
46
|
-
5. Order-facing UIs or reports can query `inventory.remainingStock` for availability and combine it with `orderStatusHistory` to display reservation timelines, while the order module itself remains oblivious to how the data originated.
|
|
47
|
-
6. Commerce core continues to publish product metadata; inventory consumes this data but does not introduce reverse dependencies on order.
|
|
48
|
-
|
|
49
|
-
```mermaid
|
|
50
|
-
sequenceDiagram
|
|
51
|
-
actor Operator
|
|
52
|
-
participant Order
|
|
53
|
-
participant Inventory
|
|
54
|
-
participant Commerce
|
|
55
|
-
|
|
56
|
-
Operator->>Order: submit orderIntent (manual or automated)
|
|
57
|
-
Order->>Order: orderIntentIngestor creates order.order
|
|
58
|
-
Order-->>Inventory: order.order CDC event (optional automation)
|
|
59
|
-
Inventory->>Inventory: inventoryReservationIntake evaluates reservation logic
|
|
60
|
-
Inventory->>Inventory: write inventory.reservation / inventory.stockLedger
|
|
61
|
-
Inventory->>Order: append inventory:* status history entries
|
|
62
|
-
Inventory-->>Inventory: reservation/ledger CDC refreshes remainingStock
|
|
63
|
-
Operator->>Inventory: manual adjustments as needed
|
|
64
|
-
Inventory-->>Order: remainingStock exposed via read-only view
|
|
65
|
-
Inventory-->>Commerce: read product metadata
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Design Considerations
|
|
69
|
-
- Keep order independent so manual-only workflows remain viable even without the inventory module; follow the contract in `../order-module-core-contract.md` when extending ingestion.
|
|
70
|
-
- Inventory automation should be idempotent and tolerant of manual edits, reconciling rather than overwriting operator input in reservation and ledger tables.
|
|
71
|
-
- Append reservation outcomes to `orderStatusHistory` with a documented status vocabulary (`inventory:reservation_*`) so order consumers do not query inventory tables directly.
|
|
72
|
-
- Downstream consumers read `inventory.remainingStock` (or similar projections) without mutating inventory-owned tables.
|
|
73
|
-
- Commerce core continues to act as the canonical source for SKU definitions; inventory depends on it, not the other way around.
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# Multi-Storefront Order Scenario
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
This scenario covers an organisation selling through multiple storefronts (e.g., Shopify, Amazon) while sharing a single stock pool. The order module stays channel-agnostic: dedicated channel integration modules capture storefront events, translate them into core orders, and coordinate inventory reservations. Channel-specific fulfilment states and acknowledgements live outside the order schema in status history and channel projections. The shared contract for the clean order core is documented in [Order Module Core Contract](../order-module-core-contract.md).
|
|
5
|
-
|
|
6
|
-
## Module Dependencies
|
|
7
|
-
|
|
8
|
-
| Module (package path) | Declared dependencies | Purpose |
|
|
9
|
-
| --- | --- | --- |
|
|
10
|
-
| Channel integration (`packages/channel-integration-module`) | Commerce core, Order | Pulls orders from external storefronts, maps product identifiers, and writes standardised order intents through the order module contract. |
|
|
11
|
-
| Order (`packages/order-module`) | — | Publishes the `orderIntent` contract, stores canonical orders, and exposes status history for downstream modules. |
|
|
12
|
-
| Inventory (`packages/inventory-module`) | Order, Commerce core | Manages shared stock, reservations, and warehouse operations. |
|
|
13
|
-
| Commerce core (`packages/commerce-core-module`) | — | Owns product catalogue, channel SKU mappings, and pricing metadata. |
|
|
14
|
-
| Channel sync (`packages/channel-sync-module`) | Inventory, Channel integration | Publishes stock levels and fulfilment confirmations back to the storefronts. |
|
|
15
|
-
|
|
16
|
-
## TailorDB Tables and Views
|
|
17
|
-
### Channel integration module
|
|
18
|
-
- `channel.orderCapture`: Raw storefront payloads kept for traceability, enrichment, and replay (shop identifier, channel order id, customer info, line allocations).
|
|
19
|
-
- `channel.orderMapping`: Links channel order ids to the generated `orderId` after the intent is processed; also records the originating `orderIntentId` for audits.
|
|
20
|
-
- `channel.statusProjection`: Channel-facing projection of statuses (acknowledged, packed, shipped) derived from history entries.
|
|
21
|
-
|
|
22
|
-
### Inventory module
|
|
23
|
-
- Uses core inventory tables (`inventory.reservation`, `inventory.stock`, `inventory.fulfillmentTask`, `inventory.statusHistory`, etc.) as defined in `../core/inventory-module.md`; not redefined here.
|
|
24
|
-
|
|
25
|
-
### Channel sync module
|
|
26
|
-
- `channel.stockFeed`: Snapshot of stock availability per storefront (SKU, channel SKU, available quantity, last synced at).
|
|
27
|
-
- `channel.fulfilmentFeed`: Outbound acknowledgements (tracking numbers, shipped quantity) queued for storefront APIs.
|
|
28
|
-
|
|
29
|
-
## Order Status
|
|
30
|
-
|
|
31
|
-
Baseline `order:*` statuses appear in [Order Module Core Contract](../order-module-core-contract.md#order-status-vocabulary). Multi-storefront flows add the following channel and inventory signals:
|
|
32
|
-
|
|
33
|
-
| Label | Writer | Trigger timing | Notes |
|
|
34
|
-
| --- | --- | --- | --- |
|
|
35
|
-
| `channel:captured` | Order module (on behalf of channel) | Immediately after `orderIntentIngestor` creates the core order and records the channel mapping. | Confirms that the storefront intent has been accepted into the core system. |
|
|
36
|
-
| `inventory:reservation_confirmed` | Inventory module | When stock is successfully reserved. | Signals to channels that fulfilment can proceed. |
|
|
37
|
-
| `inventory:reservation_backordered` | Inventory module | When stock is insufficient and a backorder is created. | Allows channel integration to notify storefronts about delays. |
|
|
38
|
-
| `inventory:shipped` | Inventory module / Warehouse | After fulfilment tasks complete and goods leave the warehouse. | Provides shipment milestone prior to storefront acknowledgement. |
|
|
39
|
-
| `channel:reservation_confirmed` | Channel integration | When `channelReservationProjector` reflects inventory confirmation back to the storefront. | Keeps channel dashboards consistent with internal state. |
|
|
40
|
-
| `channel:acknowledged` | Channel integration | Once the storefront API confirms receipt of fulfilment or stock updates. | Closes the loop and highlights any outstanding acknowledgements. |
|
|
41
|
-
|
|
42
|
-
## Executor Triggers
|
|
43
|
-
|
|
44
|
-
| Trigger table (module) | Writers (modules) | Activation timing | Target executor (module) | Responsibility |
|
|
45
|
-
| --- | --- | --- | --- | --- |
|
|
46
|
-
| `order.orderIntent` (order) | Channel integration (via contract) | Record creation (CDC) | `orderIntentIngestor` (order) | Validate intent, ensure idempotency, create `order.order`, append `channel:captured` entry to `orderStatusHistory`, and register mapping in `channel.orderMapping`. |
|
|
47
|
-
| `order.order` (order) | Order (owner) | Record creation (CDC) | `inventoryReservationIntake` (inventory) | Reserve shared stock for the order; write `inventory:reservation_*` statuses. |
|
|
48
|
-
| `inventory.reservation` (inventory) | Inventory (owner) | Record creation or update (CDC) | `channelReservationProjector` (channel integration) | Evaluate reservation results; update `channel.statusProjection` and append statuses (`channel:reservation_confirmed`, etc.). |
|
|
49
|
-
| `inventory.fulfilmentTask` (inventory) | Inventory (owner), warehouse systems | Record update (CDC) | `channelFulfilmentNotifier` (channel sync) | When tasks complete, enqueue shipping confirmations in `channel.fulfilmentFeed` and append `inventory:shipped` history entries. |
|
|
50
|
-
| `channel.fulfilmentFeed` (channel sync) | Channel sync (owner) | Record update (CDC) | `channelAckTracker` (channel integration) | Confirm storefront receipt of fulfilment data; append `channel:acknowledged` history entry when storefront confirms. |
|
|
51
|
-
| `inventory.stock` (inventory) | Inventory (owner) | Record update (CDC) | `channelStockPublisher` (channel sync) | Refresh `channel.stockFeed` to push near real-time stock availability to storefronts. |
|
|
52
|
-
|
|
53
|
-
## Flow
|
|
54
|
-
1. Shopify and Amazon orders are ingested by the channel integration module, stored in `channel.orderCapture` for traceability, deduped, and transformed into `order.orderIntent` records through the order contract.
|
|
55
|
-
2. `orderIntentIngestor` validates each intent, creates the core `order.order`, writes the channel mapping, and inserts a `channel:captured` row in `orderStatusHistory`.
|
|
56
|
-
3. The order creation triggers `inventoryReservationIntake`, which reserves stock. Depending on availability, it inserts statuses such as `inventory:reservation_confirmed` or `inventory:reservation_backordered`.
|
|
57
|
-
4. Reservation outcomes trigger `channelReservationProjector`, which updates `channel.statusProjection` for each storefront and writes additional history entries so UIs can display per-channel progress.
|
|
58
|
-
5. Warehouse operations progress via `inventory.fulfilmentTask`. When tasks complete, `channelFulfilmentNotifier` produces `channel.fulfilmentFeed` rows and appends `inventory:shipped` history entries.
|
|
59
|
-
6. `channelStockPublisher` listens to `inventory.stock` updates and refreshes `channel.stockFeed`, ensuring storefronts receive the latest availability for overselling prevention.
|
|
60
|
-
7. Storefronts acknowledge shipments and stock updates via APIs. `channelAckTracker` marks `channel.fulfilmentFeed` entries as confirmed and writes `channel:acknowledged` status history rows. Pending acknowledgements remain visible for support teams.
|
|
61
|
-
8. Customer-facing applications query `orderStatusHistory` (or derived views) to render timelines, while channel dashboards rely on `channel.statusProjection` for storefront-specific messaging.
|
|
62
|
-
|
|
63
|
-
```mermaid
|
|
64
|
-
sequenceDiagram
|
|
65
|
-
actor Shopify
|
|
66
|
-
actor Amazon
|
|
67
|
-
participant Channel as ChannelIntegration
|
|
68
|
-
participant Order
|
|
69
|
-
participant Inventory
|
|
70
|
-
participant Sync as ChannelSync
|
|
71
|
-
actor Warehouse
|
|
72
|
-
|
|
73
|
-
Shopify->>Channel: push order payload
|
|
74
|
-
Amazon->>Channel: push order payload
|
|
75
|
-
Channel->>Channel: store channel.orderCapture & dedupe
|
|
76
|
-
Channel->>Order: write order.orderIntent via contract
|
|
77
|
-
Order->>Order: orderIntentIngestor creates order + status history
|
|
78
|
-
Order-->>Inventory: order.order CDC event
|
|
79
|
-
Inventory->>Inventory: inventoryReservationIntake reserves stock
|
|
80
|
-
Inventory-->>Channel: reservation CDC updates status projection
|
|
81
|
-
Inventory->>Warehouse: emit fulfilmentTask
|
|
82
|
-
Warehouse-->>Inventory: complete fulfilmentTask
|
|
83
|
-
Inventory->>Sync: channelFulfilmentNotifier enqueues fulfilmentFeed
|
|
84
|
-
Sync->>Shopify: send shipment & stock update
|
|
85
|
-
Sync->>Amazon: send shipment & stock update
|
|
86
|
-
Shopify-->>Channel: ack shipment
|
|
87
|
-
Amazon-->>Channel: ack shipment
|
|
88
|
-
Channel->>Order: channelAckTracker appends status history
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Design Considerations
|
|
92
|
-
- Keep the order module channel-neutral; storefront-specific payloads stay in channel integration tables, while `order.orderIntent` only contains the normalised fields required by the core order schema.
|
|
93
|
-
- Maintain idempotent ingestion: dedupe channel payloads (channel order id + storefront id) before writing to `order.orderIntent` so order ingestion remains idempotent.
|
|
94
|
-
- Version the `orderIntent` contract and publish compatibility guidelines so new fields roll out without breaking existing channel connectors.
|
|
95
|
-
- Use `orderStatusHistory` to represent storefront and inventory milestones; avoid proliferating channel fields on the order record.
|
|
96
|
-
- Provide per-channel projections (`channel.statusProjection`) to avoid overloading shared history queries when storefront portals need dedicated filters.
|
|
97
|
-
- Stock publishing should throttle or batch updates per storefront to honour API limits while still preventing overselling.
|
|
98
|
-
- Errors in storefront communication should create `severity = 'blocking'` history entries so billing/fulfilment can pause until acknowledgements arrive.
|
|
99
|
-
- Document the vocabulary of channel statuses (e.g., `channel:captured`, `channel:acknowledged`) so downstream consumers interpret them consistently.
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# Order Payment Status Scenario
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
This document captures a reference flow where the order module owns the canonical order status while collaborating with optional billing, authorization, and cash receipt modules. The order module remains usable as a standalone component—for example, back-office staff can record invoice or payment outcomes manually—while downstream modules add automation by reacting to order events and pushing their results back through status history entries. The shared contract that keeps order independent is defined in [Order Module Core Contract](../order-module-core-contract.md).
|
|
5
|
-
|
|
6
|
-
## Module Dependencies
|
|
7
|
-
|
|
8
|
-
| Module (package path) | Declared dependencies | Purpose |
|
|
9
|
-
| --- | --- | --- |
|
|
10
|
-
| Order (`packages/order-module`) | — | Publishes the `order.orderIntent` contract, stores canonical orders, and exposes status history consumed by downstream financial modules. |
|
|
11
|
-
| Payment authorization (`packages/payment-authorization-module`) | Order | Manages authorization holds/captures against external PSPs and appends payment statuses to `orderStatusHistory`. |
|
|
12
|
-
| Billing (`packages/billing-module`) | Order, Payment authorization | Generates invoices (manually or automatically), links them to authorizations, and writes billing milestones into `orderStatusHistory`. |
|
|
13
|
-
| Cash receipt (`packages/cash-receipt-module`) | Order, Billing | Records cash inflows, allocates them to invoices, and publishes settlement statuses into `orderStatusHistory`. |
|
|
14
|
-
|
|
15
|
-
## TailorDB Tables and Views
|
|
16
|
-
### Payment authorization module
|
|
17
|
-
- `authorization.request`: Outbound authorization attempts for a given order.
|
|
18
|
-
- `authorization.result`: Holds/voids/captures returned from the PSP.
|
|
19
|
-
- Appends `payment:*` entries (e.g., `payment:authorized`, `payment:capture_failed`) to `orderStatusHistory` via the order dependency.
|
|
20
|
-
|
|
21
|
-
### Billing module
|
|
22
|
-
- `billing.invoice`: Invoices generated for orders.
|
|
23
|
-
- `billing.invoiceStatus`: Derived view summarizing invoice state (issued, posted, settled).
|
|
24
|
-
- Appends `billing:*` milestones (e.g., `billing:invoice_issued`, `billing:settled`) to `orderStatusHistory` and maintains projections for finance dashboards.
|
|
25
|
-
|
|
26
|
-
### Cash receipt module
|
|
27
|
-
- `cash.receipt`: Records individual cash inflows.
|
|
28
|
-
- `cash.receiptAllocation`: Maps receipts to invoices.
|
|
29
|
-
- Appends `cash:*` history entries (`cash:payment_applied`, `cash:refund_requested`) to provide audit traces within `orderStatusHistory`.
|
|
30
|
-
|
|
31
|
-
## Order Status
|
|
32
|
-
|
|
33
|
-
Baseline `order:*` statuses are documented in [Order Module Core Contract](../order-module-core-contract.md#order-status-vocabulary). Financial automation contributes the following additional entries:
|
|
34
|
-
|
|
35
|
-
| Label | Writer | Trigger timing | Notes |
|
|
36
|
-
| --- | --- | --- | --- |
|
|
37
|
-
| `payment:authorization_pending` | Payment authorization | Immediately after `paymentAuthorizationIntake` enqueues an authorization attempt. | Communicates that an authorization request is in flight. |
|
|
38
|
-
| `payment:authorized` | Payment authorization | When the PSP returns a successful authorization or capture. | Used to gate invoice issuance or fulfilment release. |
|
|
39
|
-
| `payment:capture_failed` | Payment authorization | Upon PSP decline or technical failure. | Prompts support teams to investigate or retry. |
|
|
40
|
-
| `billing:invoice_requested` | Billing | When `billingOrderIntake` decides to create an invoice. | Marks the start of the billing workflow even before the invoice record exists. |
|
|
41
|
-
| `billing:invoice_issued` | Billing | After an invoice is generated. | Downstream consumers can inform customers or trigger collections. |
|
|
42
|
-
| `billing:settled` | Billing | Once the invoice is fully settled in billing systems. | Often paired with cash entries for complete reconciliation. |
|
|
43
|
-
| `cash:payment_applied` | Cash receipt | When cash is allocated to the invoice covering the order. | Confirms funds have been received and matched. |
|
|
44
|
-
| `cash:refund_requested` | Cash receipt | If a refund or reversal is initiated. | Allows order timelines to reflect outstanding customer adjustments. |
|
|
45
|
-
|
|
46
|
-
## Executor Triggers
|
|
47
|
-
|
|
48
|
-
| Trigger table (module) | Writers (modules) | Activation timing | Target executor (module) | Responsibility |
|
|
49
|
-
| --- | --- | --- | --- | --- |
|
|
50
|
-
| `order.order` (order) | Order (owner), back-office operators | Record creation or update (CDC) | `billingOrderIntake` (billing) | React to new or updated orders, create invoices when automation is enabled, and append `billing:invoice_requested` statuses. |
|
|
51
|
-
| `order.order` (order) | Order (owner), back-office operators | Record creation or update (CDC) | `paymentAuthorizationIntake` (payment authorization) | Initiate or refresh authorization attempts based on order state or manual triggers; append `payment:authorization_pending` status. |
|
|
52
|
-
| `authorization.result` (payment authorization) | Payment authorization (owner) | Record creation or update (CDC) | `authorizationStatusWriter` (payment authorization) | Append authorization outcomes to `orderStatusHistory` (`payment:authorized`, `payment:capture_failed`) and refresh module projections. |
|
|
53
|
-
| `billing.invoice` (billing) | Billing (owner), operators | Record creation or update (CDC) | `billingStatusWriter` (billing) | Append invoice lifecycle entries (`billing:invoice_issued`, `billing:invoice_posted`) to `orderStatusHistory`. |
|
|
54
|
-
| `billing.invoiceStatus` (billing) | Billing (derived) | View refresh | `billingSettlementWriter` (billing) | Append settlement milestones (`billing:settled`) and update finance dashboards. |
|
|
55
|
-
| `cash.receiptAllocation` (cash receipt) | Cash receipt (owner) | Record creation or update (CDC) | `cashReceiptOrderWriter` (cash receipt) | Append `cash:payment_applied` entries and emit reconciliation tasks when allocations differ from expectations. |
|
|
56
|
-
|
|
57
|
-
## Flow
|
|
58
|
-
1. A new order intent is submitted (automated integration or operator input). The order module validates it, persists `order.order`, and emits a CDC event.
|
|
59
|
-
2. The billing and payment authorization modules listen to that CDC stream. If enabled, their executors (`billingOrderIntake`, `paymentAuthorizationIntake`) create invoices or authorization requests and append pending statuses (`billing:invoice_requested`, `payment:authorization_pending`). Otherwise they ignore the event, allowing manual workflows.
|
|
60
|
-
3. Authorization results are written to `authorization.result`. The `authorizationStatusWriter` executor appends outcomes such as `payment:authorized` or `payment:capture_failed` to `orderStatusHistory`, enabling order consumers to track financial progress without exposing PSP details.
|
|
61
|
-
4. Billing lifecycle changes (automation or manual invoice entry) update `billing.invoice` / `billing.invoiceStatus`. Billing executors append milestones (`billing:invoice_issued`, `billing:settled`) to `orderStatusHistory` and refresh their projections.
|
|
62
|
-
5. Cash receipts allocate payments to invoices via `cash.receiptAllocation`. The cash receipt executor appends settlement statuses (`cash:payment_applied`) so customer service teams can view payment confirmations from the order timeline.
|
|
63
|
-
6. Operators can always append manual entries to `orderStatusHistory` (e.g., `manual:write_off`) to reflect adjustments; downstream modules treat those entries as authoritative signals and reconcile their own records accordingly.
|
|
64
|
-
|
|
65
|
-
```mermaid
|
|
66
|
-
sequenceDiagram
|
|
67
|
-
actor Operator
|
|
68
|
-
participant Order
|
|
69
|
-
participant Billing
|
|
70
|
-
participant Auth as PaymentAuth
|
|
71
|
-
participant Cash
|
|
72
|
-
|
|
73
|
-
Operator->>Order: submit orderIntent (manual or automated)
|
|
74
|
-
Order->>Order: orderIntentIngestor creates order.order
|
|
75
|
-
Order-->>Billing: order.order CDC event
|
|
76
|
-
Billing->>Billing: billingOrderIntake decides on automation
|
|
77
|
-
Billing->>Order: append billing:* status history entries
|
|
78
|
-
Order-->>Auth: order.order CDC event
|
|
79
|
-
Auth->>Auth: paymentAuthorizationIntake initiates auth request
|
|
80
|
-
Auth->>Order: append payment:* status history entries
|
|
81
|
-
Billing->>Billing: invoice lifecycle progresses
|
|
82
|
-
Billing->>Order: append billing:settled when complete
|
|
83
|
-
Cash-->>Billing: cash.receiptAllocation links receipt to invoice
|
|
84
|
-
Cash->>Order: append cash:payment_applied status
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Design Considerations
|
|
88
|
-
- Keep configuration dependencies directional: downstream financial modules depend on order, not the other way around, following the guidance in `../order-module-core-contract.md`.
|
|
89
|
-
- Downstream modules append to `orderStatusHistory` using namespace-qualified status codes instead of mutating `order.order` fields, preserving the clean core.
|
|
90
|
-
- CDC-driven automation should be idempotent and tolerant of manual changes, reconciling rather than overwriting operator inputs.
|
|
91
|
-
- Maintain documented vocabularies for `payment:*`, `billing:*`, and `cash:*` statuses so shared dashboards interpret them consistently.
|
|
92
|
-
- Leverage projections (e.g., `order.financialStatusProjection`) for read-heavy contexts while keeping `orderStatusHistory` as the authoritative audit trail.
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# Procurement Order Scenario
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
This document illustrates how an order module cooperates with a procurement module when customer demand is fulfilled through supplier purchase orders rather than internal stock. The order module remains a clean, customer-facing source of truth, while procurement owns supplier relationships, purchase orders, and inbound logistics. The goal is to let organizations operate mixed models (stocked items vs. drop-ship) without embedding procurement concerns into the core order schema. The shared order contract that keeps the core independent is described in [Order Module Core Contract](../order-module-core-contract.md).
|
|
5
|
-
|
|
6
|
-
## Module Dependencies
|
|
7
|
-
|
|
8
|
-
| Module (package path) | Declared dependencies | Purpose |
|
|
9
|
-
| --- | --- | --- |
|
|
10
|
-
| Order (`packages/order-module`) | — | Publishes the `order.orderIntent` contract, stores canonical orders, and exposes status history for downstream modules. |
|
|
11
|
-
| Procurement (`packages/procurement-module`) | Order, Commerce core | Generates and tracks supplier purchase orders, manages inbound shipments, and appends procurement milestones to `orderStatusHistory`. |
|
|
12
|
-
| Commerce core (`packages/commerce-core-module`) | — | Provides product master data, supplier catalogs, and lead-time metadata consumed by procurement. |
|
|
13
|
-
| Inventory (`packages/inventory-module`) | Procurement, Commerce core | Optionally tracks goods received into stock or cross-docking locations. |
|
|
14
|
-
| Billing (`packages/billing-module`) | Order | Handles customer invoicing; may wait for procurement confirmation before finalizing revenue. |
|
|
15
|
-
|
|
16
|
-
## TailorDB Tables and Views
|
|
17
|
-
### Procurement module
|
|
18
|
-
- `procurement.purchaseOrder`: Supplier-facing purchase orders referencing `orderId` and line allocations.
|
|
19
|
-
- `procurement.supplier`: Master data for suppliers, including lead times, payment terms, and partner IDs.
|
|
20
|
-
- `procurement.inboundShipment`: Tracks ASN (advance shipping notice), shipment status, and expected arrival.
|
|
21
|
-
- `procurement.exceptions`: Captures issues such as supplier delays, quantity shortages, or quality holds.
|
|
22
|
-
- `procurement.orderStatus`: Projection of procurement milestones per order (PO issued, supplier confirmed, shipment dispatched, received).
|
|
23
|
-
- Appends `procurement:*` entries to `orderStatusHistory` for shared visibility while keeping detailed supplier data inside procurement-owned tables.
|
|
24
|
-
|
|
25
|
-
### Inventory module (optional)
|
|
26
|
-
- Uses core inventory tables (`inventory.stock`, `inventory.stockLedger`, etc.) as defined in `../core/inventory-module.md` to reflect inbound receipts and stock updates; not redefined here.
|
|
27
|
-
- `inventory.receipt`: Scenario-specific record for booking inbound shipments into stock or cross-dock locations.
|
|
28
|
-
|
|
29
|
-
## Order Status
|
|
30
|
-
|
|
31
|
-
Baseline `order:*` statuses are defined in [Order Module Core Contract](../order-module-core-contract.md#order-status-vocabulary). Procurement adds the following milestones:
|
|
32
|
-
|
|
33
|
-
| Label | Writer | Trigger timing | Notes |
|
|
34
|
-
| --- | --- | --- | --- |
|
|
35
|
-
| `procurement:po_issued` | Procurement module | Immediately after `procurementOrderIntake` creates a purchase order. | Indicates supplier engagement has started. |
|
|
36
|
-
| `procurement:po_confirmed` | Procurement module | When the supplier confirms the purchase order. | Confirms expected ship dates and quantities. |
|
|
37
|
-
| `procurement:asn_received` | Procurement module | Upon receiving an ASN or shipment notice. | Signals inbound logistics to prepare for receipt. |
|
|
38
|
-
| `procurement:received` | Procurement module / Inventory module | When goods are fully received and reconciled. | Allows billing or fulfilment to proceed confidently. |
|
|
39
|
-
| `procurement:short_shipment` | Procurement module | If received quantity is less than ordered. | Highlights the need for back-order or customer communication. |
|
|
40
|
-
| `procurement:blocking_exception` | Procurement module | When an exception (delay, quality hold) blocks fulfilment. | Downstream modules should pause until resolved. |
|
|
41
|
-
|
|
42
|
-
## Executor Triggers
|
|
43
|
-
|
|
44
|
-
| Trigger table (module) | Writers (modules) | Activation timing | Target executor (module) | Responsibility |
|
|
45
|
-
| --- | --- | --- | --- | --- |
|
|
46
|
-
| `order.order` (order) | Order (owner), operators | Record creation or update (CDC) | `procurementOrderIntake` (procurement) | Decide whether a purchase order is needed based on product supply policies and current stock; create or update `procurement.purchaseOrder` rows. |
|
|
47
|
-
| `procurement.purchaseOrder` (procurement) | Procurement (owner) | Record creation or update (CDC) | `procurementPOStatusProjector` (procurement) | Update supplier confirmations, expected ship dates, and project milestones into `procurement.orderStatus`. |
|
|
48
|
-
| `procurement.inboundShipment` (procurement) | Procurement (owner), suppliers via EDI | Record creation or update (CDC) | `procurementInboundCoordinator` (inventory) | Trigger inbound logistics tasks, e.g., allocate receiving docks or generate `inventory.receipt` placeholders. |
|
|
49
|
-
| `inventory.receipt` (inventory) | Inventory (owner) | Record creation (CDC) | `procurementReceiptReconciler` (procurement) | Match receipts to purchase orders, update quantities received, and close out procurement exceptions. |
|
|
50
|
-
| `procurement.exceptions` (procurement) | Procurement (owner), operators | Record creation or update (CDC) | `procurementExceptionProjector` (procurement) | Reflect exception state in `procurement.orderStatus` and expose signals (e.g., blocks) for downstream modules. |
|
|
51
|
-
|
|
52
|
-
## Flow
|
|
53
|
-
1. An order intent is submitted. After validation, the order module persists `order.order` and emits a CDC event that triggers `procurementOrderIntake`.
|
|
54
|
-
2. Procurement evaluates supply policies, available stock, and supplier contracts. If a supplier order is required, it creates `procurement.purchaseOrder` entries linking each order line to a supplier and expected ship date, and appends `procurement:po_issued` to `orderStatusHistory`.
|
|
55
|
-
3. Suppliers confirm the purchase order through EDI/API or operator input. `procurement.purchaseOrder` updates drive `procurementPOStatusProjector`, which writes milestones (confirmed, delayed, partial) into `procurement.orderStatus` and appends corresponding entries (e.g., `procurement:po_confirmed`) to `orderStatusHistory`.
|
|
56
|
-
4. When suppliers send advance shipping notices, `procurement.inboundShipment` records are created. `procurementInboundCoordinator` may allocate receiving resources or pre-create `inventory.receipt` placeholders while recording `procurement:asn_received` in the shared history.
|
|
57
|
-
5. Upon physical receipt, the inventory module records `inventory.receipt`, triggering `procurementReceiptReconciler` to update received quantities, close or escalate procurement exceptions, and append `procurement:received` or `procurement:short_shipment` statuses for order-facing consumers.
|
|
58
|
-
6. Any exceptions (short shipments, quality holds, supplier delays) are logged in `procurement.exceptions`. `procurementExceptionProjector` updates `procurement.orderStatus` and surfaces blocking flags via `orderStatusHistory` so downstream modules can pause fulfilment or billing.
|
|
59
|
-
7. Once procurement confirms completion, order and billing experiences reference `procurement.orderStatus` alongside the shared history to release fulfilment and issue invoices when appropriate.
|
|
60
|
-
|
|
61
|
-
```mermaid
|
|
62
|
-
sequenceDiagram
|
|
63
|
-
actor Customer
|
|
64
|
-
participant Order
|
|
65
|
-
participant Procurement
|
|
66
|
-
actor Supplier
|
|
67
|
-
participant Inventory
|
|
68
|
-
participant Billing
|
|
69
|
-
|
|
70
|
-
Customer->>Order: submit orderIntent
|
|
71
|
-
Order->>Order: orderIntentIngestor creates order.order
|
|
72
|
-
Order-->>Procurement: order.order CDC event
|
|
73
|
-
Procurement->>Procurement: procurementOrderIntake creates purchaseOrder
|
|
74
|
-
Procurement->>Order: append procurement:po_issued status
|
|
75
|
-
Procurement->>Supplier: send purchase order
|
|
76
|
-
Supplier-->>Procurement: confirmation updates purchaseOrder
|
|
77
|
-
Procurement->>Order: append procurement:po_confirmed status
|
|
78
|
-
Supplier-->>Procurement: send inboundShipment/ASN
|
|
79
|
-
Procurement->>Order: append procurement:asn_received status
|
|
80
|
-
Procurement->>Inventory: procurementInboundCoordinator prepares receipt
|
|
81
|
-
Inventory->>Inventory: record inventory.receipt
|
|
82
|
-
Inventory-->>Order: append procurement:received / procurement:short_shipment statuses
|
|
83
|
-
Procurement->>Procurement: procurementExceptionProjector updates orderStatus view
|
|
84
|
-
Procurement-->>Order: expose orderStatus for fulfillment/billing decisions
|
|
85
|
-
Order-->>Billing: release for invoicing once procurement complete
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
## Design Considerations
|
|
89
|
-
- Keep procurement logic modular so order can operate without it (e.g., stocked items). The intake executor should be configuration-driven (per SKU, channel, or merchant) and must adhere to `../order-module-core-contract.md`.
|
|
90
|
-
- Purchase orders may aggregate multiple customer orders; ensure `procurement.purchaseOrder` links to both supplier PO numbers and individual order line allocations.
|
|
91
|
-
- Exceptions should be first-class records with lifecycle management, enabling reporting and SLA tracking.
|
|
92
|
-
- Append procurement milestones to `orderStatusHistory` with namespace-qualified codes (`procurement:*`) so order-facing teams share a single timeline.
|
|
93
|
-
- Inventory integration is optional: drop-ship flows might bypass inventory entirely, while cross-docking requires temporary receipts.
|
|
94
|
-
- Billing should respect procurement status, especially when revenue recognition depends on supplier confirmation or goods receipt.
|
|
95
|
-
- Expose `procurement.orderStatus` as a read-only interface for order, billing, or customer-facing channels rather than duplicating timelines inside the order schema.
|