---
name: domain-model
scope: platform
description: "Fluent Commerce domain model — all entities, GraphQL edges, and cross-domain relationships. Validated against live schema 2026-02-27."
load: on-demand
priority: high
relevant-skills: [fluent-workflow-builder, fluent-mystique-builder, fluent-rule-scaffold, fluent-feature-plan, fluent-custom-code, fluent-settings, fluent-trace, fluent-implementation-map, fluent-feature-explain, fluent-connection-analysis, fluent-scope-decompose]
relevant-entities: [ORDER, FULFILMENT, FULFILMENT_CHOICE, ARTICLE, RETURN_ORDER, LOCATION, INVENTORY_POSITION, WAVE, CONSIGNMENT, PRODUCT, CUSTOMER, CARRIER, VIRTUAL_CATALOGUE, NETWORK, CREDIT_MEMO, BILLING_ACCOUNT, INVOICE, FINANCIAL_TRANSACTION, PAYMENT, MANIFEST]
version: 1.0
last-updated: 2026-02-27
author: schema-introspection
source: https://docs.fluentcommerce.com/essential-knowledge/domain-model-entities
---

# Fluent Commerce Domain Model (Schema-Validated)

> Extracted from official docs, then validated against the live GraphQL schema.
> Corrections and additions marked with `[SCHEMA]` where the docs are incomplete or inaccurate.

---

## 1. Order Orchestration Domain

Represents and stores details about all orders across the Fluent platform.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **Order** | `orderById`, `orders` | Yes | Customer checkout record. Contains fulfilment choices, items, financial transactions. |
| **FulfilmentChoice** | `fulfilmentChoiceById`, `fulfilmentChoices` | Yes `[SCHEMA]` | Delivery preference (HD/CC/SFS). **Docs treat this as an Order property but it is a separate orchestrable entity with its own workflow, status, and connections.** |
| **Fulfilment** | `fulfilmentById`, `fulfilments` | Yes | Plan for stock movement from a source location. Created when order is sourced. |
| **Article** | `articleById`, `articles` | Yes | Physical parcel (box, satchel, pallet) transporting items from dispatch to destination. |
| **ReturnOrder** | `returnOrder`, `returnOrders` | Yes | Return request — created after order has been fulfilled. |
| **ReturnFulfilment** | `returnFulfilment`, `returnFulfilments` | Yes | Physical return movement associated with a ReturnOrder. |
| **Customer** | `customerById`, `customers` | No | Entity that purchases goods. **No direct edge to orders in schema — query orders with customer filter.** |
| **Consignment** | `consignmentById`, `consignments` | Yes `[CORRECTED 2026-03-02]` | Orchestrable shipping entity for a parcel — has its own workflow and status transitions. Distinct from CarrierConsignment (see Shipping domain). |

### GraphQL Edges (Order)

```
Order
  ├── retailer            → Retailer
  ├── customer            → Customer (id-based)
  ├── customerLink        → Customer (ref-based) [SCHEMA: not in docs]
  ├── fulfilmentChoice    → FulfilmentChoice (singular, primary)
  ├── fulfilmentChoices   → FulfilmentChoice[] (connection, all)
  ├── items               → OrderItem[] (connection)
  ├── fulfilments         → Fulfilment[] (connection)
  ├── financialTransactions → FinancialTransaction[] (connection)
  ├── payment             → Payment (ref-based)
  └── billingAddress      → Address
      Scalars: totalPrice, totalTaxPrice, ref2, tag1, tag2, tag3
```

### GraphQL Edges (Fulfilment)

```
Fulfilment
  ├── order               → Order
  ├── waves               → Wave[] (connection) [SCHEMA: cross-domain link]
  ├── articles            → Article[] (connection)
  ├── items               → FulfilmentItem[] (connection)
  ├── rejections          → FulfilmentItemRejection[] (connection) [SCHEMA: not in docs]
  ├── consignments        → Consignment[] (connection) [SCHEMA: not in docs]
  ├── payments            → Payment[] (connection) [SCHEMA: not in docs]
  ├── user                → User (assigned picker/packer) [SCHEMA: not in docs]
  ├── fromLocation        → Location (ref-based)
  ├── fromAddress         → Address
  └── toAddress           → Address
      Scalars: deliveryType, type, eta, expiryTime, fulfilmentChoiceRef
```

