diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index f9bfe31d12..bff459fc4c 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -49,7 +49,8 @@ import { slugify } from "@calcom/lib/slugify"; import { updateWebUser as syncServicesUpdateWebUser } from "@calcom/lib/sync/SyncServiceManager"; import prisma, { userSelect } from "@calcom/prisma"; import { - bookingCreateSchemaForApiOnly, + bookingCreateBodySchemaForApi, + bookingCreateSchemaLegacyPropsForApi, customInputSchema, EventTypeMetaDataSchema, extendedBookingCreateBody, @@ -330,7 +331,7 @@ function getBookingData({ }), }) ) - : extendedBookingCreateBody.merge(bookingCreateSchemaForApiOnly); + : bookingCreateBodySchemaForApi; const reqBody = bookingDataSchema.parse(req.body); if ("responses" in reqBody) { @@ -372,7 +373,7 @@ function getBookingData({ function getCustomInputsResponses( reqBody: { responses?: Record; - customInputs?: z.infer["customInputs"]; + customInputs?: z.infer["customInputs"]; }, eventTypeCustomInputs: Awaited>["customInputs"] ) { @@ -1359,7 +1360,7 @@ async function handler( try { await scheduleWorkflowReminders( eventType.workflows, - smsReminderNumber as string | null, + smsReminderNumber || null, { ...evt, ...{ metadata } }, evt.requiresConfirmation || false, rescheduleUid ? true : false, diff --git a/packages/prisma/zod-utils.ts b/packages/prisma/zod-utils.ts index 0bee826de5..c40bc61bfe 100644 --- a/packages/prisma/zod-utils.ts +++ b/packages/prisma/zod-utils.ts @@ -143,16 +143,6 @@ export const stringOrNumber = z.union([ export const stringToDayjs = z.string().transform((val) => dayjs(val)); -export const bookingCreateSchemaForApiOnly = z.object({ - name: z.string(), - email: z.string(), - location: z.string().optional(), - guests: z.array(z.string()).optional(), - notes: z.string().optional(), - rescheduleReason: z.string().optional(), - customInputs: z.array(z.object({ label: z.string(), value: z.union([z.string(), z.boolean()]) })), -}); - export const bookingCreateBodySchema = z.object({ end: z.string(), eventTypeId: z.number(), @@ -186,13 +176,13 @@ export const bookingConfirmPatchBodySchema = z.object({ reason: z.string().optional(), }); +// `responses` is merged with it during handleNewBooking call because `responses` schema is dynamic and depends on eventType export const extendedBookingCreateBody = bookingCreateBodySchema.merge( z.object({ noEmail: z.boolean().optional(), recurringCount: z.number().optional(), allRecurringDates: z.string().array().optional(), currentRecurringIndex: z.number().optional(), - smsReminderNumber: z.string().optional().nullable(), appsStatus: z .array( z.object({ @@ -208,6 +198,23 @@ export const extendedBookingCreateBody = bookingCreateBodySchema.merge( }) ); +// It has only the legacy props that are part of `responses` now. The API can still hit old props +export const bookingCreateSchemaLegacyPropsForApi = z.object({ + email: z.string(), + name: z.string(), + guests: z.array(z.string()).optional(), + notes: z.string().optional(), + location: z.string().optional(), + smsReminderNumber: z.string().optional().nullable(), + rescheduleReason: z.string().optional(), + customInputs: z.array(z.object({ label: z.string(), value: z.union([z.string(), z.boolean()]) })), +}); + +// This is the schema that is used for the API. It has all the legacy props that are part of `responses` now. +export const bookingCreateBodySchemaForApi = extendedBookingCreateBody.merge( + bookingCreateSchemaLegacyPropsForApi +); + export const schemaBookingCancelParams = z.object({ id: z.number().optional(), uid: z.string().optional(),