HOCO B2B
Team tasksAnis

SRV-16 — Orders module — lifecycle, assisted orders, history, documents

The 11-status state machine (no automatic confirmation — every order is confirmed in the back-office), controls, refusal and controlled modification, assisted orders and confirmations, first-order attribution, cancellation with automatic restock, invoice and delivery-note PDFs.

FieldDetails
Task codeSRV-16
PhaseP1 — V1 build & integration
Product scopeV1
StatusDone (Mon 19 Oct 2026)
StartMon 19 Oct 2026
DueMon 19 Oct 2026
ResponsibleAnis — Full-stack developer
Co-responsible—
Effort2 person-day(s) planned · 8 from scratch · size M
Area · appServer · server
Depends onSRV-15
UnblocksSRV-20, SRV-17, SRV-18, SRV-26, SRV-25, WEB-01, SRV-40
Milestones—

Summary

The 11-status state machine (no automatic confirmation — every order is confirmed in the back-office), controls, refusal and controlled modification, assisted orders and confirmations, first-order attribution, cancellation with automatic restock, invoice and delivery-note PDFs.

Description

Orders are the core flow of the cahier (§4.4, §5.4, §6.7, §15.2; ORD-04…ORD-12, ORD-14, ORD-15, STK-03, STK-08). This task implements the 11-status OrderStatus state machine with an explicit transition table and actors, and the 17 Oct rule that no order is confirmed automatically: app, web, assisted and phone orders all land in SUBMITTED (or PENDING on hold) and appear in admin.orders.toConfirm until someone with orders.validate confirms them. It covers validation controls (stock, credit, minimums, reseller status) with stock reservation per stock.reserveOn, refusal with a reason, controlled modification with OrderChange history, cancellation by actor and status with automatic restock, assisted orders (delegate draft → reseller confirmation or administration validation, 72 h expiry), back-office orders on behalf of a reseller, first-order flag and attribution to the source delegate, reorder, and invoice/delivery-note PDFs. Every status change emits an outbox event that reaches the reseller live over SSE (SRV-26) and as a notification (ORD-15). Out of scope: delivery records (SRV-17), invoices/payments (SRV-18), returns (SRV-20).

Subtasks

#SubtaskOwner
1Transition table and guard functions for the 11 OrderStatus values (actor, permission, preconditions, side effects); 409 ORDER_TRANSITION_NOT_ALLOWEDAnis
2Confirmation queue admin.orders.toConfirm (SUBMITTED, PENDING, assisted confirmed by reseller) with control results per orderAnis
3admin.orders.validate: controls (STOCK_INSUFFICIENT with override, CREDIT_LIMIT_EXCEEDED, RESELLER_SUSPENDED), reservation via stock.reserveOn, VALIDATED; admin.orders.refuse with ORDER_REFUSAL_REASONAnis
4Controlled modification admin.orders.modify (lines, quantities, unit price with permission) until PREPARING, re-checks, OrderChange rows and reseller notificationAnis
5Cancellation: reseller orders.cancel while status in orders.cancelAllowedStatuses, back-office admin.orders.cancel with ORDER_CANCEL_REASON; reservation release / re-entry hooksAnis
6Assisted orders: delegate.assisted.create/update/submit/discard, AssistedConfirmation AWAITING_RESELLER with assistedExpiresAt = +72 h, orders.confirmAssisted / rejectAssisted, admin.orders.confirmAssistedAnis
7Job orders.expireAssisted every 15 min (EXPIRED → CANCELLED) with the 24-hour reminderAnis
8Back-office order on behalf (admin.orders.create, channel BACK_OFFICE) using the cart validation pipeline, landing in SUBMITTEDAnis
9OrderStatusChange and OrderChange writers; first-order flag and source-delegate attribution with revert on refusal/cancel; admin.orders.historyAnis
10Invoice and delivery-note PDF generation (BL-YYYY-NNNNNN at READY) and orders.document / admin.orders.documents with signed URLsAnis
11Outbox events order.submitted/validated/refused/modified/status_changed/cancelled with reseller, delegate and staff recipientsAnis
12Contract procedures + Zod schemas wired to the module service: orders.list/summary/get/reorder, delegate.orders.*, admin.orders.list/get/transitionAnis

