Skip to content

Commit 9ceb5ea

Browse files
Skeleton for Booking flow refactor using Factory and services (calcom#23277)
1 parent 16bd521 commit 9ceb5ea

17 files changed

Lines changed: 325 additions & 41 deletions

apps/web/pages/api/book/event.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
44
import handleNewBooking from "@calcom/features/bookings/lib/handleNewBooking";
55
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
66
import getIP from "@calcom/lib/getIP";
7+
import { piiHasher } from "@calcom/lib/server/PiiHasher";
78
import { checkCfTurnstileToken } from "@calcom/lib/server/checkCfTurnstileToken";
89
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
910
import { CreationSource } from "@calcom/prisma/enums";
10-
import { piiHasher } from "@calcom/lib/server/PiiHasher";
1111

1212
async function handler(req: NextApiRequest & { userId?: number }) {
1313
const userIp = getIP(req);
@@ -37,7 +37,24 @@ async function handler(req: NextApiRequest & { userId?: number }) {
3737
hostname: req.headers.host || "",
3838
forcedSlug: req.headers["x-cal-force-slug"] as string | undefined,
3939
});
40+
// const booking = await createBookingThroughFactory();
4041
return booking;
42+
43+
// To be added in the follow-up PR
44+
// async function createBookingThroughFactory() {
45+
// console.log("Creating booking through factory");
46+
// const regularBookingService = getRegularBookingService();
47+
48+
// const booking = await regularBookingService.createBooking({
49+
// bookingData: req.body,
50+
// bookingMeta: {
51+
// userId: session?.user?.id || -1,
52+
// hostname: req.headers.host || "",
53+
// forcedSlug: req.headers["x-cal-force-slug"] as string | undefined,
54+
// },
55+
// });
56+
// return booking;
57+
// }
4158
}
4259

4360
export default defaultResponder(handler, "/api/book/event");

apps/web/pages/api/book/instant-event.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
44
import handleInstantMeeting from "@calcom/features/instant-meeting/handleInstantMeeting";
55
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
66
import getIP from "@calcom/lib/getIP";
7+
import { piiHasher } from "@calcom/lib/server/PiiHasher";
78
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
89
import { CreationSource } from "@calcom/prisma/enums";
9-
import { piiHasher } from "@calcom/lib/server/PiiHasher";
1010

