feat: implement customer profile management and business application features
- Added customer profile controller with endpoints for retrieving, updating, and deactivating user profiles. - Introduced address model and routes for managing user addresses. - Created business application model and service for handling business applications, including approval and rejection processes. - Developed business contact and credit account models to support business customer functionalities. - Implemented settlement term model for managing payment terms. - Added email templates for business application notifications (approved, rejected, received, and status changes). - Enhanced validation schemas for customer and business inputs to ensure data integrity. - Created unit tests for business application service and validation schemas to ensure functionality and correctness. - Added migration scripts to set up new database tables and columns for customer and business features.
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
const {z}=require("zod"); const request=(body)=>z.object({body:z.object(body).strict(),params:z.object({}).passthrough(),query:z.object({}).passthrough()}); const text=(n)=>z.string().trim().min(1).max(n).transform(v=>v.replace(/\s+/g," "));
|
||||
const details={businessName:text(180),legalName:text(180),registrationNumber:text(100),taxNumber:text(100).optional().nullable(),businessType:text(80),contactEmail:z.string().trim().toLowerCase().email(),contactPhone:z.string().trim().regex(/^\+?[0-9 ()-]{7,30}$/),website:z.string().trim().url().optional().nullable()};
|
||||
module.exports={application:request(details),reject:request({reason:text(500)}),businessUpdate:request({businessName:text(180).optional(),legalName:text(180).optional(),taxNumber:text(100).optional().nullable(),businessType:text(80).optional(),contactEmail:z.string().trim().toLowerCase().email().optional(),contactPhone:z.string().trim().regex(/^\+?[0-9 ()-]{7,30}$/).optional(),website:z.string().trim().url().optional().nullable()}),credit:request({creditLimit:z.coerce.number().min(0).max(9999999999999),currency:z.string().trim().length(3).transform(v=>v.toUpperCase()),status:z.enum(["DISABLED","ACTIVE","SUSPENDED"])}),settlement:request({settlementTermId:z.string().min(1)}),status:request({status:z.enum(["ACTIVE","SUSPENDED","CLOSED"])}),contact:request({name:text(150),title:text(100).optional().nullable(),email:z.string().trim().email().optional().nullable(),phone:z.string().trim().regex(/^\+?[0-9 ()-]{7,30}$/).optional().nullable(),isPrimary:z.boolean().optional()})};
|
||||
@@ -0,0 +1,9 @@
|
||||
const { z } = require("zod");
|
||||
const request = (body) => z.object({ body: z.object(body).strict(), params: z.object({}).passthrough(), query: z.object({}).passthrough() });
|
||||
const text = (max) => z.string().trim().min(1).max(max).transform((v) => v.replace(/\s+/g, " "));
|
||||
const addressFields = { label: text(50), recipientName: text(150), phoneNumber: z.string().trim().regex(/^\+?[0-9 ()-]{7,30}$/), addressLine1: text(255), addressLine2: text(255).optional().nullable(), city: text(100), district: text(100).optional().nullable(), province: text(100).optional().nullable(), postalCode: z.string().trim().max(20).regex(/^[A-Za-z0-9 -]*$/).optional().nullable(), countryCode: z.string().trim().length(2).transform(v => v.toUpperCase()), isDefaultShipping: z.boolean().optional(), isDefaultBilling: z.boolean().optional() };
|
||||
module.exports = {
|
||||
profileUpdate: request({ firstName: text(100).optional(), lastName: text(100).optional(), phoneNumber: z.string().trim().regex(/^\+?[0-9 ()-]{7,30}$/).optional().nullable(), dateOfBirth: z.coerce.date().max(new Date()).optional().nullable(), preferredLanguage: z.enum(["en", "si", "ta"]).optional(), theme: z.enum(["light", "dark", "system"]).optional(), marketingEmailEnabled: z.boolean().optional(), marketingPushEnabled: z.boolean().optional(), inAppNotificationsEnabled: z.boolean().optional(), avatarUploadId: z.coerce.number().int().positive().optional().nullable(), backgroundUploadId: z.coerce.number().int().positive().optional().nullable() }),
|
||||
addressCreate: request(addressFields), addressUpdate: request(Object.fromEntries(Object.entries(addressFields).map(([k,v]) => [k,v.optional()]))),
|
||||
deactivate: request({ confirmation: z.literal("DEACTIVATE"), password: z.string().min(1).optional() }),
|
||||
};
|
||||
Reference in New Issue
Block a user