import { z } from "zod"; // Shared between apps/api (server-side validation, source of truth) and // apps/admin-web (client-side validation for instant feedback). Same // rationale as schemas/auth.ts — one set of rules, French messages surfaced // as-is in the admin login form. /** * Payload accepted by `POST /admin/auth/login`. Deliberately its own schema * (not a re-export of `loginSchema`): the admin surface is a separate * contract from the end-user one even though the shape currently matches. */ export const adminLoginSchema = 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 adminLoginSchema}'s validated output. */ export type AdminLoginInput = z.infer; /** * Query params for `GET /admin/metrics` — `?days=` bounds how far back the * time-series go (and how many daily buckets they carry). Coerced from the * query string; clamped to a sane window so a huge value can't make the * dashboard scan the whole history. */ export const getMetricsSchema = z.object({ days: z.coerce.number().int().min(7).max(365).default(30), }); /** Inferred TS type for {@link getMetricsSchema}'s validated output. */ export type GetMetricsInput = z.infer; /** * Payload of `POST /internal/tech-steps/heartbeat` — `services/tech-step-llm-worker` * (which has no inbound HTTP of its own) reporting that it's alive. Sent on * `boot`, on every scheduler `tick`, and after each `job` (with that job's * name, outcome and counts). The worker key is fixed server-side (only one * worker exists), so it isn't in the payload. */ export const workerHeartbeatSchema = z.object({ event: z.enum(["boot", "tick", "job"]), /** The job that just ran — present only when `event === "job"`. */ job: z.string().max(100).optional(), /** Whether that job succeeded — present only when `event === "job"`. */ ok: z.boolean().optional(), /** Small `{ label: number }` summary of that job (e.g. `{ suggestions: 3 }`). */ counts: z.record(z.string(), z.number()).optional(), }); /** Inferred TS type for {@link workerHeartbeatSchema}'s validated output. */ export type WorkerHeartbeatInput = z.infer;