feat(plan): zod schemas for plan endpoints
This commit is contained in:
97
src/schemas/plan.schema.ts
Normal file
97
src/schemas/plan.schema.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const isoDate = z
|
||||||
|
.string()
|
||||||
|
.regex(/^\d{4}-\d{2}-\d{2}$/, "Datum musí být ve formátu YYYY-MM-DD");
|
||||||
|
|
||||||
|
const intFromForm = z
|
||||||
|
.union([z.number(), z.string()])
|
||||||
|
.transform((v) => Number(v))
|
||||||
|
.refine((n) => Number.isInteger(n) && n > 0, "Neplatné ID");
|
||||||
|
|
||||||
|
const planCategoryEnum = z.enum([
|
||||||
|
"work",
|
||||||
|
"preparation",
|
||||||
|
"travel",
|
||||||
|
"leave",
|
||||||
|
"sick",
|
||||||
|
"training",
|
||||||
|
"other",
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const CreatePlanEntrySchema = z
|
||||||
|
.object({
|
||||||
|
user_id: intFromForm,
|
||||||
|
date_from: isoDate,
|
||||||
|
date_to: isoDate,
|
||||||
|
project_id: z
|
||||||
|
.union([z.number(), z.string()])
|
||||||
|
.transform((v) => Number(v))
|
||||||
|
.nullish(),
|
||||||
|
category: planCategoryEnum.default("work"),
|
||||||
|
note: z
|
||||||
|
.string()
|
||||||
|
.min(1, "Text poznámky je povinný")
|
||||||
|
.max(500, "Maximálně 500 znaků"),
|
||||||
|
})
|
||||||
|
.refine((v) => v.date_to >= v.date_from, {
|
||||||
|
message: "Datum do musí být stejné nebo po datumu od",
|
||||||
|
path: ["date_to"],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const UpdatePlanEntrySchema = z
|
||||||
|
.object({
|
||||||
|
date_from: isoDate.optional(),
|
||||||
|
date_to: isoDate.optional(),
|
||||||
|
project_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
category: planCategoryEnum.optional(),
|
||||||
|
note: z.string().min(1).max(500).optional(),
|
||||||
|
})
|
||||||
|
.refine(
|
||||||
|
(v) =>
|
||||||
|
v.date_from === undefined ||
|
||||||
|
v.date_to === undefined ||
|
||||||
|
v.date_to >= v.date_from,
|
||||||
|
{
|
||||||
|
message: "Datum do musí být stejné nebo po datumu od",
|
||||||
|
path: ["date_to"],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const CreatePlanOverrideSchema = z.object({
|
||||||
|
user_id: intFromForm,
|
||||||
|
shift_date: isoDate,
|
||||||
|
project_id: z
|
||||||
|
.union([z.number(), z.string()])
|
||||||
|
.transform((v) => Number(v))
|
||||||
|
.nullish(),
|
||||||
|
category: planCategoryEnum,
|
||||||
|
note: z
|
||||||
|
.string()
|
||||||
|
.min(1, "Text poznámky je povinný")
|
||||||
|
.max(500, "Maximálně 500 znaků"),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const UpdatePlanOverrideSchema = z.object({
|
||||||
|
project_id: z
|
||||||
|
.union([z.number(), z.string(), z.null()])
|
||||||
|
.transform((v) => (v === null ? null : Number(v)))
|
||||||
|
.nullish(),
|
||||||
|
category: planCategoryEnum.optional(),
|
||||||
|
note: z.string().min(1).max(500).optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const PlanRangeQuerySchema = z.object({
|
||||||
|
user_id: intFromForm.optional(),
|
||||||
|
date_from: isoDate,
|
||||||
|
date_to: isoDate,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const PlanGridQuerySchema = z.object({
|
||||||
|
date_from: isoDate,
|
||||||
|
date_to: isoDate,
|
||||||
|
view: z.enum(["week", "month"]).default("week"),
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user