### GraphQL Edges (FulfilmentChoice)

```
FulfilmentChoice [SCHEMA: full orchestrable entity, NOT just an Order property]
  ├── items               → FulfilmentChoiceItem[] (connection)
  ├── fulfilments         → Fulfilment[] (connection)
  └── deliveryAddress     → Address
      Scalars: currency, deliveryType, fulfilmentType, fulfilmentPrice,
               fulfilmentTaxPrice, pickupLocationRef, deliverAfter/Before, dispatchOn
```

### GraphQL Edges (Article)

```
Article
  ├── items                     → ArticleItem[] (connection)
  ├── fulfilments               → Fulfilment[] (connection)
  ├── consignmentArticles       → ConsignmentArticle[] (connection) [SCHEMA: join entity]
  ├── carrierConsignmentArticles → CarrierConsignmentArticle[] (connection) [SCHEMA: join entity]
  └── storageArea               → StorageArea [SCHEMA: not in docs]
      Scalars: description, height, length, width, weight, quantity, name
```

### GraphQL Edges (ReturnOrder)

```
ReturnOrder
  ├── order                → Order
  ├── customer             → Customer (ref-based)
  ├── returnOrderItems     → ReturnOrderItem[] (connection)
  ├── returnOrderFulfilments → ReturnFulfilment[] (connection)
  ├── returnVerifications  → ReturnVerification[] (connection) [SCHEMA: not in docs]
  ├── exchangeOrder        → Order [SCHEMA: not in docs — for exchange flows]
  ├── creditMemo           → CreditMemo [SCHEMA: not in docs — direct billing link]
  ├── lodgedLocation       → Location (ref-based)
  ├── destinationLocation  → Location
  └── pickupAddress        → Address
      Scalars: returnAuthorisationKey, returnAuthorisationKeyExpiry,
               currency, subTotalAmount, totalTax, totalAmount
```

### GraphQL Edges (Customer)

```
Customer
  └── retailer             → Retailer
      Scalars: title, department, country, firstName, lastName, username,
               primaryEmail, primaryPhone, timezone, promotionOptIn
      NOTE: No direct orders/fulfilments edge — use orders(customerId:) filter
```

---

## 2. Billing Management Domain

Facilitates the management of all billing requirements across the Fluent platform.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **BillingAccount** | `billingAccount`, `billingAccounts` | Yes | Master billing entity — holds invoices, credit memos, payments. |
| **Invoice** | `invoice`, `invoices` | Yes | Sales transaction between buyer and seller. |
| **CreditMemo** | `creditMemo`, `creditMemoes` | Yes | Reduction/refund — evidence of change in a sale. |
| **Payment** | `payment`, `payments` | Yes `[SCHEMA]` | **Separate orchestrable entity (not mentioned in docs as distinct).** Links billing to orders/fulfilments. |

### GraphQL Edges (BillingAccount)

```
BillingAccount
  ├── customer             → Customer (ref-based)
  ├── retailer             → Retailer
  ├── payments             → Payment[] (connection)
  ├── creditMemos          → CreditMemo[] (connection)
  ├── invoices             → Invoice[] (connection)
  └── address              → Address
```

### GraphQL Edges (CreditMemo)

```
CreditMemo
  ├── billingAccount       → BillingAccount
  ├── invoice              → Invoice
  ├── items                → CreditMemoItem[] (connection)
  ├── order                → Order [SCHEMA: direct order link, not in docs]
  ├── returnOrder          → ReturnOrder [SCHEMA: return-based refund link, not in docs]
  └── payments             → Payment[] (connection) [SCHEMA: not in docs]
      Scalars: issueDate, currency, subTotalAmount, totalTax, totalAmount, totalBalance
```

