import { z } from 'zod'; import { CODE_TYPES } from './codeTypes.js'; import { ROLES } from './models.js'; export const colorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/, 'Color must be #RRGGBB'); export const cardFieldsSchema = z.object({ name: z.string().trim().min(1, 'Name is required').max(200), color: colorSchema, code: z.string().min(1, 'Code is required').max(4000), codeType: z.enum(CODE_TYPES), // Free text, may be multiline. No default: partial updates must not clear it. // Multipart forms send CRLF line breaks: store plain LF. comment: z .string() .transform((s) => s.replace(/\r\n?/g, '\n').trim()) .pipe(z.string().max(2000, 'Comment is too long (max 2000 characters)')) .optional(), }); export type CardFields = z.infer; export const cardPatchSchema = cardFieldsSchema.partial().extend({ deleted: z.boolean().optional(), }); export type CardPatch = z.infer; export const emailSchema = z.string().trim().toLowerCase().pipe(z.email()); export const groupInputSchema = z.object({ name: z.string().trim().min(1, 'Name is required').max(100), }); export const userCreateSchema = z.object({ email: emailSchema, role: z.enum(ROLES).default('user'), groupId: z.string().optional(), }); export const userPatchSchema = z.object({ role: z.enum(ROLES).optional(), groupId: z.string().optional(), }); export const keyCreateSchema = z.object({ label: z.string().trim().max(100).optional(), }); export const currentGroupSchema = z.object({ groupId: z.string().min(1), });