feat: Implement loyalty and wholesale services with models, routes, and validation
CI / test (push) Successful in 10m23s
CI / test (push) Successful in 10m23s
- Added models for loyalty points allocation, redemption, rewards, tiers, tier history, and referrals. - Created business credit ledger entries, settlements, and settlement items models. - Developed services for loyalty operations including account management, point allocation, redemption, and referral handling. - Implemented wholesale credit management services for transactions and settlements. - Established routes for loyalty and wholesale admin and customer operations with appropriate middleware for authentication and permission checks. - Introduced validation schemas for loyalty and wholesale operations. - Set up cron jobs for loyalty reconciliation tasks such as birthday rewards and point expirations. - Created migration scripts to set up the database schema for loyalty and wholesale features. - Added unit tests for validation and policy enforcement in loyalty and wholesale services.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
# Loyalty and Rewards API
|
||||
|
||||
All customer APIs are authenticated and derive the loyalty owner from the session.
|
||||
|
||||
## Customer
|
||||
|
||||
- `GET /api/v1/loyalty` — balance, debt, lifetime points, current tier, benefits, and next-tier progress.
|
||||
- `GET /api/v1/loyalty/history?page=&limit=` — paginated immutable ledger.
|
||||
- `GET /api/v1/loyalty/tiers`, `GET /api/v1/loyalty/rewards`.
|
||||
- `POST /api/v1/loyalty/redeem` — requires `Idempotency-Key` and reward ID.
|
||||
- `GET /api/v1/loyalty/vouchers` — owner-specific coupon entitlements.
|
||||
- `GET /api/v1/loyalty/referral`, `POST /api/v1/loyalty/referral/claim`.
|
||||
|
||||
## Administration
|
||||
|
||||
- Loyalty accounts and referral listing.
|
||||
- Tier, earn-rule, and reward listing/creation.
|
||||
- `POST /admin/loyalty/adjustments` requires `loyalty.points.adjust`, a non-zero integer delta, reason, and idempotency key.
|
||||
|
||||
## Policy
|
||||
|
||||
Purchase points are awarded only after authoritative PAID processing. Eligible value is discounted merchandise (`subtotal - discountTotal`), excluding shipping, tax, and duties. Money is divided by configured `amountUnit`, floored to whole units, then multiplied by configured points.
|
||||
|
||||
Verified-review rewards require APPROVED and verified purchase. Referral rewards require the referred account's qualifying paid Order. Birthday events use `BIRTHDAY:user:year`; February 29 follows the actual calendar date.
|
||||
|
||||
Ledger entries are never edited. Refund reversals append negative entries. If already-spent points prevent a complete debit, available points floor at zero and the remainder becomes explicit `pointsDebt`; later earnings repay debt first.
|
||||
|
||||
Redemption locks the account/reward, validates limits, spends earliest-expiring allocations first, and creates at most one result per account/idempotency key. Coupon rewards reuse Phase 5 Coupon and issue an owner-specific entitlement.
|
||||
|
||||
Expiry is configured per earn rule and reconciled in bounded daily batches. No direct balance/tier mutation API exists.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Wholesale Completion API
|
||||
|
||||
Business endpoints require an authenticated, ACTIVE `business_customer`; organization identity is never accepted from the request.
|
||||
|
||||
## Business account
|
||||
|
||||
- `GET /api/v1/business/dashboard`
|
||||
- `GET /api/v1/business/credit`
|
||||
- `POST /api/v1/business/orders/:id/use-credit` with `Idempotency-Key`
|
||||
- `GET /api/v1/business/settlements`, `GET /api/v1/business/settlements/:id`
|
||||
- `GET /api/v1/business/orders/recent`
|
||||
|
||||
The dashboard uses paid Order snapshots for monthly/lifetime volume and discounts, existing BusinessTier for classification, the immutable credit ledger for utilization, and settlement records for next payment information.
|
||||
|
||||
## Administration
|
||||
|
||||
- `POST /admin/wholesale/credit/transactions` (`wholesale.credit.manage`)
|
||||
- `GET /admin/wholesale/businesses/:businessId/credit` (`wholesale.credit.read`)
|
||||
- Settlement list/generation/issue/mark-paid endpoints with settlement permissions.
|
||||
|
||||
Credit formula: `available = creditLimit - ledger balance`. Captures/authorizations increase utilization; payment, release, and refund entries decrease it. Every operation locks the existing BusinessCreditAccount, validates ACTIVE business/account status and currency, and uses a unique event ID. Credit-backed Order placement atomically captures credit, consumes reservations, records an INTERNAL_CREDIT Payment, marks the Order paid, and reuses invoice issuance.
|
||||
|
||||
Settlements snapshot ledger activity for a unique business/period. Due dates come from the existing SettlementTerm. Numbers use ReferenceNumber, and only explicit lifecycle actions are accepted.
|
||||
|
||||
Payment allocation storage exists as a foundation. External bank matching, general ledger, ERP, tax-authority integration, and document-worker validation remain outside this phase.
|
||||
@@ -423,3 +423,6 @@ Date: 2026-09-09. Module 09 is 86%, Module 10 is 76%, and Module 13 is revised t
|
||||
## Phase 8 Completion Update
|
||||
|
||||
Date: 2026-09-09. Module 11 is 88%; shipments are 90%, riders 86%, assignment/dispatch 86%, tracking 88%, proof of delivery 82%, and return logistics 84%. Module 09 is revised to 90% through physical fulfillment integration. Six logistics models, a forward-only migration, explicit shipment states/actions, partial fulfillment, locked rider capacity/assignment, append-only events, proof media validation, safe tracking, and approved-return pickup were added. Automated checks pass 25 suites/123 tests with 305 JavaScript files syntax-checked. The migration was not executed. Staging must validate real InnoDB concurrency, multi-instance idempotency, proof storage, notification fan-out, permission seeding, and return handoff before production or Phase 9 rollout. Module 16 AI Customer Support Chatbot remains excluded from this backend and will be developed separately.
|
||||
## Phase 9 Completion Update
|
||||
|
||||
Date: 2026-09-09. Module 12 is 86% and Module 13 is revised to 88%. Loyalty accounts are 92%, points ledger 90%, earning rules 86%, membership 88%, rewards/redemption 86%, referrals 82%, birthday rewards 80%, and expiry 80%. Business tiers are 84%, business credit 84%, settlements 78%, wholesale dashboard 82%, and wholesale analytics 76%. Module 07 is revised to 82% through coupon-entitlement foundations; Modules 09/10 are unchanged except for paid-event loyalty and internal-credit integration. Fourteen models, a forward-only migration, bounded cron reconciliation, new owner/admin APIs, and immutable concurrency-safe ledgers were added. Migration and real MySQL/cron/document/notification validation remain staging requirements. Module 16 AI Customer Support Chatbot remains intentionally excluded and will be developed separately.
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# ZUMRI Phase 9 Loyalty and Wholesale Completion
|
||||
|
||||
## Objective
|
||||
Connect immutable loyalty rewards and wholesale credit/settlement accounting to existing users, paid orders, reviews, coupons, payments, and invoices.
|
||||
|
||||
## Existing Components Reused
|
||||
User/Profile DOB, BusinessCustomer/Tier/CreditAccount/SettlementTerm, Orders, Payments, Refunds, Invoices, Reviews, Coupons, pricing money helpers, ReferenceNumber, cron, notifications, audit, and RBAC.
|
||||
|
||||
## Loyalty Architecture
|
||||
One account caches balances while an append-only ledger remains authoritative. All mutations lock the account and use unique events.
|
||||
|
||||
## Loyalty Account
|
||||
ACTIVE/SUSPENDED/CLOSED state, spendable/pending/debt balances, lifetime totals, tier, and last activity are maintained transactionally.
|
||||
|
||||
## Points Ledger
|
||||
Integer EARN, REDEEM, EXPIRE, ADJUSTMENT, and REVERSAL entries store source, resulting balance, expiry, and sanitized metadata.
|
||||
|
||||
## Earning Rules
|
||||
Data-driven effective rules support amount-based purchases and fixed review/referral/birthday awards.
|
||||
|
||||
## Purchase Rewards
|
||||
Confirmed PAID processing awards discounted merchandise value only, with integer-safe floor rounding and deterministic Order event identity.
|
||||
|
||||
## Refund Reversals
|
||||
Reversals append history. Insufficient available points produce tracked debt rather than silently discarding value.
|
||||
|
||||
## Verified Review Rewards
|
||||
Only APPROVED verified-purchase reviews earn, once per review.
|
||||
|
||||
## Referral Rewards
|
||||
Opaque random codes prevent self/multiple referral claims; signup alone does not reward, while a qualifying paid Order does.
|
||||
|
||||
## Birthday Rewards
|
||||
Daily bounded reconciliation uses a unique user/calendar-year event, preventing DOB edits or retries from duplicating rewards.
|
||||
|
||||
## Points Expiry
|
||||
Earn rules may assign expiry. Allocation records support earliest-expiring-first redemption and idempotent expiry debits.
|
||||
|
||||
## Membership Tiers
|
||||
Active data-driven LIFETIME_POINTS thresholds select the highest rank and append tier history.
|
||||
|
||||
## Reward Catalogue
|
||||
Scheduled, limited COUPON or MANUAL rewards use integer point costs.
|
||||
|
||||
## Reward Redemption
|
||||
Account/reward/allocation locks enforce balance, stock, per-user limits, FIFO spending, and idempotency.
|
||||
|
||||
## Voucher Integration
|
||||
COUPON rewards reference Phase 5 Coupon and issue customer entitlements rather than creating another coupon engine.
|
||||
|
||||
## Loyalty Notifications and Permissions
|
||||
Phase 2 notification/audit remain the delivery boundaries. Accounts read, points adjustment, management, and referral-read permissions were added.
|
||||
|
||||
## Wholesale Architecture
|
||||
Existing business identity/pricing remain authoritative. Phase 9 adds financial ledgers and period snapshots.
|
||||
|
||||
## Business Credit Ledger
|
||||
Unique immutable events store amount, balance delta/after, currency, Order/Payment references, and event time.
|
||||
|
||||
## Credit Utilization
|
||||
Account row locks prevent limits being exceeded. Cached `usedCredit` was not added to BusinessCreditAccount; the latest ledger balance is authoritative.
|
||||
|
||||
## Credit Purchase Integration
|
||||
An eligible pending wholesale Order is captured, inventory-consumed, paid, and invoiced in one transaction.
|
||||
|
||||
## Settlement Terms and Lifecycle
|
||||
Existing term days derive due dates. DRAFT, ISSUED, PARTIALLY_PAID, PAID, OVERDUE, and CANCELLED use explicit transitions.
|
||||
|
||||
## Business Statements, Invoice Integration, Payment Allocation
|
||||
Settlement items reference source Orders/Invoices/ledger entries. Existing Invoice and Payment are reused; allocation persistence prepares later bank matching.
|
||||
|
||||
## Wholesale Dashboard and Analytics
|
||||
Owner-scoped SQL aggregates provide monthly/lifetime volume, discount totals, credit utilization, next settlement, and recent Orders without loading all history.
|
||||
|
||||
## Security, Audit, Idempotency, Concurrency
|
||||
No IDs select another organization on business routes. Strict schemas reject balance/tier/client financial fields. Unique event keys plus account/settlement/reward locks protect retries and competing writes.
|
||||
|
||||
## Database Changes
|
||||
Forward-only `20260909090000` creates fourteen focused loyalty/wholesale tables. Earlier migrations are unchanged.
|
||||
|
||||
## Tests
|
||||
Policy tests cover integer money conversion, configured caps, referral entropy, strict inputs, terminal settlement state, and permission denial, alongside Phase 0–8 regression.
|
||||
|
||||
## Remaining Known Issues
|
||||
Refund-completion reversal wiring, coupon-entitlement enforcement in the Phase 6 quote path, payment allocation APIs, settlement document generation, notification fan-out, and broader integration/concurrency tests require hardening.
|
||||
|
||||
## Phase 10 Prerequisites
|
||||
Run legacy loyalty/credit/voucher/DOB/reference prechecks, migrate restored staging, seed rules/tiers/rewards/permissions, and test real concurrent redemptions, credit purchases, settlements, webhook rewards, refunds, birthday, and expiry jobs.
|
||||
|
||||
Module 16 AI Customer Support Chatbot is intentionally excluded and will be developed as a separate service.
|
||||
Reference in New Issue
Block a user