### GraphQL Edges (Invoice)

```
Invoice
  ├── billingAccount       → BillingAccount
  ├── order                → Order
  ├── fulfilment           → Fulfilment [SCHEMA: not in docs — fulfilment-level billing]
  ├── items                → InvoiceItem[] (connection)
  └── creditMemos          → CreditMemo[] (inline, not connection)
      Scalars: issueDate, dueDate, currency, subTotalAmount, totalTax, totalAmount, totalBalance
```

### GraphQL Edges (Payment)

```
Payment [SCHEMA: entire entity missing from docs]
  ├── billingAccount       → BillingAccount
  ├── retailer             → Retailer
  ├── orders               → Order[] (connection)
  ├── financialTransaction → FinancialTransaction (singular)
  ├── fulfilment           → Fulfilment
  ├── creditMemo           → CreditMemo
  └── paymentTransactions  → PaymentTransaction[] (connection)
      Scalars: amount { amount, scale, unscaledValue }
```

---

## 3. Global Inventory Domain

Represents aggregations of product inventory across e-Commerce systems.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **ProductCatalogue** | `productCatalogue`, `productCatalogues` | Yes | Grouping of products and their attributes. |
| **Category** | `category`, `categories` | Yes | Product classification within a catalogue. |
| **StandardProduct** | `standardProduct`, `standardProducts` | Yes | Base product (detail page level). Typically has no inventory — customers buy variants. |
| **VariantProduct** | `variantProduct`, `variantProducts` | Yes | Variation of a base product (color, size). |
| **GroupProduct** | `groupProduct`, `groupProducts` | Yes | Bundle of products sold as a single item. |
| **InventoryCatalogue** | `inventoryCatalogue`, `inventoryCatalogues` | Yes | Tracks on-hand quantities by product + location. |
| **InventoryPosition** | `inventoryPosition`, `inventoryPositions` | Yes | Single product at a single location — the core inventory record. |
| **InventoryQuantity** | `inventoryQuantity`, `inventoryQuantities` | Yes `[SCHEMA]` | Typed quantity bucket within an InventoryPosition. **Has workflowRef.** |
| **VirtualCatalogue** | `virtualCatalogue`, `virtualCatalogues` | Yes | Intersection of product catalogue + inventory catalogue + networks. Provides ATS view. |
| **VirtualPosition** | `virtualPosition`, `virtualPositions` | Yes | ATS for a single product at a location (or aggregate). |
| **ControlGroup** | `controlGroup`, `controlGroups` | Yes | Collection of buffers/exclusions affecting ATS calculation. |
| **Control** | `control`, `controls` | Yes | Individual buffer or exclusion rule. |

### GraphQL Edges (InventoryPosition)

```
InventoryPosition
  ├── product              → Product (generic)
  ├── location             → StoreAddress type (NOT Location entity!) [SCHEMA: confusing]
  ├── locationLink         → Location (actual Location entity) [SCHEMA: use this for entity traversal]
  ├── catalogue            → InventoryCatalogue
  ├── quantities           → InventoryQuantity[] (connection)
  └── quantitiesAggregate  → { sum, count } [SCHEMA: useful shortcut, not in docs]
      Scalars: productRef, locationRef, onHand
```

### GraphQL Edges (VirtualCatalogue)

```
VirtualCatalogue
  └── virtualPositions     → VirtualPosition[] (connection)
      Scalars (ref-based linking, NOT id-based edges):
        inventoryCatalogueRef, productCatalogueRef, controlGroupRef,
        networkIds (array), retailerRefs (array)
```

### GraphQL Edges (VirtualPosition)

```
VirtualPosition
  ├── product              → Product
  ├── locationLink         → Location
  └── catalogue            → VirtualCatalogue
      Scalars: quantity, groupRef, productRef
```

