URD: Orders
| Module | Version | Updated |
|---|---|---|
CORE-07 | v0.7 | 2026-06-26 |
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
| Included | Excluded |
|---|---|
| Sale order lifecycle (DRAFT → PROCESSING → PARTIAL → COMPLETED / CANCELLED) | Refund / return flow (Planned) |
| Order items (product, combo fan-out, custom) | Stock mutation (Inventory) |
| Checkout and revert | Payment provider integration (Payment) |
| Order split and merge | Tax 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 reports | Dedicated kitchen display application (Planned) |
| Reservations | Order templates (Planned) |
| Loyalty point earning | Technical API specifications (see developer docs) |
| Real-time updates to kitchen & dashboards |
3. Definitions
| Term | Definition |
|---|---|
| Sale Order | A transaction containing items being sold; one entity serves as both cart (DRAFT) and committed order. |
| Order Item | A line item - a product variant (PRODUCT mode) or a manual entry (CUSTOM mode). |
| Combo | A product that fans out into priced child lines when added to the cart. |
| Sale Check | An independently-payable group within an order, used to split the bill. |
| Kitchen Ticket | A ticket sent to the kitchen for F&B preparation; contains items from a sale order. |
| Kitchen Station | A named preparation area (e.g., grill, bar) that receives tickets. |
| POS Session | A cashier's shift on a specific device; tracks opening / closing cash and generates reports. |
| X Report | Interim shift summary - can be generated multiple times. |
| Z Report | Final closing report - only one per session. |
| Reservation | A 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.
| Feature ID | Feature | Phase | Epic | Status | Priority |
|---|---|---|---|---|---|
ORD | Sale Order | P1 | — | Built | High |
CHK | Check Splitting | P2 | E9 | Built | Medium |
KIT | Kitchen Tickets | P2 | E8 | Built | High |
STA | Kitchen Stations | P2 | E8 | Built | Medium |
POS | POS Sessions | P2 | — | Built | High |
RSV | Reservations | P2 | — | Built | Medium |
PNT | Loyalty Points | P2 | — | Built | Medium |
PCK | Product Picker | P2 | E9 | Planned | High |
SLF | QR Self-order | P2 | E8 | Planned | High |
SHF | Multi-employee shifts | P2 | E4 | In-progress | High |
ENT | Entitlements | P1 | E3 | Built | High |
SLD | Sold Products History | P2 | — | Planned | Medium |
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
| ID | P | Requirement |
|---|---|---|
| URD-ORD-001 | M | Create draft orders (cart) with items |
| URD-ORD-002 | M | Add, update, remove items only while in DRAFT |
| URD-ORD-003 | M | Adding the same product merges quantity onto the existing line |
| URD-ORD-004 | M | Setting an item quantity to zero removes the line |
| URD-ORD-005 | M | Add a combo item that fans out into priced child lines |
| URD-ORD-006 | M | Checkout: DRAFT → PROCESSING (validates items, locks prices) |
| URD-ORD-007 | M | Checkout validates: non-empty cart, prices ≥ 0, quantity ≥ 1 |
| URD-ORD-008 | M | Revert: PROCESSING → DRAFT |
| URD-ORD-009 | M | Cancel from DRAFT, PROCESSING, or PARTIAL (with optional reason) |
| URD-ORD-010 | M | Partial payment → PARTIAL status |
| URD-ORD-011 | M | Full payment → COMPLETED status |
| URD-ORD-012 | S | Split one order into multiple (DRAFT only) |
| URD-ORD-013 | S | Merge multiple orders (DRAFT only) |
| URD-ORD-014 | S | Attach a customer to the order |
| URD-ORD-015 | S | Multi-currency with exchange rate (default VND) |
| URD-ORD-016 | C | Enforce a maximum number of items per order |
| URD-ORD-017 | M | Split 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-018 | M | A 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-019 | M | Merge 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-020 | M | Every transferred item records an append-only transfer-history entry (source, target, time, quantity) forming the split / merge lineage |
| URD-ORD-021 | S | A 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-022 | M | Split, merge and rollback are atomic; allocation usages clone (split) / move (merge) / cancel (rollback) in lock-step and affected orders are repriced |
| URD-ORD-023 | M | An order with active checks cannot be split, merged, or rolled back |
Acceptance
AC-ORD-01: Order lifecycle
| Given | When | Then |
|---|---|---|
| DRAFT order | Checkout | PROCESSING (prices locked) |
| PROCESSING | Full payment | COMPLETED |
| PROCESSING | Partial payment | PARTIAL |
| Any non-terminal status | Cancel | CANCELLED |
| Empty cart | Checkout | Rejected |
AC-ORD-02: Combo fan-out
| Given | When | Then |
|---|---|---|
| A combo product | Add to cart | One lead line + zero-priced child lines created |
| The same combo already in order | Add again | Rejected (already in order) |
AC-ORD-03: Split a draft
| Given | When | Then |
|---|---|---|
| A DRAFT order with items | Split into groups, taking a line's full quantity | The line moves whole to the new draft, stamped with a transfer entry |
| A DRAFT order with a line of qty 5 | Split assigning 2 to a new draft | The 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
| Given | When | Then |
|---|---|---|
| Two DRAFT orders of the same merchant + channel | Merge into a target | All items move to the target, sources cancelled (MERGED_INTO_<target>), reserved stock moved |
| A merged target still in DRAFT | Rollback | Every item returns to its original source via the lineage; sources restored to DRAFT |
| A line whose quantity was increased after the merge | Rollback | The surplus stays on the target; only the originally-transferred quantity returns |
| A target that was never merged | Rollback | Refused (not merged) |
AC-ORD-05: Combo atomicity & active checks
| Given | When | Then |
|---|---|---|
| A combo (lead + children) on a draft | Split assigning only the lead, or a child's partial quantity | Refused (combo must move together at full quantity) |
| An order with active checks | Split, merge, or rollback | Refused - 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
| ID | P | Requirement |
|---|---|---|
| URD-CHK-001 | S | Split an order into multiple payment checks |
| URD-CHK-002 | S | Allocate specific items and quantities to each check |
| URD-CHK-003 | S | Different customer per check |
| URD-CHK-004 | S | Order completes when all its checks complete |
| URD-CHK-005 | C | Roll back a split while no check is paid |
Acceptance
AC-CHK-01: Bill split
| Given | When | Then |
|---|---|---|
| An order with items | Split into multiple checks with allocated items | Each 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
| ID | P | Requirement |
|---|---|---|
| URD-KIT-001 | M | Send order items to kitchen (creates ticket + items) |
| URD-KIT-002 | M | Idempotent send - a duplicate send produces the same ticket |
| URD-KIT-003 | M | Ticket lifecycle: PENDING → PROCESSING → READY → COMPLETED / VOIDED |
| URD-KIT-004 | M | Item lifecycle: PENDING → COOKING → READY → SERVED / VOIDED |
| URD-KIT-005 | M | Ticket status auto-progresses from its item statuses |
| URD-KIT-006 | M | Changes use void-and-resend (sent items are not edited in place) |
| URD-KIT-007 | S | Rush flag and per-order sequence for ticket ordering |
| URD-KIT-008 | M | Real-time updates to kitchen displays and dashboards |
| URD-KIT-009 | S | Marking an item served triggers stock consumption |
Acceptance
AC-KIT-01: Kitchen
| Given | When | Then |
|---|---|---|
| Order items | Send to kitchen | Ticket created |
| Same idempotency key | Duplicate send | No 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
| ID | P | Requirement |
|---|---|---|
| URD-STA-001 | S | Create named stations per merchant (i18n) |
| URD-STA-002 | S | Route product categories to stations |
| URD-STA-003 | S | Per-station printer config with auto-print |
Acceptance
AC-STA-01: Station routing
| Given | When | Then |
|---|---|---|
| A station with a routed product category | An item in that category is sent to kitchen | The 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
| ID | P | Requirement |
|---|---|---|
| URD-POS-001 | M | Open a session on a device with an opening cash float |
| URD-POS-002 | M | Only one open session per device |
| URD-POS-003 | M | Close a session: count cash, record discrepancy |
| URD-POS-004 | M | Z report (closing) - one per session |
| URD-POS-005 | S | X report (interim) - repeatable |
| URD-POS-006 | S | Orders created during a shift attach to the session |
| URD-POS-007 | S | Track expected vs. actual for non-cash methods |
| URD-POS-008 | C | Recount support on close |
Acceptance
AC-POS-01: Session
| Given | When | Then |
|---|---|---|
| No open session on device | Open | Session created |
| Existing open session on device | Open | Rejected |
| Open session | Close with cash count | Discrepancy 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
| ID | P | Requirement |
|---|---|---|
| URD-RSV-001 | S | Create a reservation: guest name, phone, party size, date / time |
| URD-RSV-002 | S | Lifecycle: PENDING → CONFIRMED → CHECKED_IN / CANCELLED |
| URD-RSV-003 | S | Source tracking: phone, walk-in, online, other |
| URD-RSV-004 | S | Occasion tagging: birthday, anniversary, business, etc. |
| URD-RSV-005 | S | On check-in, spawn and link a sale order |
Acceptance
AC-RSV-01: Reservation
| Given | When | Then |
|---|---|---|
| Guest info | Create | Status PENDING, table held |
| Confirmed reservation | Check in | Status 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
| ID | P | Requirement |
|---|---|---|
| URD-PNT-001 | S | Earn points on completed orders |
| URD-PNT-002 | S | Point award is idempotent per order |
| URD-PNT-003 | S | Point balance tracked per customer per merchant |
Acceptance
AC-PNT-01: Point earning
| Given | When | Then |
|---|---|---|
| A customer-linked order | The order completes | Points 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 a typical item in just a few taps (≤3 for single-variant, defaults, or a one-option change). Products with Options resolve to exactly one Variant through option choices; single-variant items skip the chooser entirely.
Requirements
| ID | P | Requirement |
|---|---|---|
| URD-PCK-001 | M | Cashier picks a typical item in ≤3 taps (single-variant · defaults · one option changed) |
| URD-PCK-002 | M | A product with Options resolves to exactly one Variant via option choices |
| URD-PCK-003 | M | Single-variant products skip the chooser (one tap adds to cart) |
| URD-PCK-004 | M | Price updates live as options are chosen |
| URD-PCK-005 | S | Invalid option combinations cannot be selected |
| URD-PCK-006 | S | Default options are pre-selected for the fastest path |
| URD-PCK-007 | S | Barcode scan bypasses the picker (scan = item in cart) |
Acceptance
AC-PCK-01: Option resolution
| Given | When | Then |
|---|---|---|
| A product with size + ice options | Cashier picks size then ice | Exactly one variant added, correct price; 2 changed options = 4 taps (product + size + ice + confirm) |
| A product with one variant | Cashier taps it | It lands in the cart immediately, no chooser |
SLF - QR Self-order Planned
Feature ID: sale/SLF · Phase: P2 (Jul-Aug) · PRDs: PRD-SLF-001 · PRD-SLF-002 · 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
| ID | P | Requirement |
|---|---|---|
| URD-SLF-001 | M | Guest scans a table QR and gets the menu on their phone (no app) |
| URD-SLF-002 | M | The menu served is policy-based (time/channel) from the merchant's Menu |
| URD-SLF-003 | M | Guest builds a cart and submits an order for that table |
| URD-SLF-004 | M | The order lands in the POS tied to the table; staff confirm or reject |
| URD-SLF-005 | M | A confirmed order flows to the kitchen like a staff-entered order |
| URD-SLF-006 | S | Guest sees order status updates |
| URD-SLF-007 | S | Sold-out items are hidden / not orderable |
| URD-SLF-008 | C | Guest can re-order within the same session |
| URD-SLF-009 | M | Deleting a non-terminal order that occupies a table requires an explicit, table-aware confirmation before it proceeds, and every confirmed delete is audit-logged |
Acceptance
AC-SLF-01: Guest order reaches the kitchen
| Given | When | Then |
|---|---|---|
| A guest at table 5 scans its QR | They submit an order of 2 items | POS shows the order on table 5 pending confirmation; on confirm, kitchen receives the ticket |
| An item is sold out | Guest browses the menu | The 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 merchant 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
| ID | P | Requirement |
|---|---|---|
| URD-SHF-001 | M | A staff member opens and closes a shift on a device |
| URD-SHF-002 | M | Multiple staff can enrol in one shift (multi-employee) |
| URD-SHF-003 | M | An X report is available mid-shift; a Z report at close |
| URD-SHF-004 | M | Cash is reconciled at close: counted vs expected, discrepancy recorded |
| URD-SHF-005 | M | Sales during the shift attribute to the acting staff member |
| URD-SHF-006 | S | Cash movements (pay-in/pay-out/safe-drop) are recorded against the drawer |
| URD-SHF-007 | S | Owners see revenue by shift and by period |
| URD-SHF-008 | M | Closing with a non-zero discrepancy requires a reason note |
| URD-SHF-009 | S | The opening float is locked once the shift opens |
Acceptance
AC-SHF-01: A full shift
| Given | When | Then |
|---|---|---|
| Two staff enrolled in an open shift | They sell through the day and close | Z report is correct; expectedCash = openingFloat + cash sales − refunds + pay-ins − pay-outs; discrepancy = counted − expected |
| A shift is open on a device | A second device tries to open another | Behaviour 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
| ID | P | Requirement |
|---|---|---|
| URD-ENT-001 | M | A policy binds 1:1 to a sellable variant (the variant sold as the entitlement) |
| URD-ENT-002 | M | A policy declares its limit dimensions: COUNT (discrete uses), TIME_WINDOW (valid window, no usage cap), METERED (continuous units); these may combine |
| URD-ENT-003 | M | A policy carries an optional quota (amount + unit) and an optional validity duration; either axis may be absent |
| URD-ENT-004 | M | A policy declares an activation mode - on purchase, on first use, or scheduled - governing when validity starts counting |
| URD-ENT-005 | S | A policy may require an attached customer (named entitlement) or allow a bearer entitlement |
| URD-ENT-006 | M | A policy's redemption scope is defined by targets; an empty target set means open access |
| URD-ENT-007 | M | A target binds a policy to a specific item (variant by default) with an ordering sequence; unique per (policy, item) |
| URD-ENT-008 | M | Selling the entitlement variant mints a grant with a unique code, a quota balance, and a validity window resolved from policy + activation mode |
| URD-ENT-009 | M | The grant freezes a snapshot of the policy and its targets at sale time, isolating it from later catalogue edits |
| URD-ENT-010 | M | A grant tracks quota total vs used; the used counter is the source of truth and available = total − used |
| URD-ENT-011 | M | A grant moves through PENDING → ACTIVE → EXHAUSTED / EXPIRED / SUSPENDED / CANCELLED |
| URD-ENT-012 | M | A redemption draws the used counter down for a quantity, recorded against its consuming order / item |
| URD-ENT-013 | S | A redemption quantity in a different unit from the grant's quota unit is converted via the unit ratio |
| URD-ENT-014 | M | A redemption validates the redeemed item against the grant's frozen target scope (open when no targets) |
| URD-ENT-015 | M | A reversal redemption returns quota to the grant; the ledger is append-only (corrections are new entries, never edits) |
| URD-ENT-016 | S | Redemptions can be linked to the sale order / order item that consumed them |
| URD-ENT-017 | S | Every policy, target, grant, and redemption is merchant-scoped and soft-deleted |
Acceptance
AC-ENT-01: Sell a grant
| Given | When | Then |
|---|---|---|
| A configured policy on a variant | The variant is sold | A 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 grant | The policy is later edited | The grant's terms are unchanged - read from its frozen snapshot |
AC-ENT-02: Redeem and exhaust
| Given | When | Then |
|---|---|---|
| An ACTIVE grant with balance remaining | A use is redeemed for a quantity | A 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
| Given | When | Then |
|---|---|---|
| A prior redeem on a grant | A reversal is recorded | An append-only reversal entry returns the quota; the original redeem is not edited or deleted |
AC-ENT-04: Target scope
| Given | When | Then |
|---|---|---|
| A grant scoped to specific items | A redeem targets an item outside the scope | Refused |
| A grant whose snapshot has no targets | A redeem targets any item | Allowed (open access) |
SLD - Sold Products History Planned
Feature ID: sale/SLD · Phase: P2 (Jun) · PRDs: PRD-SLD-001 · Dev: @nx/sale
What it does for users: developers and merchant owners can review the detailed transaction history of specific products/variants sold (from completed or partially paid orders), apply filters, search, and export reports for item-level reconciliation.
Requirements
| ID | P | Requirement |
|---|---|---|
| URD-SLD-001 | M | Display the list of sold products/variants as a detailed item-level transaction table |
| URD-SLD-002 | M | Display detailed information for each item row: Product Name, Variant, SKU/Barcode, Quantity, Unit Price, Tax, Discount, Line Total, Order Number, Channel, Payment Method, Salesperson, Customer, and Completion Time |
| URD-SLD-003 | M | Provide filters by date range (from date - to date), Merchant, Sales Channel (POS, Web, QR), Payment Method, and Salesperson |
| URD-SLD-004 | M | Search products by product name, variant name, SKU, or Barcode |
| URD-SLD-005 | S | Aggregate key KPIs at the top of the page: Total quantity sold, Total revenue, and Total line discount |
| URD-SLD-006 | S | Export the filtered sold products history list to Excel (XLSX) or CSV |
| URD-SLD-007 | S | Click on the order number link on any row to open the details drawer/modal of the corresponding sale order |
| URD-SLD-008 | M | Enforce access control permissions (only accessible to manager roles such as OWNER, ADMIN, and OPERATOR) |
Acceptance
AC-SLD-01: Query and filter sold products list
| Given | When | Then |
|---|---|---|
Order ORD-001 with COMPLETED status containing 2 items: Product A (Qty: 2) and Product B (Qty: 1) | Administrator accesses the Sold Products History page and filters by today | Displays 2 item rows for Product A and Product B with correct quantities, price, and revenue |
Order ORD-002 with DRAFT status containing Product C | - | Product C is not displayed in the sold products history (only items from completed or partially paid orders are listed) |
Filtering by sales channel POS | - | The list only displays items sold from orders created via the POS channel |
AC-SLD-02: Export data
| Given | When | Then |
|---|---|---|
| The active filtered list shows 10 product items | User clicks the "Export Excel" button | System generates an Excel file containing exactly those 10 product items with all detail columns and starts the download |
7. Constraints & Non-Goals
Constraints
| ID | Constraint |
|---|---|
| C-01 | Items are modifiable only while the order is in DRAFT |
| C-02 | Order split / merge only in DRAFT |
| C-03 | At most one open POS session per device |
| C-04 | Exactly one Z report per session |
| C-05 | Kitchen ticket send is idempotent via key |
| C-06 | All records use soft-delete |
| C-07 | All 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
| Date | Author | Description | Ver |
|---|---|---|---|
| 2026-02-26 | P. Do - Product Owner | Initial user stories | v0.1 |
| 2026-04-16 | P. Do - Product Owner | Restructured to functional-area requirement tables; added combo, check-splitting, station, reservation, points areas | v0.3 |
| 2026-06-04 | Claude (AI pair) | Reorganize by feature (Feature Spine); each feature carries its own requirements + acceptance; CON moved to Constraints | v0.4 |
| 2026-06-15 | Phát Nguyễn | Add ENT Entitlements feature (policy / target / grant / redemption) with requirements + acceptance | v0.5 |
| 2026-06-15 | Phát Nguyễn | Extend ORD with split / merge / rollback + transfer-history lineage (URD-ORD-017..023, AC-ORD-03..05); link PRD-ORD-002 | v0.6 |
| 2026-06-26 | Phát Nguyễn | Add SLD Sold Products History feature with requirements + acceptance; link PRD-SLD-001 | v0.7 |