Added more strict form validation rules with user feedback
Some checks failed
Continuous Deployment / Update Deployment (push) Failing after 1m55s

This commit is contained in:
2025-12-03 00:55:53 -05:00
parent b40f37c959
commit 41cdd0b74f
2 changed files with 52 additions and 4 deletions

View File

@@ -1,11 +1,11 @@
import { z } from "zod";
export const courseEventAttendeeSchema = z.object({
attendee_id: z.number({invalid_type_error: "Must select a member"}).int().positive(),
attendee_id: z.number({ invalid_type_error: "Must select a member" }).int().positive(),
passed_bookwork: z.boolean(),
passed_qual: z.boolean(),
remarks: z.string(),
attendee_role_id: z.number({invalid_type_error: "Must select a role"}).int().positive()
attendee_role_id: z.number({ invalid_type_error: "Must select a role" }).int().positive()
})
export const trainingReportSchema = z.object({
@@ -19,5 +19,42 @@ export const trainingReportSchema = z.object({
),
remarks: z.string().nullable().optional(),
attendees: z.array(courseEventAttendeeSchema).default([]),
}).superRefine((data, ctx) => {
const trainerRole = 1;
const traineeRole = 2;
const hasTrainer = data.attendees.some((a) => a.attendee_role_id === trainerRole);
const hasTrainee = data.attendees.some((a) => a.attendee_role_id === traineeRole);
if (!hasTrainer) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["attendees"],
message: "At least one Primary Trainer is required.",
});
}
if (!hasTrainee) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["attendees"],
message: "At least one Trainee is required.",
});
}
//no duplicates
const idCounts = new Map<number, number>();
data.attendees.forEach((a, index) => {
idCounts.set(a.attendee_id, (idCounts.get(a.attendee_id) ?? 0) + 1);
if (idCounts.get(a.attendee_id)! > 1) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["attendees"],
message: "Cannot have duplicate attendee.",
});
}
})
})