### GraphQL Edges (StandardProduct)

```
StandardProduct
  ├── catalogue            → ProductCatalogue
  ├── categories           → Category[] (connection)
  └── variants             → VariantProduct[] (connection)
      Scalars: gtin, name, summary, prices[], tax[]
```

---

## 4. Foundation Domain

Setup and configurations needed to build on the Fluent platform.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **Retailer** | `retailerById`, `retailers` | No | Business entity — distinct workflows, users, entities. |
| **Location** | `locationById`, `locations` | Yes | Physical place (store, warehouse, 3PL). Has LOCATION workflows (e.g., CREATED → ACTIVE). |
| **Network** | `networkById`, `networks` | No `[SCHEMA]` | Named group of locations (geographic or logical). **No workflowRef in schema.** |
| **StorageArea** | `storageAreaById`, `storageAreas` | No `[SCHEMA]` | Subdivision within a location (not in docs). |
| **OpeningSchedule** | `openingSchedules` | No `[SCHEMA]` | Location trading hours (not in docs as entity). |

> **Note:** `Account` is NOT a GraphQL entity — it's the implicit auth context.
> `Activity/Events` are accessed via the Event API, not GraphQL queries.

### GraphQL Edges (Location)

```
Location
  ├── retailer             → Retailer
  ├── primaryAddress       → StoreAddress
  ├── networks             → Network[] (connection)
  ├── storageAreas         → StorageArea[] (connection) [SCHEMA: not in docs]
  ├── openingSchedule      → OpeningSchedule [SCHEMA: not in docs]
  └── manifests            → Manifest[] (connection) [SCHEMA: shipping link, not in docs]
      Scalars: name, supportPhoneNumber, defaultCarrier, defaultCarrierName
```

### GraphQL Edges (Network)

```
Network
  ├── retailers            → Retailer[] (connection) [SCHEMA: not in docs — multi-retailer networks]
  └── locations            → Location[] (connection)
      Scalars: ref (NO name field!), type, status
```

---

## 5. Store Fulfilment Domain

Manages batch pick/pack/ship processes at locations.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **Wave** | `waveById`, `waves` | Yes | Batch grouping of fulfilments at a single location. |

### GraphQL Edges (Wave)

```
Wave
  ├── location             → Location
  ├── retailer             → Retailer
  ├── fulfilments          → Fulfilment[] (connection)
  ├── items                → WaveItem[] (connection) [SCHEMA: not in docs]
  ├── allocatedTo          → User [SCHEMA: assigned picker/packer, not in docs]
  └── processingLocation   → Location (ref-based) [SCHEMA: not in docs]
      Scalars: name, type
```

---

## 6. Security Domain

Users, roles, and permissions across the Fluent platform.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **User** | `userById`, `users` | No | System user with role-based access. |
| **Role** | `role`, `roles` | No | Set of permissions scoped to context. |
| **Permission** | `permission`, `permissions` | No | Individual capability. |

### Rubix Users (Workflow Execution Context)

Each retailer has a platform-managed **Rubix user** that the workflow engine authenticates as when executing rules.

| Property | Value |
|----------|-------|
| Naming | `<ACCOUNT>-<RETAILER_ID>-rubix` |
| Type | `API` (service account) |
| Scope | One per retailer, auto-created |
| Typical roles | `ADMIN` + `GRAPHQL` |

`context.api()` calls inside rules run under this user's permissions. The dispatching user's identity is NOT available to rules by default — pass via `@EventAttribute`.

### GraphQL Edges (User)

```
User
  ├── primaryRetailer      → Retailer [SCHEMA: not in docs]
  ├── primaryLocation      → Location [SCHEMA: not in docs — default store assignment]
  ├── retailer             → Retailer
  ├── roles                → { role: Role, contexts: Context[] }[] [SCHEMA: structured, not flat]
  └── apps                 → App[] [SCHEMA: assigned applications, not in docs]
      Scalars: firstName, lastName, username, primaryEmail, primaryPhone,
               department, country, timezone, language, promotionOptIn
```

