import { z } from 'zod'; import { createInsertSchema, createUpdateSchema } from 'drizzle-zod'; import { brochures } from '@/lib/db/schema/brochures'; // Derived from the Drizzle table — adding a column to `brochures` // auto-includes it here. Refinements override per-field. export const createBrochureSchema = createInsertSchema(brochures, { label: (s) => s.trim().min(1).max(120), description: (s) => s.max(500), }).pick({ label: true, description: true, isDefault: true }); export const updateBrochureSchema = createUpdateSchema(brochures, { label: (s) => s.trim().min(1).max(120), description: (s) => s.max(500), }).pick({ label: true, description: true, isDefault: true }); export const registerBrochureVersionSchema = z.object({ storageKey: z .string() .min(1) .max(500) // Mirrors the `validateStorageKey` regex in `src/lib/storage/filesystem.ts` // — defense-in-depth against path-traversal payloads from the client. .regex(/^[a-zA-Z0-9/_.-]+$/, 'Invalid storage key format') .refine((s) => !s.includes('..'), 'Storage key may not contain ".."') .refine((s) => !s.startsWith('/'), 'Storage key may not be absolute'), fileName: z.string().min(1).max(255), fileSizeBytes: z .number() .int() .positive() .max(100 * 1024 * 1024), // 100MB hard ceiling contentSha256: z.string().regex(/^[0-9a-f]{64}$/, 'sha256 must be 64-char hex'), }); export type CreateBrochureInput = z.infer; export type UpdateBrochureInput = z.infer; export type RegisterBrochureVersionInput = z.infer;