Skip to content

URD: Orders

ModuleCORE-07Versionv0.6
StatusIn-progressDate2026-06-04

Business documentation. This URD is Orders' feature list - each feature below is one Functional Area (<AREA>). The same <AREA> keys the feature's PRDs (PRD-<AREA>-NNN) and tests (TC-<AREA>-NNN), and each feature is listed in the Delivery feature catalog. See the Feature Spine convention.

1. Purpose

Define user-facing requirements for order management - the sale order lifecycle from cart to checkout to payment, plus the F&B extensions a full-service venue needs: check splitting, kitchen tickets, POS shift sessions, table reservations, and loyalty point earning.

2. Scope

IncludedExcluded
Sale order lifecycle (DRAFT → PROCESSING → PARTIAL → COMPLETED / CANCELLED)Refund / return flow (Planned)
Order items (product, combo fan-out, custom)Stock mutation (Inventory)
Checkout and revertPayment provider integration (Payment)
Order split and mergeTax engine & e-invoice issuance
Check splitting (split the bill)Delivery order tracking (Planned)
Kitchen tickets and stations (F&B)Table-layout / seating management (Planned)
POS sessions (shifts) with X/Z reportsDedicated kitchen display application (Planned)
ReservationsOrder templates (Planned)
Loyalty point earningTechnical API specifications (see developer docs)
Real-time updates to kitchen & dashboards

3. Definitions

TermDefinition
Sale OrderA transaction containing items being sold; one entity serves as both cart (DRAFT) and committed order.
Order ItemA line item - a product variant (PRODUCT mode) or a manual entry (CUSTOM mode).
ComboA product that fans out into priced child lines when added to the cart.
Sale CheckAn independently-payable group within an order, used to split the bill.
Kitchen TicketA ticket sent to the kitchen for F&B preparation; contains items from a sale order.
Kitchen StationA named preparation area (e.g., grill, bar) that receives tickets.
POS SessionA cashier's shift on a specific device; tracks opening / closing cash and generates reports.
X ReportInterim shift summary - can be generated multiple times.
Z ReportFinal closing report - only one per session.
ReservationA guest booking for a future date / time with a party size.

4. Conceptual Model

Conceptual only - full schema lives in the developer domain model.

5. Feature Catalog

The feature list of this module. Each row is one feature (a Functional Area). Detail in §6. Mirrored in the Delivery feature catalog.

Feature IDFeaturePhaseStatusPriority
ORDSale OrderP1BuiltHigh
CHKCheck SplittingP2BuiltMedium
KITKitchen TicketsP2BuiltHigh
STAKitchen StationsP2BuiltMedium
POSPOS SessionsP2BuiltHigh
RSVReservationsP2BuiltMedium
PNTLoyalty PointsP2BuiltMedium
PCKProduct PickerP2PlannedHigh
SLFQR Self-orderP2PlannedHigh
SHFMulti-employee shiftsP2In-progressHigh
ENTEntitlementsP1BuiltHigh

Status: live from Plane where mapped, otherwise registry-declared. Vocabulary mirrors Plane (state-group / phase).

6. Features