---

## 7. Shipping Domain

Shipping labels, carriers, consignments, and manifests.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **Carrier** | `carrierById`, `carriers` | Yes | Delivery service provider. |
| **CarrierConsignment** | `carrierConsignment`, `carrierConsignments` | Yes | Shipping record for home delivery article. One per article max. |
| **Consignment** | `consignmentById`, `consignments` | Yes `[SCHEMA]` | **Separate from CarrierConsignment — docs don't distinguish these. Has workflowRef.** |
| **Manifest** | `manifest`, `manifests` | Yes | Shipping manifest — documents all shipment details for a dispatch. |
| **ConsignmentArticle** | `consignmentArticleById` | No `[SCHEMA]` | Join entity: Consignment ↔ Article. |
| **CarrierConsignmentArticle** | `carrierConsignmentArticleById` | No `[SCHEMA]` | Join entity: CarrierConsignment ↔ Article. |

### GraphQL Edges (Carrier)

```
Carrier
  ├── retailer             → Retailer
  ├── carrierConsignments  → CarrierConsignment[] (connection)
  └── manifests            → Manifest[] (array, not connection)
```

### GraphQL Edges (CarrierConsignment)

```
CarrierConsignment
  ├── carrier              → Carrier
  ├── retailer             → Retailer
  ├── carrierConsignmentArticles → CarrierConsignmentArticle[] (connection)
  └── manifests            → Manifest[] (connection)
      Scalars: consignmentReference, trackingLabel, labelUrl, orderSummaryUrl
```

### GraphQL Edges (Manifest)

```
Manifest
  ├── carrier              → Carrier
  ├── location             → Location [SCHEMA: dispatch location, not in docs]
  └── carrierConsignments  → CarrierConsignment[] (connection)
      Scalars: name, carrierManifestLink
```

### Article → Shipping Path

```
Article
  ├── consignmentArticles       → ConsignmentArticle → Consignment
  └── carrierConsignmentArticles → CarrierConsignmentArticle → CarrierConsignment
```

> **IMPORTANT:** The path from Article to shipping is through join entities, NOT direct edges.

---

## 8. Payment Domain

Payment processing and financial transaction records.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **FinancialTransaction** | `financialTransaction`, `financialTransactions` | Yes | Pre-auth token / payment record. Fluent does NOT store card details. |
| **Payment** | `payment`, `payments` | Yes `[SCHEMA]` | **Distinct entity (docs only mention FinancialTransaction).** Orchestrable billing-side payment. |
| **PaymentTransaction** | `paymentTransaction`, `paymentTransactions` | No `[SCHEMA]` | Granular transaction records within a Payment. |
| **PaymentServiceProvider** | `paymentServiceProvider`, `paymentServiceProviders` | No `[SCHEMA]` | Payment gateway configuration. |

### GraphQL Edges (FinancialTransaction)

```
FinancialTransaction
  ├── order                → Order
  └── payments             → Payment[] (connection)
      Scalars: total, scale, unscaledValue, currency, externalTransactionCode,
               externalTransactionId, cardType, paymentMethod, paymentProviderName
```

---

## 9. Product Availability Domain

Availability information and fulfilment planning.

### Entities

| Entity | GraphQL Root | Orchestrable | Description |
|--------|-------------|-------------|-------------|
| **FulfilmentOption** | `fulfilmentOptionById`, `fulfilmentOptions` | Yes | Availability request — returns multiple plans with ETA/pricing. |
| **FulfilmentPlan** | `fulfilmentPlanById`, `fulfilmentPlans` | Yes | Strategy for fulfilling an order — may require multiple fulfilments. |

### GraphQL Edges (FulfilmentOption)

```
FulfilmentOption
  └── plans                → FulfilmentPlan[] (connection)
      Scalars: retailerId, orderType, locationRef, trackingCode [SCHEMA: async lookup],
               products[] (inline: productRef, catalogueRef, requestedQuantity),
               address (inline)
```

