Added 'hosts' to POST call, PATCH needs a db migration on web (#239)
Complete, but bit of a WIP due to _patch
This commit is contained in:
1 parent
2b9af8457c
commit
cb54ab670e
4 files changed
+93
-15
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { _EventTypeModel as EventType } from "@calcom/prisma/zod";
|
||||
import { _EventTypeModel as EventType, _HostModel } from "@calcom/prisma/zod";
|
||||
import { customInputSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { Frequency } from "~/lib/types";
|
||||
@@ -18,6 +18,11 @@ const recurringEventInputSchema = z.object({
|
||||
tzid: timeZone.optional(),
|
||||
});
|
||||
|
||||
const hostSchema = _HostModel.pick({
|
||||
isFixed: true,
|
||||
userId: true,
|
||||
});
|
||||
|
||||
export const schemaEventTypeBaseBodyParams = EventType.pick({
|
||||
title: true,
|
||||
description: true,
|
||||
@@ -25,11 +30,11 @@ export const schemaEventTypeBaseBodyParams = EventType.pick({
|
||||
length: true,
|
||||
hidden: true,
|
||||
position: true,
|
||||
teamId: true,
|
||||
eventName: true,
|
||||
timeZone: true,
|
||||
periodType: true,
|
||||
periodStartDate: true,
|
||||
schedulingType: true,
|
||||
periodEndDate: true,
|
||||
periodDays: true,
|
||||
periodCountCalendarDays: true,
|
||||
@@ -39,13 +44,14 @@ export const schemaEventTypeBaseBodyParams = EventType.pick({
|
||||
minimumBookingNotice: true,
|
||||
beforeEventBuffer: true,
|
||||
afterEventBuffer: true,
|
||||
schedulingType: true,
|
||||
teamId: true,
|
||||
price: true,
|
||||
currency: true,
|
||||
slotInterval: true,
|
||||
successRedirectUrl: true,
|
||||
locations: true,
|
||||
})
|
||||
.merge(z.object({ hosts: z.array(hostSchema).optional().default([]) }))
|
||||
.partial()
|
||||
.strict();
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import { SchedulingType } from "@prisma/client";
|
||||
import type { NextApiRequest } from "next";
|
||||
import type { z } from "zod";
|
||||
|
||||
@@ -7,6 +9,7 @@ import { defaultResponder } from "@calcom/lib/server";
|
||||
import type { schemaEventTypeBaseBodyParams } from "~/lib/validations/event-type";
|
||||
import { schemaEventTypeEditBodyParams, schemaEventTypeReadPublic } from "~/lib/validations/event-type";
|
||||
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
|
||||
import ensureOnlyMembersAsHosts from "~/pages/api/event-types/_utils/ensureOnlyMembersAsHosts";
|
||||
|
||||
import checkTeamEventEditPermission from "../_utils/checkTeamEventEditPermission";
|
||||
|
||||
@@ -49,6 +52,16 @@ import checkTeamEventEditPermission from "../_utils/checkTeamEventEditPermission
|
||||
* slug:
|
||||
* type: string
|
||||
* description: Unique slug for the event type
|
||||
* hosts:
|
||||
* type: array
|
||||
* items:
|
||||
* type: object
|
||||
* properties:
|
||||
* userId:
|
||||
* type: number
|
||||
* isFixed:
|
||||
* type: boolean
|
||||
* description: Host MUST be available for any slot to be bookable.
|
||||
* hidden:
|
||||
* type: boolean
|
||||
* description: If the event type should be hidden from your public booking page
|
||||
@@ -156,10 +169,25 @@ import checkTeamEventEditPermission from "../_utils/checkTeamEventEditPermission
|
||||
export async function patchHandler(req: NextApiRequest) {
|
||||
const { prisma, query, body } = req;
|
||||
const { id } = schemaQueryIdParseInt.parse(query);
|
||||
const data = schemaEventTypeEditBodyParams.parse(body);
|
||||
await checkPermissions(req, body);
|
||||
const event_type = await prisma.eventType.update({ where: { id }, data });
|
||||
return { event_type: schemaEventTypeReadPublic.parse(event_type) };
|
||||
const { hosts = [], ...parsedBody } = schemaEventTypeEditBodyParams.parse(body);
|
||||
|
||||
const data: Prisma.EventTypeUpdateArgs["data"] = {
|
||||
...parsedBody,
|
||||
};
|
||||
|
||||
if (hosts) {
|
||||
await ensureOnlyMembersAsHosts(req, parsedBody);
|
||||
data.hosts = {
|
||||
deleteMany: {},
|
||||
create: hosts.map((host) => ({
|
||||
...host,
|
||||
isFixed: data.schedulingType === SchedulingType.COLLECTIVE || host.isFixed,
|
||||
})),
|
||||
};
|
||||
}
|
||||
await checkPermissions(req, parsedBody);
|
||||
const eventType = await prisma.eventType.update({ where: { id }, data });
|
||||
return { event_type: schemaEventTypeReadPublic.parse(eventType) };
|
||||
}
|
||||
|
||||
async function checkPermissions(req: NextApiRequest, body: z.infer<typeof schemaEventTypeBaseBodyParams>) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { defaultResponder } from "@calcom/lib/server";
|
||||
import { schemaEventTypeCreateBodyParams, schemaEventTypeReadPublic } from "~/lib/validations/event-type";
|
||||
|
||||
import checkTeamEventEditPermission from "./_utils/checkTeamEventEditPermission";
|
||||
import ensureOnlyMembersAsHosts from "./_utils/ensureOnlyMembersAsHosts";
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
@@ -46,6 +47,17 @@ import checkTeamEventEditPermission from "./_utils/checkTeamEventEditPermission"
|
||||
* slug:
|
||||
* type: string
|
||||
* description: Unique slug for the event type
|
||||
* example: my-event
|
||||
* hosts:
|
||||
* type: array
|
||||
* items:
|
||||
* type: object
|
||||
* properties:
|
||||
* userId:
|
||||
* type: number
|
||||
* isFixed:
|
||||
* type: boolean
|
||||
* description: Host MUST be available for any slot to be bookable.
|
||||
* hidden:
|
||||
* type: boolean
|
||||
* description: If the event type should be hidden from your public booking page
|
||||
@@ -176,22 +188,33 @@ import checkTeamEventEditPermission from "./_utils/checkTeamEventEditPermission"
|
||||
* description: Authorization information is missing or invalid.
|
||||
*/
|
||||
async function postHandler(req: NextApiRequest) {
|
||||
const { userId, isAdmin, prisma } = req;
|
||||
const body = schemaEventTypeCreateBodyParams.parse(req.body);
|
||||
let args: Prisma.EventTypeCreateArgs = {
|
||||
data: { ...body, userId, users: { connect: { id: userId } } },
|
||||
const { userId, isAdmin, prisma, body } = req;
|
||||
|
||||
const { hosts = [], ...parsedBody } = schemaEventTypeCreateBodyParams.parse(body || {});
|
||||
|
||||
let data: Prisma.EventTypeCreateArgs["data"] = {
|
||||
...parsedBody,
|
||||
userId,
|
||||
users: { connect: { id: userId } },
|
||||
};
|
||||
|
||||
await checkPermissions(req);
|
||||
|
||||
if (isAdmin && body.userId) args = { data: { ...body, users: { connect: { id: body.userId } } } };
|
||||
if (isAdmin && parsedBody.userId) {
|
||||
data = { ...parsedBody, users: { connect: { id: parsedBody.userId } } };
|
||||
}
|
||||
|
||||
await checkTeamEventEditPermission(req, body);
|
||||
await checkTeamEventEditPermission(req, parsedBody);
|
||||
await ensureOnlyMembersAsHosts(req, parsedBody);
|
||||
|
||||
const data = await prisma.eventType.create(args);
|
||||
if (hosts) {
|
||||
data.hosts = { createMany: { data: hosts } };
|
||||
}
|
||||
|
||||
const eventType = await prisma.eventType.create({ data });
|
||||
|
||||
return {
|
||||
event_type: schemaEventTypeReadPublic.parse(data),
|
||||
event_type: schemaEventTypeReadPublic.parse(eventType),
|
||||
message: "Event type created successfully",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { NextApiRequest } from "next";
|
||||
import type { z } from "zod";
|
||||
|
||||
import type { schemaEventTypeCreateBodyParams } from "~/lib/validations/event-type";
|
||||
|
||||
export default async function ensureOnlyMembersAsHosts(
|
||||
req: NextApiRequest,
|
||||
body: Pick<z.infer<typeof schemaEventTypeCreateBodyParams>, "hosts" | "teamId">
|
||||
) {
|
||||
if (body.teamId && body.hosts && body.hosts.length > 0) {
|
||||
const teamMemberCount = await req.prisma.membership.count({
|
||||
where: {
|
||||
teamId: body.teamId,
|
||||
userId: { in: body.hosts.map((host) => host.userId) },
|
||||
},
|
||||
});
|
||||
if (teamMemberCount !== body.hosts.length) {
|
||||
throw new Error("You can only add members of the team to a team event type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user