77 lines
3.1 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 addressSchema = z.object({
street: z.string().max(200, "Street address is too long").nullable(),
streetLine2: z.string().max(200, "Street address line 2 is too long").nullable(),
city: z.string().max(100, "City name is too long").nullable(),
state: z.string().max(100, "State/Prefecture name is too long").nullable(),
postalCode: z.string().max(20, "Postal code is too long").nullable(),
country: z.string().max(100, "Country name is too long").nullable(),
});
export const requiredAddressSchema = z.object({
street: z.string().min(1, "Street address is required").max(200, "Street address is too long").trim(),
streetLine2: z.string().max(200, "Street address line 2 is too long").optional(),
city: z.string().min(1, "City is required").max(100, "City name is too long").trim(),
state: z
.string()
.min(1, "State/Prefecture is required")
.max(100, "State/Prefecture name is too long")
.trim(),
postalCode: z.string().min(1, "Postal code is required").max(20, "Postal code is too long").trim(),
country: z.string().min(1, "Country is required").max(100, "Country name is too long").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",
]);