### GraphQL Edges (FulfilmentPlan)

```
FulfilmentPlan
  ├── fulfilmentOption     → FulfilmentOption
  ├── fulfilments          → inline[] (NOT entity connection) [SCHEMA: important distinction]
  │     { fulfilmentType, locationRef, eta, items[] }
  └── exceptions           → { code, message, attributes }[] [SCHEMA: error reporting, not in docs]
      Scalars: splitCount, eta, retailerId
```

---

## 10. Additional Entities (Not in Domain Model Docs)

These exist in the GraphQL schema but are not documented in the domain model page.

| Entity | GraphQL Root | Orchestrable | Domain | Notes |
|--------|-------------|-------------|--------|-------|
| **InventoryFeed** | `inventoryFeed`, `inventoryFeeds` | No | Inventory | Import tracking |
| **InventoryFeedRun** | `inventoryFeedRun`, `inventoryFeedRuns` | No | Inventory | Feed execution records |
| **SourcingProfile** | `sourcingProfile`, `sourcingProfiles` | No | Availability | Responsive sourcing config |
| **ReturnVerification** | `returnVerifications` | No | Order | Return validation records |
| **FulfilmentItemRejection** | `fulfilmentItemRejections` | No | Order | Item rejection tracking |
| **CreditMemoItem** | `creditMemoItem`, `creditMemoItems` | No | Billing | Line items on credit memos |
| **InvoiceItem** | `invoiceItem`, `invoiceItems` | No | Billing | Line items on invoices |
| **ReturnOrderItem** | `returnOrderItem`, `returnOrderItems` | No | Order | Return line items |
| **ReturnFulfilmentItem** | `returnFulfilmentItems` | No | Order | Return fulfilment line items |
| **Currency** | `currency`, `currencies` | No | Billing | Currency configuration |
| **Comment** | `commentById`, `comments` | No | Foundation | Audit trail notes on any entity |

---

## Cross-Domain Relationship Map

```
ORDER ──fulfilments──→ FULFILMENT ──articles──→ ARTICLE ──consignmentArticles──→ CONSIGNMENT
  │                       │                       │
  ├──fulfilmentChoices──→ FULFILMENT_CHOICE       ├──carrierConsignmentArticles──→ CARRIER_CONSIGNMENT
  │                       │                       │                                    │
  ├──customer──→ CUSTOMER ├──waves──→ WAVE         └──storageArea──→ STORAGE_AREA       ├──carrier──→ CARRIER
  │                       │            │                                                │
  ├──financialTransactions──→ FINANCIAL_TRANSACTION                                     └──manifests──→ MANIFEST
  │                                                                                          │
  ├──payment──→ PAYMENT ──billingAccount──→ BILLING_ACCOUNT ──invoices──→ INVOICE             └──location──→ LOCATION
  │                │                          │                   │                                  │
  │                └──creditMemo──→ CREDIT_MEMO │                  └──fulfilment──→ FULFILMENT       ├──networks──→ NETWORK
  │                                            │                                                    │
  └──returnOrders (query)──→ RETURN_ORDER ─────┘                                                    └──storageAreas──→ STORAGE_AREA
                               │
                               ├──returnOrderFulfilments──→ RETURN_FULFILMENT
                               ├──exchangeOrder──→ ORDER
                               └──creditMemo──→ CREDIT_MEMO

PRODUCT_CATALOGUE ──categories──→ CATEGORY
       │
       └──standardProducts──→ STANDARD_PRODUCT ──variants──→ VARIANT_PRODUCT

INVENTORY_CATALOGUE ──inventoryPositions──→ INVENTORY_POSITION ──quantities──→ INVENTORY_QUANTITY
                                                │
                                                ├──product──→ PRODUCT
                                                └──locationLink──→ LOCATION

VIRTUAL_CATALOGUE ──virtualPositions──→ VIRTUAL_POSITION
  (refs: inventoryCatalogueRef, productCatalogueRef, controlGroupRef, networkIds)

CONTROL_GROUP ──controls──→ CONTROL

FULFILMENT_OPTION ──plans──→ FULFILMENT_PLAN
```

