import { z } from "zod"; import { MEALS, WEEK_DAYS } from "../types/planning.js"; // See schemas/auth.ts for the shared client/server validation rationale. /** * Payload accepted by `GET /planning`'s `?date=` query param. Only checks * the `YYYY-MM-DD` *shape* — whether it's a real calendar date (e.g. * rejecting `2026-02-30`) is checked service-side via * `@batch-cooking/date-tools`'s `parseDateOnly`, not here: `packages/shared` * has no runtime dependencies of its own, and pulling in a date library just * for this one check isn't worth losing that. */ export const getPlanningByDateSchema = z.object({ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date invalide"), }); /** Inferred TS type for {@link getPlanningByDateSchema}'s validated output. */ export type GetPlanningByDateInput = z.infer; /** * Payload accepted by `POST /planning/items` — adds a recipe to one * (day, meal) slot of the household's planning for the week containing * `date`, creating that week's `Planning` row on the fly if it doesn't * exist yet (see `planning.service.ts`'s `addPlanningItem`). `weekDay`/ * `meal` are finally validated against a closed set here — until now * `WEEK_DAYS`/`MEALS` were only a documented convention (see their doc * comments in `types/planning.ts`), never enforced, since no write endpoint * existed yet. */ export const addPlanningItemSchema = z.object({ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date invalide"), weekDay: z.enum(WEEK_DAYS), meal: z.enum(MEALS), recipeId: z.number().int().positive(), /** * How many portions this slot must actually feed. The server derives the * batched `portions` to prepare from this plus the recipe's own yield * (`computeBatchedPortions`, `@batch-cooking/shared`) — the client never * sends `portions` directly. See `PlanningItemView.portionsRequested`. */ portionsRequested: z.number().int().positive("Le nombre de portions doit être positif"), }); /** Inferred TS type for {@link addPlanningItemSchema}'s validated output. */ export type AddPlanningItemInput = z.infer; /** * Payload accepted by `POST /planning/items/leftover` — serves `portions` * of another item's leftover pool on the `(date, weekDay, meal)` slot, * creating a "leftovers" `PlanningItem` (see `planning.service.ts`'s * `assignLeftoverPlanningItem`). `recipeId` is deliberately **not** here: * a leftovers item can only be the same recipe as its source, so the * server copies it from `sourceItemId` rather than trusting the client. * `portions` is re-checked against the pool actually still available * server-side — a client value over that is a `409 LEFTOVER_QUANTITY_EXCEEDED`. */ export const assignLeftoverSchema = z.object({ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date invalide"), weekDay: z.enum(WEEK_DAYS), meal: z.enum(MEALS), sourceItemId: z.number().int().positive(), portions: z.number().int().positive("Le nombre de portions doit être positif"), }); /** Inferred TS type for {@link assignLeftoverSchema}'s validated output. */ export type AssignLeftoverInput = z.infer;