Developer Resourcescart
Cart Module Feature List
Functional behavior of cart operations, quantity management, manual delivery address flow, and async cart lifecycle hooks.
Cart Module - Feature List
1. Feature Overview
Cart supports physical-product cart operations with shipping projection and quantity controls.
Eligible product types:
physical— tangible goods requiring shippingdigital— non-physical goods (no shipping required)care_package— service contracts (no shipping required)
2. Exposed Surfaces
| Surface | Prefix |
|---|---|
| Customer API | /api/cart |
| Mobile-composed customer API | /api/mobile/cart |
| Admin support API | /api/admin/cart |
3. Core Features
| Feature | Behavior |
|---|---|
| Active cart lifecycle | One active cart per user via partial unique index |
| Add item with quantity | Adds new line or increases existing line quantity |
| Quantity controls | Increase / decrease / set quantity with min/max validation (1..99) |
| Pricing snapshot | unitMrp, unitSp persisted per line item |
| Effective SP fallback | Backend uses unitSp > 0 ? unitSp : unitMrp |
| Applied promo maintenance | Applied coupon is revalidated automatically after every cart mutation |
| Manual address location | Stores shipping district + full address + optional coordinates at cart level |
| Guest quote preview | Public read-only quote for guest cart snapshot + shipping district |
| Final payable | totalSp - appliedDiscount + shippingFee |
| Cache-aside reads | Cart reads cached with TTL; writes invalidate by user prefix |
| Rate limiting | Redis sliding-window limit on mutating endpoints |
4. Location Features
| Endpoint | Purpose |
|---|---|
GET /cart/location | Read current cart shipping location projection |
GET /cart/location/districts | List active shipping districts for selector UX |
POST /cart/guest/quote | Public backend quote for guest cart + shipping fee preview |
POST /cart/location | Manual location set (canonical) |
POST /cart/location/auto | Disabled by default; returns 410 CART_LOCATION_AUTO_DISABLED |
DELETE /cart/location | Clear shipping location projection |
Manual location payload requires:
districtNameaddressLine1citypostalCode
5. Quantity Features
| Endpoint | Effect |
|---|---|
POST /cart/items/:itemId/increase | quantity = quantity + 1 |
POST /cart/items/:itemId/decrease | quantity = quantity - 1 or remove when quantity hits 1 |
PUT /cart/items/:itemId/quantity | explicit set quantity (operation=set) |
Rules:
- quantity range:
1..99 - stock reservation adjusts on quantity deltas
- item
discountis per-unit;totalDiscountis quantity-aware - all amounts are integer minor units across cart/order/payment boundaries
- if a cart mutation makes the current coupon invalid, the backend removes it from pricing and returns
promoNotice
6. Queue/Worker Integration
| Job | Queue | Trigger |
|---|---|---|
cart.clear_after_order_confirmed | QueueName.CART | order payment success flow |
cart.expire | QueueName.CART | cart expiration workflow |
7. Care-Package Cart Integration
Care packages are attached to individual cart items (not to the cart as a whole). Each cart item may have at most one care package attached.
| Feature | Behavior |
|---|---|
| Add care package to cart item | POST /api/mobile/cart/items/:cartItemId/care-package with { carePackageId, pricingTierId } |
| Remove care package from cart item | DELETE /api/mobile/cart/items/:cartItemId/care-package |
| Guest quote | POST /api/mobile/cart/guest/quote accepts optional items[].carePackage for read-only totals |
| Guest-to-auth sync | POST /api/mobile/cart/sync persists optional items[].carePackage after login |
| 1-per-cart-item constraint | Unique index on cartItemId — second add returns CARE_PACKAGE_CART_ITEM_ALREADY_HAS_PACKAGE |
| Cart total | finalPayable includes care package unitPrice per attached item |
| Shipping | Care package lines do not contribute to shipping fee; hasPhysicalItem check in checkout skips shippingDistrict validation when all items are care-package-only |
| Snapshot capture | Cart stores selected IDs + unitPrice; immutable carePackageSnapshot + pricingSnapshot are captured during checkout/subscription creation |
All care-package attach surfaces revalidate that the product is physical, the package is active, package eligibility rules match the product, and the selected tier is active. The direct cartItemId add/remove endpoints are JWT-only; guest clients use quote before login and sync after login.
8. Admin Feature
| Endpoint | Behavior |
|---|---|
GET /api/admin/cart/users/:userId | Read active cart for support/debug, including shipping + address projection |
9. UX/Integration Guidance
- Client should always render per-item
quantityfrom API response. - Client should not recalculate line quantity from totals.
- Client should load district options from
GET /cart/location/districts. - For guest users, client should call
POST /cart/guest/quotewith optionalitems[].carePackageto render backend-trusted totals. - Guest quote is read-only and does not persist cart/order data; persist the same shape through
POST /cart/syncafter login. - Client should set manual delivery location before checkout when shipping fee is required.
GET /cart/locationmay return{}when no location is selected.- Client should not re-apply a coupon after add/remove/quantity/sync mutations; normal cart mutation APIs now return the correct post-mutation coupon state.
- If cart response includes
promoNotice, client should showpromoNotice.messageand trust the returned totals/appliedCoupon state. - Checkout still keeps final coupon validation as a safety guard, including payment-method compatibility checks.
10. Environment Variables
| Variable | Default | Purpose |
|---|---|---|
CART_CUSTOMER_OPERATION_RATE_LIMIT | 60 | max mutating operations per window |
CART_CUSTOMER_RATE_WINDOW_SECONDS | 60 | rate limit window size |
CART_CUSTOMER_CACHE_TTL_SECONDS | 60 | customer cart cache TTL |
CART_AUTO_LOCATE_ENABLED | false | enables/disables /cart/location/auto endpoint |
CART_EXPIRE_IDLE_MS | 1800000 | idle threshold after which active carts are expired by worker |
11. Related Modules
- Order checkout/buy-now APIs own payment initiation.
- Payment module confirms payment, then order flow triggers cart clear job.