Skip to content

Commit d009682

Browse files
authored
Revert "perf: deduplicating DB fetches + leverage unique DB index for team ty…" (calcom#21969)
This reverts commit 7900be3.
1 parent 8adb720 commit d009682

3 files changed

Lines changed: 111 additions & 153 deletions

File tree

apps/web/lib/getTemporaryOrgRedirect.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { stringify } from "querystring";
33

44
import logger from "@calcom/lib/logger";
55
import { safeStringify } from "@calcom/lib/safeStringify";
6-
import type { PrismaClient } from "@calcom/prisma";
76
import type { RedirectType } from "@calcom/prisma/client";
87

98
const log = logger.getSubLogger({ prefix: ["lib", "getTemporaryOrgRedirect"] });
@@ -12,15 +11,13 @@ export const getTemporaryOrgRedirect = async ({
1211
redirectType,
1312
eventTypeSlug,
1413
currentQuery,
15-
prismaClient,
1614
}: {
1715
slugs: string[] | string;
1816
redirectType: RedirectType;
1917
eventTypeSlug: string | null;
2018
currentQuery: ParsedUrlQuery;
21-
prismaClient?: PrismaClient;
2219
}) => {
23-
const prisma = prismaClient ?? (await import("@calcom/prisma")).default;
20+
const prisma = (await import("@calcom/prisma")).default;
2421
slugs = slugs instanceof Array ? slugs : [slugs];
2522
log.debug(
2623
`Looking for redirect for`,

apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx

Lines changed: 109 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ import type { GetServerSidePropsContext } from "next";
22
import { z } from "zod";
33

44
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
5+
import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking";
56
import { getBookingForReschedule } from "@calcom/features/bookings/lib/get-booking";
6-
import {
7-
orgDomainConfig,
8-
whereClauseForOrgWithSlugOrRequestedSlug,
9-
} from "@calcom/features/ee/organizations/lib/orgDomains";
7+
import { getSlugOrRequestedSlug, orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
108
import { getOrganizationSEOSettings } from "@calcom/features/ee/organizations/lib/orgSettings";
119
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
1210
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
@@ -32,7 +30,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
3230
const { req, params, query } = context;
3331
const session = await getServerSession({ req });
3432
const { slug: teamSlug, type: meetingSlug } = paramsSchema.parse(params);
35-
const { rescheduleUid, isInstantMeeting: queryIsInstantMeeting } = query;
33+
const { rescheduleUid, isInstantMeeting: queryIsInstantMeeting, email } = query;
3634
const allowRescheduleForCancelledBooking = query.allowRescheduleForCancelledBooking === "true";
3735
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(req, params?.orgSlug);
3836
const isOrgContext = currentOrgDomain && isValidOrgDomain;
@@ -43,57 +41,50 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
4341
redirectType: RedirectType.Team,
4442
eventTypeSlug: meetingSlug,
4543
currentQuery: context.query,
46-
prismaClient: prisma,
4744
});
4845

4946
if (redirect) {
5047
return redirect;
5148
}
5249
}
5350

54-
const [orgId, booking] = await Promise.all([
55-
isOrgContext ? getOrgId(currentOrgDomain) : Promise.resolve(null),
56-
rescheduleUid ? getBookingForReschedule(`${rescheduleUid}`, session?.user?.id) : Promise.resolve(null),
57-
]);
51+
const team = await getTeamWithEventsData(teamSlug, meetingSlug, isValidOrgDomain, currentOrgDomain);
5852

59-
const team = await getTeamData(teamSlug, orgId);
60-
61-
if (!team) {
53+
if (!team || !team.eventTypes?.[0]) {
6254
return { notFound: true } as const;
6355
}
6456

65-
const eventData = await getEventTypeData(meetingSlug, team.id);
66-
67-
if (!eventData) {
68-
return { notFound: true } as const;
69-
}
57+
const eventData = team.eventTypes[0];
7058

7159
if (rescheduleUid && eventData.disableRescheduling) {
7260
return { redirect: { destination: `/booking/${rescheduleUid}`, permanent: false } };
7361
}
7462

75-
if (
76-
booking?.status === BookingStatus.CANCELLED &&
77-
!allowRescheduleForCancelledBooking &&
78-
!eventData.allowReschedulingCancelledBookings
79-
) {
80-
return {
81-
redirect: {
82-
permanent: false,
83-
destination: `/team/${teamSlug}/${meetingSlug}`,
84-
},
85-
};
86-
}
87-
8863
const eventTypeId = eventData.id;
64+
const eventHostsUserData = await getUsersData(
65+
team.isPrivate,
66+
eventTypeId,
67+
eventData.hosts.map((h) => h.user)
68+
);
8969
const orgSlug = isValidOrgDomain ? currentOrgDomain : null;
9070
const name = team.parent?.name ?? team.name ?? null;
9171

92-
const eventHostsUserData = getEventHosts(
93-
team.isPrivate,
94-
eventData.hosts.map((h) => h.user),
95-
eventData.users ?? []
96-
);
72+
let booking: GetBookingType | null = null;
73+
if (rescheduleUid) {
74+
booking = await getBookingForReschedule(`${rescheduleUid}`, session?.user?.id);
75+
if (
76+
booking?.status === BookingStatus.CANCELLED &&
77+
!allowRescheduleForCancelledBooking &&
78+
!eventData.allowReschedulingCancelledBookings
79+
) {
80+
return {
81+
redirect: {
82+
permanent: false,
83+
destination: `/team/${teamSlug}/${meetingSlug}`,
84+
},
85+
};
86+
}
87+
}
9788

9889
const fromRedirectOfNonOrgLink = context.query.orgRedirection === "true";
9990
const isUnpublished = team.parent ? !team.parent.slug : !team.slug;
@@ -104,9 +95,11 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
10495

10596
// Handle string[] type from query params
10697
let teamMemberEmail = Array.isArray(crmContactOwnerEmail) ? crmContactOwnerEmail[0] : crmContactOwnerEmail;
98+
10799
let crmOwnerRecordType = Array.isArray(crmContactOwnerRecordType)
108100
? crmContactOwnerRecordType[0]
109101
: crmContactOwnerRecordType;
102+
110103
let crmAppSlug = Array.isArray(crmAppSlugParam) ? crmAppSlugParam[0] : crmAppSlugParam;
111104

112105
if (!teamMemberEmail || !crmOwnerRecordType || !crmAppSlug) {
@@ -129,6 +122,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
129122

130123
const organizationSettings = getOrganizationSEOSettings(team);
131124
const allowSEOIndexing = organizationSettings?.allowSEOIndexing ?? false;
125+
132126
const featureRepo = new FeaturesRepository();
133127
const teamHasApiV2Route = await featureRepo.checkIfTeamHasFeature(team.id, "use-api-v2-for-team-slots");
134128
const useApiV2 = teamHasApiV2Route && hasApiV2RouteInEnv();
@@ -178,149 +172,116 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
178172
};
179173
};
180174

181-
const getOrgId = async (orgSlug: string): Promise<number | null> => {
182-
const org = await prisma.team.findFirst({
183-
where: whereClauseForOrgWithSlugOrRequestedSlug(orgSlug),
184-
select: { id: true },
185-
});
186-
187-
return org?.id ?? null;
188-
};
189-
190-
const getTeamData = async (teamSlug: string, orgId: number | null) => {
191-
const teamSelectFields = {
192-
id: true,
193-
isPrivate: true,
194-
hideBranding: true,
195-
logoUrl: true,
196-
name: true,
197-
slug: true,
198-
isOrganization: true,
199-
parent: {
200-
select: {
201-
slug: true,
202-
name: true,
203-
bannerUrl: true,
204-
logoUrl: true,
205-
hideBranding: true,
206-
organizationSettings: {
207-
select: {
208-
allowSEOIndexing: true,
209-
},
210-
},
211-
},
212-
},
213-
organizationSettings: {
214-
select: {
215-
allowSEOIndexing: true,
216-
},
217-
},
218-
};
219-
220-
if (orgId !== null) {
221-
const publishedTeam = await prisma.team.findUnique({
222-
where: {
223-
slug_parentId: {
224-
slug: teamSlug,
225-
parentId: orgId,
226-
},
227-
isOrganization: false,
228-
},
229-
select: teamSelectFields,
230-
});
231-
if (publishedTeam) return publishedTeam;
232-
}
233-
175+
const getTeamWithEventsData = async (
176+
teamSlug: string,
177+
meetingSlug: string,
178+
isValidOrgDomain: boolean,
179+
currentOrgDomain: string | null
180+
) => {
234181
return await prisma.team.findFirst({
235182
where: {
236-
parentId: orgId ?? null,
237-
isOrganization: false,
238-
OR: [
239-
{ slug: teamSlug },
240-
{
241-
metadata: {
242-
path: ["requestedSlug"],
243-
equals: teamSlug,
244-
},
245-
},
246-
],
183+
...getSlugOrRequestedSlug(teamSlug),
184+
parent: isValidOrgDomain && currentOrgDomain ? getSlugOrRequestedSlug(currentOrgDomain) : null,
247185
},
248-
select: teamSelectFields,
249186
orderBy: {
250187
slug: { sort: "asc", nulls: "last" },
251188
},
252-
});
253-
};
254-
255-
const getEventTypeData = async (meetingSlug: string, teamId: number) => {
256-
return await prisma.eventType.findUnique({
257-
where: {
258-
// Use the EventType_teamId_slug_key unique index
259-
teamId_slug: {
260-
teamId: teamId,
261-
slug: meetingSlug,
262-
},
263-
},
264189
select: {
265190
id: true,
266-
title: true,
267-
isInstantEvent: true,
268-
schedulingType: true,
269-
metadata: true,
270-
length: true,
271-
hidden: true,
272-
disableCancelling: true,
273-
disableRescheduling: true,
274-
allowReschedulingCancelledBookings: true,
275-
interfaceLanguage: true,
276-
hosts: {
277-
take: 3,
191+
isPrivate: true,
192+
hideBranding: true,
193+
parent: {
278194
select: {
279-
user: {
195+
slug: true,
196+
name: true,
197+
bannerUrl: true,
198+
logoUrl: true,
199+
hideBranding: true,
200+
organizationSettings: {
280201
select: {
281-
name: true,
282-
username: true,
202+
allowSEOIndexing: true,
283203
},
284204
},
285205
},
286206
},
287-
// Include users for when hosts is empty
288-
users: {
289-
take: 1,
207+
logoUrl: true,
208+
name: true,
209+
slug: true,
210+
eventTypes: {
211+
where: {
212+
slug: meetingSlug,
213+
},
290214
select: {
291-
username: true,
292-
name: true,
215+
id: true,
216+
title: true,
217+
isInstantEvent: true,
218+
schedulingType: true,
219+
metadata: true,
220+
length: true,
221+
hidden: true,
222+
disableCancelling: true,
223+
disableRescheduling: true,
224+
allowReschedulingCancelledBookings: true,
225+
interfaceLanguage: true,
226+
hosts: {
227+
take: 3,
228+
select: {
229+
user: {
230+
select: {
231+
name: true,
232+
username: true,
233+
email: true,
234+
},
235+
},
236+
},
237+
},
238+
},
239+
},
240+
isOrganization: true,
241+
organizationSettings: {
242+
select: {
243+
allowSEOIndexing: true,
293244
},
294245
},
295246
},
296247
});
297248
};
298249

299-
const getEventHosts = (
250+
const getUsersData = async (
300251
isPrivateTeam: boolean,
301-
hosts: Pick<User, "username" | "name">[],
252+
eventTypeId: number,
302253
users: Pick<User, "username" | "name">[]
303254
) => {
304-
if (isPrivateTeam) {
305-
return [];
306-
}
307-
308-
if (hosts.length > 0) {
309-
return hosts
255+
if (!isPrivateTeam && users.length > 0) {
256+
return users
310257
.filter((user) => user.username)
311258
.map((user) => ({
312259
username: user.username ?? "",
313260
name: user.name ?? "",
314261
}));
315262
}
316-
317-
if (users.length > 0) {
318-
return [
319-
{
320-
username: users[0].username ?? "",
321-
name: users[0].name ?? "",
263+
if (!isPrivateTeam && users.length === 0) {
264+
const { users: data } = await prisma.eventType.findUniqueOrThrow({
265+
where: { id: eventTypeId },
266+
select: {
267+
users: {
268+
take: 1,
269+
select: {
270+
username: true,
271+
name: true,
272+
},
273+
},
322274
},
323-
];
275+
});
276+
277+
return data.length > 0
278+
? [
279+
{
280+
username: data[0].username ?? "",
281+
name: data[0].name ?? "",
282+
},
283+
]
284+
: [];
324285
}
325286

326287
return [];

packages/features/bookings/lib/get-booking.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ export const getBookingForReschedule = async (uid: string, userId?: number) => {
156156
let attendeeEmail: string | null = null;
157157
let bookingSeatData: { description?: string; responses: Prisma.JsonValue } | null = null;
158158
if (!theBooking) {
159-
const bookingSeat = await prisma.bookingSeat.findUnique({
159+
const bookingSeat = await prisma.bookingSeat.findFirst({
160160
where: {
161161
referenceUid: uid,
162162
},

0 commit comments

Comments
 (0)