SRV-15 — Cart & checkout rules
Server-side cart, re-validation of price/stock/promotions, minimum amount and quantities, max per order, credit check, checkout options and idempotent checkout.
| Field | Details |
|---|---|
| Task code | SRV-15 |
| Phase | P1 — V1 build & integration |
| Product scope | V1 |
| Status | Done (Mon 19 Oct 2026) |
| Start | Mon 19 Oct 2026 |
| Due | Mon 19 Oct 2026 |
| Responsible | Anis — Full-stack developer |
| Co-responsible | — |
| Effort | 1 person-day(s) planned · 5 from scratch · size S |
| Area · app | Server · server |
| Depends on | SRV-12, SRV-13 |
| Unblocks | SRV-16, SRV-19, SRV-40 |
| Milestones | — |
Summary
Server-side cart, re-validation of price/stock/promotions, minimum amount and quantities, max per order, credit check, checkout options and idempotent checkout.
Description
The cart is server-side and shared across the reseller's devices (ORD-01, RWA-02), and checkout must never trust the client (cahier §5.3, §8, §12; ORD-02, ORD-03, PRC-05, FIN-05). This task implements Cart/CartItem, re-validation on every read (current customer-type price, promotions through the pricing hook, availability, visibility), the cart rules — orders.minAmount (ORDER_MIN_AMOUNT_NOT_MET), minimum quantity and step per variant (QUANTITY_NOT_ALLOWED), maximum per order, stock (STOCK_INSUFFICIENT without revealing the available quantity), basic credit check for the CREDIT method (CREDIT_LIMIT_EXCEEDED) — checkout options (addresses, enabled payment methods, delivery-fee estimate, note) and the idempotent cart.checkout that creates the order in SUBMITTED with snapshots and a CMD-YYYY-NNNNNN number. Every order then waits for back-office confirmation (ORD-14). Guests have no cart. Out of scope: the order state machine after submission (SRV-16) and promotion definitions (SRV-19).
Subtasks
| # | Subtask | Owner |
|---|---|---|
| 1 | Cart and CartItem services: cart.get, items.add (idem), items.update, items.remove, clear; one active cart per reseller | Anis |
| 2 | Re-validation pipeline on read: visibility/status (PRODUCT_UNAVAILABLE), price by customer type, promotions hook, availability, line issues list | Anis |
| 3 | Quantity rules: minQty, qtyStep, maxQtyPerOrder per variant and orders.minAmount per order | Anis |
| 4 | Stock check against available without exposing quantities (issue STOCK_INSUFFICIENT only) | Anis |
| 5 | Credit check for CREDIT payment via the CreditAccount read interface (ceiling − exposure), policy credit.overLimitPolicy | Anis |
| 6 | cart.checkoutOptions: addresses, payment methods enabled by setting, delivery-fee estimate from the delivery-fee policy, note limits | Anis |
| 7 | cart.checkout: Idempotency-Key required, account ACTIVE gate, expectedTotal comparison (409 CART_CHANGED with re-validated cart), order + item snapshots, number allocation, cart emptied, promotion caps consumed — one transaction | Anis |
| 8 | Outbox order.submitted with channel RESELLER_APP or RESELLER_WEB from X-App-Platform / client | Anis |
| 9 | Cart issue codes and checkout error payloads reviewed for the mobile cart screens | Imad |
Deliverables
- apps/server/src/modules/cart/{cart.service.ts,validation.ts,checkout.service.ts,router.ts}
- packages/contracts/src/cart.ts implemented end to end
- Cart rules section in /docs/srs/business-rules confirmed
Acceptance criteria
- The same cart is returned from the mobile app and the web for one reseller (ORD-01, RWA-02)
- Checkout below orders.minAmount returns 422 ORDER_MIN_AMOUNT_NOT_MET with the missing amount in details (ORD-02)
- Checkout with a CREDIT payment above the available credit returns 422 CREDIT_LIMIT_EXCEEDED (FIN-05)
- Replaying cart.checkout with the same Idempotency-Key returns the same order; a different body with the same key returns 409 IDEMPOTENCY_KEY_REUSED
- A price change between cart view and checkout returns 409 CART_CHANGED and creates no order (PRC-05)
- A successful checkout creates an order in SUBMITTED (never VALIDATED) visible in admin.orders.toConfirm (ORD-03, ORD-14)
Requirements covered
| Requirement | Title | Release |
|---|---|---|
| ORD-01 | Server-side cart shared across the reseller's devices (mobile and web) | V1 |
| ORD-02 | Cart rules: minimum amount, minimum quantities and steps, maximum per order, stock and credit checks | V1 |
| ORD-03 | Checkout: address, note, payment method; a unique order number; immediately visible in the back-office | V1 |
| PRC-05 | Prices and stock re-validated at cart and at checkout; the reseller only ever sees their own price | V1 |
| FIN-05 | Basic credit control: ceiling, used and available credit checked at checkout | V1 |
Screens
API surface
| Endpoint group | Operations |
|---|---|
| Cart & checkout | 8 |
Test measures
- DB tests for checkout atomicity (failure after number allocation rolls everything back)
- Unit tests for quantity and minimum-amount rules
- Concurrent double-tap test: two checkouts with the same key create one order
Risks
- Credit exposure is owned by billing (SRV-18, later) — define the CreditAccount read interface now with a stub returning no ceiling, replaced when SRV-18 lands
KPI
- Delivered by Mon 19 Oct 2026 within 1 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.
SRV-14 — CRM module — resellers, prospects, lifecycle, tasks
Reseller records, unique normalised phone, lifecycle automation from events, assignment, segments, interaction timeline, follow-up tasks, documents/photos, validation queue.
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.