1111
async function handler(req: NextApiRequest & { userId?: number }) {
1212
const userIp = getIP(req);

apps/web/pages/api/book/recurring-event.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { handleNewRecurringBooking } from "@calcom/features/bookings/lib/handleN
55
import type { BookingResponse } from "@calcom/features/bookings/types";
66
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
77
import getIP from "@calcom/lib/getIP";
8+
import { piiHasher } from "@calcom/lib/server/PiiHasher";
89
import { checkCfTurnstileToken } from "@calcom/lib/server/checkCfTurnstileToken";
910
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
10-
import { piiHasher } from "@calcom/lib/server/PiiHasher";
1111

1212
// @TODO: Didn't look at the contents of this function in order to not break old booking page.
1313

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createContainer } from "@evyweb/ioctopus";
2+
3+
import { DI_TOKENS } from "@calcom/lib/di/tokens";
4+
5+
import type { InstantBookingCreateService } from "../modules/InstantBookingCreateServiceModule";
6+
import { instantBookingCreateServiceModule } from "../modules/InstantBookingCreateServiceModule";
7+
8+
const container = createContainer();
9+
container.load(DI_TOKENS.INSTANT_BOOKING_CREATE_SERVICE_MODULE, instantBookingCreateServiceModule);
10+
11+
export function getInstantBookingCreateService(): InstantBookingCreateService {
12+
return container.get<InstantBookingCreateService>(DI_TOKENS.INSTANT_BOOKING_CREATE_SERVICE);
13+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { createContainer } from "@evyweb/ioctopus";
2+
3+
import { bookingRepositoryModule } from "@calcom/lib/di/modules/Booking";
4+
import { cacheModule } from "@calcom/lib/di/modules/Cache";
5+
import { checkBookingAndDurationLimitsModule } from "@calcom/lib/di/modules/CheckBookingAndDurationLimits";
6+
import { checkBookingLimitsModule } from "@calcom/lib/di/modules/CheckBookingLimits";
7+
import { featuresRepositoryModule } from "@calcom/lib/di/modules/Features";
8+
import { DI_TOKENS } from "@calcom/lib/di/tokens";
9+
import { prismaModule } from "@calcom/prisma/prisma.module";
10+
11+
import type { RecurringBookingService } from "../modules/RecurringBookingServiceModule";
12+
import { recurringBookingServiceModule } from "../modules/RecurringBookingServiceModule";
13+
14+
const container = createContainer();
15+
container.load(DI_TOKENS.PRISMA_MODULE, prismaModule);
16+
container.load(DI_TOKENS.BOOKING_REPOSITORY_MODULE, bookingRepositoryModule);
17+
container.load(DI_TOKENS.CACHE_SERVICE_MODULE, cacheModule);
18+
container.load(DI_TOKENS.CHECK_BOOKING_LIMITS_SERVICE_MODULE, checkBookingLimitsModule);
19+
container.load(DI_TOKENS.FEATURES_REPOSITORY_MODULE, featuresRepositoryModule);
20+
container.load(
21+
DI_TOKENS.CHECK_BOOKING_AND_DURATION_LIMITS_SERVICE_MODULE,
22+
checkBookingAndDurationLimitsModule
23+
);
24+
container.load(DI_TOKENS.RECURRING_BOOKING_SERVICE_MODULE, recurringBookingServiceModule);
25+
26+
export function getRecurringBookingService(): RecurringBookingService {
27+
return container.get<RecurringBookingService>(DI_TOKENS.RECURRING_BOOKING_SERVICE);
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { createContainer } from "@evyweb/ioctopus";
2+
3+
import { DI_TOKENS } from "@calcom/lib/di/tokens";
4+
5+
import type { RegularBookingService } from "../modules/RegularBookingServiceModule";
6+
import {
7+
regularBookingServiceModule,
8+
loadModuleDeps,
9+
moduleToken,
10+
} from "../modules/RegularBookingServiceModule";
11+
12+
const regularBookingServiceContainer = createContainer();
13+
14+
regularBookingServiceContainer.load(DI_TOKENS.REGULAR_BOOKING_SERVICE_MODULE, regularBookingServiceModule);
15+
16+
export function getRegularBookingService(): RegularBookingService {
17+
loadModuleDeps(regularBookingServiceContainer);
18+
19+
return regularBookingServiceContainer.get<RegularBookingService>(moduleToken);
20+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { createModule } from "@evyweb/ioctopus";
2+
3+
import { InstantBookingCreateService } from "@calcom/features/instant-meeting/handleInstantMeeting";
4+
import { DI_TOKENS } from "@calcom/lib/di/tokens";
5+
6+
export const instantBookingCreateServiceModule = createModule();
7+
8+
instantBookingCreateServiceModule
9+
.bind(DI_TOKENS.INSTANT_BOOKING_CREATE_SERVICE)
10+
.toClass(InstantBookingCreateService);
11+
export type { InstantBookingCreateService };
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createModule } from "@evyweb/ioctopus";
2+
3+
import { DI_TOKENS } from "@calcom/lib/di/tokens";
4+
5+
import { RecurringBookingService } from "../../handleNewRecurringBooking";
6+
7+
export const recurringBookingServiceModule = createModule();
8+
9+
recurringBookingServiceModule.bind(DI_TOKENS.RECURRING_BOOKING_SERVICE).toClass(RecurringBookingService, {
10+
regularBookingService: DI_TOKENS.REGULAR_BOOKING_SERVICE,
11+
});
12+
13+
export type { RecurringBookingService };
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import type { Container } from "@evyweb/ioctopus";
2+
import { createModule } from "@evyweb/ioctopus";
3+
4+
import { bookingRepositoryModule } from "@calcom/lib/di/modules/Booking";
5+
import { cacheModule } from "@calcom/lib/di/modules/Cache";
6+
import { checkBookingAndDurationLimitsModule } from "@calcom/lib/di/modules/CheckBookingAndDurationLimits";
7+
import { checkBookingLimitsModule } from "@calcom/lib/di/modules/CheckBookingLimits";
8+
import { featuresRepositoryModule } from "@calcom/lib/di/modules/Features";
9+
import { DI_TOKENS } from "@calcom/lib/di/tokens";
10+
import { prismaModule } from "@calcom/prisma/prisma.module";
11+
12+
import { RegularBookingService } from "../../handleNewBooking";
13+
14+
export const regularBookingServiceModule = createModule();
15+
const moduleToken = DI_TOKENS.REGULAR_BOOKING_SERVICE;
16+
regularBookingServiceModule.bind(moduleToken).toClass(RegularBookingService, {
17+
cacheService: DI_TOKENS.CACHE_SERVICE,
18+
checkBookingAndDurationLimitsService: DI_TOKENS.CHECK_BOOKING_AND_DURATION_LIMITS_SERVICE,
19+
prismaClient: DI_TOKENS.PRISMA_CLIENT,
20+
bookingRepository: DI_TOKENS.BOOKING_REPOSITORY,
21+
featuresRepository: DI_TOKENS.FEATURES_REPOSITORY,
22+
checkBookingLimitsService: DI_TOKENS.CHECK_BOOKING_LIMITS_SERVICE,
23+
});
24+
25+
// Load the dependencies defined for the module above
26+
function loadModuleDeps(container: Container) {
27+
container.load(DI_TOKENS.CACHE_SERVICE_MODULE, cacheModule);
28+
container.load(
29+
DI_TOKENS.CHECK_BOOKING_AND_DURATION_LIMITS_SERVICE_MODULE,
30+
checkBookingAndDurationLimitsModule
31+
);
32+
container.load(DI_TOKENS.PRISMA_MODULE, prismaModule);
33+
container.load(DI_TOKENS.BOOKING_REPOSITORY_MODULE, bookingRepositoryModule);
34+
container.load(DI_TOKENS.FEATURES_REPOSITORY_MODULE, featuresRepositoryModule);
35+
container.load(DI_TOKENS.CHECK_BOOKING_LIMITS_SERVICE_MODULE, checkBookingLimitsModule);
36+
}
37+
38+
export { loadModuleDeps, moduleToken };
39+
export type { RegularBookingService };
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Domain types for BookingCreateService
3+
* These types are framework-agnostic and contain only the data required for booking operations
4+
*/
5+
import type { z } from "zod";
6+
7+
import type getBookingDataSchema from "@calcom/features/bookings/lib/getBookingDataSchema";
8+
import type getBookingDataSchemaForApi from "@calcom/features/bookings/lib/getBookingDataSchemaForApi";
9+
import type { BookingCreateBody as BaseCreateBookingData } from "@calcom/prisma/zod/custom/booking";
10+
import type { extendedBookingCreateBody } from "@calcom/prisma/zod/custom/booking";
11+
12+
export type ExtendedBookingCreateData = z.input<typeof extendedBookingCreateBody>;
13+
export type BookingDataSchemaGetter = typeof getBookingDataSchema | typeof getBookingDataSchemaForApi;
14+
15+
export type CreateRegularBookingData = BaseCreateBookingData;
16+
17+
export type CreateInstantBookingData = BaseCreateBookingData;
18+
19+
export type CreateRecurringBookingData = (BaseCreateBookingData & {
20+
schedulingType?: SchedulingType;
21+
})[];
22+
23+
export type PlatformParams = {
24+
platformClientId?: string;
25+
platformCancelUrl?: string;
26+
platformBookingUrl?: string;
27+
platformRescheduleUrl?: string;
28+
platformBookingLocation?: string;
29+
areCalendarEventsEnabled?: boolean;
30+
};
31+
32+
export type CreateBookingMeta = {
33+
userId?: number;
34+
// These used to come from headers but now we're passing them as params
35+
hostname?: string;
36+
forcedSlug?: string;
37+
noEmail?: boolean;
38+
} & PlatformParams;
39+
40+
export type BookingHandlerInput = {
41+
bookingData: CreateRegularBookingData;
42+
} & CreateBookingMeta;
43+
44+
export type CreateInstantBookingResponse = {
45+
message: string;
46+
meetingTokenId: number;
47+
bookingId: number;
48+
bookingUid: string;
49+
expires: Date;
50+
userId: number | null;
51+
};

0 commit comments

Comments
 (0)