---

## Workflow Entity Hierarchy & CREATE Event Automation

Each workflow has a **root entity** (the workflow's `entityType`) and zero or more **sub-entities** that are
created/managed within the same workflow. Sub-entities share the parent workflow's lifecycle. The **Platform
CREATE Event** column indicates whether the `create<Entity>` GraphQL mutation automatically fires a `CREATE`
event into the workflow engine — enabling automatic rule execution on entity creation.

| Root Entity | Sub-Entities (in same workflow) | Event Reference | Platform CREATE Event? |
|---|---|---|---|
| **Location** | Wave | `LOCATION`, `WAVE` | LOCATION: No, WAVE: Yes |
| **Order** | Fulfilment, FulfilmentChoice, Article, Consignment | `ORDER`, `FULFILMENT`, `FULFILMENT_CHOICE`, `ARTICLE`, `CONSIGNMENT` | ORDER: Yes, FULFILMENT: Yes, FULFILMENT_CHOICE: Yes, ARTICLE: Yes, CONSIGNMENT: Yes |
| **Fulfilment Options** | Fulfilment Plan | `FULFILMENT_OPTIONS`, `FULFILMENT_PLAN` | Both: Yes |
| **Product Catalogue** | Standard Product, Variant Product, Group Product, Category | `PRODUCT_CATALOGUE`, `PRODUCT`, `CATEGORY` | All: Yes |
| **Inventory Catalogue** | Inventory Position, Inventory Quantity | `INVENTORY_CATALOGUE`, `INVENTORY_POSITION`, `INVENTORY_QUANTITY` | All: Yes |
| **Virtual Catalogue** | Virtual Position | `VIRTUAL_CATALOGUE`, `VIRTUAL_POSITION` | Both: No |
| **Control Group** | Control | `CONTROL_GROUP`, `CONTROL` | Both: No |
| **Return Order** | Return Fulfilment | `RETURN_ORDER`, `RETURN_FULFILMENT` | Both: Yes |
| **Billing Account** | Credit Memo, Invoice, Payment, Payment Transaction | `BILLING_ACCOUNT`, `CREDIT_MEMO`, `INVOICE`, `PAYMENT`, `PAYMENT_TRANSACTION` | All: Yes |

**Key implications:**
- **No CREATE event** (Location, Virtual Catalogue, Control Group): Entity creation does NOT trigger workflow rules. You must send an explicit event (e.g., `LOCATION_CREATED`) to kick off processing.
- **Has CREATE event** (Order, Fulfilment, etc.): The `createOrder`, `createFulfilment`, etc. mutations automatically fire a `CREATE` event. Workflows can have a ruleset triggered by `entityType: "ORDER"`, `eventName: "CREATE"` to begin processing immediately. See `knowledge/platform/create-order-reference.md` for full mutation input schemas, fulfilmentChoice wiring, and ORDER::MULTI patterns.
- **Sub-entities inherit the parent workflow**: A Fulfilment's statuses and rulesets are defined within the Order workflow (or a dedicated Fulfilment workflow). The workflow engine routes events by `entityType` + `entitySubtype`.

---

## Key Schema Gotchas

1. **FulfilmentChoice is a full entity** — has workflow, status, connections. Not just an Order property.
2. **Two consignment types** — `Consignment` and `CarrierConsignment` are separate entities with different schemas.
3. **Article → Shipping uses join entities** — `ConsignmentArticle` and `CarrierConsignmentArticle`, not direct edges.
4. **Customer has NO order edge** — query `orders(customerId:)` instead.
5. **InventoryPosition has dual location** — `location` (StoreAddress type) and `locationLink` (Location entity). Use `locationLink` for entity traversal.
6. **VirtualCatalogue uses ref-based links** — `inventoryCatalogueRef`, `productCatalogueRef`, `controlGroupRef`. No direct entity edges.
7. **Network has no `name` field** — use `ref` instead.
8. **Payment is a separate entity from FinancialTransaction** — docs only mention FinancialTransaction.
9. **FulfilmentPlan.fulfilments are inline data** — `{ fulfilmentType, locationRef, eta, items[] }`, not entity connections.
10. **ReturnOrder has exchangeOrder and creditMemo edges** — critical for exchange/refund flows.
11. **Invoice has a `fulfilment` edge** — billing can be fulfilment-level, not just order-level.
12. **Wave has `allocatedTo` (User)** — tracks who is picking/packing.
13. **Fulfilment has `consignments` and `payments` connections** — shipping and billing at fulfilment level.

---

## All GraphQL Query Roots (140 total)

### Order Orchestration
`orderById`, `order`, `orders`, `orderItemById`, `orderItems`, `orderBillingAddresses`, `fulfilmentById`, `fulfilment`, `fulfilments`, `fulfilmentItemRejections`, `fulfilmentItems`, `fulfilmentChoiceById`, `fulfilmentChoice`, `fulfilmentChoices`, `articleById`, `articles`, `articleItems`, `consignmentById`, `consignments`, `consignmentArticleById`, `consignmentArticles`, `customerById`, `customer`, `customers`, `customerAddressById`, `customerAddresses`, `returnOrder`, `returnOrders`, `returnOrderItem`, `returnOrderItems`, `returnFulfilment`, `returnFulfilments`, `returnFulfilmentItem`, `returnFulfilmentItems`, `returnVerifications`

### Billing
`billingAccount`, `billingAccounts`, `creditMemo`, `creditMemoes`, `creditMemoItem`, `creditMemoItems`, `invoice`, `invoices`, `invoiceItem`, `invoiceItems`, `currency`, `currencies`

### Inventory
`productCatalogue`, `productCatalogues`, `standardProduct`, `standardProducts`, `variantProduct`, `variantProducts`, `groupProduct`, `groupProducts`, `product`, `products`, `category`, `categories`, `prices`, `inventoryCatalogue`, `inventoryCatalogues`, `inventoryPosition`, `inventoryPositions`, `inventoryQuantity`, `inventoryQuantities`, `virtualCatalogue`, `virtualCatalogues`, `virtualPosition`, `virtualPositions`, `controlGroup`, `controlGroups`, `control`, `controls`, `inventoryFeed`, `inventoryFeeds`, `inventoryFeedRun`, `inventoryFeedRuns`

### Foundation
`retailerById`, `retailers`, `locationById`, `location`, `locations`, `storeAddressById`, `storeAddresses`, `storageAreaById`, `storageAreas`, `networkById`, `network`, `networks`, `openingSchedules`, `setting`, `settings`, `commentById`, `comments`

### Store Fulfilment
`waveById`, `wave`, `waves`, `waveItems`

### Shipping
`carrierById`, `carrier`, `carriers`, `carrierConsignment`, `carrierConsignments`, `carrierConsignmentArticleById`, `carrierConsignmentArticles`, `manifest`, `manifests`, `carrierDetailses`, `carrierAttributes`

### Payment
`payment`, `payments`, `paymentTransaction`, `paymentTransactions`, `paymentServiceProvider`, `paymentServiceProviders`, `financialTransaction`, `financialTransactions`

### Availability
`fulfilmentOptionById`, `fulfilmentOptions`, `fulfilmentPlanById`, `fulfilmentPlans`, `searchVirtualInventory`, `inventoryPositionAggregate`, `inventoryQuantityAggregate`, `sourcingProfile`, `sourcingProfiles`, `articlesByLocation`

### System
`me`, `userById`, `user`, `users`, `role`, `roles`, `permission`, `permissions`, `metricInstant`, `metricRange`, `accountUsage`, `analytics`
