Happy House - Ecommerce Docs
Developer ResourcesOrder

Order Features and Flows

Complete feature list, actor journeys, state flows, business rules, edge cases, and diagrams for the Order module.

Order Features and Flows

Use this page for the order domain: what it does for customers and admins, and how each flow behaves from start to finish.

1. Documentation Evidence

Source TypeFiles or DocsWhat Was Extracted
APIapps/api/src/modules/order/customer/order-customer.controller.ts, admin/{order,return,refund}/*.controller.tsRoutes, permissions
Backendorder-customer.service.ts, order-*.service.ts, return/refund services, workersLifecycle, transitions, money
Schemapackages/db/src/schema/order/*.ts12 tables, 9 statuses, CHECKs
Moneyapps/api/src/utils/money/money.util.tsallocateProportionally, valueOfUnits
Error registryapps/api/src/common/types/error-codes.ts (// ORDER)ORDER_* codes

2. Feature Summary

FieldValue
Moduleorder
Submoduledispatch, returns, refunds, receipts, emails
Primary user valueA permanent, truthful commercial record with a full post-purchase lifecycle — dispatch, delivery, returns and refunds
ActorsCustomer, admin (orders/returns/refunds permissions), background jobs
Main entry points/api/mobile/orders (8), /api/orders (11), /api/order-returns (5), /api/order-refunds (4)
Main outputsOrders, shipments, returns, refunds, receipt PDFs, emails
Related docsAPI, Backend

3. Actor Matrix

ActorCan DoCannot DoAuth RequirementNotes
CustomerList orders, read one, poll status, download receipt, cancel before dispatch, request/cancel returnsCreate orders (background job does), return after the window, cancel after dispatch (409 → offer return)JWTORDER_NOT_FOUND for another customer's order
Admin (orders)Confirm, processing, cancel, notes, COD collection, shipments, deliver/failCreate refunds without Refunds_UPDATE, decide returns without Returns_UPDATEAdmin JWT + Orders_*Permission modules are separate by design
Admin (returns)Decide, receive, inspectApprove refundsAdmin JWT + Returns_*
Admin (refunds)Create (via order), approve (with method), reject, settle (with reference)Mark paid, edit amountsAdmin JWT + Refunds_*Settlement is human, never gateway-integrated
WorkerCREATE_ORDER from the outbox rowBullMQOne order per completed checkout (unique index)

4. Capability Matrix

CapabilitySurfaceActorRoute/TriggerState ReadState WrittenLinked API Section
List/read/status/receiptCustomerCustomerGET /api/mobile/orders*ordersAPI §4
Cancel before dispatchCustomerCustomerPOST /:id/cancelorderstatus, restockAPI
Request returnCustomerCustomerPOST /:id/returnsorder + itemsreturn rowsAPI
Cancel returnCustomerCustomerPOST /returns/:returnId/cancelreturnstatusAPI
Confirm/processing/cancel/notes/CODAdminAdminPOST /api/orders/:id/*orderorder fieldsAPI
Shipments + deliver/failAdminAdminPOST /:id/shipments*order + itemsshipment, serialsAPI
Create refundAdminAdminPOST /api/orders/:id/refundsorder + itemsrefund rowsAPI
Return workflowAdminAdmin/api/order-returns/*returnstatusAPI
Refund workflowAdminAdmin/api/order-refunds/*refundstatus + settlementAPI
Create orderWorkerSystemoutbox → CREATE_ORDERcheckout, paymentorder rowsbackend §6

5. User-Facing Flows

5.1 The order is born

Summary

Payment marks the attempt succeeded; the same transaction writes an order.eligible outbox row. The CREATE_ORDER worker builds the order from the frozen checkout — items, prices, promotions, address — and the order appears in the customer's list.

Sequence Diagram

Branches and Edge Cases

BranchConditionBehaviorError/Result
Redelivered outbox rowDuplicateUnique index → no second orderone order
Short orderA hold lapsed between charge and completionOrder created with unavailableQuantity > 0Distinct email; operator decides
Reconciliation flagPayment flaggedOrder stays created until a human confirmscreated = "a human has to look"

5.2 Short orders

A customer can pay for three items and receive two: the inventory hold on one lapsed between the charge landing and the checkout completing. Checkout completes anyway, because stranding a charged customer is worse. Those lines come back with unavailableQuantity > 0 and a per-line label of unavailable. The customer paid for those items and they are not coming — distinct email, and the order waits for an operator to decide between refunding, sourcing or substituting. Never render a short order as though it shipped complete.

5.3 COD — committed, not collected

A COD order is paid in the data model from the moment it is placed — that is what lets stock be deducted. The cash arrives days later. codCollectedAt says money actually changed hands. Until it is set, cancelling that order refunds nothing — correctly — and the cancellation email says so. The customer must not be shown a refund that does not exist.

5.4 The lifecycle

NINE statuses, none of them returned or refunded: created · confirmed · processing · partially_shipped · shipped · partially_delivered · delivered · completed · cancelled. A return does not change the order's status — the order stays delivered forever, because that is what happened. Returns and refunds are separate objects with their own statuses, several per order allowed.

The aggregate status is recomputed from the line quantities rather than incremented — a line of three can have one delivered, one in transit and one cancelled at the same instant, and no single label describes that.

6. Admin Flows

  • Confirm — normally instant at creation; an order stays created only when something needs a decision (short order, reconciliation flag). created means "a human has to look at this".
  • DispatchPOST /:id/shipments with quantities and device serial numbers (unique per product; entered at dispatch). Deliver and fail close a shipment.
  • COD collection — records when cash changed hands; only applicable for COD, delivered, not already counted.
  • Returns — decide (approve/reject), receive (goods back), inspect (quantities + rejection reason). The budget: return_pending_quantity + returned_quantity <= delivered_quantity.
  • Refunds — create (lines and quantities — the server computes the money), approve (choose the method), reject, settle (record a settlement reference — required by constraint). An approved refund can never be rejected. ORDER_REFUND_EXCEEDS_PAID is reachable with no operator fault — two people approving at once — so say the figure changed and refresh.

7. Lifecycle and State Transitions

7.1 Order statuses

Covered in §5.4. Legal transitions are guarded — ORDER_TRANSITION_NOT_ALLOWED (409) on anything else.

7.2 Return statuses

FromEvent/ActionToGuardSide Effects
requestpendingdelivered + within windowbudget held
pendingdecide approveapprovedawaits receipt
pendingdecide rejectrejectedbudget released
approvedreceivereceivedgoods back
receivedinspectinspected / rejectedquantities + reasonrefund eligibility
anycustomer cancelcancelledstill pendingbudget released

7.3 Refund statuses

FromEvent/ActionToGuardSide Effects
create (from order)pendinglines within net ceilings
pendingapprove (with method)approvedcannot be rejected after
pendingrejectrejected
approvedsettle (with reference)settledreference required (400)money moved by a human

9. Data and Side Effects by Flow

FlowDB WritesCache EffectsJobsRealtimeAnalyticsNotifications
CREATE_ORDERorder + 12 tables' rowsfrom outboxconfirmation email (or short-order email)
Cancelstatus + restockcancellation email (COD: no refund stated)
Shipmentshipment + serialsdispatch email
Return decide/receive/inspectreturn rowsreturn email
Refund approve/settlerefund rows

10. Error and Recovery Flows

ScenarioTriggerUser/System ExperienceRecoverySource
Transition blockedOrder moved409Refresh, show current stateORDER_TRANSITION_NOT_ALLOWED
Cancel after dispatchToo late409Offer a return — message says whichORDER_NOT_CANCELLABLE
Restock refusedInventory declined500, cancellation rolled backRetry, escalate — nothing changedORDER_RESTOCK_REFUSED
Double-tap returnSame units twice409Refresh — not alarmingORDER_RETURN_QUANTITY_UNAVAILABLE
Double-approve refundTwo admins409Figure changed — refreshORDER_REFUND_EXCEEDS_PAID
Settle without referenceMissing evidence400Require the fieldORDER_REFUND_SETTLEMENT_REFERENCE_REQUIRED

11. Diagrams Required Per Module

  • Actor capability diagram — §3/§4.
  • Sequence diagram per major flow — §5.1.
  • State machine diagram — §5.4/§7.
  • Data side-effect diagram — §9.
  • Error branch diagram — §10.

12. Mandatory Feature and Flow Deep-Dive Pack

12.1 Feature Inventory With Minor Behaviors

FeatureMinor BehaviorActorTriggerUser/System ResultBackend Side EffectSource
Status pollpollAfterSecondsCustomerPollServer-set intervalhonoured
ReceiptGenerated on demandCustomerDownloadAlways currentPDF stream
Serial entryPer-unit at dispatchAdminShipmentUnique per productORDER_SERIAL_ALREADY_RECORDED on dup
Short orderDistinct emailCustomerHold lapsedTold what is missingoperator decision
COD cancelNo refundCustomerBefore collectionCancellation email says socorrect
Return cancelBudget releaseCustomerCancelUnits available again
Refund approveMethod chosenAdminApproveRow gains methodnot rejectable
Refund settleReference requiredAdminSettleEvidence recorded400 without

12.2 Business Process Diagram Pack

12.3 Business Rules and Policy Traceability

RuleBusiness ReasonActor ImpactEnforced InAPI ImpactBackend ImpactTests
No returned statusHistory is truthDerived badgeenumnine-status enumprobe
Quantities are truthOne line, three statesLabels for displayschemano item status columnprobe
Returns as budgetNo over-returnCHECKpending + returned <= deliveredprobe
Refund ceilingsNever more than paidtwo CHECKsorder + lineprobe
COD committed ≠ collectedCash days laterNo refund pre-collectionfieldcodCollectedAtspec
Settlement reference requiredHuman evidenceconstraint400probe
One order per checkoutNo duplicatesunique indexuq_order_checkout_session_idspec
Outbox row in completion txNo paid-no-ordercheckout paymentorder.eligiblespec

12.4 Tradeoffs and Product Rationale

Product DecisionUser BenefitEngineering BenefitAlternativeTradeoffRisk
Background order creationClient never fakes ordersOutbox guaranteeSynchronousSlight delayUnique index
Returns/refunds as aggregatesSeveral in flightNo status explosionStatusesDerive badgesDocumented
No item statusOne truthQuantities add upLabel columnClient derivesLabel provided
Human-settled refundsMoney controlNo gateway depAuto-refundManual queueReference required
Receipt not tax invoiceLegal honestyTax invoiceNo VAT claimsVerbatim disclaimer

12.5 Flow Edge-Case Matrix

FlowEdge CaseTriggerExpected BehaviorUser/System FeedbackSource
CreateOutbox redeliveredDuplicateOne orderunique index
CreateShort lineHold lapsedOrder + unavailable labeldistinct email
CancelCOD uncollectedPre-collectionNo refundemail says so
CancelRestock refusedInventory downRollback, 500nothing changed
ShipmentSerial duplicateTypo/real409operator checks
ShipmentSplit dispatchTwo parcelspartially_shipped then shipped
DeliverPartialFirst parcelpartially_delivered, second dispatchable
ReturnPast windowLate409date in message
ReturnDouble-tapConcurrent409refresh
RefundOver ceilingTwo approvers409figure changed
RefundApproved then rejectMistakeRefusedtransition guard

12.6 Flow-to-Data Trace

FlowReadsWritesCacheJobs/EventsResponse Fields
Createcheckout, paymentorder + items + promotions + addressoutbox → CREATE_ORDERorder
Statusorder, itemsstatus, labels, timeline, pollAfterSeconds
Cancelorder, inventorystatus, restockmessage
Shipmentorder, itemsshipment, serialsdispatch emailshipment
Returnorder, itemsreturn rowsreturn emailreturn
Refundorder, items, returnrefund rowsrefund

12.7 Experience Quality Checklist

  • The doc explains what the actor is trying to accomplish.
  • The doc explains what the backend does that the actor does not see (outbox chain, derived labels, budget).
  • The doc covers every minor flow and branch.
  • The doc includes user, admin and worker flows.
  • The doc explains business logic, tradeoffs, and rationale.
  • The doc maps every flow to API routes and backend side effects.
  • The doc includes diagrams appropriate to each flow type.
  • The doc covers edge cases and failure recovery.

13. Completion Checklist

  • Every feature, minor action, and submodule capability is listed.
  • Every actor has allowed and forbidden behavior.
  • Every major and minor flow includes steps, branches, and diagrams.
  • Every lifecycle has a transition table and state diagram.
  • Every flow links to the API and backend docs.
  • TDD dependencies are called out where they shape behavior (no TDD pages published yet).

See Also