Files
Zumri-Backend/app/validation/loyaltyWholesale.schemas.js
Sathira Sri Sathara abb760cc19
CI / test (push) Successful in 10m23s
feat: Implement loyalty and wholesale services with models, routes, and validation
- 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.
2026-09-09 13:56:37 +05:30

2 lines
2.2 KiB
JavaScript

const{z}=require("zod"),wrap=body=>z.object({body:body.strict(),params:z.object({}).passthrough(),query:z.object({}).passthrough()}),id=z.string().min(1).max(180),money=z.string().regex(/^\d+(\.\d{1,2})?$/);exports.redeem=wrap(z.object({rewardId:id}));exports.referral=wrap(z.object({code:z.string().trim().min(8).max(32).transform(x=>x.toUpperCase())}));exports.adjust=wrap(z.object({userId:id,pointsDelta:z.number().int().refine(x=>x!==0),reasonCode:z.string().min(1).max(80),note:z.string().max(500).optional()}));exports.tier=wrap(z.object({code:z.string().min(1).max(60),name:z.string().min(1).max(120),status:z.enum(["ACTIVE","INACTIVE"]).default("ACTIVE"),rank:z.number().int().nonnegative(),qualificationThreshold:z.number().int().nonnegative(),benefits:z.record(z.string(),z.unknown()).optional(),sortOrder:z.number().int().default(0)}));exports.rule=wrap(z.object({sourceType:z.enum(["PURCHASE","VERIFIED_REVIEW","REFERRAL","BIRTHDAY"]),status:z.enum(["ACTIVE","INACTIVE"]),pointsPerAmount:z.number().int().positive().optional(),amountUnit:money.optional(),fixedPoints:z.number().int().positive().optional(),minimumAmount:money.optional(),maximumPoints:z.number().int().positive().optional(),expiryDays:z.number().int().positive().optional(),effectiveFrom:z.coerce.date(),effectiveTo:z.coerce.date().optional()}));exports.reward=wrap(z.object({code:z.string().min(1).max(60),name:z.string().min(1).max(160),description:z.string().optional(),type:z.enum(["COUPON","MANUAL"]),pointsCost:z.number().int().positive(),status:z.enum(["ACTIVE","INACTIVE","ARCHIVED"]),startsAt:z.coerce.date().optional(),endsAt:z.coerce.date().optional(),stockLimit:z.number().int().positive().optional(),perUserLimit:z.number().int().positive().optional(),configuration:z.record(z.string(),z.unknown()).default({})}));exports.credit=wrap(z.object({businessCustomerId:id,type:z.enum(["AUTHORIZATION","CAPTURE","RELEASE","PAYMENT","REFUND","ADJUSTMENT"]),amount:money,currency:z.string().length(3),orderId:id.optional(),paymentId:id.optional(),reference:z.string().max(160).optional()}));exports.settlement=wrap(z.object({businessCustomerId:id,periodStart:z.string().date(),periodEnd:z.string().date(),currency:z.string().length(3)}));