import { z } from "zod"; // Shared between apps/api (server-side validation, source of truth) and // apps/web (client-side validation for instant feedback before the round // trip) — one set of rules, no risk of the two drifting apart. // Zod's own `.min()`/`.email()` messages are in French: this is the only // place end users ever see them (surfaced as-is in apps/web's forms), and // the whole UI is French. This is distinct from the ErrorCode-based i18n // used for *API* errors (see error-codes.ts) — these are purely // client-side, pre-submit validation messages that never leave the browser. /** Payload accepted by `POST /auth/signup`. */ export const signupSchema = z.object({ firstName: z.string().trim().min(1, "Le prénom est requis").max(100), lastName: z.string().trim().min(1, "Le nom est requis").max(100), email: z.string().trim().toLowerCase().email("Email invalide"), // Length only — not the place to enforce complexity rules; argon2 already // makes brute-forcing short-but-random passwords impractical, and // complexity rules mostly push users toward predictable patterns. password: z.string().min(8, "8 caractères minimum").max(200), }); /** Inferred TS type for {@link signupSchema}'s validated output. */ export type SignupInput = z.infer; /** Payload accepted by `POST /auth/login`. */ export const loginSchema = z.object({ email: z.string().trim().toLowerCase().email("Email invalide"), password: z.string().min(1, "Le mot de passe est requis"), }); /** Inferred TS type for {@link loginSchema}'s validated output. */ export type LoginInput = z.infer;