import { z } from "zod"; /** * Input shapes for the booking Server Actions. Kept separate from the * scheduling services' own TS types deliberately — these describe what * crosses the client→server boundary as JSON (dates as ISO strings, no * Date objects), the services describe the domain. */ export const getAvailableServicesSchema = z.object({ businessId: z.string(), categoryId: z.string().optional(), staffId: z.string().optional(), }); /** Home's Services tab "Book" button — see preselectServiceAction. Only a service id ever crosses this boundary; price/duration/eligibility are always re-read from the database server-side, never trusted from the client. */ export const preselectServiceSchema = z.object({ serviceId: z.string().min(1), }); export const getAvailableBarbersSchema = z.object({ businessId: z.string(), serviceIds: z.array(z.string()).min(1), }); export const getAvailableDatesSchema = z.object({ businessId: z.string(), serviceIds: z.array(z.string()).min(1), staffId: z.string().optional(), fromDate: z.string(), toDate: z.string(), }); export const getAvailableTimeSlotsSchema = z.object({ businessId: z.string(), serviceIds: z.array(z.string()).min(1), staffId: z.string().optional(), date: z.string(), }); export const createBookingSchema = z.object({ businessId: z.string(), customerId: z.string(), serviceIds: z.array(z.string()).min(1), staffId: z.string().optional(), startAt: z.iso.datetime(), notes: z.string().optional(), }); export const rescheduleBookingSchema = z.object({ appointmentId: z.string(), staffId: z.string().optional(), startAt: z.iso.datetime(), }); export const cancelBookingSchema = z.object({ appointmentId: z.string(), cancelledByUserId: z.string().optional(), reason: z.string().optional(), }); export const updateBookingNotesSchema = z.object({ appointmentId: z.string(), notes: z.string().max(2000), }); // ── Customer booking-flow draft steps ──────────────────────────────────── export const saveServicesStepSchema = z.object({ businessId: z.string(), serviceIds: z.array(z.string()).min(1, "Select at least one service"), }); export const saveBarberTimeStepSchema = z.object({ businessId: z.string(), staffId: z.string().optional(), date: z.string(), startAt: z.iso.datetime(), }); export const saveDetailsStepSchema = z.object({ businessId: z.string(), firstName: z.string().trim().min(1, "First name is required").optional(), lastName: z.string().trim().min(1, "Last name is required").optional(), email: z.email("Enter a valid email address").optional(), phone: z.string().trim().min(1, "Phone number is required").optional(), notes: z.string().max(2000).optional(), policyAcknowledged: z.boolean(), }); export const startRebookSchema = z.object({ appointmentId: z.string(), guestToken: z.string().optional(), }); export const customerCancelSchema = z.object({ appointmentId: z.string(), reason: z.string().max(500).optional(), guestToken: z.string().optional(), }); export const customerRescheduleSchema = z.object({ appointmentId: z.string(), staffId: z.string().optional(), startAt: z.iso.datetime(), guestToken: z.string().optional(), });