One sub-section per feature, in catalog order. Each feature keeps its description, requirements, and acceptance together. Priority = MoSCoW (Must / Should / Could / Won't).

ORD - Sale Order Built

Feature ID: orders/ORD · Phase: P1 · PRDs: PRD-ORD-001 · PRD-ORD-002 · Dev: @nx/sale

What it does for users: cashiers build an order as a cart, add products (including combos), and move it through checkout to payment - with split/merge and a customer link while still in draft.

Requirements

IDPRequirement
URD-ORD-001MCreate draft orders (cart) with items
URD-ORD-002MAdd, update, remove items only while in DRAFT
URD-ORD-003MAdding the same product merges quantity onto the existing line
URD-ORD-004MSetting an item quantity to zero removes the line
URD-ORD-005MAdd a combo item that fans out into priced child lines
URD-ORD-006MCheckout: DRAFT → PROCESSING (validates items, locks prices)
URD-ORD-007MCheckout validates: non-empty cart, prices ≥ 0, quantity ≥ 1
URD-ORD-008MRevert: PROCESSING → DRAFT
URD-ORD-009MCancel from DRAFT, PROCESSING, or PARTIAL (with optional reason)
URD-ORD-010MPartial payment → PARTIAL status
URD-ORD-011MFull payment → COMPLETED status
URD-ORD-012SSplit one order into multiple (DRAFT only)
URD-ORD-013SMerge multiple orders (DRAFT only)
URD-ORD-014SAttach a customer to the order
URD-ORD-015SMulti-currency with exchange rate (default VND)
URD-ORD-016CEnforce a maximum number of items per order
URD-ORD-017MSplit assigns specific items / quantities into new draft orders (optional name / customer each); a fully-assigned line moves whole, a partial line splits leaving the remainder on the source; an empty source is cancelled (FULL_SPLIT), a partial source is repriced; non-positive quantity, unknown item, or over-allocation is refused
URD-ORD-018MA combo's lead and all its children must move together, at full quantity, into the same target group; partial or orphaning combo moves are refused
URD-ORD-019MMerge moves every item of the source draft orders into the target draft order and cancels the sources (MERGED_INTO_<target>); only orders of the same merchant and sale channel can merge
URD-ORD-020MEvery transferred item records an append-only transfer-history entry (source, target, time, quantity) forming the split / merge lineage
URD-ORD-021SA merge can be rolled back while the target is still draft and was merged; items return to their original source orders (restored to draft) via the lineage; quantity added after the merge stays on the target
URD-ORD-022MSplit, merge and rollback are atomic; allocation usages clone (split) / move (merge) / cancel (rollback) in lock-step and affected orders are repriced
URD-ORD-023MAn order with active checks cannot be split, merged, or rolled back

Acceptance

AC-ORD-01: Order lifecycle
GivenWhenThen
DRAFT orderCheckoutPROCESSING (prices locked)
PROCESSINGFull paymentCOMPLETED
PROCESSINGPartial paymentPARTIAL
Any non-terminal statusCancelCANCELLED
Empty cartCheckoutRejected
AC-ORD-02: Combo fan-out
GivenWhenThen
A combo productAdd to cartOne lead line + zero-priced child lines created
The same combo already in orderAdd againRejected (already in order)
AC-ORD-03: Split a draft
GivenWhenThen
A DRAFT order with itemsSplit into groups, taking a line's full quantityThe line moves whole to the new draft, stamped with a transfer entry
A DRAFT order with a line of qty 5Split assigning 2 to a new draftThe line splits - 2 on the new draft, 3 left on the source; both repriced
A split that empties the source-The source is cancelled (FULL_SPLIT) and its reserved stock cancelled
A split assigning more than a line's available quantity-Refused (over-allocation)
AC-ORD-04: Merge & rollback
GivenWhenThen
Two DRAFT orders of the same merchant + channelMerge into a targetAll items move to the target, sources cancelled (MERGED_INTO_<target>), reserved stock moved
A merged target still in DRAFTRollbackEvery item returns to its original source via the lineage; sources restored to DRAFT
A line whose quantity was increased after the mergeRollbackThe surplus stays on the target; only the originally-transferred quantity returns
A target that was never mergedRollbackRefused (not merged)
AC-ORD-05: Combo atomicity & active checks
GivenWhenThen
A combo (lead + children) on a draftSplit assigning only the lead, or a child's partial quantityRefused (combo must move together at full quantity)
An order with active checksSplit, merge, or rollbackRefused - roll back the checks first

CHK - Check Splitting Built

Feature ID: orders/CHK · Phase: P2 · PRDs: - · Dev: @nx/sale

What it does for users: a table splits one order into several independently-payable checks, allocating specific items and quantities (and even a different customer) to each, completing the order only when all checks are paid.

Requirements

IDPRequirement
URD-CHK-001SSplit an order into multiple payment checks
URD-CHK-002SAllocate specific items and quantities to each check
URD-CHK-003SDifferent customer per check
URD-CHK-004SOrder completes when all its checks complete
URD-CHK-005CRoll back a split while no check is paid

Acceptance

AC-CHK-01: Bill split
GivenWhenThen
An order with itemsSplit into multiple checks with allocated itemsEach check is independently payable
All checks of the order complete-The order completes

KIT - Kitchen Tickets Built

Feature ID: orders/KIT · Phase: P2 · PRDs: - · Dev: @nx/sale

What it does for users: order items are sent to the kitchen as tickets that progress through cooking statuses, update displays in real time, and trigger stock consumption when served.

Requirements

IDPRequirement
URD-KIT-001MSend order items to kitchen (creates ticket + items)
URD-KIT-002MIdempotent send - a duplicate send produces the same ticket
URD-KIT-003MTicket lifecycle: PENDING → PROCESSING → READY → COMPLETED / VOIDED
URD-KIT-004MItem lifecycle: PENDING → COOKING → READY → SERVED / VOIDED
URD-KIT-005MTicket status auto-progresses from its item statuses
URD-KIT-006MChanges use void-and-resend (sent items are not edited in place)
URD-KIT-007SRush flag and per-order sequence for ticket ordering
URD-KIT-008MReal-time updates to kitchen displays and dashboards
URD-KIT-009SMarking an item served triggers stock consumption

Acceptance

AC-KIT-01: Kitchen
GivenWhenThen
Order itemsSend to kitchenTicket created
Same idempotency keyDuplicate sendNo duplicate ticket
All items READY/SERVED-Ticket auto-progresses
Item marked served-Stock consumption triggered

STA - Kitchen Stations Built

Feature ID: orders/STA · Phase: P2 · PRDs: - · Dev: @nx/sale

What it does for users: merchants define named preparation stations and route product categories to them, with per-station printer configuration and auto-print.

Requirements

IDPRequirement
URD-STA-001SCreate named stations per merchant (i18n)
URD-STA-002SRoute product categories to stations
URD-STA-003SPer-station printer config with auto-print

Acceptance

AC-STA-01: Station routing
GivenWhenThen
A station with a routed product categoryAn item in that category is sent to kitchenThe ticket is routed to that station

POS - POS Sessions Built

Feature ID: orders/POS · Phase: P2 · PRDs: - · Dev: @nx/sale

What it does for users: a cashier opens a shift on a device with an opening cash float, attaches orders to it, and closes it with a cash count that produces a Z report and an interim-X summary.

Requirements

IDPRequirement
URD-POS-001MOpen a session on a device with an opening cash float
URD-POS-002MOnly one open session per device
URD-POS-003MClose a session: count cash, record discrepancy
URD-POS-004MZ report (closing) - one per session
URD-POS-005SX report (interim) - repeatable
URD-POS-006SOrders created during a shift attach to the session
URD-POS-007STrack expected vs. actual for non-cash methods
URD-POS-008CRecount support on close

Acceptance

AC-POS-01: Session
GivenWhenThen
No open session on deviceOpenSession created
Existing open session on deviceOpenRejected
Open sessionClose with cash countDiscrepancy computed, Z report generated

RSV - Reservations Built

Feature ID: orders/RSV · Phase: P2 · PRDs: - · Dev: @nx/sale

What it does for users: hosts take table bookings with guest details, party size and source, track them through a lifecycle, and spawn a linked sale order on check-in.

Requirements

IDPRequirement
URD-RSV-001SCreate a reservation: guest name, phone, party size, date / time
URD-RSV-002SLifecycle: PENDING → CONFIRMED → CHECKED_IN / CANCELLED
URD-RSV-003SSource tracking: phone, walk-in, online, other
URD-RSV-004SOccasion tagging: birthday, anniversary, business, etc.
URD-RSV-005SOn check-in, spawn and link a sale order

Acceptance

AC-RSV-01: Reservation
GivenWhenThen
Guest infoCreateStatus PENDING, table held
Confirmed reservationCheck inStatus CHECKED_IN, sale order spawned & linked

PNT - Loyalty Points Built

Feature ID: orders/PNT · Phase: P2 · PRDs: - · Dev: @nx/sale

What it does for users: customers earn loyalty points on completed orders, awarded once per order, with a balance tracked per customer per merchant.

Requirements

IDPRequirement
URD-PNT-001SEarn points on completed orders
URD-PNT-002SPoint award is idempotent per order
URD-PNT-003SPoint balance tracked per customer per merchant

Acceptance

AC-PNT-01: Point earning
GivenWhenThen
A customer-linked orderThe order completesPoints are earned and added to the customer's balance
The same completed order replayed-No duplicate award (idempotent per order)

PCK - Product Picker Planned

Feature ID: sale/PCK · Phase: P2 (Jun) · PRDs: PRD-PCK-001 · Dev: @nx/sale · @nx/commerce

What it does for users: a cashier picks any sellable item in at most 3 taps. Products with Options resolve to exactly one Variant through option choices; single-variant items skip the chooser entirely.

Requirements

IDPRequirement
URD-PCK-001MCashier picks any sellable item in ≤3 taps
URD-PCK-002MA product with Options resolves to exactly one Variant via option choices
URD-PCK-003MSingle-variant products skip the chooser (one tap adds to cart)
URD-PCK-004MPrice updates live as options are chosen
URD-PCK-005SInvalid option combinations cannot be selected
URD-PCK-006SDefault options are pre-selected for the fastest path
URD-PCK-007SBarcode scan bypasses the picker (scan = item in cart)

Acceptance

AC-PCK-01: Option resolution
GivenWhenThen
A product with size + ice optionsCashier picks size then iceExactly one variant is added, correct price shown - ≤3 taps total
A product with one variantCashier taps itIt lands in the cart immediately, no chooser

SLF - QR Self-order Planned

Feature ID: sale/SLF · Phase: P2 (Jul-Aug) · PRDs: PRD-SLF-001 · Dev: @nx/sale · @nx/commerce

What it does for users: a guest at a table scans a QR code and orders from their own phone - no app install. The order lands in the POS tied to that table; staff confirm and it flows to the kitchen like any other order.

Requirements

IDPRequirement
URD-SLF-001MGuest scans a table QR and gets the menu on their phone (no app)
URD-SLF-002MThe menu served is policy-based (time/channel) from the merchant's Menu
URD-SLF-003MGuest builds a cart and submits an order for that table
URD-SLF-004MThe order lands in the POS tied to the table; staff confirm or reject
URD-SLF-005MA confirmed order flows to the kitchen like a staff-entered order
URD-SLF-006SGuest sees order status updates
URD-SLF-007SSold-out items are hidden / not orderable
URD-SLF-008CGuest can re-order within the same session

Acceptance

AC-SLF-01: Guest order reaches the kitchen
GivenWhenThen
A guest at table 5 scans its QRThey submit an order of 2 itemsPOS shows the order on table 5 pending confirmation; on confirm, kitchen receives the ticket
An item is sold outGuest browses the menuThe item is not orderable

SHF - Multi-employee Shifts In-progress

Feature ID: sale/SHF · Phase: P2 (Jul) · PRDs: PRD-SHF-001 · Dev: @nx/sale

What it does for users: a multi-staff store runs sales shifts: open/close on a device, multiple staff enrolled in one shift, X/Z reports at close, and the till reconciled - counted cash vs expected, discrepancy recorded. (As-built note: the multi-employee backend is on develop; the POS still runs the old single-user session - the increment wires the front end over.)

Requirements

IDPRequirement
URD-SHF-001MA staff member opens and closes a shift on a device
URD-SHF-002MMultiple staff can enrol in one shift (multi-employee)
URD-SHF-003MAn X report is available mid-shift; a Z report at close
URD-SHF-004MCash is reconciled at close: counted vs expected, discrepancy recorded
URD-SHF-005MSales during the shift attribute to the acting staff member
URD-SHF-006SCash movements (pay-in/pay-out/safe-drop) are recorded against the drawer
URD-SHF-007SOwners see revenue by shift and by period
URD-SHF-008MClosing with a non-zero discrepancy requires a reason note
URD-SHF-009SThe opening float is locked once the shift opens

Acceptance

AC-SHF-01: A full shift
GivenWhenThen
Two staff enrolled in an open shiftThey sell through the day and closeZ report is correct; expectedCash = openingFloat + cash sales − refunds + pay-ins − pay-outs; discrepancy = counted − expected
A shift is open on a deviceA second device tries to open anotherBehaviour follows the shift policy (shared vs per-device)

ENT - Entitlements Built

Feature ID: sale/ENT · Phase: P2 · PRDs: PRD-ENT-001 · Dev: @nx/sale · @nx/core

What it does for users: a merchant sells something the customer draws down over time - a drinks bundle, a class pass, a membership window, a block of metered minutes. A policy defines what is sold (quota + validity + scope); selling its variant mints a per-customer grant that freezes a snapshot of the policy so later catalogue edits never alter a sold pass; each use writes an append-only redemption that draws the balance down, validates the item against the frozen scope, and can be reversed.

Requirements

IDPRequirement
URD-ENT-001MA policy binds 1:1 to a sellable variant (the variant sold as the entitlement)
URD-ENT-002MA policy declares its limit dimensions: COUNT (discrete uses), TIME_WINDOW (valid window, no usage cap), METERED (continuous units); these may combine
URD-ENT-003MA policy carries an optional quota (amount + unit) and an optional validity duration; either axis may be absent
URD-ENT-004MA policy declares an activation mode - on purchase, on first use, or scheduled - governing when validity starts counting
URD-ENT-005SA policy may require an attached customer (named entitlement) or allow a bearer entitlement
URD-ENT-006MA policy's redemption scope is defined by targets; an empty target set means open access
URD-ENT-007MA target binds a policy to a specific item (variant by default) with an ordering sequence; unique per (policy, item)
URD-ENT-008MSelling the entitlement variant mints a grant with a unique code, a quota balance, and a validity window resolved from policy + activation mode
URD-ENT-009MThe grant freezes a snapshot of the policy and its targets at sale time, isolating it from later catalogue edits
URD-ENT-010MA grant tracks quota total vs used; the used counter is the source of truth and available = total − used
URD-ENT-011MA grant moves through PENDING → ACTIVE → EXHAUSTED / EXPIRED / SUSPENDED / CANCELLED
URD-ENT-012MA redemption draws the used counter down for a quantity, recorded against its consuming order / item
URD-ENT-013SA redemption quantity in a different unit from the grant's quota unit is converted via the unit ratio
URD-ENT-014MA redemption validates the redeemed item against the grant's frozen target scope (open when no targets)
URD-ENT-015MA reversal redemption returns quota to the grant; the ledger is append-only (corrections are new entries, never edits)
URD-ENT-016SRedemptions can be linked to the sale order / order item that consumed them
URD-ENT-017SEvery policy, target, grant, and redemption is merchant-scoped and soft-deleted

Acceptance

AC-ENT-01: Sell a grant
GivenWhenThen
A configured policy on a variantThe variant is soldA grant is minted with a unique code, the policy's quota balance, and a validity window; status ACTIVE (or PENDING per activation mode)
A sold grantThe policy is later editedThe grant's terms are unchanged - read from its frozen snapshot
AC-ENT-02: Redeem and exhaust
GivenWhenThen
An ACTIVE grant with balance remainingA use is redeemed for a quantityA redemption is appended and the used counter rises; available = total − used
The used counter reaches the quota total-The grant reads EXHAUSTED; further redeems are refused
AC-ENT-03: Reversal returns quota
GivenWhenThen
A prior redeem on a grantA reversal is recordedAn append-only reversal entry returns the quota; the original redeem is not edited or deleted
AC-ENT-04: Target scope
GivenWhenThen
A grant scoped to specific itemsA redeem targets an item outside the scopeRefused
A grant whose snapshot has no targetsA redeem targets any itemAllowed (open access)

7. Constraints & Non-Goals

Constraints

IDConstraint
C-01Items are modifiable only while the order is in DRAFT
C-02Order split / merge only in DRAFT
C-03At most one open POS session per device
C-04Exactly one Z report per session
C-05Kitchen ticket send is idempotent via key
C-06All records use soft-delete
C-07All operations require authentication and are scoped to the merchant

Non-Goals

  • Refund / return flow
  • Delivery order tracking
  • Table-layout / seating management
  • Dedicated kitchen display application
  • Order templates

8. Version History

DateAuthorDescriptionVer
2026-02-26P. Do - Product OwnerInitial user storiesv0.1
2026-04-16P. Do - Product OwnerRestructured to functional-area requirement tables; added combo, check-splitting, station, reservation, points areasv0.3
2026-06-04Claude (AI pair)Reorganize by feature (Feature Spine); each feature carries its own requirements + acceptance; CON moved to Constraintsv0.4
2026-06-15Sale squadAdd ENT Entitlements feature (policy / target / grant / redemption) with requirements + acceptancev0.5
2026-06-15Sale squadExtend ORD with split / merge / rollback + transfer-history lineage (URD-ORD-017..023, AC-ORD-03..05); link PRD-ORD-002v0.6

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.