Developer Resourcespromotion
Promotion Module Backend Documentation
Promotion schema, digital eligibility constraints, runtime contracts, and file ownership map.
Promotion Module - Backend Documentation
1. Digital Eligibility Model
Promotion eligibility is aligned to the digital-only commerce contract.
cartTypeEligibility:digitalpaymentMethodEligibility:online- no COD-specific branch
cart_type_eligibility and payment_method_eligibility remain enums to preserve stable schema contracts for future controlled expansion.
2. Schema Overview
Primary schema files:
packages/db/src/schema/promotion/enums.tspackages/db/src/schema/promotion/promotion.tspackages/db/src/schema/promotion/promotion-scope.tspackages/db/src/schema/promotion/promotion-usage.ts
Core invariants:
promotion_usage_target_check:num_nonnulls(cart_id, order_id) >= 1promotion_scope_target_check:num_nonnulls(product_id, category_id, tag_id) = 1promotion_discount_value_non_negative:discount_value >= 0promotion_max_discount_cap_non_negative:max_discount_cap IS NULL OR max_discount_cap >= 0promotion_min_cart_value_non_negative:min_cart_value IS NULL OR min_cart_value >= 0
3. Core Backend Responsibilities
- create/update/disable/delete promotions (admin)
- customer coupon validate/apply/remove
- customer active-promotion browsing and usage-history retrieval
- scope-based applicability checks by product/category/tag
- usage-limit enforcement with stable code normalization
4. API Routes
Admin routes (/api/admin/promotions):
GET /GET /:idPOST /PATCH /:idDELETE /:idPOST /:id/disable
Customer routes (/api/promotions):
POST /applyPOST /removeGET /GET /my-usage
Mobile equivalents are composed under /api/mobile/promotions/....
5. Cache Keyspaces
| Surface | Prefix |
|---|---|
| Admin list | promotions:admin:list: |
| Admin detail | promotions:admin:detail: |
| Customer list | promotions:customer:list: |
| Promotion by code | promotions:code: |
All keys use deterministic segments and admin writes invalidate affected prefixes.
6. Idempotency & Integrity
- create path uses conflict-safe code uniqueness handling
- coupon usage writes remain transactionally consistent with cart coupon updates
- input code normalization is deterministic (
trim + uppercase) - invalid legacy usage rows are remediated or rejected before strict checks are enforced
7. Integration Notes
- customer promotion operations are tightly integrated with cart totals and applied-coupon fields
- promotion scope lookups integrate with catalog entities (product/category/tag)
- removed physical/COD behavior must not be reintroduced without schema and API contract changes
8. Runtime Configuration
Admin rate limit:
PROMOTION_ADMIN_RATE_LIMIT(default120)PROMOTION_ADMIN_RATE_WINDOW_SECONDS(default60)
Customer operation rate limit:
PROMOTION_CUSTOMER_OPERATION_RATE_LIMIT(default60)PROMOTION_CUSTOMER_RATE_WINDOW_SECONDS(default60)
Cache TTL:
PROMOTION_ADMIN_CACHE_TTL_SECONDS(default120)PROMOTION_CUSTOMER_CACHE_TTL_SECONDS(default120)
9. Error Handling
| HTTP | errorCode | Message |
|---|---|---|
| 400 | PROMOTION_USAGE_CONFLICT | Cannot extend end date for promotions that already have usage. |
| 400 | PROMOTION_USAGE_CONFLICT | Cannot change code for promotions that already have usage. |
| 400 | PROMOTION_USAGE_CONFLICT | Cannot delete promotion with usage history. |
| 400 | PROMOTION_INVALID_DATE_RANGE | Invalid startDate or endDate. |
| 400 | PROMOTION_INVALID_DATE_RANGE | endDate must be after startDate. |
| 400 | PROMOTION_DISCOUNT_INVALID | discountValue must be greater than zero. |
| 400 | PROMOTION_DISCOUNT_INVALID | maxDiscountCap must be greater than or equal to discountValue for percentage discounts. |
| 400 | PROMOTION_SCOPE_INVALID | One or more scoped IDs are invalid. |
| 400 | PROMOTION_NOT_APPLICABLE | Coupon not applicable to cart/product context. |
| 404 | PROMOTION_NOT_FOUND | Promotion not found. |
| 409 | PROMOTION_CODE_EXISTS | Promotion code already exists. |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests. Please try again later. |
10. Backend Diagram
11. Module Composition
PromotionModule- shared module- imports:
ConfigModule,DatabaseModule,RedisModule
- imports:
PromotionAdminModule- admin leaf- controller:
PromotionAdminController - service:
PromotionAdminService
- controller:
PromotionCustomerModule- customer leaf- controller:
PromotionCustomerController - service:
PromotionCustomerService
- controller:
12. File Map
apps/api/src/modules/promotion/admin/*apps/api/src/modules/promotion/customer/*apps/api/src/modules/promotion/__tests__/*packages/db/src/schema/promotion/enums.tspackages/db/src/schema/promotion/promotion.tspackages/db/src/schema/promotion/promotion-scope.tspackages/db/src/schema/promotion/promotion-usage.ts
13. Environment Variables
| Variable | Default | Description |
|---|---|---|
PROMOTION_ADMIN_RATE_LIMIT | 120 | Rate limit for admin promotion operations |
PROMOTION_ADMIN_RATE_WINDOW_SECONDS | 60 | Rate limit window for admin operations |
PROMOTION_CUSTOMER_OPERATION_RATE_LIMIT | 60 | Rate limit for customer promotion operations |
PROMOTION_CUSTOMER_RATE_WINDOW_SECONDS | 60 | Rate limit window for customer operations |
PROMOTION_ADMIN_CACHE_TTL_SECONDS | 120 | Cache TTL for admin promotion views |
PROMOTION_CUSTOMER_CACHE_TTL_SECONDS | 120 | Cache TTL for customer promotion views |
Time fields in this module are stored as timezone-aware values and should be handled as ISO-8601 instants by API consumers.
See Also
- Feature Guide: See Promotion - Feature List Section 6 (State Models) for promotion lifecycle and scope diagrams.
- API Reference: See Promotion - API & Integration Guide Section 7 (Endpoint Reference + Payload Cheatsheet) for API contracts.