- Imported salesforceIdSchema and nonEmptyStringSchema from the common domain for better consistency. - Simplified the creation of SOQL field name validation schema. - Refactored the InvoiceTable component to utilize useCallback for improved performance. - Streamlined payment method handling in the PaymentMethodCard component by removing unused props. - Enhanced the checkout process by integrating new validation schemas and improving cart handling logic. - Updated various components to ensure better type safety and clarity in data handling.
161 lines
5.0 KiB
TypeScript
161 lines
5.0 KiB
TypeScript
/**
|
|
* Common Domain - Schemas
|
|
*
|
|
* Shared validation primitives used across all domains.
|
|
*/
|
|
|
|
import { z } from "zod";
|
|
|
|
export const emailSchema = z
|
|
.string()
|
|
.email("Please enter a valid email address")
|
|
.toLowerCase()
|
|
.trim();
|
|
|
|
export const passwordSchema = z
|
|
.string()
|
|
.min(8, "Password must be at least 8 characters")
|
|
.regex(/[A-Z]/, "Password must contain at least one uppercase letter")
|
|
.regex(/[a-z]/, "Password must contain at least one lowercase letter")
|
|
.regex(/[0-9]/, "Password must contain at least one number")
|
|
.regex(/[^A-Za-z0-9]/, "Password must contain at least one special character");
|
|
|
|
export const nameSchema = z.string().min(1, "Name is required").max(100, "Name must be less than 100 characters").trim();
|
|
|
|
export const phoneSchema = z
|
|
.string()
|
|
.regex(/^[+]?[0-9\s\-()]{7,20}$/u, "Please enter a valid phone number")
|
|
.trim();
|
|
|
|
export const countryCodeSchema = z.string().length(2, "Country code must be 2 characters");
|
|
export const currencyCodeSchema = z.string().length(3, "Currency code must be 3 characters");
|
|
|
|
export const timestampSchema = z.string().datetime("Invalid timestamp format");
|
|
export const dateSchema = z.string().date("Invalid date format");
|
|
|
|
export const moneyAmountSchema = z.number().int().nonnegative("Amount must be non-negative");
|
|
export const percentageSchema = z.number().min(0).max(100, "Percentage must be between 0 and 100");
|
|
|
|
export const genderEnum = z.enum(["male", "female", "other"]);
|
|
export const statusEnum = z.enum(["active", "inactive", "pending", "suspended"]);
|
|
export const priorityEnum = z.enum(["low", "medium", "high", "urgent"]);
|
|
export const categoryEnum = z.enum(["technical", "billing", "account", "general"]);
|
|
|
|
export const billingCycleEnum = z.enum(["Monthly", "Quarterly", "Annually", "Onetime", "Free"]);
|
|
export const subscriptionBillingCycleEnum = z.enum([
|
|
"Monthly",
|
|
"Quarterly",
|
|
"Semi-Annually",
|
|
"Annually",
|
|
"Biennially",
|
|
"Triennially",
|
|
"One-time",
|
|
"Free",
|
|
]);
|
|
|
|
// ============================================================================
|
|
// Salesforce and SOQL Validation Schemas
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Schema for validating Salesforce Account IDs
|
|
*/
|
|
export const salesforceAccountIdSchema = z.string().min(1, "Salesforce AccountId is required");
|
|
|
|
/**
|
|
* Schema for validating Salesforce IDs (15 or 18 characters)
|
|
*/
|
|
export const salesforceIdSchema = z
|
|
.string()
|
|
.regex(/^[a-zA-Z0-9]{15,18}$/, "Invalid Salesforce ID format")
|
|
.trim();
|
|
|
|
/**
|
|
* Schema for validating non-empty strings
|
|
*/
|
|
export const nonEmptyStringSchema = z.string().min(1, "Value cannot be empty").trim();
|
|
|
|
/**
|
|
* Schema for validating SOQL field names
|
|
*/
|
|
export const soqlFieldNameSchema = z.string().trim().regex(/^[A-Za-z0-9_.]+$/, "Invalid SOQL field name");
|
|
|
|
// ============================================================================
|
|
// API Response Schemas
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Schema for successful API responses
|
|
* Usage: apiSuccessResponseSchema(yourDataSchema)
|
|
*/
|
|
export const apiSuccessResponseSchema = <T extends z.ZodTypeAny>(dataSchema: T) =>
|
|
z.object({
|
|
success: z.literal(true),
|
|
data: dataSchema,
|
|
});
|
|
|
|
/**
|
|
* Schema for error API responses
|
|
*/
|
|
export const apiErrorResponseSchema = z.object({
|
|
success: z.literal(false),
|
|
error: z.object({
|
|
code: z.string(),
|
|
message: z.string(),
|
|
details: z.unknown().optional(),
|
|
}),
|
|
});
|
|
|
|
/**
|
|
* Discriminated union schema for API responses
|
|
* Usage: apiResponseSchema(yourDataSchema)
|
|
*/
|
|
export const apiResponseSchema = <T extends z.ZodTypeAny>(dataSchema: T) =>
|
|
z.discriminatedUnion("success", [
|
|
apiSuccessResponseSchema(dataSchema),
|
|
apiErrorResponseSchema,
|
|
]);
|
|
|
|
// ============================================================================
|
|
// Pagination Schemas
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Schema for pagination query parameters
|
|
*/
|
|
export const paginationParamsSchema = z.object({
|
|
page: z.coerce.number().int().positive().optional().default(1),
|
|
limit: z.coerce.number().int().positive().max(100).optional().default(20),
|
|
offset: z.coerce.number().int().nonnegative().optional(),
|
|
});
|
|
|
|
/**
|
|
* Schema for paginated response data
|
|
*/
|
|
export const paginatedResponseSchema = <T extends z.ZodTypeAny>(itemSchema: T) =>
|
|
z.object({
|
|
items: z.array(itemSchema),
|
|
total: z.number().int().nonnegative(),
|
|
page: z.number().int().positive(),
|
|
limit: z.number().int().positive(),
|
|
hasMore: z.boolean(),
|
|
});
|
|
|
|
// ============================================================================
|
|
// Query Parameter Schemas
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Schema for common filter parameters
|
|
*/
|
|
export const filterParamsSchema = z.object({
|
|
search: z.string().optional(),
|
|
sortBy: z.string().optional(),
|
|
sortOrder: z.enum(["asc", "desc"]).optional(),
|
|
});
|
|
|
|
/**
|
|
* Combined query params schema (pagination + filters)
|
|
*/
|
|
export const queryParamsSchema = paginationParamsSchema.merge(filterParamsSchema);
|