import { z } from "zod"; export const entityIdSchema = z.string().min(1).max(191); export const ipv4Schema = z .string() .trim() .regex( /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/, "Must be a valid IPv4 address", ); export const optionalTextSchema = z.string().trim().max(5000).nullable().optional(); export const hostnameSchema = z .string() .trim() .min(1) .max(253) .regex( /^(?=.{1,253}$)(?!-)(?:[a-zA-Z0-9-]{1,63}\.)+[a-zA-Z]{2,63}$/, "Must be a valid domain or subdomain", ); export const serverStatusSchema = z.enum(["active", "maintenance", "inactive"]); export const serviceTypeSchema = z.enum(["web_app", "mail", "database", "api", "proxy", "other"]); export const serviceProtocolSchema = z.enum(["http", "https", "tcp", "udp", "other"]); export const serviceStatusSchema = z.enum(["active", "down", "maintenance"]); export const domainCheckStatusSchema = z.enum(["MATCH", "MISMATCH", "UNRESOLVED"]); export const byIdSchema = z.object({ id: entityIdSchema, }); export const serverCreateSchema = z.object({ name: z.string().trim().min(1).max(120), primaryIpAddress: ipv4Schema, secondaryIpAddress: ipv4Schema.nullable().optional(), operatingSystem: z.string().trim().max(120).nullable().optional(), location: z.string().trim().max(120).nullable().optional(), provider: z.string().trim().max(120).nullable().optional(), description: optionalTextSchema, status: serverStatusSchema.default("active"), }); export const serverUpdateSchema = serverCreateSchema.partial().extend({ id: entityIdSchema, }); export const serviceListSchema = z .object({ serverId: entityIdSchema.optional(), }) .optional(); export const serviceCreateSchema = z.object({ serverId: entityIdSchema, name: z.string().trim().min(1).max(120), type: serviceTypeSchema.default("other"), internalPort: z.coerce.number().int().min(1).max(65535).nullable().optional(), externalPort: z.coerce.number().int().min(1).max(65535).nullable().optional(), protocol: serviceProtocolSchema.default("http"), status: serviceStatusSchema.default("active"), description: optionalTextSchema, }); export const serviceUpdateSchema = serviceCreateSchema.partial().extend({ id: entityIdSchema, }); export const domainListSchema = z .object({ serviceId: entityIdSchema.optional(), }) .optional(); export const domainCreateSchema = z.object({ serviceId: entityIdSchema, name: hostnameSchema, expectedServerIp: ipv4Schema.optional(), remarks: optionalTextSchema, }); export const domainUpdateSchema = z.object({ id: entityIdSchema, serviceId: entityIdSchema.optional(), name: hostnameSchema.optional(), expectedServerIp: ipv4Schema.optional(), remarks: optionalTextSchema, }); export const noteListSchema = z .object({ serverId: entityIdSchema.optional(), }) .optional(); export const noteCreateSchema = z.object({ serverId: entityIdSchema, title: z.string().trim().min(1).max(160), content: z.string().trim().min(1).max(10000), category: z.string().trim().max(80).nullable().optional(), }); export const noteUpdateSchema = noteCreateSchema.partial().extend({ id: entityIdSchema, }); export const updateUserRolesSchema = z.object({ userId: entityIdSchema, roleIds: z.array(entityIdSchema).min(1, "Select at least one role"), }); export const userCreateSchema = z.object({ name: z.string().trim().min(2, "Name must be at least 2 characters").max(120), email: z.email("Invalid email address").max(255), password: z.string().min(8, "Password must be at least 8 characters").max(255), roleIds: z.array(entityIdSchema).min(1, "Select at least one role"), });