Deliverables

  • apps/server/src/modules/orders/{router,service,repo,state-machine,assisted,events,jobs}.ts
  • packages/contracts/src/{orders.ts,delegate/orders.ts,admin/orders.ts}
  • apps/server/src/modules/orders/documents/{invoice,delivery-note}.tsx PDF templates
  • Order lifecycle table in /docs/srs/lifecycles-and-statuses matching the transition table code

Acceptance criteria

  • No code path moves an order to VALIDATED without an explicit admin.orders.validate by a user holding orders.validate (ORD-14)
  • Every transition not in the table returns 409 ORDER_TRANSITION_NOT_ALLOWED; a user without the permission gets 403 PERMISSION_DENIED (ORD-04)
  • A reseller can cancel only while SUBMITTED or PENDING; cancellation releases reserved stock automatically (ORD-10, STK-03)
  • An assisted order not confirmed within 72 h becomes EXPIRED/CANCELLED and the delegate is notified (ORD-08)
  • Each status change writes an OrderStatusChange and emits order.status_changed received by the reseller's SSE stream within 2 seconds (ORD-06, ORD-15)
  • The first delivered-path order of a reseller is flagged and attributed to the source delegate in reports (ORD-09)
  • Invoice and delivery-note PDFs are downloadable by the reseller through a signed URL (ORD-12)

Requirements covered

RequirementTitleRelease
ORD-04Order lifecycle (11 statuses) with an explicit transition table and actors; no order is ever confirmed automaticallyV1
ORD-05Back-office processing: automatic controls, validation, controlled modification, refusal with reasonV1
ORD-06Every modification and status change is historised, dated and notifiedV1
ORD-07Reseller order tracking: counters by status, filters, progress, details, invoice download, support, reorderV1
ORD-08Assisted orders prepared by a delegate, confirmed by the reseller or validated by the administrationV1
ORD-09First order flagged and attributed to the reseller and the source delegate in reportsV1
ORD-10Cancellation rules by actor and status, with stock releaseV1
ORD-11Back-office order entry on behalf of a reseller (phone orders)V1
ORD-12Order documents: invoice and delivery note PDFsV1
STK-03Reservation and deduction triggered by configurable order statuses; cancellations and returns put quantities back automaticallyV1
STK-08No order validated beyond available stock unless an authorised override is recordedV1
ORD-14Every order — app, web, assisted or phone — waits for an explicit confirmation by the back-office before preparationV1
ORD-15Order status changes reach the reseller in real time (live update in the app and web) and as a notificationV1

Screens

ScreenNameApp
BO-38Orders listBO
BO-39Order detail (controls, actions, history)BO
BO-40New order on behalf of a resellerBO
BO-41Orders to confirm (new, on hold, assisted)BO

API surface

Test measures

  • Table-driven unit tests over the full transition matrix (status × actor × permission)
  • DB tests against real Postgres for validate/cancel stock and credit side effects
  • Job test for assisted expiry with a fake clock
  • E2E on staging: reseller checkout → back-office confirm → status visible live in the reseller web

Risks

  • Back-office becomes a bottleneck since every order needs manual confirmation — to-confirm queue sorted by age with counters and SSE alerts; bulk confirmation of clean orders (all controls green) as a pilot option
  • Modification after reservation leaves stock inconsistent — modification re-runs reserve/release deltas in the same transaction

KPI

  • Delivered by Mon 19 Oct 2026 within 2 person-day(s).
  • Every acceptance criterion above demonstrated before hand-off; linked requirements' acceptance criteria pass.
  • Zero open critical defects, permission gaps or data-integrity regressions at sign-off.

Generated from content/plan/tasks.json by scripts/generate-team-tasks.mjs. Dates are computed by the scheduler (Sunday–Thursday weeks, holidays excluded) — change the plan, not this page.

On this page