chore: [Booking flow refactor - 2] Integrate Booking services#23156
chore: [Booking flow refactor - 2] Integrate Booking services#23156keithwillcode merged 3 commits intomainfrom
Conversation
WalkthroughReplaces direct booking handler usage with DI-backed services across the codebase: RegularBookingService, RecurringBookingService, and InstantBookingCreateService. API handlers, tests, and platform-library consumers now obtain services from new DI containers/modules (moduleLoader/container files) and call service.createBooking variants; booking metadata fields are nested under bookingMeta. Adds DTO types (RegularBookingCreateResult, InstantBookingCreateResult), refactors booking schemas (ExtendedBookingCreateBody and recurring partial), introduces NestJS modules and service wrappers, and removes legacy platform-library handler exports (handleNewBooking, handleNewRecurringBooking, handleInstantMeeting). Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (3)**/*.ts📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Files:
**/*.{ts,tsx,js,jsx}⚙️ CodeRabbit configuration file
Files:
🧠 Learnings (2)📓 Common learnings📚 Learning: 2025-09-03T09:52:51.182ZApplied to files:
🧬 Code graph analysis (1)packages/features/bookings/lib/handleNewBooking.ts (4)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Hey there and thank you for opening this pull request! 👋🏼 We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted. Details: |
1ef7ace to
deb45db
Compare
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
d6110f9 to
2a486aa
Compare
88ac0dd to
f5bf407
Compare
f5bf407 to
1db6a91
Compare
cfa68e6 to
b4d1f46
Compare
b4d1f46 to
86690b5
Compare
c20b210 to
5549cda
Compare
| attendee.email === input.bookingData.responses.email || | ||
| (input.bookingData.responses.attendeePhoneNumber && | ||
| attendee.phoneNumber === input.bookingData.responses.attendeePhoneNumber) | ||
| attendee.email === bookingData.responses.email || |
There was a problem hiding this comment.
Using bookingData instead of input.bookingData here because bookingData is parsed by schema and thus has responses always while input.bookingData doesn't have it always.
In a followup PR we are removing input.bookingData usage from everwhere.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
packages/features/bookings/lib/handleNewBooking.ts (4)
591-596: Payment gating logic likely inverted — may suppress payment form when none exists.Use hasPayments to indicate paid evidence; don’t treat “no payments” as paid.
- const hasPayments = existingBooking.payment.length > 0; - const isPaidBooking = existingBooking.paid || !hasPayments; + const hasPayments = existingBooking.payment.length > 0; + const isPaidBooking = existingBooking.paid || hasPayments;
1173-1189: Spreading possibly nullresponseswill throw.Guard when building
eventNameObject.- const responses = reqBody.responses || null; + const responses = reqBody.responses ?? null; ... - bookingFields: { ...responses }, + bookingFields: responses ? { ...responses } : {},
1221-1227: Unsafe write:calEventResponses["location"]may be undefined.Protect access or initialize the key.
- if (reqBody.calEventResponses) - reqBody.calEventResponses["location"].value = { + if (reqBody.calEventResponses?.location) { + reqBody.calEventResponses.location.value = { value: platformBookingLocation ?? bookingLocation, optionValue: "", - }; + }; + }
472-495: Name collision:luckyUsers(IDs from first booking) vs. local array of host objects. Causes incorrect filtering.Alias the destructured IDs and use them below.
@@ - luckyUsers, + luckyUsers: luckyUserIdsFromFirstBooking, @@ - const luckyUsersFromFirstBooking = luckyUsers - ? eventTypeWithUsers.users.filter((user) => luckyUsers.find((luckyUserId) => luckyUserId === user.id)) - : []; + const luckyUsersFromFirstBooking = Array.isArray(luckyUserIdsFromFirstBooking) + ? eventTypeWithUsers.users.filter((user) => luckyUserIdsFromFirstBooking.includes(user.id)) + : [];Also applies to: 1042-1047
♻️ Duplicate comments (5)
apps/web/pages/api/book/recurring-event.ts (1)
46-58: Sanitize bookingData; avoid sentinel userId; pass hostname/forcedSlugStrip cfToken, don’t inject -1, and forward hostname/forcedSlug.
- const recurringBookingService = getRecurringBookingService(); - const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ - bookingData: req.body, - bookingMeta: { - userId: session?.user?.id || -1, + const recurringBookingService = getRecurringBookingService(); + const bookingDataInput = req.body; + const sanitizedBookingData = Array.isArray(bookingDataInput) + ? bookingDataInput.map(({ cfToken, ...rest }) => rest) + : bookingDataInput; + const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ + bookingData: sanitizedBookingData, + bookingMeta: { + userId: session?.user?.id ?? undefined, + hostname: req.hostname, + forcedSlug: req.forcedSlug, platformClientId: req.platformClientId, platformCancelUrl: req.platformCancelUrl, platformBookingUrl: req.platformBookingUrl, platformRescheduleUrl: req.platformRescheduleUrl, platformBookingLocation: req.platformBookingLocation, noEmail: req.noEmail, }, });packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
57-66: Bug: first recurring result not returned; series ID not propagatedPush the first result and seed thirdPartyRecurringEventId for subsequent slots.
- const firstBookingResult = await regularBookingService.createBooking({ + const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + createdBookings.push(firstBookingResult); + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + const ref = firstBookingResult.references.find((r) => r.thirdPartyRecurringEventId); + if (ref?.thirdPartyRecurringEventId) thirdPartyRecurringEventId = ref.thirdPartyRecurringEventId; + } + luckyUsers = firstBookingResult.luckyUsers;apps/web/pages/api/book/event.ts (1)
34-41: Don’t inject sentinel userId; remove cfToken before service callUse undefined (or 401) instead of -1 and strip cfToken.
- const regularBookingService = getRegularBookingService(); - const booking = await regularBookingService.createBooking({ - bookingData: req.body, - bookingMeta: { - userId: session?.user?.id || -1, + const regularBookingService = getRegularBookingService(); + const { cfToken, ...sanitized } = (req.body ?? {}) as Record<string, unknown>; + const booking = await regularBookingService.createBooking({ + bookingData: sanitized, + bookingMeta: { + userId: session?.user?.id ?? undefined, hostname: req.headers.host || "", forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, }, });packages/features/bookings/lib/handleNewBooking.ts (2)
1607-1613: Attendee lookup should usebookerEmail/bookerPhoneNumber, notbookingData.responses.- const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + const currentAttendee = booking.attendees.find( + (attendee) => + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );
2425-2431: Spreading possibly undefinedbookingMetawill throw.Default it to
{}in both methods.async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); } @@ async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); }
🧹 Nitpick comments (11)
packages/features/bookings/lib/dto/types.d.ts (1)
53-55: Avoid ReturnType tie to service method; define explicit result typeCoupling a public type to RegularBookingService["createBooking"] hinders refactors and can cause circular type deps. Define a concrete RegularBookingCreateResult DTO here and let the service return it.
-// TODO: In a followup PR, we working on defining the type here itself instead of inferring it. -export type RegularBookingCreateResult = Awaited<ReturnType<RegularBookingService["createBooking"]>>; +// Stable public DTO (align fields with handler’s output) +export type RegularBookingCreateResult = { + id: number; + uid: string; + userId: number | null; + startTime: Date; + endTime: Date; + references?: { thirdPartyRecurringEventId?: string }[]; + luckyUsers?: unknown; + fromReschedule?: boolean; + // add any other serialized fields actually returned +};apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (2)
188-202: Propagate noEmail in bookingMeta for regular bookingsCurrently only set in body by createNextApiBookingRequest; bookingMeta should carry it per new contract.
const booking = await regularBookingService.createBooking({ bookingData: bookingRequest.body, bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", forcedSlug: orgSlug, platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: !bookingRequest.arePlatformEmailsEnabled, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, });
363-367: Remove unused req.userId assignment in instant flowcreateNextApiBookingRequest computes userId internally; the earlier set at Line 361 is redundant. Also we only need body for createBooking.
- const instantBookingService = getInstantBookingCreateService(); - const bookingReq = await this.createNextApiBookingRequest(req, oAuthClientId, undefined, isEmbed); - const instantMeeting = await instantBookingService.createBooking({ - bookingData: bookingReq.body, - }); + const instantBookingService = getInstantBookingCreateService(); + const bookingReq = await this.createNextApiBookingRequest(req, oAuthClientId, undefined, isEmbed); + const instantMeeting = await instantBookingService.createBooking({ bookingData: bookingReq.body });Follow-up (optional): delete Line 361 (
req.userId = …).packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
92-92: Use strict equalityPrefer
===over==.- isFirstRecurringSlot: key == 0, + isFirstRecurringSlot: key === 0,
100-107: Inline await; temporary promise variable is unnecessarySlight tidy-up.
- const promiseEachRecurringBooking = regularBookingService.createBooking({ + const eachRecurringBooking = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - - const eachRecurringBooking = await promiseEachRecurringBooking;packages/features/bookings/lib/handleNewBooking.ts (6)
1196-1201: Prisma: select only needed fields.Follow repo guideline; only
organizationIdis used.- const organizerOrganizationProfile = await prisma.profile.findFirst({ - where: { - userId: organizerUser.id, - username: dynamicUserList[0], - }, - }); + const organizerOrganizationProfile = await prisma.profile.findFirst({ + where: { userId: organizerUser.id, username: dynamicUserList[0] }, + select: { organizationId: true }, + });
554-556: Use schema-validatedbookingDatainstead ofinput.bookingData.Avoid mixing sources; use the parsed data.
- const isNormalBookingOrFirstRecurringSlot = input.bookingData.allRecurringDates - ? !!input.bookingData.isFirstRecurringSlot + const isNormalBookingOrFirstRecurringSlot = bookingData.allRecurringDates + ? !!bookingData.isFirstRecurringSlot : true;
789-793: Standardize onbookingData(parsed) instead ofinput.bookingData.Multiple branches read from
input.bookingData.*. For consistency and correctness (schema guarantees), switch tobookingData.*in these spots.Also applies to: 803-810, 842-842, 957-971, 1038-1040, 1297-1300, 1541-1541
812-824: Avoidfor..inover arrays.Use
for..ofto iterate actual items, not enumerable keys.- for (const key in fixedUsers) { - await ensureAvailableUsers( - { ...eventTypeWithUsers, users: [fixedUsers[key]] }, + for (const fixedUser of fixedUsers) { + await ensureAvailableUsers( + { ...eventTypeWithUsers, users: [fixedUser] }, { dateFrom: dayjs(start).tz(reqBody.timeZone).format(), dateTo: dayjs(end).tz(reqBody.timeZone).format(), timeZone: reqBody.timeZone, originalRescheduledBooking: originalRescheduledBooking ?? null, }, loggerWithEventDetails, shouldServeCache ); }
826-826: Remove no-op access.
eventTypeWithUsers.users[0].credentials;has no effect.- eventTypeWithUsers.users[0].credentials;
1129-1135: Avoid logging guest emails (PII) at info level.Consider redacting or sampling to reduce PII in logs.
- if (guestsRemoved.length > 0) { - log.info("Removed guests from the booking", guestsRemoved); - } + if (guestsRemoved.length > 0) { + log.debug("Removed guests from the booking", { count: guestsRemoved.length }); + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (28)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(4 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(7 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(3 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (20)
- apps/web/lib/types/booking.ts
- packages/features/bookings/lib/index.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- packages/features/bookings/lib/create-instant-booking.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- apps/api/v1/pages/api/bookings/_post.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- packages/features/bookings/lib/bookingCreateBodySchema.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- packages/lib/di/bookings/containers/RecurringBookingService.container.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts
- packages/features/instant-meeting/handleInstantMeeting.ts
- packages/features/bookings/types.ts
- apps/web/pages/api/book/instant-event.ts
- packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
- packages/lib/di/bookings/modules/RecurringBookingService.module.ts
- packages/platform/libraries/bookings.ts
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/web/pages/api/book/recurring-event.tspackages/lib/di/bookings/modules/RegularBookingService.module.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/web/pages/api/book/recurring-event.tspackages/lib/di/bookings/modules/RegularBookingService.module.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
apps/web/pages/api/book/recurring-event.tspackages/lib/di/bookings/modules/RegularBookingService.module.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
🧠 Learnings (16)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
apps/web/pages/api/book/recurring-event.tspackages/lib/di/bookings/modules/RegularBookingService.module.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/modules/RegularBookingService.module.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-22T16:38:00.225Z
Learnt from: bandhan-majumder
PR: calcom/cal.com#23192
File: packages/lib/server/service/InsightsBookingBaseService.ts:814-816
Timestamp: 2025-08-22T16:38:00.225Z
Learning: In the InsightsBookingBaseService (packages/lib/server/service/InsightsBookingBaseService.ts), when filtering for "accepted" bookings in getMembersStatsWithCount(), using `endTime <= now()` in the SQL condition should be avoided as it conflicts with existing date filtering logic. The components already handle completion filtering by setting `endDate: currentTime` in their query parameters, making additional SQL-level endTime filtering unnecessary and potentially problematic.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.ts
🧬 Code graph analysis (7)
apps/web/pages/api/book/recurring-event.ts (2)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/lib/di/bookings/modules/RegularBookingService.module.ts (7)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
moduleLoader(18-21)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
moduleLoader(21-24)packages/lib/di/modules/Attribute.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Host.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Ooo.ts (1)
moduleLoader(18-21)packages/lib/di/modules/LuckyUser.ts (1)
moduleLoader(28-31)packages/lib/di/modules/User.ts (1)
moduleLoader(18-21)
apps/web/pages/api/book/event.ts (2)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)packages/features/auth/lib/next-auth-options.ts (1)
session(746-771)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (5)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
packages/features/bookings/lib/handleNewBooking.ts (5)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (4)
packages/features/bookings/lib/dto/types.d.ts (1)
7-7: Good fix: import SchedulingTypeResolves the missing symbol error.
packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
32-37: Resolved — IBookingServiceDependencies includes the new deps
IBookingServiceDependencies in packages/features/bookings/lib/handleNewBooking.ts declares luckyUserService, hostRepository, oooRepository, userRepository, and attributeRepository (lines 414–425).packages/features/bookings/lib/handleNewBooking.ts (2)
414-426: DI surface verified — all deps are bound.All keys from IBookingServiceDependencies (packages/features/bookings/lib/handleNewBooking.ts) are present in packages/lib/di/bookings/modules/RegularBookingService.module.ts.
2071-2090: Double-check credential.key never leaks — server-side selects are OK only if redaction is enforced.
- Findings: credential.key is selected in server flows for payment/calendar (e.g. packages/features/bookings/lib/handleNewBooking.ts — prisma.findMany select { key: true }; packages/lib/server/repository/credential.ts — findFirstByIdWithKeyAndUser select { ... key: true }; packages/lib/server/getUsersCredentialsIncludeServiceAccountKey uses credentialForCalendarServiceSelect which includes key). packages/prisma/selects/credential.ts defines credentialForCalendarServiceSelect (key: true) and safeCredentialSelect (omits key).
- Required checks (quick, exact places to verify):
- packages/lib/delegationCredential/server.ts — confirm buildNonDelegationCredential and enrichUserWithDelegationCredentialsIncludeServiceAccountKey remove/redact the key before returning credential objects.
- packages/lib/server/repository/credential.ts — findFirstByIdWithKeyAndUser returns buildNonDelegationCredential; ensure that returned object does not expose key.
- apps/api/v1/pages/api/credential-sync/* (post/patch/delete/get) — ensure they only return safe fields (id/appId/type) and never pass a full credential object containing key to the response.
- Any TRPC/Controller handlers that call getUsersCredentialsIncludeServiceAccountKey (e.g. packages/trpc/server/routers/viewer/*) — verify they filter out credential/key before sending responses (appById.handler already strips credential fields; confirm others do likewise).
- Grep for logging of credential objects (safeStringify/console.log/log.*) and confirm logs use getPiiFreeCredential or otherwise redact the key (examples to check: calendar-cache safeStringify usages — the local variable name key is a cache key there, not credential.key; still verify callers).
- If any handler must return credential metadata to clients, return a DTO/safe select that explicitly excludes key (use safeCredentialSelect or DTOs). If you find any direct returns of credential objects that may include key, redact the key field before returning and add a unit test.
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
packages/features/bookings/lib/handleNewBooking.ts (2)
1175-1188: Bug: spreading possibly null responses will throw.responses can be null;
{ ...responses }crashes. Use a safe fallback.- bookingFields: { ...responses }, + bookingFields: responses ?? {},
1196-1201: Prisma: select only needed fields.Per guidelines, avoid returning full rows. Only organizationId is used.
const organizerOrganizationProfile = await prisma.profile.findFirst({ where: { userId: organizerUser.id, username: dynamicUserList[0], }, + select: { organizationId: true }, });packages/features/instant-meeting/handleInstantMeeting.ts (3)
73-89: Fix: promises are never awaited (map callback doesn't return).subscribers.map uses a block body without return, so Promise.all receives an array of undefined and webhooks aren’t awaited.
Apply:
- const promises = subscribers.map((sub) => { - sendGenericWebhookPayload({ - secretKey: sub.secret, - triggerEvent: eventTrigger, - createdAt: new Date().toISOString(), - webhook: sub, - data: webhookData, - }).catch((e) => { - console.error( - `Error executing webhook for event: ${eventTrigger}, URL: ${sub.subscriberUrl}`, - sub, - e - ); - }); - }); + const promises = subscribers.map((sub) => + sendGenericWebhookPayload({ + secretKey: sub.secret, + triggerEvent: eventTrigger, + createdAt: new Date().toISOString(), + webhook: sub, + data: webhookData, + }).catch((e) => { + console.error( + `Error executing webhook for event: ${eventTrigger}, URL: ${sub.subscriberUrl}, webhookId: ${sub.id}`, + { id: sub.id, subscriberUrl: sub.subscriberUrl }, + e + ); + }) + );
81-85: Don’t log webhook secrets.Console error logs the entire webhook record (includes secret). Log only non-sensitive fields.
See diff in previous comment; it redacts secret by logging { id, subscriberUrl } instead of sub.
Also applies to: 63-69
259-266: Prisma: replace include with select (repo guideline).include eagerly loads attendees but they’re unused. Select only needed fields.
- const createBookingObj = { - include: { - attendees: true, - }, - data: newBookingData, - }; - - const newBooking = await prisma.booking.create(createBookingObj); + const newBooking = await prisma.booking.create({ + data: newBookingData, + select: { + id: true, + uid: true, + title: true, + responses: true, + customInputs: true, + userId: true, + }, + });
♻️ Duplicate comments (10)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (2)
22-28: Import ErrorCode (referenced but not imported).Without this import, the file won’t type-check when those tests are enabled.
Apply:
import { WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants"; +import { ErrorCode } from "@calcom/lib/errorCodes"; import { getRecurringBookingService } from "@calcom/lib/di/bookings/containers/RecurringBookingService.container";
375-383: Fix rejects assertion and move userId under bookingMeta.
rejectsmust receive a Promise, not a function. Also, the new API expectsbookingMeta.userId, not a top‑leveluserId.Apply:
- const recurringBookingService = getRecurringBookingService(); - await expect( - async () => - await recurringBookingService.createBooking({ - bookingData: bookingDataArray, - userId: -1, - }) - ).rejects.toThrow(ErrorCode.NoAvailableUsersFound); + const recurringBookingService = getRecurringBookingService(); + await expect( + recurringBookingService.createBooking({ + bookingData: bookingDataArray, + bookingMeta: { userId: -1 }, + }) + ).rejects.toThrow(ErrorCode.NoAvailableUsersFound);packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
60-76: Good split: recurring schema partial + end now optional.This addresses the earlier concern about undefined end values in recurring slots.
packages/features/bookings/lib/dto/types.d.ts (1)
7-7: Importing SchedulingType fixes the missing symbol error.packages/features/bookings/lib/handleNewBooking.ts (2)
1607-1613: Seat attendee lookup uses bookingData.responses; switch to parsed bookerEmail/Phone.bookingData.responses may be undefined; use bookerEmail/bookerPhoneNumber parsed above.
- const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + const currentAttendee = booking.attendees.find( + (attendee) => + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );
2425-2431: Bug: spreading possibly undefined bookingMeta can throw.input.bookingMeta is optional; spreading undefined crashes. Default to {}.
- async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); - } + async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); + } - async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); - } + async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); + }apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (4)
499-511: Add missing noEmail to bookingMeta (recurring seated).Email behavior will diverge from other flows without it.
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
757-769: Add missing noEmail to bookingMeta (reschedule).Keeps reschedule email behavior consistent with creation.
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
524-537: Add missing noEmail to bookingMeta (regular booking).Aligns with createRecurringBooking and API v2 controller.
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
559-572: Add missing noEmail to bookingMeta (seated booking).Prevents unintended emails in seated flow.
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
🧹 Nitpick comments (7)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
548-554: Align skipped Round‑robin test with service API and proper rejects usage.Replace legacy
handleNewRecurringBookingcall with the DI service and fix the assertion.Apply:
- await expect(() => - handleNewRecurringBooking({ - bookingData: bookingDataArray, - userId: -1, - }) - ).rejects.toThrow(ErrorCode.NoAvailableUsersFound); + const recurringBookingService = getRecurringBookingService(); + await expect( + recurringBookingService.createBooking({ + bookingData: bookingDataArray, + bookingMeta: { userId: -1 }, + }) + ).rejects.toThrow(ErrorCode.NoAvailableUsersFound);packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
40-43: Type the exported moduleLoader for consistency with other modules.Use the common ModuleLoader annotation.
+import type { ModuleLoader } from "../../di"; … -export const moduleLoader = { +export const moduleLoader: ModuleLoader = { token, loadModule, };packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
78-98: customInputs as z.undefined() is surprising; clarify intent or enforce with z.never().If the goal is to forbid customInputs at this layer (non-API), prefer z.never() (property disallowed) rather than allowing presence with undefined. bookingCreateBodySchemaForApi later re-enables it, which is fine.
- customInputs: z.undefined().optional(), + // Disallow at this layer; API schema re-enables it via merge with legacy props + customInputs: z.never().optional(),If you intentionally need the key present-but-undefined, keep as-is and note it in a comment.
packages/features/bookings/lib/handleNewBooking.ts (3)
790-841: Hot path: heavy Day.js ops inside nested loops. Consider precomputing.Repeated tz/format in loops impacts perf under large recurring sets. Precompute Day.js objects or use .utc() where possible; pass Date instances when acceptable to downstream functions.
812-825: Use for…of over for…in for array iteration.for…in iterates string keys; for…of is clearer and avoids accidental prototype keys.
- for (const key in fixedUsers) { - await ensureAvailableUsers( - { ...eventTypeWithUsers, users: [fixedUsers[key]] }, + for (const u of fixedUsers) { + await ensureAvailableUsers( + { ...eventTypeWithUsers, users: [u] }, { dateFrom: dayjs(start).tz(reqBody.timeZone).format(), dateTo: dayjs(end).tz(reqBody.timeZone).format(), timeZone: reqBody.timeZone, originalRescheduledBooking: originalRescheduledBooking ?? null, }, loggerWithEventDetails, shouldServeCache ); }
301-306: Consistent enum usage for SchedulingType.You compare against string "COLLECTIVE" here but use SchedulingType.* elsewhere. Normalize to enum for consistency and type safety.
Also applies to: 1181-1183
packages/features/instant-meeting/handleInstantMeeting.ts (1)
283-300: Nit: use Date object for DateTime fields.updatedAt should be a Date, not ISO string.
- updatedAt: new Date().toISOString(), + updatedAt: new Date(),
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (28)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(4 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(7 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(3 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (17)
- packages/features/bookings/lib/index.ts
- apps/web/pages/api/book/recurring-event.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts
- packages/features/bookings/types.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/web/pages/api/book/event.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- packages/lib/di/bookings/containers/RecurringBookingService.container.ts
- apps/web/lib/types/booking.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- packages/features/bookings/lib/handleNewRecurringBooking.ts
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- apps/web/pages/api/book/instant-event.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- apps/api/v1/pages/api/bookings/_post.ts
- packages/features/bookings/lib/create-instant-booking.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/platform/libraries/bookings.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/lib/dto/types.d.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/platform/libraries/bookings.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/lib/dto/types.d.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/platform/libraries/bookings.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/lib/dto/types.d.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/platform/libraries/bookings.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/modules/RegularBookingService.module.ts
📚 Learning: 2025-08-22T16:38:00.225Z
Learnt from: bandhan-majumder
PR: calcom/cal.com#23192
File: packages/lib/server/service/InsightsBookingBaseService.ts:814-816
Timestamp: 2025-08-22T16:38:00.225Z
Learning: In the InsightsBookingBaseService (packages/lib/server/service/InsightsBookingBaseService.ts), when filtering for "accepted" bookings in getMembersStatsWithCount(), using `endTime <= now()` in the SQL condition should be avoided as it conflicts with existing date filtering logic. The components already handle completion filtering by setting `endDate: currentTime` in their query parameters, making additional SQL-level endTime filtering unnecessary and potentially problematic.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/dto/types.d.tspackages/features/instant-meeting/handleInstantMeeting.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
🧬 Code graph analysis (8)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(40-43)
packages/lib/di/bookings/modules/RegularBookingService.module.ts (7)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
moduleLoader(18-21)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
moduleLoader(21-24)packages/lib/di/modules/Attribute.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Host.ts (1)
moduleLoader(18-21)packages/lib/di/modules/LuckyUser.ts (1)
moduleLoader(28-31)packages/lib/di/modules/Ooo.ts (1)
moduleLoader(18-21)packages/lib/di/modules/User.ts (1)
moduleLoader(18-21)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (5)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (4)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)packages/platform/libraries/bookings.ts (3)
getInstantBookingCreateService(7-7)getRecurringBookingService(5-5)getRegularBookingService(6-6)packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/bookings/lib/dto/types.d.ts (3)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/platform/libraries/bookings.ts (2)
InstantBookingCreateResult(9-9)RegularBookingCreateResult(10-10)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(44-51)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
packages/features/bookings/lib/handleNewBooking.ts (7)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/lib/server/repository/host.ts (1)
HostRepository(3-40)packages/lib/server/repository/user.ts (1)
UserRepository(123-1071)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (2)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)packages/platform/libraries/bookings.ts (1)
getRecurringBookingService(5-5)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: Tests / E2E API v2
- GitHub Check: Tests / E2E (1/4)
🔇 Additional comments (17)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
155-162: Good migration to DI service + bookingMeta.Using
getRecurringBookingService().createBooking({ bookingData, bookingMeta: { userId } })aligns with the new API.packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
100-101: Exported ExtendedBookingCreateBody type looks correct.packages/features/bookings/lib/dto/types.d.ts (2)
15-21: Uniformly moving Create*BookingData to ExtendedBookingCreateBody is consistent.
53-55: Be cautious with cross-file ReturnType on a class method.Type-only import avoids runtime cycles, but this tight coupling complicates external consumption. Consider defining a stable explicit result type in this file in a follow‑up.
packages/features/bookings/lib/handleNewBooking.ts (2)
414-426: IBookingServiceDependencies surface looks complete. Ensure DI provides all keys at runtime.Run the deps/interface comparison script from my earlier comment on RegularBookingService.module.ts. It should report no missing keys.
2080-2089: Credential.key is selected — ensure it never leaks beyond server internals.Selection here is fine for internal payment handling. Confirm it’s never logged or exposed via API/tRPC.
packages/platform/libraries/bookings.ts (1)
5-11: Aggregator exports look good and align with DI-based services.Type re-exports keep platform libs in sync with the new flow.
packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
32-37: Deps map now aligns with IBookingServiceDependencies — verified.
Confirmed no missing or extra keys (Missing in depsMap: [], Extra in depsMap: []).packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
21-24: Exported moduleLoader is consistent with RegularBookingService.module.No issues.
11-19: DI wiring looks correct.RecurringBookingService's constructor accepts IRecurringBookingServiceDependencies, which defines regularBookingService — the depsMap key matches.
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
58-58: Imports align with service-based API.Switch to service getters + InstantBookingCreateResult type looks good.
188-201: Regular booking: service call + bookingMeta LGTM.Payload shape matches the new contract.
319-331: Recurring booking: service call LGTM.Consistent with the refactor.
358-368: Instant booking: body-only contract correctly applied.Passing only bookingData to the service is appropriate here.
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
65-65: Service getters import OK.Matches the new platform-libraries surface.
451-454: Instant booking path: service usage LGTM.Correct delegation to InstantBookingCreateService.
472-486: Recurring booking: includes noEmail (good).Consistent with platform email settings.
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
Outdated
Show resolved
Hide resolved
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
498-511: Missing noEmail in bookingMeta.The recurring booking service call omits the
noEmailproperty that's present in regular bookings, which could lead to inconsistent email behavior.Apply this diff to include the missing parameter:
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },packages/features/bookings/lib/dto/types.d.ts (1)
53-54: Consider defining the type explicitly.While inferring from the service method works, an explicit type definition would provide better maintainability and documentation.
Consider defining the type explicitly instead of inferring it:
-// TODO: In a followup PR, we working on defining the type here itself instead of inferring it. -export type RegularBookingCreateResult = Awaited<ReturnType<RegularBookingService["createBooking"]>>; +export type RegularBookingCreateResult = { + // Define the actual structure based on the service implementation + uid: string; + id: number; + // ... other properties +};
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (28)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(4 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(7 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(3 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (16)
- packages/lib/di/bookings/modules/RegularBookingService.module.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- packages/platform/libraries/bookings.ts
- packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- apps/api/v1/pages/api/bookings/_post.ts
- packages/features/bookings/lib/index.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- apps/web/lib/types/booking.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- packages/features/bookings/lib/create-instant-booking.ts
- apps/web/pages/api/book/event.ts
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/web/pages/api/book/instant-event.ts
- packages/features/instant-meeting/handleInstantMeeting.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tsapps/web/pages/api/book/recurring-event.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tsapps/web/pages/api/book/recurring-event.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tsapps/web/pages/api/book/recurring-event.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.ts
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tsapps/web/pages/api/book/recurring-event.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
packages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
🧬 Code graph analysis (10)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(40-43)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (2)
packages/lib/di/di.ts (1)
createContainer(114-114)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
RecurringBookingService(25-25)recurringBookingServiceModule(9-9)
apps/web/pages/api/book/recurring-event.ts (2)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)packages/features/auth/lib/next-auth-options.ts (1)
session(746-771)
packages/features/bookings/lib/dto/types.d.ts (3)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/platform/libraries/bookings.ts (2)
InstantBookingCreateResult(9-9)RegularBookingCreateResult(10-10)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/bookings/types.ts (2)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(54-54)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (4)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)packages/platform/libraries/bookings.ts (3)
getInstantBookingCreateService(7-7)getRecurringBookingService(5-5)getRegularBookingService(6-6)packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (2)
packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (2)
InstantBookingCreateService(17-17)instantBookingCreateServiceModule(6-6)
packages/features/bookings/lib/handleNewBooking.ts (5)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (7)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/types.ts (1)
BookingResponse(98-98)packages/platform/types/api.ts (1)
ApiResponse(33-35)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
🔇 Additional comments (42)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
4-5: LGTM! Module loader pattern implementation is consistent.The migration to the lazy-loading moduleLoader pattern is well-structured and aligns with the broader DI architecture changes in this PR.
21-24: LGTM! Consistent moduleLoader export pattern.The moduleLoader export follows the established pattern used across other booking service modules.
11-19: Dependency mapping complete — no action required.
IRecurringBookingServiceDependencies declares only regularBookingService, and the module's depsMap maps it to regularBookingServiceModuleLoader.packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (2)
4-4: LGTM! Clean import aliasing.The import statement correctly aliases the moduleLoader to instantBookingCreateServiceModule for consistency.
10-11: LGTM! Proper module loading pattern.The container correctly loads the module and retrieves the service using the moduleLoader pattern. This is consistent with the other service containers in the codebase.
packages/features/bookings/lib/bookingCreateBodySchema.ts (4)
60-76: LGTM! Schema refactoring improves modularity.The extraction of recurring booking fields into a separate partial schema improves code organization and follows the TODO's plan for separate schemas for different booking types.
71-71: LGTM! Optional end field handling is correct.The optional
endfield inallRecurringDatesis correctly handled as noted in past review comments.
78-98: LGTM! Schema merge pattern is well-structured.The merge of the base schema with the new object and recurring partial schema maintains backward compatibility while improving type safety.
100-100: LGTM! Public type export added.The
ExtendedBookingCreateBodytype export provides proper type access for consumers.packages/features/bookings/lib/handleNewBooking.ts (8)
414-426: DI interface is comprehensive but needs verification of module mappings.The
IBookingServiceDependenciesinterface covers all the necessary dependencies. However, as noted in previous reviews, ensure all these dependencies are properly mapped in the DI modules.
428-432: LGTM! Handler signature updated for DI pattern.The handler now correctly accepts the
depsparameter for dependency injection, which aligns with the service-based architecture.
446-452: LGTM! Clean dependency destructuring.The destructuring of dependencies from the
depsparameter is clean and follows good DI patterns.
583-589: LGTM! Repository method call updated correctly.The call to
bookingRepository.getValidBookingFromEventTypeForAttendeeusing the injected dependency is correct.
1608-1614: Attendee lookup should use parsed variables, not raw responses.As noted in past reviews, the attendee lookup should use
bookerEmailandbookerPhoneNumberinstead ofbookingData.responses.emailandbookingData.responses.attendeePhoneNumber.
2425-2427: Fix undefined bookingMeta spreading.The spreading of
input.bookingMetacan throw when undefined. Apply the suggested fix to useinput.bookingMeta ?? {}as the default.Also applies to: 2396-2398
2433-2450: LGTM! Deprecation notice for API v1 method.The deprecation comment clearly indicates the transition plan, and the method implementation correctly uses the same handler with proper parameter handling.
14-28: Imports validated — DTO types are exported in dto/types.d.tsCreateRegularBookingData (line 15), CreateBookingMeta (line 32), and BookingHandlerInput (line 40) are exported from packages/features/bookings/lib/dto/types.d.ts; imports are correct.
packages/features/bookings/types.ts (2)
3-4: LGTM! Import path updates are correct.The import changes align with the new DTO structure and enum location changes.
97-98: LGTM! Type alias simplification improves maintainability.The direct alias to
RegularBookingCreateResultsimplifies the type definition while maintaining backward compatibility. The TODO comment appropriately documents the future unification plan.packages/lib/di/bookings/containers/RecurringBookingService.container.ts (2)
4-4: LGTM! Consistent moduleLoader import pattern.The import aliasing follows the established pattern across the DI refactor.
10-12: LGTM! Module loading pattern correctly implemented.The container function properly loads the module and retrieves the service using the moduleLoader token, consistent with the other service containers.
apps/web/pages/api/book/recurring-event.ts (2)
6-6: LGTM! Service import follows DI pattern.The import of
getRecurringBookingServicefrom the container follows the established DI pattern.
46-58: Security and data sanitization issues need attention.As noted in previous review comments, several issues need to be addressed:
- Strip
cfTokenfromreq.bodybefore passing to the service- Change
userId: session?.user?.id || -1touserId: session?.user?.id ?? undefinedto avoid sentinel values- Add missing
hostnameandforcedSlugfields tobookingMetaApply the suggested diff from the previous review to address these issues.
packages/features/bookings/lib/handleNewRecurringBooking.ts (6)
13-16: LGTM! Handler signature updated for DI pattern.The updated function signature correctly accepts the
depsparameter for dependency injection, maintaining consistency with the regular booking handler.
18-18: LGTM! Clean dependency extraction.The destructuring of
regularBookingServicefrom deps follows the established DI pattern.
57-64: LGTM! Service call updated correctly for first booking.The call to
regularBookingService.createBookingwith properbookingMetawrapping is correctly implemented.
100-107: LGTM! Consistent service usage in recurring loop.The recurring booking creation uses the same service pattern as the first booking, maintaining consistency.
127-129: LGTM! Clear dependency interface.The
IRecurringBookingServiceDependenciesinterface is simple and focused, requiring only theRegularBookingServicedependency.
142-150: LGTM! Service implementation follows established pattern.Both
createBookingandrescheduleBookingmethods correctly delegate to the handler with proper parameter transformation.apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (6)
65-65: Align with NestJS DI best practices.According to NestJS best practices, API v2 should leverage NestJS's native DI container instead of external service getters. The current approach bypasses NestJS's IoC container and defeats the purpose of dependency injection.
472-486: Use NestJS DI instead of external service getter.This pattern bypasses NestJS's native dependency injection, making testing and mocking difficult.
524-537: Use NestJS DI instead of external service getter.This pattern bypasses NestJS's native dependency injection, making testing and mocking difficult.
559-572: Use NestJS DI instead of external service getter.This pattern bypasses NestJS's native dependency injection, making testing and mocking difficult.
757-770: Use NestJS DI instead of external service getter.This pattern bypasses NestJS's native dependency injection, making testing and mocking difficult.
451-454: Use NestJS DI instead of external service getter.This pattern bypasses NestJS's native dependency injection, making testing and mocking difficult.
Inject the service through the constructor instead:
+import { InstantBookingCreateService } from "@calcom/platform-libraries/bookings"; @Injectable() export class BookingsService_2024_08_13 { constructor( + private readonly instantBookingCreateService: InstantBookingCreateService, // ... other dependencies ) {} async createInstantBooking( request: Request, body: CreateInstantBookingInput_2024_08_13, eventType: EventTypeWithOwnerAndTeam ) { - const instantBookingService = getInstantBookingCreateService(); - const booking = await instantBookingService.createBooking({ + const booking = await this.instantBookingCreateService.createBooking({ bookingData: bookingRequest.body, });You'll also need to register
InstantBookingCreateServicein the module's providers array.packages/features/bookings/lib/dto/types.d.ts (3)
7-7: LGTM!The import for
SchedulingTypecorrectly fixes the TypeScript error.
15-21: LGTM!The type definitions correctly use
ExtendedBookingCreateBodyas the foundation for all booking data types, providing consistent structure across regular, instant, and recurring bookings.
44-51: LGTM!The
InstantBookingCreateResulttype provides a clear, well-defined structure for instant booking responses.apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
58-58: LGTM!The import changes correctly bring in the new service getters and types from the platform libraries.
319-331: Missing noEmail in recurring booking meta.The recurring booking service call omits the
noEmailproperty that's present in regular bookings, which could lead to inconsistent email behavior.
188-202: Use NestJS DI instead of external service getter.This pattern bypasses NestJS's native dependency injection, making testing and mocking difficult.
363-367: Use NestJS DI instead of external service getter.This pattern bypasses NestJS's native dependency injection, making testing and mocking difficult.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (7)
packages/features/bookings/lib/dto/types.d.ts (2)
53-54: Fix TODO grammar; avoid type-level coupling to service implementation
- Minor copy fix — apply diff below.
- packages/features/bookings/lib/dto/types.d.ts currently imports RegularBookingService from ../handleNewBooking, creating a type-level coupling. Export the result type from a neutral "contracts" (shared) module consumed by both the service and DTOs to decouple the public surface.
-// TODO: In a followup PR, we working on defining the type here itself instead of inferring it. +// TODO: In a follow-up PR, we are defining the type here instead of inferring it.
19-21: Extract a CreateRecurringBookingItem type and keep schedulingType optional.Introduce a single-item alias for readability; keep schedulingType optional — DB schema marks it nullable and callsites treat it as absent (packages/prisma/schema.prisma:189, packages/features/bookings/lib/handleNewBooking.ts:279).
+export type CreateRecurringBookingItem = ExtendedBookingCreateBody & { + schedulingType?: SchedulingType; +}; -export type CreateRecurringBookingData = (ExtendedBookingCreateBody & { - schedulingType?: SchedulingType; -})[]; +export type CreateRecurringBookingData = CreateRecurringBookingItem[];packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
22-25: Optionally type moduleLoader to ModuleLoader.For IDE help and consistency with other modules, export
moduleLoaderasModuleLoader.-export const moduleLoader = { +export const moduleLoader: ModuleLoader = { token, loadModule, };apps/web/pages/api/book/recurring-event.ts (1)
32-37: Guard cfToken access for array shape.Avoid potential runtime errors when body isn’t an array.
- if (process.env.NEXT_PUBLIC_CLOUDFLARE_USE_TURNSTILE_IN_BOOKER === "1") { - await checkCfTurnstileToken({ - token: req.body[0]["cfToken"] as string, - remoteIp: userIp, - }); - } + if (process.env.NEXT_PUBLIC_CLOUDFLARE_USE_TURNSTILE_IN_BOOKER === "1") { + const token = Array.isArray(req.body) ? req.body[0]?.cfToken : undefined; + await checkCfTurnstileToken({ token: String(token ?? ""), remoteIp: userIp }); + }apps/web/pages/api/book/event.ts (1)
15-20: Sanitize cfToken before passing bookingData.Remove Turnstile token from the payload.
if (process.env.NEXT_PUBLIC_CLOUDFLARE_USE_TURNSTILE_IN_BOOKER === "1") { - await checkCfTurnstileToken({ - token: req.body["cfToken"] as string, - remoteIp: userIp, - }); + const token = (req.body as any)?.cfToken; + await checkCfTurnstileToken({ token: String(token ?? ""), remoteIp: userIp }); } @@ - const regularBookingService = getRegularBookingService(); - const booking = await regularBookingService.createBooking({ - bookingData: req.body, + const { cfToken, ...sanitized } = (req.body ?? {}) as Record<string, unknown>; + const regularBookingService = getRegularBookingService(); + const booking = await regularBookingService.createBooking({ + bookingData: sanitized, bookingMeta: { userId: session?.user?.id || -1, hostname: req.headers.host || "", forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, }, });Also applies to: 34-41
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
521-551: Remove unused createNextApiRecurringBookingRequestDeclared at apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts:521; no call-sites found — delete or implement to avoid drifting from createNextApiBookingRequest.
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
521-551: Remove unused helper: createNextApiRecurringBookingRequestDefined in apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (≈ lines 521–551) but not referenced anywhere — delete it or update the recurring booking flow to use it.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(9 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (13)
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- packages/features/bookings/lib/create-instant-booking.ts
- packages/features/bookings/types.ts
- packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- packages/platform/libraries/bookings.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- apps/web/pages/api/book/instant-event.ts
- apps/web/lib/types/booking.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- packages/features/bookings/lib/index.ts
- packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tsapps/api/v2/src/lib/modules/recurring-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-04-15/bookings.module.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/dto/types.d.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/lib/services/regular-booking.service.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tsapps/api/v2/src/lib/modules/recurring-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-04-15/bookings.module.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/dto/types.d.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/lib/services/regular-booking.service.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tsapps/api/v2/src/lib/modules/recurring-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-04-15/bookings.module.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/dto/types.d.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/lib/services/regular-booking.service.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/lib/services/recurring-booking.service.tsapps/api/v2/src/lib/services/regular-booking.service.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
apps/api/v2/src/lib/modules/instant-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-04-15/bookings.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/dto/types.d.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/lib/services/regular-booking.service.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/bookings.module.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/lib/di/bookings/modules/RegularBookingService.module.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewBooking.tsapps/web/pages/api/book/event.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/bookings/lib/handleNewBooking.tspackages/features/instant-meeting/handleInstantMeeting.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.ts
🧬 Code graph analysis (19)
apps/api/v2/src/lib/modules/instant-booking.module.ts (5)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
Module(5-10)apps/api/v2/src/lib/modules/regular-booking.module.ts (1)
Module(15-32)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/lib/modules/recurring-booking.module.ts (7)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
Module(4-8)apps/api/v2/src/lib/modules/regular-booking.module.ts (1)
Module(15-32)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
RecurringBookingService(26-26)packages/platform/libraries/bookings.ts (1)
RecurringBookingService(6-6)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(42-45)
apps/web/pages/api/book/recurring-event.ts (1)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)
apps/api/v2/src/lib/modules/regular-booking.module.ts (5)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
Module(4-8)apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
Module(5-10)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
apps/api/v2/src/lib/services/instant-booking-create.service.ts (5)
apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
Injectable(6-13)apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
InstantBookingCreateService(18-18)packages/platform/libraries/bookings.ts (1)
InstantBookingCreateService(7-7)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
packages/features/bookings/lib/handleNewBooking.ts (5)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
apps/api/v2/src/lib/services/recurring-booking.service.ts (3)
apps/api/v2/src/lib/services/instant-booking-create.service.ts (1)
Injectable(5-6)apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (2)
packages/features/bookings/lib/dto/types.d.ts (1)
BookingHandlerInput(40-42)packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
RecurringBookingService(26-26)recurringBookingServiceModule(10-10)
packages/lib/di/bookings/modules/RegularBookingService.module.ts (8)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
moduleLoader(19-22)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
moduleLoader(22-25)packages/lib/di/modules/Attribute.ts (1)
moduleLoader(18-21)packages/lib/di/modules/LuckyUser.ts (1)
moduleLoader(28-31)packages/lib/di/modules/Host.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Ooo.ts (1)
moduleLoader(18-21)packages/lib/di/modules/User.ts (1)
moduleLoader(18-21)packages/prisma/prisma.module.ts (1)
moduleLoader(13-19)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(44-51)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
apps/web/pages/api/book/event.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
apps/api/v2/src/lib/services/regular-booking.service.ts (4)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
Injectable(90-1142)apps/api/v2/src/lib/services/instant-booking-create.service.ts (1)
Injectable(5-6)apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
Injectable(6-13)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: Production builds / Build Docs
- GitHub Check: Production builds / Build Web App
- GitHub Check: Production builds / Build Atoms
- GitHub Check: Production builds / Build API v2
- GitHub Check: Production builds / Build API v1
- GitHub Check: Type check / check-types
- GitHub Check: Tests / Unit
- GitHub Check: Linters / lint
🔇 Additional comments (37)
packages/features/bookings/lib/bookingCreateBodySchema.ts (2)
60-76: Schema refactoring properly separates recurring booking concerns.The extraction of
recurringBookingCreateBodyPartialSchemacleanly separates recurring booking fields from the base schema. The optionalendfield on line 71 is correctly handled as mentioned in past review comments.
79-98: Clarify legacy handling ofcustomInputs
customInputsis intentionallyz.undefined().optional()in the extended schema — the actual schema lives in bookingCreateSchemaLegacyPropsForApi (packages/features/bookings/lib/bookingCreateBodySchema.ts:customInputs: z.array(z.object({ label: z.string(), value: z.union([z.string(), z.boolean()]) }))) and is merged into bookingCreateBodySchemaForApi for API compatibility. Action: add a one-line inline comment at thez.undefined()site explaining this legacy/merge behavior, or only change the schema if you intend to acceptcustomInputson the new shape.Likely an incorrect or invalid review comment.
packages/features/instant-meeting/handleInstantMeeting.ts (2)
158-158: Function rename from_handlertohandlerimproves clarity.The removal of the underscore prefix makes the function name more conventional and clearer.
339-341: Service implementation follows consistent pattern.The
InstantBookingCreateServicecorrectly implements theIBookingCreateServiceinterface and follows the same pattern asRegularBookingServiceandRecurringBookingService, which promotes consistency across the codebase.apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
1-10: Approve — RecurringBookingModule correctly imports RegularBookingModuleRecurringBookingService's constructor receives RegularBookingService and forwards it to the base class, so importing RegularBookingModule to provide that dependency is correct.
apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
1-8: Approve — InstantBookingModule verifiedInstantBookingModule correctly provides and exports InstantBookingCreateService; apps/api/v2/src/lib/services/instant-booking-create.service.ts exists and the service simply extends BaseInstantBookingCreateService from @calcom/platform-libraries/bookings.
apps/api/v1/pages/api/bookings/_post.ts (1)
242-252: Service integration lazy loading verified
getRegularBookingService creates a new Container on each call and only invokes moduleLoader.loadModule—no modules are loaded at import time and there’s no global caching or singleton behavior.apps/api/v2/src/lib/services/instant-booking-create.service.ts (1)
1-6: LGTM! Appropriate service wrapper implementation.The service correctly extends the base InstantBookingCreateService and uses the @Injectable decorator for NestJS DI. This follows the same pattern established in the other booking services.
apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
1-13: LGTM! Clean dependency injection pattern.The service correctly extends the base service and properly injects RegularBookingService as a dependency, passing it to the parent constructor. This establishes the expected relationship where recurring bookings can delegate to regular booking logic.
apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (2)
19-21: LGTM! Proper module imports for booking services.The three booking modules (InstantBookingModule, RecurringBookingModule, RegularBookingModule) are correctly imported to provide the necessary booking services.
64-66: LGTM! Module registration is consistent.The booking modules are properly registered in the imports array, making the booking services available to the module's controllers and providers.
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (2)
9-11: LGTM! Consistent module import pattern.The booking modules are imported following the same pattern as the 2024-08-13 version, maintaining consistency across API versions.
41-43: LGTM! Proper module registration.The booking modules are correctly added to the imports array, ensuring the services are available for dependency injection.
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (2)
4-14: LGTM! Proper migration to service-based approach.The handler correctly:
- Uses the new service-based pattern with getRegularBookingService()
- Properly destructures input into bookingData and bookingMeta
- Calls the service's createBooking method with the correct parameters
This aligns with the broader architectural shift to service-based booking flows.
16-18: LGTM! Clean function export.The getNewBookingHandler function correctly returns the handler, maintaining the expected API while internally using the new service-based implementation.
packages/lib/di/bookings/modules/RegularBookingService.module.ts (3)
3-3: LGTM! Comprehensive dependency expansion.The module correctly adds the new dependencies (attributeRepository, hostRepository, luckyUserService, oooRepository, userRepository) with their corresponding module loaders, properly expanding the RegularBookingService capabilities.
Also applies to: 10-13
34-38: LGTM! Consistent dependency mapping.The dependency map correctly includes all the new services with their respective module loaders, maintaining consistency with the existing pattern.
42-45: LGTM! Proper moduleLoader export pattern.The export follows the established moduleLoader pattern used by other modules in the codebase, providing consistent lazy loading behavior.
apps/api/v2/src/lib/modules/regular-booking.module.ts (2)
15-32: LGTM! Well-structured NestJS module.The module correctly:
- Imports PrismaModule for database access
- Provides all necessary repositories and services as dependencies
- Exports RegularBookingService for use by other modules
- Follows NestJS module conventions
1-14: Import paths and named exports verified — no changes required.All referenced repository and service files exist under apps/api/v2/src/lib and export the expected named classes (PrismaAttributeRepository, PrismaBookingRepository, PrismaFeaturesRepository, PrismaHostRepository, PrismaOOORepository, PrismaUserRepository, CacheService, CheckBookingAndDurationLimitsService, CheckBookingLimitsService, LuckyUserService, RegularBookingService).
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (2)
4-4: LGTM! Consistent moduleLoader import pattern.The import correctly uses the moduleLoader pattern that's being adopted across the booking service modules.
9-13: LGTM! Proper moduleLoader usage pattern.The function correctly:
- Loads the module using the moduleLoader pattern
- Retrieves the service using the moduleLoader's token
- Returns the properly typed RecurringBookingService
This follows the same pattern established in other container files.
packages/features/bookings/lib/dto/types.d.ts (5)
2-2: Docstring LGTMClear scope statement for “domain types”.
7-7: SchedulingType import fixedThe missing import noted earlier is now present.
9-10: Type‑only imports: goodKeeps runtime clean; no action needed.
15-15: Mapping to ExtendedBookingCreateBody looks correctConsistent with the new input schema.
Also applies to: 17-17
12-12: Resolved — BookingCreateBody is exportedpackages/features/bookings/lib/bookingCreateBodySchema.ts exports BookingCreateBody (line 58), so the re‑export in packages/features/bookings/lib/dto/types.d.ts is valid.
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
12-20: DI binding looks correct and matches constructor keys.
depsMapkeyregularBookingServicealigns with RecurringBookingService’s constructor. No issues.
8-10: DI tokens exist and are unique.RECURRING_BOOKING_SERVICE and RECURRING_BOOKING_SERVICE_MODULE are defined as Symbol(...) in packages/lib/di/bookings/tokens.ts and are included in DI_TOKENS via ...BOOKING_DI_TOKENS in packages/lib/di/tokens.ts — no action required.
apps/api/v2/src/lib/services/regular-booking.service.ts (1)
17-46: Nest DI wiring LGTM.Constructor deps map cleanly to base service; Prisma client injection approach is acceptable here.
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
456-460: Instant booking path LGTM.DI usage and payload shape align with platform service expectations.
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
194-207: Regular booking service integration LGTM.Meta includes
forcedSlugandareCalendarEventsEnabled; matches platform service expectations.apps/web/pages/api/book/recurring-event.ts (1)
46-57: Don’t pass -1 userId; strip cfToken; include hostname/forcedSlug.Sanitize input and avoid sentinel IDs; pass host context for routing.
- const recurringBookingService = getRecurringBookingService(); - const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ - bookingData: req.body, - bookingMeta: { - userId: session?.user?.id || -1, + const recurringBookingService = getRecurringBookingService(); + const inputBody = req.body; + const bookingData = Array.isArray(inputBody) + ? inputBody.map(({ cfToken, ...rest }) => rest) + : inputBody; + const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ + bookingData, + bookingMeta: { + userId: session?.user?.id ?? undefined, + hostname: req.hostname, + forcedSlug: req.forcedSlug, platformClientId: req.platformClientId, platformCancelUrl: req.platformCancelUrl, platformBookingUrl: req.platformBookingUrl, platformRescheduleUrl: req.platformRescheduleUrl, platformBookingLocation: req.platformBookingLocation, noEmail: req.noEmail, }, });apps/web/pages/api/book/event.ts (1)
34-41: Don’t proceed unauthenticated; avoid -1 sentinel.Return 401 (or omit userId) instead of injecting
-1.- const regularBookingService = getRegularBookingService(); - const booking = await regularBookingService.createBooking({ + if (!session?.user?.id) { + throw new Error("Unauthorized"); + } + const regularBookingService = getRegularBookingService(); + const booking = await regularBookingService.createBooking({ bookingData: req.body, bookingMeta: { - userId: session?.user?.id || -1, + userId: session.user.id, hostname: req.headers.host || "", forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, }, });packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
57-66: Bug: first recurring RR slot isn’t added; series ID not propagated.You await the first slot but don’t push it to results or seed
thirdPartyRecurringEventId.- const firstBookingResult = await regularBookingService.createBooking({ + const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + // include first slot and propagate series id for subsequent slots + createdBookings.push(firstBookingResult); + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + const ref = firstBookingResult.references.find((r) => r.thirdPartyRecurringEventId); + if (ref?.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = ref.thirdPartyRecurringEventId; + } + } + luckyUsers = firstBookingResult.luckyUsers;packages/features/bookings/lib/handleNewBooking.ts (2)
2425-2431: Fix runtime crash when bookingMeta is undefined.Spreading
input.bookingMetathrows if undefined. Default to{}.async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); } @@ async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); }
1607-1613: Attendee lookup uses possibly undefined responses; use parsed booker fields.Match against
bookerEmail/bookerPhoneNumberinstead ofbookingData.responses.- const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + const currentAttendee = booking.attendees.find( + (attendee) => attendee.email === bookerEmail || (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (2)
501-512: Remove duplicate bookingMeta in recurring seated bookings.The
bookingMetastructure appears identical to lines 478-488. Consider extracting a helper function to avoid code duplication and ensure consistency.private buildBookingMeta(bookingRequest: any) { return { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }; }
526-526: Remove debug console.log before production.The debug console statement should be removed from production code.
- console.log('Regularrr Booking service from Nest DI')packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
29-33: Guard against empty bookingData array.Accessing data[0] without a precondition will throw on empty input.
- const firstBooking = data[0]; + if (data.length === 0) return []; + const firstBooking = data[0];packages/features/bookings/lib/handleNewBooking.ts (1)
1196-1201: Prisma: select only required fields.Return only organizationId to reduce data/PII surface.
- const organizerOrganizationProfile = await prisma.profile.findFirst({ - where: { - userId: organizerUser.id, - username: dynamicUserList[0], - }, - }); + const organizerOrganizationProfile = await prisma.profile.findFirst({ + where: { + userId: organizerUser.id, + username: dynamicUserList[0], + }, + select: { organizationId: true }, + });packages/features/bookings/lib/dto/types.d.ts (1)
44-51: Define a transport DTO for HTTP responsesInstantBookingCreateResult.expires is a Date (domain) and will be serialized to ISO strings over HTTP. Introduce a transport type with
expires: stringand update your controller to use it:// packages/features/bookings/lib/dto/types.d.ts export type InstantBookingCreateTransport = Omit<InstantBookingCreateResult, "expires"> & { expires: string };In apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts:362, change the return type to
ApiResponse<InstantBookingCreateTransport>and mapexpires.toISOString()before returning.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (20)
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- packages/platform/libraries/bookings.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- apps/api/v2/src/lib/services/regular-booking.service.ts
- apps/web/pages/api/book/event.ts
- packages/features/bookings/lib/index.ts
- apps/api/v2/src/lib/services/recurring-booking.service.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- packages/features/bookings/lib/create-instant-booking.ts
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- packages/lib/di/bookings/containers/RecurringBookingService.container.ts
- apps/web/lib/types/booking.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- packages/features/instant-meeting/handleInstantMeeting.ts
- apps/api/v2/src/lib/modules/instant-booking.module.ts
- packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/web/pages/api/book/recurring-event.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/web/pages/api/book/instant-event.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/web/pages/api/book/recurring-event.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/web/pages/api/book/instant-event.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
apps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/web/pages/api/book/recurring-event.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/web/pages/api/book/instant-event.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
apps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/web/pages/api/book/recurring-event.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/lib/di/bookings/modules/RegularBookingService.module.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/web/pages/api/book/instant-event.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/types.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧬 Code graph analysis (14)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
apps/api/v2/src/lib/modules/regular-booking.module.ts (5)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
Module(4-8)apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
Module(5-10)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
apps/web/pages/api/book/recurring-event.ts (3)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(42-45)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (3)
packages/lib/di/di.ts (1)
createContainer(114-114)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (2)
InstantBookingCreateService(18-18)instantBookingCreateServiceModule(7-7)
apps/web/pages/api/book/instant-event.ts (1)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (3)
packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
packages/lib/di/bookings/modules/RegularBookingService.module.ts (7)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
moduleLoader(19-22)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
moduleLoader(22-25)packages/lib/di/modules/Attribute.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Host.ts (1)
moduleLoader(18-21)packages/lib/di/modules/LuckyUser.ts (1)
moduleLoader(28-31)packages/lib/di/modules/Ooo.ts (1)
moduleLoader(18-21)packages/lib/di/modules/User.ts (1)
moduleLoader(18-21)
packages/features/bookings/lib/handleNewBooking.ts (5)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/bookings/types.ts (5)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/index.ts (1)
BookingResponse(9-9)packages/platform/libraries/index.ts (1)
BookingResponse(49-49)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(54-54)packages/platform/libraries/bookings.ts (1)
RegularBookingCreateResult(10-10)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
🔇 Additional comments (31)
packages/features/bookings/lib/bookingCreateBodySchema.ts (3)
60-76: LGTM! Schema restructuring for recurring booking flow.The
recurringBookingCreateBodyPartialSchemaproperly encapsulates recurring-specific fields. Line 71 correctly makesendoptional as noted by the maintainer, sincehandleNewRecurringBookingmay pass undefined values.
78-98: Good schema composition using merge pattern.The updated
extendedBookingCreateBodycleanly merges the base schema with new top-level fields (noEmail, appsStatus, luckyUsers, customInputs) and the recurring partial schema. This prepares well for the TODO's planned separate schemas for different booking types.
100-100: Export the new type for proper typing.
ExtendedBookingCreateBodycorrectly provides proper types forinput.bookingData, replacing the previousRecord<string, any>typing mentioned in the PR objectives.packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (2)
4-4: Clean moduleLoader aliasing pattern.The alias
moduleLoader as instantBookingCreateServiceModulemaintains backward compatibility while adopting the new pattern. This approach is consistent with the broader DI refactoring.
10-11: Proper token-based service resolution.The container now correctly loads the module first, then retrieves the service using the module's token instead of hardcoded DI_TOKENS. This aligns with the lazy-loading strategy.
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (5)
9-11: Service imports align with new DI architecture.The imports of
InstantBookingCreateService,RecurringBookingService, andRegularBookingServicefrom their respective services properly integrate with the new service-based booking flow.
112-114: Constructor properly wired for NestJS DI.The new service dependencies are correctly injected via NestJS constructor DI, replacing the direct handler calls as intended by the refactoring.
456-458: Instant booking flow simplified with service call.The transition from direct
handleInstantMeetingtoinstantBookingCreateService.createBookingmaintains the same payload structure while delegating to the DI-managed service. Payload remains asbookingDataonly since instant bookings don't needbookingMeta.
476-489: Consistent bookingMeta structure for recurring bookings.The
bookingMetaobject properly includes all necessary platform-specific metadata (userId, hostname, platformClientId, etc.) and flags (noEmail, areCalendarEventsEnabled). This aligns with the new service interface expectations.
527-538: Regular booking implementation looks correct.The service call with proper
bookingMetastructure follows the expected pattern established for other booking types.packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
6-6: Verify RegularBookingService module dependency.The import and dependency on
regularBookingServiceModuleLoaderis correct sinceRecurringBookingServicedepends onRegularBookingServicefor its implementation.
12-20: Proper moduleLoader setup with dependency mapping.The
bindModuleToClassOnTokencorrectly maps theregularBookingServicedependency toregularBookingServiceModuleLoaderin thedepsMap. This ensures the dependency is loaded when the RecurringBookingService is instantiated.
22-25: Consistent moduleLoader export pattern.The
moduleLoaderexport withtokenandloadModulefollows the same pattern as other booking service modules, maintaining consistency in the DI architecture.packages/features/bookings/types.ts (1)
97-98: Type alias correctly simplifies public API.The type alias
BookingResponse = RegularBookingCreateResultprovides backward compatibility while migrating to the new service-based types. The TODO comment appropriately notes the planned consolidation in a future PR.apps/web/pages/api/book/instant-event.ts (2)
5-5: Proper service container import.The import of
getInstantBookingCreateServicealigns with the new DI container pattern for service resolution.
23-28: Service-based booking flow with proper payload structure.The transition from direct
handleInstantMeetingcall to service-basedinstantBookingService.createBooking({ bookingData: req.body })maintains the same runtime validation while using the new architecture. The TODO comment correctly identifies the opportunity to move runtime validation to the API layer.apps/api/v2/src/lib/modules/regular-booking.module.ts (2)
15-31: Complete NestJS module setup for RegularBookingService.The module properly imports
PrismaModuleand provides all necessary dependencies (repositories, services, limits checking, cache) thatRegularBookingServicerequires according to theIBookingServiceDependenciesinterface. The exports correctly makeRegularBookingServiceavailable to other modules.
1-32: Verified — no Prisma 'include' usage found. Scanned apps/api/v2/src/lib/repositories (those imported by RegularBookingModule); noinclude:occurrences detected.packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
1-22: Verify moduleLoader pattern is consistent across booking modules.Verified: moduleLoader is exported in packages/lib/di/bookings/modules/{InstantBookingCreateService.module.ts, RecurringBookingService.module.ts, RegularBookingService.module.ts}; containers call .loadModule(...), DI tokens align, and the empty depsMap is appropriate.
apps/api/v1/pages/api/bookings/_post.ts (1)
242-252: Service wiring for API v1 LGTM.createBookingForApiV1 is correctly supplied with bookingMeta and schema getter.
packages/features/bookings/lib/handleNewBooking.ts (3)
2433-2449: API v1 shim correctly defaults bookingMeta; good.The safer spread with bookingMeta ?? {} is applied here.
1609-1613: Bug: attendee lookup uses bookingData.responses; use parsed bookerEmail/Phone.bookingData.responses may be absent; prefer the already parsed bookerEmail/bookerPhoneNumber.
- const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + const currentAttendee = booking.attendees.find( + (attendee) => + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );
2425-2431: Spreading possibly undefined bookingMeta throws at runtime.Object spread with undefined crashes. Default to {} first.
async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); } async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); }apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (3)
194-207: Regular booking service integration LGTM.Metadata parity (hostname, forcedSlug, platform params, areCalendarEventsEnabled) is preserved.
324-334: Recurring booking service wiring is consistent.Note: Omitting areCalendarEventsEnabled/noEmail matches stated existing behavior.
368-371: Instant booking: passing only body is correct.Constructor no longer needs the full request context.
packages/features/bookings/lib/dto/types.d.ts (1)
9-21: Type imports/re-exports look correct.SchedulingType import and ExtendedBookingCreateBody usage align with upstream types.
apps/web/pages/api/book/recurring-event.ts (1)
46-58: Avoid sentinel userId (-1); sanitize bookingData (strip cfToken); pass hostname/forcedSlug.Passing -1 risks leaking invalid user IDs. Also strip cfToken from the payload and include hostname/forcedSlug for parity with other routes.
- const recurringBookingService = getRecurringBookingService(); - const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ - bookingData: req.body, - bookingMeta: { - userId: session?.user?.id || -1, - platformClientId: req.platformClientId, - platformCancelUrl: req.platformCancelUrl, - platformBookingUrl: req.platformBookingUrl, - platformRescheduleUrl: req.platformRescheduleUrl, - platformBookingLocation: req.platformBookingLocation, - noEmail: req.noEmail, - }, - }); + const recurringBookingService = getRecurringBookingService(); + const bookingDataInput = req.body; + const sanitizedBookingData = Array.isArray(bookingDataInput) + ? bookingDataInput.map(({ cfToken, ...rest }) => rest) + : bookingDataInput; + + const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ + bookingData: sanitizedBookingData, + bookingMeta: { + userId: session?.user?.id ?? undefined, + hostname: req.headers?.host || "", + forcedSlug: (req.headers?.["x-cal-force-slug"] as string | undefined) ?? undefined, + platformClientId: req.platformClientId, + platformCancelUrl: req.platformCancelUrl, + platformBookingUrl: req.platformBookingUrl, + platformRescheduleUrl: req.platformRescheduleUrl, + platformBookingLocation: req.platformBookingLocation, + noEmail: req.noEmail, + }, + });packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
57-66: First recurring booking result is dropped; also seed series ID from first result.You await the first booking but don’t push it, and you don’t propagate thirdPartyRecurringEventId for subsequent slots.
- const firstBookingResult = await regularBookingService.createBooking({ + const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + // include first slot and propagate series id for later slots + createdBookings.push(firstBookingResult); + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + const ref = firstBookingResult.references.find((r) => r.thirdPartyRecurringEventId); + if (ref?.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = ref.thirdPartyRecurringEventId; + } + } + luckyUsers = firstBookingResult.luckyUsers;packages/lib/di/bookings/modules/RegularBookingService.module.ts (2)
34-38: Deps map keys match IBookingServiceDependencies — approved.
Verified: depsMap keys exactly match the IBookingServiceDependencies properties; no drift found.
42-45: Export rename verified — imports updatedModule now exports moduleLoader and callers import it (often aliased back to regularBookingServiceModule); e.g. packages/lib/di/bookings/containers/RegularBookingService.container.ts and packages/lib/di/bookings/modules/RecurringBookingService.module.ts. No direct imports of regularBookingServiceModule found.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
376-383: Fix async rejection assertion and new API shape.Pass the promise to expect.rejected and use bookingMeta for userId.
- await expect( - async () => - await recurringBookingService.createBooking({ - bookingData: bookingDataArray, - userId: -1, - }) - ).rejects.toThrow(ErrorCode.NoAvailableUsersFound); + await expect( + recurringBookingService.createBooking({ + bookingData: bookingDataArray, + bookingMeta: { userId: -1 }, + }) + ).rejects.toThrow(ErrorCode.NoAvailableUsersFound);
🧹 Nitpick comments (8)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
258-263: Use Prisma select (no include) per repo guideline.Return only needed fields; avoid include.
Apply:
- const createBookingObj = { - include: { - attendees: true, - }, - data: newBookingData, - }; + const createBookingObj = { + select: { + id: true, + uid: true, + userId: true, + title: true, + responses: true, + customInputs: true, + smsReminderNumber: true, + }, + data: newBookingData, + };
1196-1201: Prisma: select only required fields.findFirst is fetching full profile; select organizationId.
- const organizerOrganizationProfile = await prisma.profile.findFirst({ - where: { - userId: organizerUser.id, - username: dynamicUserList[0], - }, - }); + const organizerOrganizationProfile = await prisma.profile.findFirst({ + where: { + userId: organizerUser.id, + username: dynamicUserList[0], + }, + select: { organizationId: true }, + });packages/features/bookings/lib/handleNewBooking.ts (2)
1196-1201: Prisma: select only required fields.Limit profile query to organizationId.
- const organizerOrganizationProfile = await prisma.profile.findFirst({ + const organizerOrganizationProfile = await prisma.profile.findFirst({ where: { userId: organizerUser.id, username: dynamicUserList[0], }, + select: { organizationId: true }, });
789-841: Micro‑perf: avoid repeated dayjs.tz/format in loops.Precompute formatted dates or reuse Day.js instances; reduces allocations in multi‑slot checks.
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
476-489: Optional: deduplicate bookingMeta construction.Extract a private buildBookingMeta(bookingRequest, extras?) to avoid drift and repeated literals.
Example (outside this diff for illustration):
private buildBookingMeta(req: any, extras?: Partial<Record<string, unknown>>) { return { userId: req.userId, hostname: req.headers?.host || "", platformClientId: req.platformClientId, platformRescheduleUrl: req.platformRescheduleUrl, platformCancelUrl: req.platformCancelUrl, platformBookingUrl: req.platformBookingUrl, platformBookingLocation: req.platformBookingLocation, areCalendarEventsEnabled: req.areCalendarEventsEnabled, ...(extras || {}), }; }Also applies to: 501-513, 526-537, 560-571, 757-768
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
29-34: Guard empty bookingData arrays.Accessing data[0] throws when array is empty.
- const firstBooking = data[0]; - const isRoundRobin = firstBooking.schedulingType === SchedulingType.ROUND_ROBIN; + if (!Array.isArray(data) || data.length === 0) return []; + const firstBooking = data[0]; + const isRoundRobin = firstBooking.schedulingType === SchedulingType.ROUND_ROBIN;apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
363-371: Swagger/typing: expires should be string on the wire.ApiResponse uses InstantBookingCreateResult (expires: Date). Ensure the OpenAPI schema reflects expires as string (ISO).
packages/features/bookings/lib/dto/types.d.ts (1)
44-51: Expose a transport DTO for HTTP surfaces (expires as string).Keep domain type as Date, but export an HTTP-safe variant to avoid leaking Date in API typings.
export type InstantBookingCreateResult = { message: string; meetingTokenId: number; bookingId: number; bookingUid: string; expires: Date; userId: number | null; }; + +// Transport-safe DTO for HTTP/JSON responses +export type InstantBookingCreateResultHttp = Omit<InstantBookingCreateResult, "expires"> & { + expires: string; +};
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (21)
- packages/features/bookings/lib/index.ts
- packages/lib/di/bookings/modules/RegularBookingService.module.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- packages/lib/di/bookings/containers/RecurringBookingService.container.ts
- packages/features/bookings/lib/bookingCreateBodySchema.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- apps/api/v2/src/lib/services/regular-booking.service.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- apps/api/v2/src/lib/modules/instant-booking.module.ts
- apps/web/lib/types/booking.ts
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- apps/api/v2/src/lib/services/recurring-booking.service.ts
- packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts
- apps/api/v2/src/lib/modules/regular-booking.module.ts
- apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
- apps/web/pages/api/book/instant-event.ts
- packages/platform/libraries/bookings.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/features/bookings/lib/create-instant-booking.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/event.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/features/bookings/lib/create-instant-booking.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/event.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/features/bookings/lib/create-instant-booking.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/event.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-18T08:50:49.906Z
Learnt from: eunjae-lee
PR: calcom/cal.com#23752
File: packages/lib/server/service/InsightsBookingBaseService.ts:340-371
Timestamp: 2025-09-18T08:50:49.906Z
Learning: In the InsightsBookingBaseService (packages/lib/server/service/InsightsBookingBaseService.ts), the startTime date range filter intentionally uses different fields for the lower and upper bounds: `startDate <= "startTime" AND "endTime" <= endDate`. This ensures bookings start within the selected range but don't extend beyond the end date, which is the intended business logic and not an inconsistency.
Applied to files:
packages/features/bookings/lib/create-instant-booking.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
packages/features/bookings/lib/create-instant-booking.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/event.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/create-instant-booking.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/bookings/lib/create-instant-booking.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/event.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/types.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
🧬 Code graph analysis (13)
packages/features/bookings/lib/create-instant-booking.ts (3)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
createInstantBooking(357-390)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)packages/lib/fetch-wrapper.ts (1)
post(28-36)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(42-45)
apps/web/pages/api/book/recurring-event.ts (1)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(44-51)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (2)
packages/features/bookings/lib/dto/types.d.ts (1)
BookingHandlerInput(40-42)packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/bookings/types.ts (2)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(54-54)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/web/pages/api/book/event.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
🔇 Additional comments (19)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
12-20: Good DI wiring with moduleLoader.Binding RecurringBookingService with RegularBookingService via depsMap looks correct and consistent with the new loader pattern.
22-25: Export shape LGTM.moduleLoader exposes token and loadModule as expected.
apps/api/v1/pages/api/bookings/_post.ts (1)
241-252: Service integration and typed booking flow look solid.createBookingForApiV1 + bookingMeta + schema getter are wired correctly.
packages/features/instant-meeting/handleInstantMeeting.ts (1)
339-341: API surface is clean.InstantBookingCreateService delegates to handler and returns typed result. 👍
packages/features/bookings/types.ts (2)
3-5: Type source updates look correct.Switch to enums import and alias BookingResponse → RegularBookingCreateResult is consistent with the new service API.
97-99: Transitional alias acknowledged.Keeping BookingResponse as alias is fine until follow‑up rename.
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (1)
4-13: Test helper now exercises the real service — good.Dynamic import of the container keeps tests light and mirrors prod wiring.
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
155-162: Service usage in tests looks correct.Passing bookingMeta with userId to RecurringBookingService aligns with the new API.
Ensure all other tests moved off handleNewRecurringBooking to the service (there’s still a call later in this file under a skipped test).
packages/features/bookings/lib/handleNewBooking.ts (2)
1608-1613: Bug: attendee lookup should use parsed email/phone, not bookingData.responses.Use bookerEmail/bookerPhoneNumber to avoid undefined access.
- const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + const currentAttendee = booking.attendees.find( + (attendee) => + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );
2426-2431: Runtime crash: spreading possibly undefined bookingMeta....input.bookingMeta throws when bookingMeta is undefined. Default it.
- return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + return handler({ bookingData: input.bookingData, ...(input.bookingMeta ?? {}) }, this.deps);- return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + return handler({ bookingData: input.bookingData, ...(input.bookingMeta ?? {}) }, this.deps);apps/web/pages/api/book/event.ts (1)
34-42: Return 401 when unauthenticated; don’t pass userId = -1.Proceeding with -1 can cause confusing downstream behavior.
- const regularBookingService = getRegularBookingService(); - const booking = await regularBookingService.createBooking({ - bookingData: req.body, - bookingMeta: { - userId: session?.user?.id || -1, - hostname: req.headers.host || "", - forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, - }, - }); + if (!session?.user?.id) { + throw new Error("Unauthorized"); + } + const regularBookingService = getRegularBookingService(); + const booking = await regularBookingService.createBooking({ + bookingData: req.body, + bookingMeta: { + userId: session.user.id, + hostname: req.headers.host || "", + forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, + }, + });apps/web/pages/api/book/recurring-event.ts (1)
46-58: Sanitize bookingData, avoid sentinel -1, and pass hostname/forcedSlug.Strip cfToken before calling the service, don’t send -1 as userId, and include hostname/forcedSlug in bookingMeta.
const recurringBookingService = getRecurringBookingService(); - const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ - bookingData: req.body, + const bookingDataInput = req.body; + const sanitizedBookingData = Array.isArray(bookingDataInput) + ? bookingDataInput.map(({ cfToken, ...rest }) => rest) + : bookingDataInput; + const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ + bookingData: sanitizedBookingData, bookingMeta: { - userId: session?.user?.id || -1, + userId: session?.user?.id ?? undefined, + hostname: req.hostname, + forcedSlug: (req as any).forcedSlug, platformClientId: req.platformClientId, platformCancelUrl: req.platformCancelUrl, platformBookingUrl: req.platformBookingUrl, platformRescheduleUrl: req.platformRescheduleUrl, platformBookingLocation: req.platformBookingLocation, noEmail: req.noEmail, }, });packages/features/bookings/lib/create-instant-booking.ts (1)
9-11: Use transport type: serialize Date to string in HTTP response.HTTP returns ISO strings, not Date. Type the response accordingly.
const response = await post< BookingCreateBody, - // TODO: Fetch response can't have a Date type, it must be a string. We need to type expires as a string here but it breaks types down the line, fix it in a follow-up PR. - InstantBookingCreateResult + // transport DTO: expires serialized as string + (Omit<InstantBookingCreateResult, "expires"> & { expires: string }) >("/api/book/instant-event", data);apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (2)
456-458: LGTM: instant bookings now use the dedicated service.
501-513: noEmail omitted for recurring seated bookings — confirm intent.Regular/recurring paths include noEmail elsewhere; it’s missing here.
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (3)
110-117: LGTM: services injected via Nest DI.
194-207: LGTM: regular booking routed through service with bookingMeta (incl. forcedSlug, calendarEvents).
324-335: Recurring bookingMeta omits areCalendarEventsEnabled/noEmail — verify this is intentional.Behavior differs from regular bookings.
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
57-66: Round‑robin bug: first slot not added and series ID not seeded.You await firstBookingResult but don’t push it, and you don’t propagate thirdPartyRecurringEventId.
const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + // include the first slot + createdBookings.push(firstBookingResult); + // seed series id for subsequent slots + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + const ref = firstBookingResult.references.find((r) => r.thirdPartyRecurringEventId); + if (ref?.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = ref.thirdPartyRecurringEventId; + } + } + luckyUsers = firstBookingResult.luckyUsers;
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
376-383: Fix rejection assertion and payload shape
rejectsmust receive a Promise, not a function.- Payload should use
bookingMeta, not top-leveluserId.Apply:
- await expect( - async () => - await recurringBookingService.createBooking({ - bookingData: bookingDataArray, - userId: -1, - }) - ).rejects.toThrow(ErrorCode.NoAvailableUsersFound); + await expect( + recurringBookingService.createBooking({ + bookingData: bookingDataArray, + bookingMeta: { + userId: -1, + }, + }) + ).rejects.toThrow(ErrorCode.NoAvailableUsersFound);Also ensure
ErrorCodeis imported at the top:import { ErrorCode } from "@calcom/lib/errorCodes";apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
396-399: Config key mismatch for API key prefix (owner resolution may fail)Using different config keys for check vs strip can break API key auth.
- if (isApiKey(bearerToken, this.config.get<string>("api.apiKeyPrefix") ?? "cal_")) { - const strippedApiKey = stripApiKey(bearerToken, this.config.get<string>("api.keyPrefix")); + if (isApiKey(bearerToken, this.config.get<string>("api.apiKeyPrefix") ?? "cal_")) { + const strippedApiKey = stripApiKey( + bearerToken, + this.config.get<string>("api.apiKeyPrefix") ?? "cal_" + );packages/features/bookings/lib/handleNewBooking.ts (1)
1196-1202: Prisma: select only required fieldsPer guidelines, avoid fetching entire rows. Select organizationId only.
const organizerOrganizationProfile = await prisma.profile.findFirst({ where: { userId: organizerUser.id, username: dynamicUserList[0], }, + select: { organizationId: true }, });
🧹 Nitpick comments (12)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (1)
5-8: Optional: memoize the container import to avoid reloading per callIn tests this is fine, but you can cache the resolved service across calls to shave overhead.
You could keep the dynamic import (to avoid restricted-import linting and cycles) but memoize the instance:
// outside handler let regularBookingServiceSingleton: ReturnType<typeof getRegularBookingService> | null = null; async function handler(input: BookingHandlerInput) { if (!regularBookingServiceSingleton) { const { getRegularBookingService } = await import("@calcom/lib/di/bookings/containers/RegularBookingService.container"); regularBookingServiceSingleton = getRegularBookingService(); } const { bookingData, ...bookingMeta } = input; return regularBookingServiceSingleton.createBooking({ bookingData, bookingMeta }); }packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts (1)
41-41: Minor: avoid repeated handler creationConsider hoisting
const handleNewBooking = getNewBookingHandler();to a beforeEach to reuse within the suite.Also applies to: 101-101, 164-164, 225-225, 290-290
packages/features/instant-meeting/handleInstantMeeting.test.ts (1)
39-39: Minor: instantiate service once per suiteHoist
const instantBookingCreateService = getInstantBookingCreateService();to a beforeEach or the describe scope to avoid repeated container loads.Also applies to: 138-138
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
757-769: Call the explicit reschedule method for clarityFunctionally equivalent today, but
rescheduleBookingis clearer and future-proof if behaviors diverge.Apply:
- const booking = await this.regularBookingService.createBooking({ + const booking = await this.regularBookingService.rescheduleBooking({ bookingData: bookingRequest.body, bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, });packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
78-98: Intentional override — add a short inline commentConfirmed. extendedBookingCreateBody intentionally sets customInputs to z.undefined().optional() so internal flows prefer/new
responsesshape; bookingCreateBodySchemaForApi then reintroduces legacycustomInputsvia .merge(bookingCreateSchemaLegacyPropsForApi.partial()) (Zod merge gives precedence to the later shape). Add a short inline comment at packages/features/bookings/lib/bookingCreateBodySchema.ts (around the extendedBookingCreateBody and bookingCreateBodySchemaForApi merges) documenting this override and the Zod precedence to avoid regression.apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
209-214: Avoid awaiting fire-and-forget usage meteringIf non-blocking is intended, drop await inside void to prevent unnecessary latency.
- if (booking.userId && booking.uid && booking.startTime) { - void (await this.billingService.increaseUsageByUserId(booking.userId, { - uid: booking.uid, - startTime: booking.startTime, - fromReschedule: booking.fromReschedule, - })); - } + if (booking.userId && booking.uid && booking.startTime) { + void this.billingService.increaseUsageByUserId(booking.userId, { + uid: booking.uid, + startTime: booking.startTime, + fromReschedule: booking.fromReschedule, + }); + }
324-334: Prefer for...of over async forEach for metering loopforEach with async is not awaited and mixes control flow. Use for...of and drop inner await if fire-and-forget.
- createdBookings.forEach(async (booking) => { - if (booking.userId && booking.uid && booking.startTime) { - void (await this.billingService.increaseUsageByUserId(booking.userId, { - uid: booking.uid, - startTime: booking.startTime, - })); - } - }); + for (const booking of createdBookings) { + if (booking.userId && booking.uid && booking.startTime) { + void this.billingService.increaseUsageByUserId(booking.userId, { + uid: booking.uid, + startTime: booking.startTime, + }); + } + }Also applies to: 337-344
362-370: Instant booking: pass body only (good); drop await in fire-and-forget meteringService usage is correct; consider removing await inside void.
- void (await this.billingService.increaseUsageByUserId(instantMeeting.userId, { + void this.billingService.increaseUsageByUserId(instantMeeting.userId, { uid: instantMeeting.bookingUid, startTime: now, - })); + });Also applies to: 376-380
521-551: Unused helper createNextApiRecurringBookingRequestThis function isn’t used in this controller. Remove, or use it for the recurring endpoint for consistency.
packages/features/bookings/lib/handleNewBooking.ts (2)
789-807: Day.js in hot loopsMultiple dayjs.tz/utc calls in loops; cache formatted strings or precompute to reduce overhead.
Also applies to: 965-985
826-826: No-op property accesseventTypeWithUsers.users[0].credentials; has no effect. Remove.
- eventTypeWithUsers.users[0].credentials;packages/features/bookings/lib/dto/types.d.ts (1)
53-55: Decouple RegularBookingCreateResult from service method signatureDefine the result shape here to avoid cross-module type coupling; aligns with the TODO.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
✅ Files skipped from review due to trivial changes (1)
- apps/api/v2/src/lib/services/recurring-booking.service.ts
🚧 Files skipped from review as they are similar to previous changes (18)
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- apps/web/lib/types/booking.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- apps/api/v2/src/lib/modules/instant-booking.module.ts
- packages/features/bookings/lib/index.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- packages/features/bookings/lib/create-instant-booking.ts
- packages/features/instant-meeting/handleInstantMeeting.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- apps/api/v2/src/lib/modules/regular-booking.module.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- packages/features/bookings/types.ts
- apps/api/v2/src/lib/services/regular-booking.service.ts
- apps/web/pages/api/book/recurring-event.ts
- apps/web/pages/api/book/instant-event.ts
- packages/platform/libraries/bookings.ts
- apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/modules/RecurringBookingService.module.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/modules/RecurringBookingService.module.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/modules/RecurringBookingService.module.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/modules/RecurringBookingService.module.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/lib/di/bookings/modules/RegularBookingService.module.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/event.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/bookings/lib/handleNewBooking.tsapps/web/pages/api/book/event.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
🧬 Code graph analysis (15)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (2)
packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (2)
InstantBookingCreateService(18-18)instantBookingCreateServiceModule(7-7)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (2)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
RecurringBookingService(26-26)recurringBookingServiceModule(10-10)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts (1)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (1)
getNewBookingHandler(16-18)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/bookings/lib/handleNewBooking.ts (4)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
packages/features/instant-meeting/handleInstantMeeting.test.ts (1)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
packages/lib/di/bookings/modules/RegularBookingService.module.ts (11)
packages/lib/di/modules/Attribute.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Host.ts (1)
moduleLoader(18-21)packages/lib/di/modules/LuckyUser.ts (1)
moduleLoader(28-31)packages/lib/di/modules/Ooo.ts (1)
moduleLoader(18-21)packages/lib/di/modules/User.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Booking.ts (1)
moduleLoader(11-16)packages/lib/di/modules/Cache.ts (1)
moduleLoader(14-19)packages/lib/di/modules/CheckBookingAndDurationLimits.ts (1)
moduleLoader(14-19)packages/lib/di/modules/CheckBookingLimits.ts (1)
moduleLoader(13-18)packages/lib/di/modules/Features.ts (1)
moduleLoader(11-16)packages/prisma/prisma.module.ts (1)
moduleLoader(13-19)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (5)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/types.ts (1)
BookingResponse(98-98)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
apps/web/pages/api/book/event.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (2)
packages/features/bookings/lib/dto/types.d.ts (1)
BookingHandlerInput(40-42)packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(42-45)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (27)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (1)
4-13: Service-based handler LGTMSolid switch to RegularBookingService.createBooking with typed BookingHandlerInput and bookingMeta separation.
packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts (1)
22-23: Switch to getNewBookingHandler helper looks goodConsistent usage across tests; aligns with the service-based flow.
Also applies to: 41-41, 101-101, 164-164, 225-225, 290-290
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (2)
26-26: Container import LGTMgetRecurringBookingService usage matches the DI/container pattern.
155-162: BookingMeta wrapping and service call LGTMCorrectly passing
{ bookingData, bookingMeta: { userId: -1 } }tocreateBooking.packages/lib/di/bookings/modules/RecurringBookingService.module.ts (4)
1-25: DI module refactor LGTMThe bindModuleToClassOnToken usage and moduleLoader export are consistent with the new DI pattern.
8-10: Token wiring verified — RECURRING_BOOKING_SERVICE and RECURRING_BOOKING_SERVICE_MODULE exist in DI_TOKENS
Defined in packages/lib/di/bookings/tokens.ts (BOOKING_DI_TOKENS) and merged into DI_TOKENS via ...BOOKING_DI_TOKENS in packages/lib/di/tokens.ts.
12-20: Resolved — depsMap key 'regularBookingService' matches constructorIRecurringBookingServiceDependencies in packages/features/bookings/lib/handleNewRecurringBooking.ts declares regularBookingService and the module's depsMap uses the same key — no change required.
22-25: No action required — container already uses moduleLoaderpackages/lib/di/bookings/containers/RecurringBookingService.container.ts imports moduleLoader (aliased as recurringBookingServiceModule) and calls loadModule / uses token, so no change needed.
packages/features/instant-meeting/handleInstantMeeting.test.ts (1)
17-17: Instant booking service adoption LGTMCorrect switch to
getInstantBookingCreateService().createBooking({ bookingData })and assertions look good.Also applies to: 39-39, 113-115, 138-138, 194-198
packages/lib/di/bookings/modules/RegularBookingService.module.ts (3)
42-45: Module loader export shape looks consistentToken + loadModule shape matches other modules.
26-26: No change required —classsis the declared parameter name. bindModuleToClassOnToken defines and usesclasssin packages/lib/di/di.ts and other modules consistently reference it; no fix needed.
28-38: Verified — depsMap matches RegularBookingService constructor & IBookingServiceDependenciesIBookingServiceDependencies contains luckyUserService, hostRepository, oooRepository, userRepository, attributeRepository; depsMap and RegularBookingService constructor use the same keys (prisma is mapped from prismaWriteService.prisma). No action required.
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
10-12: Good switch to moduleLoader patternContainer uses
moduleLoader.loadModule+tokenconsistently.packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
60-76: Recurring partial schema extraction looks goodExplicit optional
endaligns with downstream usage.apps/web/pages/api/book/event.ts (1)
38-41: Don’t proceed with unauthenticated user; return 401 insteadAvoid passing
userId: -1. Short-circuit with 401 when session is missing.Apply:
- const booking = await regularBookingService.createBooking({ + if (!session?.user?.id) { + throw new Error("Unauthorized"); + } + const booking = await regularBookingService.createBooking({ bookingData: req.body, bookingMeta: { - userId: session?.user?.id || -1, + userId: session.user.id, hostname: req.headers.host || "", forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, }, });packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
10-13: ModuleLoader usage is consistentMatches the pattern used by other containers.
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (2)
501-513: noEmail omitted for recurring seated flow (intentional?)This differs from recurring non-seated where
noEmailis passed. If that was intentional per existing behavior, ignore; otherwise, include it for parity.
111-115: No action needed — services are provided via imported modulesbookings.module.ts imports RegularBookingModule, RecurringBookingModule and InstantBookingModule which export RegularBookingService, RecurringBookingService and InstantBookingCreateService respectively (see apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts and apps/api/v2/src/lib/modules/{regular-booking.module.ts,recurring-booking.module.ts,instant-booking.module.ts}).
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
100-107: LGTM on passing bookingMeta to serviceConsistent with the new service contract.
57-66: Bug: first round‑robin slot result is dropped and series ID not seededYou await the first booking but don’t push it to
createdBookingsor seedthirdPartyRecurringEventId, returning N‑1 results and risking broken series linkage.Fix:
const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + // include first slot and propagate series id for subsequent slots + createdBookings.push(firstBookingResult); + // seed third-party recurring series id if available + if ( + !thirdPartyRecurringEventId && + firstBookingResult.references && + firstBookingResult.references.length > 0 + ) { + for (const reference of firstBookingResult.references) { + if (reference.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = reference.thirdPartyRecurringEventId; + break; + } + } + } + luckyUsers = firstBookingResult.luckyUsers;apps/api/v1/pages/api/bookings/_post.ts (1)
242-252: LGTM — bookingDataSchemaGetter returns the API schemagetBookingDataSchemaForApi composes the API-specific zod schema (imports bookingCreateBodySchemaForApi / bookingCreateSchemaLegacyPropsForApi), so passing it as bookingDataSchemaGetter into createBookingForApiV1 is correct.
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (2)
110-117: DI services wiring looks correctConstructor injects the three booking services and UsersService as expected for the refactor.
194-207: LGTM: bookingMeta consolidation for regular bookingsPassing hostname, forcedSlug, platform params, and areCalendarEventsEnabled under bookingMeta is consistent with the new service API.
packages/features/bookings/lib/handleNewBooking.ts (2)
1608-1613: Use parsed bookerEmail/phoneNumber for attendee matching (not bookingData.responses)- const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + const currentAttendee = booking.attendees.find( + (attendee) => + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );
2425-2431: Spreading possibly undefined bookingMeta throws at runtimeObject spread of undefined/null will crash. Default before spreading.
async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); } async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); }packages/features/bookings/lib/dto/types.d.ts (2)
6-8: Correct: SchedulingType import addedResolves the reference in CreateRecurringBookingData.
44-52: Accepting existing API Date serialization for expiresKeeping expires as Date in domain type is fine; transport can address string conversion later.
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
Outdated
Show resolved
Hide resolved
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
45-66: Critical: First booking result not added to createdBookings array.When
isRoundRobinis true, the first booking is created but never added to thecreatedBookingsarray. This will cause the function to return N-1 results instead of N, and the first booking won't be included in the response.Apply this fix to include the first booking result:
const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); + createdBookings.push(firstBookingResult); luckyUsers = firstBookingResult.luckyUsers; + + // Extract the third-party recurring event ID from the first booking + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + const ref = firstBookingResult.references.find((r) => r.thirdPartyRecurringEventId); + if (ref?.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = ref.thirdPartyRecurringEventId; + } + }
🧹 Nitpick comments (2)
apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
64-66: Consider re-exporting these modules if downstream modules need their providers transitivelyIf other modules import BookingsModule_2024_08_13 and expect these providers without importing the lib modules directly, add them to this module’s exports. Otherwise, current setup is fine.
Would you like to make them available transitively? If yes, update the exports as below:
@@ controllers: [BookingsController_2024_08_13], - exports: [InputBookingsService_2024_08_13, OutputBookingsService_2024_08_13, BookingsService_2024_08_13], + exports: [ + InputBookingsService_2024_08_13, + OutputBookingsService_2024_08_13, + BookingsService_2024_08_13, + RegularBookingModule, + RecurringBookingModule, + InstantBookingModule, + ],apps/api/v1/pages/api/bookings/_post.ts (1)
242-243: Optional: hoist service initialization to module scope to avoid per-request loadIf
getRegularBookingService()and its deps are safe to reuse across requests, initialize once at module scope to reduce per-request overhead. Keep as-is if per-request scoping is intentional.Module-scope snippet to consider:
// at module scope const regularBookingService = getRegularBookingService(); // inside handler: reuse the instance // const regularBookingService = getRegularBookingService();
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (22)
- apps/web/lib/types/booking.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- apps/api/v2/src/lib/modules/instant-booking.module.ts
- packages/features/bookings/lib/index.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- packages/features/bookings/types.ts
- apps/api/v2/src/lib/services/regular-booking.service.ts
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- apps/api/v2/src/lib/modules/regular-booking.module.ts
- packages/platform/libraries/bookings.ts
- packages/features/bookings/lib/bookingCreateBodySchema.ts
- apps/web/pages/api/book/instant-event.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- packages/lib/di/bookings/containers/RecurringBookingService.container.ts
- packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- packages/features/bookings/lib/create-instant-booking.ts
- packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
- apps/web/pages/api/book/event.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/lib/di/bookings/modules/RegularBookingService.module.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/lib/di/bookings/modules/RegularBookingService.module.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/lib/di/bookings/modules/RegularBookingService.module.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/lib/services/recurring-booking.service.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/lib/di/bookings/modules/RegularBookingService.module.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/modules/RegularBookingService.module.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
🧬 Code graph analysis (12)
packages/lib/di/bookings/modules/RegularBookingService.module.ts (7)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
moduleLoader(19-22)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
moduleLoader(22-25)packages/lib/di/modules/Attribute.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Ooo.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Host.ts (1)
moduleLoader(18-21)packages/lib/di/modules/LuckyUser.ts (1)
moduleLoader(28-31)packages/lib/di/modules/User.ts (1)
moduleLoader(18-21)
apps/api/v2/src/lib/services/recurring-booking.service.ts (2)
apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(42-45)
apps/web/pages/api/book/recurring-event.ts (3)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(44-51)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
packages/features/bookings/lib/handleNewBooking.ts (4)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (4)
packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
moduleLoader(22-25)
packages/features/bookings/lib/dto/types.d.ts (4)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/platform/libraries/bookings.ts (3)
InstantBookingCreateResult(9-9)RegularBookingCreateResult(10-10)RegularBookingService(5-5)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
RegularBookingService(47-47)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: Production builds / Build Docs
- GitHub Check: Production builds / Build Web App
- GitHub Check: Production builds / Build API v2
- GitHub Check: Production builds / Build API v1
- GitHub Check: Tests / Unit
- GitHub Check: Production builds / Build Atoms
- GitHub Check: Type check / check-types
- GitHub Check: Linters / lint
🔇 Additional comments (29)
apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
19-21: Booking modules wiring OK — providers exported and no DI cycle foundInstantBookingModule exports InstantBookingCreateService; RecurringBookingModule exports RecurringBookingService (and imports RegularBookingModule); RegularBookingModule exports RegularBookingService. No references to BookingsModule_2024_08_13 found in those modules.
apps/api/v1/pages/api/bookings/_post.ts (1)
4-4: Good move: switch to DI container for booking serviceThis aligns this route with the new service-based flow and keeps concerns out of the handler.
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (2)
1-1: LGTM! Clean DI module migration.The migration to the moduleLoader pattern is well-implemented. The module correctly implements the pattern established across other booking modules, with consistent token/loadModule structure.
15-15: Empty depsMap is correct for InstantBookingCreateService. The class declares no constructor or DI dependencies (see packages/features/instant-meeting/handleInstantMeeting.ts), so depsMap: {} is valid.packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
127-129: Well-structured dependency interface.The
IRecurringBookingServiceDependenciesinterface properly defines the dependency onRegularBookingService, maintaining clean separation of concerns and enabling proper dependency injection.apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
1-13: LGTM! Clean NestJS service implementation.The service correctly extends the base RecurringBookingService and properly wires the RegularBookingService dependency through the constructor. The implementation follows NestJS patterns and maintains proper dependency injection.
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
1-26: LGTM! Consistent moduleLoader implementation.The module properly implements the moduleLoader pattern with correct dependency wiring to RegularBookingService. The implementation is consistent with other booking modules.
packages/lib/di/bookings/modules/RegularBookingService.module.ts (2)
42-45: Module export naming is consistent.The change from
regularBookingServiceModuletomoduleLoaderaligns with the pattern established across all other DI modules in the codebase, improving consistency.
27-39: DepsMap matches updated IBookingServiceDependenciesIBookingServiceDependencies (packages/features/bookings/lib/handleNewBooking.ts:414-426) defines the 11 properties; depsMap in packages/lib/di/bookings/modules/RegularBookingService.module.ts:27-39 matches them.
apps/web/pages/api/book/recurring-event.ts (1)
47-58: Sanitize bookingData, avoid sentinel userId, and include hostname/forcedSlugSeveral issues need to be addressed based on the past review comments:
- The
cfTokenfield should be removed fromreq.bodybefore passing it tocreateBooking- Change
userId: session?.user?.id || -1touserId: session?.user?.id ?? undefinedto avoid sentinel values- Add
hostname: req.hostnameandforcedSlug: req.forcedSlugto thebookingMetaobjectApply this diff to address these issues:
+ const bookingDataInput = req.body; + const sanitizedBookingData = Array.isArray(bookingDataInput) + ? bookingDataInput.map(({ cfToken, ...rest }) => rest) + : (() => { + const { cfToken, ...rest } = (bookingDataInput ?? {}) as Record<string, unknown>; + return rest; + })(); + const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ - bookingData: req.body, + bookingData: sanitizedBookingData, bookingMeta: { - userId: session?.user?.id || -1, + userId: session?.user?.id ?? undefined, + hostname: req.hostname, + forcedSlug: req.forcedSlug, platformClientId: req.platformClientId, platformCancelUrl: req.platformCancelUrl, platformBookingUrl: req.platformBookingUrl, platformRescheduleUrl: req.platformRescheduleUrl, platformBookingLocation: req.platformBookingLocation, noEmail: req.noEmail, }, });packages/features/instant-meeting/handleInstantMeeting.ts (2)
158-158: LGTM! Clean function signature updateThe handler function now accepts only
bookingDataparameter, which is correctly typed asCreateInstantBookingData. This aligns well with the service-based approach where instant meetings need only the booking data without additional metadata.
339-341: LGTM! Service implementation follows DI pattern correctlyThe
InstantBookingCreateServicecorrectly implementsIBookingCreateServiceand delegates to the internal handler with proper input extraction. The signature is clean and consistent with other booking services.apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
111-116: LGTM! Service dependencies properly injectedThe new booking services are correctly injected as private readonly dependencies. This follows NestJS DI patterns and provides clean separation between the API service and the underlying booking logic.
456-458: LGTM! Instant booking service integrationThe instant booking service is correctly used with only
bookingData, which matches the simplified signature for instant bookings that don't require additional metadata.
476-489: Consistent bookingMeta construction across booking flowsThe
bookingMetaconstruction is consistent with other booking flows in this service, including all necessary platform parameters and settings. The metadata properly includesareCalendarEventsEnabledand other platform-specific configurations.apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (5)
10-12: LGTM! Service imports correctly updatedThe new service imports replace the legacy handler imports cleanly. The service-based approach provides better separation of concerns and enables proper DI.
113-116: LGTM! Constructor dependencies properly injectedThe booking services are correctly injected as constructor dependencies following NestJS patterns. This enables proper DI and testing.
194-207: LGTM! RegularBookingService integration with proper metadataThe service is correctly used with both
bookingDataandbookingMeta. The metadata includes all necessary fields likeuserId,hostname,forcedSlug, and platform-specific configurations. The structure matches the expected service interface.
324-335: Note: Existing behavior preserved for recurring bookingsThe recurring booking service omits
forcedSlug,areCalendarEventsEnabled, andnoEmailfrom thebookingMeta, which differs from regular bookings. Based on maintainer feedback, this reflects existing behavior and is intentional.
368-370: LGTM! InstantBookingCreateService correctly integratedThe instant booking service correctly uses only
bookingDatawithoutbookingMeta, matching the simplified interface for instant bookings. The return type is properly typed asInstantBookingCreateResult.packages/features/bookings/lib/handleNewBooking.ts (5)
414-426: LGTM! Comprehensive dependency interface for DIThe
IBookingServiceDependenciesinterface properly defines all the dependencies needed by the booking service. The interface includes all necessary repositories, services, and clients required for booking operations.
428-432: LGTM! Handler signature updated for DI supportThe handler now accepts
depsparameter of typeIBookingServiceDependencies, enabling proper dependency injection. The signature is clean and maintains backward compatibility with the optionalbookingDataSchemaGetter.
446-452: LGTM! Dependencies destructured from injected depsThe dependencies are properly extracted from the
depsparameter, replacing the previous direct service instantiation pattern. This enables proper testing and DI.
2425-2427: Fix: Guard against undefined bookingMetaThe spread of
input.bookingMetacan throw at runtime if it's undefined. Use nullish coalescing to provide a safe default.Apply this fix:
async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + return handler({ bookingData: input.bookingData, ...(input.bookingMeta ?? {}) }, this.deps); }Also apply the same fix to
rescheduleBookingat lines 2429-2431.
2436-2450: LGTM! Deprecated API v1 method with proper handlingThe
createBookingForApiV1method is properly marked as deprecated and safely handles the optionalbookingMetaparameter. The method will be removed when API v1 is deprecated, providing a clean migration path.packages/features/bookings/lib/dto/types.d.ts (4)
1-4: LGTM! Clear documentation for domain typesThe comment clearly indicates these are framework-agnostic domain types for booking services, which aligns well with the DI architecture.
15-21: LGTM! Consistent data types using ExtendedBookingCreateBodyAll booking data types now consistently use
ExtendedBookingCreateBodyas the base, providing type safety and consistency across regular, instant, and recurring bookings. The recurring booking data properly extends withschedulingTypeas needed.
44-51: LGTM! InstantBookingCreateResult type properly definedThe type correctly defines the instant booking result structure with appropriate field types. The
expiresfield asDateis consistent with the domain model, and serialization concerns are appropriately handled at API boundaries.
53-54: LGTM! RegularBookingCreateResult inferred from serviceUsing
Awaited<ReturnType<>>ensures type safety and keeps the result type synchronized with the actual service implementation. The TODO note indicates future consolidation plans.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
73-90: Bug: promises from webhook dispatch aren’t returned, so Promise.all doesn’t wait.
The map callback doesn’t return the promise;Promise.all(promises)resolves immediately and doesn’t truly await webhook calls.Apply this diff to return the promises so awaiting works as intended:
- const promises = subscribers.map((sub) => { - sendGenericWebhookPayload({ + const promises = subscribers.map((sub) => { + return sendGenericWebhookPayload({ secretKey: sub.secret, triggerEvent: eventTrigger, createdAt: new Date().toISOString(), webhook: sub, data: webhookData, - }).catch((e) => { + }).catch((e) => { console.error( `Error executing webhook for event: ${eventTrigger}, URL: ${sub.subscriberUrl}`, sub, e ); - }); + }); }); await Promise.all(promises);Alternatively, drop the per-call catch and use
Promise.allSettled(promises)to avoid short-circuiting on one failure.
258-263: Use Prisma select instead of include; and select only needed fields.
Per repo guidelines, avoidinclude. Also, attendees aren’t used later, so fetching them is wasted I/O.Apply this diff:
- const createBookingObj = { - include: { - attendees: true, - }, - data: newBookingData, - }; + const createBookingObj = { + select: { + id: true, + uid: true, + userId: true, + responses: true, + customInputs: true, + title: true, + }, + data: newBookingData, + };packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
29-33: Guard against empty bookingDataAccessing data[0] will throw when bookingData is empty. Add an explicit check.
Apply:
// for round robin, the first slot needs to be handled first to define the lucky user - const firstBooking = data[0]; + if (data.length === 0) { + throw new Error("bookingData must contain at least one slot for recurring booking"); + } + const firstBooking = data[0];
🧹 Nitpick comments (11)
packages/features/instant-meeting/handleInstantMeeting.ts (1)
132-137: Guard JSON.parse to avoid throwing for malformed subscriptions.
A malformed DB value will throw before Zod validation and break the whole notification fanout.Apply this diff:
- const parsedSubscription = subscriptionSchema.safeParse(JSON.parse(subscription)); + let raw; + try { + raw = JSON.parse(subscription); + } catch (e) { + logger.error("Invalid subscription JSON", { error: String(e) }); + return Promise.resolve(); + } + const parsedSubscription = subscriptionSchema.safeParse(raw);packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts (4)
33-35: Use resetAllMocks to avoid leaking stubbed implementations across testsclearAllMocks resets call history only; resetAllMocks also resets mock implementations, preventing cross-test coupling.
Apply:
- beforeEach(() => { - vi.clearAllMocks(); - }); + beforeEach(() => { + vi.resetAllMocks(); + });
86-91: Prefer rejects.toMatchObject for object property assertionstoThrow is intended for message/class matching. Use toMatchObject to assert error object shape.
- await expect(handleNewBooking({ bookingData: mockBookingData })).rejects.toThrow( - expect.objectContaining({ - statusCode: 400, - message: "email_verification_required", - }) - ); + await expect(handleNewBooking({ bookingData: mockBookingData })).rejects.toMatchObject({ + statusCode: 400, + message: "email_verification_required", + });
149-154: Use rejects.toMatchObject to assert error detailsImproves correctness over toThrow with asymmetric matchers.
- await expect(handleNewBooking({ bookingData: mockBookingData })).rejects.toThrow( - expect.objectContaining({ - statusCode: 400, - message: "invalid_verification_code", - }) - ); + await expect(handleNewBooking({ bookingData: mockBookingData })).rejects.toMatchObject({ + statusCode: 400, + message: "invalid_verification_code", + });
275-280: Use rejects.toMatchObject for rate limit mapping assertionEnsures robust matching of the mapped error object.
- await expect(handleNewBooking({ bookingData: mockBookingData })).rejects.toThrow( - expect.objectContaining({ - statusCode: 400, - message: "invalid_verification_code", - }) - ); + await expect(handleNewBooking({ bookingData: mockBookingData })).rejects.toMatchObject({ + statusCode: 400, + message: "invalid_verification_code", + });apps/api/v2/src/lib/services/instant-booking-create.service.ts (1)
1-6: Nest wrapper over platform service — OKThin injectable wrapper is appropriate for Nest DI.
If/when introducing method overrides or logging, consider adding a constructor with DI-injected logger for parity with other services.
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
79-98: Avoid shadowing customInputs unless strictly requiredDefining
customInputs: z.undefined().optional()inextendedBookingCreateBodythen overriding it inbookingCreateBodySchemaForApiworks, but is slightly surprising. If the goal is to bancustomInputsexcept for API, consider omitting it here entirely and documenting that only the API merge adds it.luckyUsers: z.array(z.number()).optional(), - customInputs: z.undefined().optional(), }) .merge(recurringBookingCreateBodyPartialSchema)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
476-489: Avoid empty-string hostname; prefer undefined/nullish when absentPassing
""can be misinterpreted downstream. Useundefinedif header is missing.bookingMeta: { userId: bookingRequest.userId, - hostname: bookingRequest.headers?.host || "", + hostname: bookingRequest.headers?.host, platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
337-344: Avoid async forEach with awaited callsThe current pattern makes the awaits inside callbacks meaningless and surprising. Either fire-and-forget without await or await deterministically.
Apply (fire-and-forget, sequential iteration):
- createdBookings.forEach(async (booking) => { - if (booking.userId && booking.uid && booking.startTime) { - void (await this.billingService.increaseUsageByUserId(booking.userId, { - uid: booking.uid, - startTime: booking.startTime, - })); - } - }); + for (const booking of createdBookings) { + if (booking.userId && booking.uid && booking.startTime) { + void this.billingService.increaseUsageByUserId(booking.userId, { + uid: booking.uid, + startTime: booking.startTime, + }); + } + }packages/lib/di/bookings/modules/RegularBookingService.module.ts (2)
8-9: Remove unnecessaryno-restricted-importsdisable (likely redundant).The import is from our DI modules namespace and shouldn’t be restricted. Prefer removing the disable unless there’s a specific rule violation.
Apply:
-// eslint-disable-next-line no-restricted-imports import { moduleLoader as featuresRepositoryModuleLoader } from "@calcom/lib/di/modules/Features";If lint still fails after removal, keep the disable and add a brief reason.
42-45: Type the exported moduleLoader for consistency with other modules.Adds compile-time checks and aligns with Attribute/Host/User/etc. modules.
Apply:
-export const moduleLoader = { +export const moduleLoader: ModuleLoader = { token, loadModule, };Also import the type (adjust if your DI types are exported elsewhere):
// At the existing import from "../../di" import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "../../di";
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (20)
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- apps/api/v2/src/lib/services/recurring-booking.service.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- apps/api/v1/pages/api/bookings/_post.ts
- apps/api/v2/src/lib/modules/regular-booking.module.ts
- apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- apps/api/v2/src/lib/modules/instant-booking.module.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- packages/platform/libraries/bookings.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- packages/features/bookings/lib/create-instant-booking.ts
- packages/lib/di/bookings/modules/RecurringBookingService.module.ts
- apps/web/pages/api/book/event.ts
- apps/web/lib/types/booking.ts
- packages/features/bookings/lib/index.ts
- packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- packages/lib/di/bookings/containers/RecurringBookingService.container.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/lib/di/bookings/modules/RegularBookingService.module.tsapps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/web/pages/api/book/recurring-event.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/lib/di/bookings/modules/RegularBookingService.module.tsapps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/web/pages/api/book/recurring-event.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/lib/di/bookings/modules/RegularBookingService.module.tsapps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/web/pages/api/book/recurring-event.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/services/regular-booking.service.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/lib/di/bookings/modules/RegularBookingService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/types.tspackages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/web/pages/api/book/recurring-event.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/modules/RegularBookingService.module.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/dto/types.d.tspackages/features/instant-meeting/handleInstantMeeting.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
🧬 Code graph analysis (14)
packages/lib/di/bookings/modules/RegularBookingService.module.ts (8)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
moduleLoader(19-22)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
moduleLoader(22-25)packages/lib/di/modules/Attribute.ts (1)
moduleLoader(18-21)packages/lib/di/modules/LuckyUser.ts (1)
moduleLoader(28-31)packages/lib/di/modules/Ooo.ts (1)
moduleLoader(18-21)packages/lib/di/modules/User.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Host.ts (1)
moduleLoader(18-21)packages/prisma/prisma.module.ts (1)
moduleLoader(13-19)
apps/api/v2/src/lib/services/instant-booking-create.service.ts (5)
apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
Injectable(6-13)apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
InstantBookingCreateService(18-18)packages/platform/libraries/bookings.ts (1)
InstantBookingCreateService(7-7)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/web/pages/api/book/instant-event.ts (1)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
packages/features/bookings/types.ts (2)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(54-54)
packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts (1)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (1)
getNewBookingHandler(16-18)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (2)
InstantBookingCreateService(18-18)instantBookingCreateServiceModule(7-7)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
apps/web/pages/api/book/recurring-event.ts (3)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)packages/features/bookings/types.ts (1)
BookingResponse(98-98)packages/features/auth/lib/next-auth-options.ts (1)
session(746-771)
apps/api/v2/src/lib/services/regular-booking.service.ts (2)
apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
Injectable(6-13)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(44-51)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
packages/features/bookings/lib/handleNewBooking.ts (5)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
🔇 Additional comments (50)
packages/features/instant-meeting/handleInstantMeeting.ts (5)
5-5: Import of Cal Video client looks correct.
No issues spotted with this import change.
9-10: Type migration to InstantBookingCreateResult is sound.
Ensure downstream call sites expect the new result shape.
158-158: Internal handler rename is fine.
Signature and usage look consistent with the service wrapper.
332-332: Good: compile-time check with satisfies InstantBookingCreateResult.
Keeps the return payload aligned with the public contract.
339-341: Service method signature and delegation look correct.
Typed input/output and reuse of handler are appropriate.packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts (6)
41-41: Per-test handler retrieval — OKCreating/getting the handler per test is fine and keeps DI state isolated.
101-101: Per-test handler retrieval — OKConsistent with the new helper pattern.
165-165: Per-test handler retrieval — OKMatches the migration approach used elsewhere in the suite.
225-225: Per-test handler retrieval — OKNo issues.
290-290: Per-test handler retrieval — OKConsistent and clear.
22-23: DI-backed handler import — LGTMConfirmed: getNewBookingHandler imports getRegularBookingService and the returned handler delegates to regularBookingService.createBooking({ bookingData, bookingMeta }).
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
4-11: Verify moduleLoader export and container lifecycleConfirm that InstantBookingCreateService.module exports
moduleLoaderandtokenas used here, and that repeatedloadModule(container)calls are idempotent with the singletoncontainer.apps/web/pages/api/book/instant-event.ts (2)
5-5: Import switch to DI container looks good
23-28: Service-based instant booking call — looks goodClean replacement of the legacy handler with
createBooking({ bookingData }).Please verify that
CreateInstantBookingDataschema includescreationSourceor treats it as optional so the runtime validation passes unchanged.packages/features/bookings/lib/bookingCreateBodySchema.ts (2)
60-76: Recurring partial schema extraction is a good moveThis improves reuse and keeps the base schema lean.
100-101: Type export LGTM
ExtendedBookingCreateBodybased onz.inputis consistent with consumer-side input types.packages/features/bookings/types.ts (2)
3-4: Type import updates look correctUsing
RegularBookingCreateResultaligns app/web with the new service flow.
97-99: Alias BookingResponse to RegularBookingCreateResult — OKThis minimizes churn while moving to the new naming.
Confirm all downstream imports of
BookingResponseare type-only and do not rely on removedInstantBookingResponse.apps/web/pages/api/book/recurring-event.ts (2)
6-6: DI import for recurring service — OK
46-58: Don’t pass sentinel -1; include host context; strip cfToken from bookingDataPassing
-1risks leaking a sentinel into downstream logic. Also, includehostname/forcedSlugif present, and avoid forwardingcfTokeninbookingData.const recurringBookingService = getRecurringBookingService(); const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ - bookingData: req.body, + bookingData: Array.isArray(req.body) ? req.body.map(({ cfToken, ...rest }) => rest) : req.body, bookingMeta: { - userId: session?.user?.id || -1, + userId: session?.user?.id ?? undefined, + hostname: (req as any).hostname ?? req.headers?.host, + forcedSlug: (req as any).forcedSlug, platformClientId: req.platformClientId, platformCancelUrl: req.platformCancelUrl, platformBookingUrl: req.platformBookingUrl, platformRescheduleUrl: req.platformRescheduleUrl, platformBookingLocation: req.platformBookingLocation, noEmail: req.noEmail, }, });Please confirm
forcedSlugis present on this request type in all callers; if not, omit it or gate it.apps/api/v2/src/lib/services/regular-booking.service.ts (1)
1-46: Nest RegularBookingService wiring looks correctDependencies mirror the platform service’s expected deps; Prisma client is correctly sourced from
PrismaWriteService.apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (7)
9-11: Importing new booking services — OK
111-115: Constructor DI additions — OKServices injected here match usage below.
455-458: Instant booking via service — LGTM
501-513: Add noEmail for recurring seated flowOther flows pass
noEmail; recur-seated should too for consistency.bookingMeta: { userId: bookingRequest.userId, - hostname: bookingRequest.headers?.host || "", + hostname: bookingRequest.headers?.host, platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
526-538: Add noEmail for regular booking metaBring this in line with recurring flow’s meta to control email delivery.
bookingMeta: { userId: bookingRequest.userId, - hostname: bookingRequest.headers?.host || "", + hostname: bookingRequest.headers?.host, platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
560-572: Add noEmail for seated booking metaMaintain consistent email toggling across flows.
bookingMeta: { userId: bookingRequest.userId, - hostname: bookingRequest.headers?.host || "", + hostname: bookingRequest.headers?.host, platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
757-769: Consider passing noEmail on reschedule as wellIf reschedules should suppress emails in some contexts, thread
noEmailthrough here too. Otherwise, explicitly document why it’s omitted.bookingMeta: { userId: bookingRequest.userId, - hostname: bookingRequest.headers?.host || "", + hostname: bookingRequest.headers?.host, platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },Please confirm expected behavior for reschedule email notifications; if emails must always fire on reschedule, keep it omitted.
packages/features/bookings/lib/handleNewRecurringBooking.ts (3)
13-16: Signature refactor looks goodDI via deps is clear and contained.
20-21: Type tightening for recurring dates is correctstart as string and end as string | undefined aligns with downstream usage.
57-66: Round-robin: first result not added and series ID not propagatedYou don’t push the firstBookingResult to createdBookings and you don’t seed thirdPartyRecurringEventId from it. This returns N-1 results and may break series linkage for subsequent slots.
Apply:
const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + // include first slot and propagate series id for subsequent slots + createdBookings.push(firstBookingResult); + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + const ref = firstBookingResult.references.find((r) => r.thirdPartyRecurringEventId); + if (ref?.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = ref.thirdPartyRecurringEventId; + } + } + luckyUsers = firstBookingResult.luckyUsers;apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
10-12: Service imports aligned with DIUsing InstantBookingCreateService, RecurringBookingService, RegularBookingService is consistent with the new flow.
113-117: Constructor injection looks correctAll three services are injected and used in handlers.
194-207: Pass-through bookingMeta is completeareCalendarEventsEnabled included; matches regular booking path requirements.
362-371: Instant booking flow is correctPassing only bookingData to the service matches the new contract.
packages/features/bookings/lib/handleNewBooking.ts (8)
24-28: Public types import is appropriateGood move to centralized DTOs and handler input types.
414-426: Deps surface is comprehensiveInterface covers all needed collaborators for DI.
430-452: Handler now DI-drivenPassing deps in is a solid refactor and removes hidden singletons.
555-556: Boolean coercion is correctEnsures isFirstRecurringSlot is a boolean when present.
789-793: Recurring availability checks gated properlyNullish-safe checks for recurring context avoid runtime errors.
1610-1613: Use parsed bookerEmail/Phone for attendee matching (not bookingData.responses)Apply:
- const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + const currentAttendee = booking.attendees.find( + (attendee) => + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );
2441-2449: Good: guarded spread for API v1 pathbookingMeta defaulting avoids runtime errors here.
2425-2431: Bug: spreading possibly undefined bookingMeta throws{ ...input.bookingMeta } will crash when bookingMeta is undefined. Default it.
Apply:
async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); } async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); }packages/features/bookings/lib/dto/types.d.ts (4)
7-8: Fix for missing SchedulingType importImporting as type resolves earlier TS error.
15-22: Type aliases read wellCreateRegular/Instant map to ExtendedBookingCreateBody; recurring extends for schedulingType — consistent with usage.
44-52: InstantBookingCreateResult export is coherentFields/types align with feature code; domain-level Date is acceptable here.
53-55: RegularBookingCreateResult alias is fineKeeps consumers in sync with service return type.
packages/lib/di/bookings/modules/RegularBookingService.module.ts (3)
1-2: Scoped ESLint disable is fine here.Using the service class directly for DI wiring is consistent with the pattern. Scoped to a single import — LGTM.
3-3: New DI module loaders look correct — exports verified.
Confirmedexport const moduleLoaderexists in packages/lib/di/modules/Attribute.ts, Host.ts, LuckyUser.ts, Ooo.ts, User.ts.
34-39: Verified — IBookingServiceDependencies contains the new keys.All of luckyUserService, hostRepository, oooRepository, userRepository and attributeRepository are present in packages/features/bookings/lib/handleNewBooking.ts.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
packages/features/bookings/lib/handleNewBooking.ts (1)
1545-1546: Use injected UsersRepository instead of instantiating a new oneBypassing DI may use a different Prisma/logging context and breaks testability.
Apply this diff:
- if (booking?.userId) { - const usersRepository = new UsersRepository(); - await usersRepository.updateLastActiveAt(booking.userId); + if (booking?.userId) { + await deps.userRepository.updateLastActiveAt(booking.userId);packages/features/instant-meeting/handleInstantMeeting.ts (4)
73-90: Fix: return promises from map and avoid logging secretsThe promises aren’t returned from the map callback, so
Promise.allresolves immediately. Also, loggingsubleaks the webhook secret. Return the promise and log a sanitized subset; preferPromise.allSettledsince each call already catches errors.- const promises = subscribers.map((sub) => { - sendGenericWebhookPayload({ - secretKey: sub.secret, - triggerEvent: eventTrigger, - createdAt: new Date().toISOString(), - webhook: sub, - data: webhookData, - }).catch((e) => { - console.error( - `Error executing webhook for event: ${eventTrigger}, URL: ${sub.subscriberUrl}`, - sub, - e - ); - }); - }); - - await Promise.all(promises); + const promises = subscribers.map((sub) => { + const webhook = { + id: sub.id, + subscriberUrl: sub.subscriberUrl, + payloadTemplate: sub.payloadTemplate, + appId: sub.appId, + }; + return sendGenericWebhookPayload({ + secretKey: sub.secret, + triggerEvent: eventTrigger, + createdAt: new Date().toISOString(), + webhook, + data: webhookData, + }).catch((e) => { + logger.error( + `Error executing webhook for event: ${eventTrigger}, URL: ${sub.subscriberUrl}`, + { id: sub.id, url: sub.subscriberUrl, error: (e as Error)?.message } + ); + }); + }); + + await Promise.allSettled(promises);
258-266: Prisma: replace include with select (avoid returning unneeded data)Per guidelines, don’t use include; select only required fields.
- const createBookingObj = { - include: { - attendees: true, - }, - data: newBookingData, - }; + const createBookingObj = { + data: newBookingData, + select: { + id: true, + uid: true, + responses: true, + customInputs: true, + title: true, + userId: true, + }, + };
283-300: Prisma: select only needed fields from instantMeetingToken.createYou only use id and expires; restrict the return.
- const instantMeetingToken = await prisma.instantMeetingToken.create({ - data: { + const instantMeetingToken = await prisma.instantMeetingToken.create({ + data: { token, // current time + offset Seconds expires: new Date(new Date().getTime() + 1000 * instantMeetingExpiryTimeOffsetInSeconds), team: { connect: { id: eventType.team.id, }, }, booking: { connect: { id: newBooking.id, }, }, updatedAt: new Date().toISOString(), - }, - }); + }, + select: { id: true, expires: true }, + });
298-299: Remove manual updatedAt on InstantMeetingToken creationpackages/prisma/schema.prisma: InstantMeetingToken.updatedAt is declared DateTime @updatedat — Prisma manages this field; remove the manually set updatedAt from the create call in packages/features/instant-meeting/handleInstantMeeting.ts (line ~298).
🧹 Nitpick comments (11)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts (1)
134-134: Reduce repetition with a local alias for the response typeDefine a local alias once and use it across tests to cut noise and ease future renames.
Add near the imports (outside selected range):
type RegularBookingResponse = ApiSuccessResponse<RegularBookingCreateResult>;Then apply this change here:
-const responseBody: ApiSuccessResponse<RegularBookingCreateResult> = response.body; +const responseBody: RegularBookingResponse = response.body;You can apply the same replacement at Lines 233, 290, and 387.
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
10-11: Avoid re-loading the module on every call (make load idempotent).Repeated loadModule calls can rebind providers if the container doesn’t guard by moduleToken. Guard the load with a local “loaded” flag.
Apply this diff:
const container = createContainer(); export function getInstantBookingCreateService(): InstantBookingCreateService { - instantBookingCreateServiceModule.loadModule(container); + // Ensure we only bind once per process + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const anyContainer = container as any; + anyContainer.__instantBookingCreateServiceLoaded ||= false; + if (!anyContainer.__instantBookingCreateServiceLoaded) { + instantBookingCreateServiceModule.loadModule(container); + anyContainer.__instantBookingCreateServiceLoaded = true; + } return container.get<InstantBookingCreateService>(instantBookingCreateServiceModule.token); }apps/web/pages/api/book/instant-event.ts (1)
23-28: Consider validating req.body here before passing to the service.You noted the TODO; moving runtime validation to the handler (Zod schema) will let createBooking drop internal validation later and remove any from req.body.
I can wire a lightweight Zod schema here and type req.body to CreateInstantBookingInput_2024_08_13. Want me to draft it?
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (4)
501-513: Include noEmail in bookingMeta for seated recurring bookings for parityOther flows pass noEmail; seated recurring does not. This can cause inconsistent email behavior.
Apply this diff:
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
525-538: Include noEmail in bookingMeta for regular bookingsKeep email behavior consistent across flows.
Apply this diff:
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
560-571: Include noEmail in bookingMeta for seated bookingsAlign with other create flows.
Apply this diff:
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
757-769: Include noEmail in bookingMeta for rescheduleParities reschedule with create flows.
Apply this diff:
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },packages/features/bookings/lib/handleNewRecurringBooking.ts (3)
92-97: Use strict equality for slot index checks- isFirstRecurringSlot: key == 0, + isFirstRecurringSlot: key === 0,
27-27: Refine type of thirdPartyRecurringEventId- let thirdPartyRecurringEventId = null; + let thirdPartyRecurringEventId: string | null = null;
100-111: Inline await instead of intermediate promise variable- const promiseEachRecurringBooking = regularBookingService.createBooking({ - bookingData: recurringEventData, - bookingMeta: { - hostname: input.hostname || "", - forcedSlug: input.forcedSlug as string | undefined, - ...handleBookingMeta, - }, - }); - - const eachRecurringBooking = await promiseEachRecurringBooking; + const eachRecurringBooking = await regularBookingService.createBooking({ + bookingData: recurringEventData, + bookingMeta: { + hostname: input.hostname || "", + forcedSlug: input.forcedSlug as string | undefined, + ...handleBookingMeta, + }, + });packages/features/instant-meeting/handleInstantMeeting.ts (1)
303-311: Review webhook payload for PII exposureSending raw
responsesandcustomInputsto webhooks can include PII, unlike the restricted booking DTOs used elsewhere. If consumers don’t need these full structures, wrap this event in a constrained DTO.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (20)
- apps/api/v2/src/lib/services/recurring-booking.service.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- packages/lib/di/bookings/modules/RegularBookingService.module.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- apps/api/v2/src/lib/modules/regular-booking.module.ts
- apps/api/v2/src/lib/modules/instant-booking.module.ts
- apps/api/v2/src/lib/services/regular-booking.service.ts
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- apps/web/lib/types/booking.ts
- packages/features/bookings/lib/create-instant-booking.ts
- apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
- apps/web/pages/api/book/recurring-event.ts
- packages/features/bookings/lib/index.ts
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- apps/web/pages/api/book/event.ts
- packages/platform/libraries/bookings.ts
- packages/features/bookings/types.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tsapps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tsapps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tsapps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (22)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/lib/di/bookings/modules/RecurringBookingService.module.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T10:07:30.026Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/larkcalendar/api/callback.ts:109-117
Timestamp: 2025-09-08T10:07:30.026Z
Learning: In office365calendar and zohocalendar callback handlers, vijayraghav-io chose to manually call BookingReferenceRepository.reconnectWithNewCredential() after credential creation instead of using SelectedCalendarRepository.upsert(), to avoid disturbing existing error handling logic in catch blocks while still ensuring booking reference reconnection happens.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-09-23T08:00:07.590Z
Learnt from: hariombalhara
PR: calcom/cal.com#23918
File: packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts:16-23
Timestamp: 2025-09-23T08:00:07.590Z
Learning: In calcom/cal.com test files, particularly packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts, the TIMEZONE_OFFSETS mapping is intentionally limited to only UTC variants and Asia/Kolkata. This is by design and should not be flagged as incomplete in future reviews (confirmed by maintainer hariombalhara).
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
🧬 Code graph analysis (14)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (2)
InstantBookingCreateService(18-18)instantBookingCreateServiceModule(7-7)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (3)
packages/lib/di/di.ts (1)
createContainer(114-114)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
RecurringBookingService(26-26)recurringBookingServiceModule(10-10)
apps/web/pages/api/book/instant-event.ts (1)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts (2)
packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(54-54)packages/platform/types/api.ts (1)
ApiSuccessResponse(8-8)
packages/features/bookings/lib/handleNewRecurringBooking.ts (3)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(44-51)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (2)
packages/features/bookings/lib/dto/types.d.ts (1)
BookingHandlerInput(40-42)packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(42-45)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/bookings/lib/handleNewBooking.ts (5)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: Linters / lint
- GitHub Check: Production builds / Build API v1
- GitHub Check: Tests / Unit
- GitHub Check: Production builds / Build Web App
- GitHub Check: Production builds / Build Docs
- GitHub Check: Production builds / Build Atoms
- GitHub Check: Production builds / Build API v2
- GitHub Check: Type check / check-types
🔇 Additional comments (45)
apps/api/v1/pages/api/bookings/_post.ts (2)
4-4: Good DI migration to RegularBookingService.This aligns with the container/moduleLoader pattern and decouples the route from legacy handlers.
242-252: Fix unsafe header cast for x-cal-force-slug (can be string[]).Normalize the header to a string to avoid leaking a string[] at runtime. This was flagged previously; proposing a concrete inline fix.
Apply this diff:
- return await regularBookingService.createBookingForApiV1({ + const forcedSlugHeader = req.headers["x-cal-force-slug"]; + const forcedSlug = Array.isArray(forcedSlugHeader) ? forcedSlugHeader[0] : forcedSlugHeader; + + return await regularBookingService.createBookingForApiV1({ bookingData: req.body, bookingMeta: { userId, hostname: req.headers.host || "", - forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, + forcedSlug, }, bookingDataSchemaGetter: getBookingDataSchemaForApi, });apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts (5)
24-24: Good switch to a type‑only importPrevents runtime coupling and avoids circular dep risks. Looks correct.
44-44: TypingcreatedBookingto the public result type is appropriateKeeps tests aligned with the new service contract.
233-233: Same alias refactor as above applies hereReplace the verbose generic with the local alias.
290-290: Same alias refactor as above applies hereReplace the verbose generic with the local alias.
387-387: Same alias refactor as above applies hereReplace the verbose generic with the local alias.
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
4-5: LGTM on moduleLoader usageSwitch to moduleLoader/token is consistent with the new DI pattern.
apps/web/pages/api/book/instant-event.ts (1)
5-5: LGTM: using DI container for instant bookingsImporting getInstantBookingCreateService aligns this route with the service-based flow.
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (4)
9-11: LGTM: injected booking servicesService imports are correct and match the refactor direction.
111-115: LGTM: Nest DI for new servicesConstructor injection follows Nest standards and addresses prior feedback to rely on native DI.
455-458: LGTM: instant booking via servicecreateInstantBooking delegates correctly to instantBookingCreateService.
476-489: LGTM: recurring booking passes full bookingMeta (incl. noEmail)Parity looks good here.
packages/features/bookings/lib/handleNewBooking.ts (9)
14-17: LGTM: metadata schema importUsing eventTypeMetaDataSchemaWithTypedApps is correct here.
24-28: LGTM: explicit DTO/type importsClearer type surface; matches the refactor direction.
428-432: LGTM: handler now receives deps explicitlySignature change is sound and keeps default schema getter.
446-452: LGTM: minimal deps destructuringOnly what’s needed is destructured; the rest remain available via deps when needed.
555-556: Guarded recurring-slot check is correctUsing !! for isFirstRecurringSlot avoids falsy pitfalls after adding proper types.
789-793: Safe gating for multi-slot availability checksAll guards present before entering the loop.
2425-2431: Fix: spreading possibly undefined bookingMeta throwsSpreading undefined crashes. Default bookingMeta to {} as done in createBookingForApiV1.
Apply this diff:
async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); } async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); }
1607-1613: Fix: possible crash accessing bookingData.responses; use bookerEmail/phonebookingData.responses can be undefined; currentAttendee lookup should rely on already-parsed bookerEmail/bookerPhoneNumber.
Apply this diff:
- if (booking && booking.id && eventType.seatsPerTimeSlot) { - const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + if (booking && booking.id && eventType.seatsPerTimeSlot) { + const currentAttendee = booking.attendees.find( + (attendee) => + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );
414-426: Resolved — DI module binds all IBookingServiceDependencies keysRegularBookingService.module.ts's depsMap provides bindings for every property in IBookingServiceDependencies (see packages/lib/di/bookings/modules/RegularBookingService.module.ts).
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
12-20: LGTM: moduleLoader with depsMap (regularBookingService) wired correctlyBinding RecurringBookingService via bindModuleToClassOnToken with regularBookingService dependency matches the constructor.
22-25: LGTM: exported moduleLoader surfacetoken + loadModule exported in the standard pattern.
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (1)
4-13: Service-based test handler: LGTMTyped input, DI lookup, and bookingMeta destructuring look correct.
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (3)
26-26: Switched to DI getter for recurring bookings: LGTMUsing getRecurringBookingService() aligns tests with the service flow.
155-162: Service invocation with bookingMeta: LGTMCorrect payload shape: bookingData array + bookingMeta.userId.
376-383: Fix async rejection assertion and bookingMeta shape
- Use expect(promise).rejects, not expect(() => promise).rejects.
- Pass userId inside bookingMeta.
Apply:
- await expect( - async () => - await recurringBookingService.createBooking({ - bookingData: bookingDataArray, - userId: -1, - }) - ).rejects.toThrow(ErrorCode.NoAvailableUsersFound); + await expect( + recurringBookingService.createBooking({ + bookingData: bookingDataArray, + bookingMeta: { userId: -1 }, + }) + ).rejects.toThrow(ErrorCode.NoAvailableUsersFound);Also ensure ErrorCode is imported at the top:
import { ErrorCode } from "@calcom/lib/errorCodes";packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
9-13: Module loader-based DI container: LGTMIdempotent load + token-based get are consistent with the new pattern.
packages/features/bookings/lib/bookingCreateBodySchema.ts (3)
60-76: Recurring booking partial schema: LGTMOptional end in allRecurringDates matches handler expectations.
78-98: Extended schema merge: LGTMSeparation of recurring fields into a partial keeps the base schema clean.
100-101: Exported ExtendedBookingCreateBody type: LGTMapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (6)
10-12: Import DI-backed booking services: LGTM
114-117: Constructor DI for services: LGTM
194-207: Regular booking via service with bookingMeta: LGTMForwarded hostname, forcedSlug, and platform params correctly.
324-335: Recurring booking via service: LGTMCorrectly passes bookingData array and platform/user metadata.
362-362: Instant booking response type update: LGTM
367-371: Instant booking via service with body-only input: LGTMpackages/features/bookings/lib/dto/types.d.ts (2)
19-22: CreateRecurringBookingData shape: LGTMArray type with optional SchedulingType aligns with handler expectations.
44-51: InstantBookingCreateResult: LGTMTypes match existing behavior; no changes needed here.
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
57-66: Round-robin: first slot not returned and series ID not propagatedYou create the first slot but don’t push it to results or seed thirdPartyRecurringEventId. This returns N-1 items and may break series linkage.
Apply:
const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + createdBookings.push(firstBookingResult); + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + for (const ref of firstBookingResult.references) { + if (ref.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = ref.thirdPartyRecurringEventId; + break; + } + } + } + luckyUsers = firstBookingResult.luckyUsers;packages/features/instant-meeting/handleInstantMeeting.ts (4)
158-158: Typed input LGTMSwitch to typed
bookingData: CreateInstantBookingDatais correct and aligns with DI-based services.
332-333: Return shape checked with satisfies — goodEnsures the response conforms to InstantBookingCreateResult at compile time.
339-341: Service method signature LGTM
createBooking(input: { bookingData })returningInstantBookingCreateResultaligns with IBookingCreateService usage.
243-246: No change needed — "integrations:daily" is the canonical Cal Video locationThe codebase maps "cal-video" ↔ "integrations:daily" (e.g. packages/app-store/constants.ts DailyLocationType, apps/api/v2/.../transformers internal/locations.ts), so using location: "integrations:daily" is correct.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
81-86: Avoid logging webhook secrets
console.error(..., sub, ...)printssub.secret. Don’t log secrets.- }).catch((e) => { - console.error( - `Error executing webhook for event: ${eventTrigger}, URL: ${sub.subscriberUrl}`, - sub, - e - ); - }); + }).catch((e) => { + console.error( + `Error executing webhook for event: ${eventTrigger}, URL: ${sub.subscriberUrl}, id: ${sub.id}`, + e + ); + });
259-263: Useselectinstead ofincludeand return only needed fieldsNo code later uses
attendees. Follow our Prisma guideline: select only what you need.- const createBookingObj = { - include: { - attendees: true, - }, - data: newBookingData, - }; + const createBookingObj = { + select: { + id: true, + uid: true, + userId: true, + responses: true, + customInputs: true, + }, + data: newBookingData, + };apps/web/pages/api/book/event.ts (1)
27-33: Return 401 when unauthenticated; don’t proceed withuserId: -1Continuing with a sentinel ID risks confusing downstream behavior.
const session = await getServerSession({ req }); /* To mimic API behavior and comply with types */ req.body = { ...req.body, creationSource: CreationSource.WEBAPP, }; + if (!session?.user?.id) { + throw new Error("Unauthorized"); + }
🧹 Nitpick comments (7)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
25-25: Prefer using provided availability check count (when present)Hardcoding
1ignores client-provided intent. Derive from input with a sane default.-const numSlotsToCheckForAvailability = 1; +const numSlotsToCheckForAvailability = + (Array.isArray(input.bookingData) && input.bookingData[0]?.numSlotsToCheckForAvailability) ?? 1;apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
324-335: Parity: passareCalendarEventsEnabledto recurring bookings tooRegular bookings receive this flag; recurring path omits it. If this difference isn’t intentional, add it for consistency.
const createdBookings: BookingResponse[] = await this.recurringBookingService.createBooking({ bookingData: bookingRequest.body, bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, });If divergence is intentional, consider adding a brief comment to prevent future regressions.
packages/features/bookings/lib/dto/types.d.ts (1)
53-54: Define explicit RegularBookingCreateResult type (or confirm deferral)createBooking is implemented at packages/features/bookings/lib/handleNewBooking.ts and currently has no explicit return annotation, so RegularBookingCreateResult is inferred (currently: export type RegularBookingCreateResult = Awaited<ReturnType<RegularBookingService['createBooking']>>;). Because BookingResponse is widely consumed, either: define an explicit DTO in packages/features/bookings/lib/dto/types.d.ts, or keep the inference but remove the TODO and add a short comment justifying why inference is acceptable.
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
22-25: Optional: Type the moduleLoader for better DXAnnotating moduleLoader with a ModuleLoader type can improve IntelliSense and guard against shape drift.
-export const moduleLoader = { +export const moduleLoader /* : ModuleLoader */ = { token, loadModule, };
1-1: Minimize eslint escape hatchIf feasible, remove the no-restricted-imports override once the public import surface stabilizes or add a TODO so it’s not forgotten.
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (2)
4-12: Use a clearer alias and allow passing a custom container
- Rename the alias to recurringBookingServiceModuleLoader for clarity/consistency with other modules.
- Allow an optional container param for testability and composability; default to a shared container.
import { createContainer } from "../../di"; import { type RecurringBookingService, - moduleLoader as recurringBookingServiceModule, + moduleLoader as recurringBookingServiceModuleLoader, } from "../modules/RecurringBookingService.module"; -const container = createContainer(); +const defaultContainer = createContainer(); -export function getRecurringBookingService(): RecurringBookingService { - recurringBookingServiceModule.loadModule(container); - - return container.get<RecurringBookingService>(recurringBookingServiceModule.token); +export function getRecurringBookingService(container = defaultContainer): RecurringBookingService { + recurringBookingServiceModuleLoader.loadModule(container); + return container.get<RecurringBookingService>(recurringBookingServiceModuleLoader.token); }
10-12: Confirm container.load behavior / guard repeated loadscontainer.load (from @evyweb/ioctopus) allows repeated loads and rebinds bindings ("last loaded wins") — it won't throw. recurringBookingServiceModule.loadModule(container) (packages/lib/di/bookings/containers/RecurringBookingService.container.ts:10) calls container.load via bindModuleToClassOnToken (packages/lib/di/di.ts:101–112). If you need true idempotency or to avoid stale cached instances, guard the loader or call container.unload before reloading.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (23)
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/api/v2/src/lib/modules/regular-booking.module.ts
- packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts
- apps/web/lib/types/booking.ts
- packages/lib/di/bookings/containers/RegularBookingService.container.ts
- packages/lib/di/bookings/modules/RegularBookingService.module.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- packages/platform/libraries/bookings.ts
- packages/features/bookings/lib/index.ts
- apps/api/v2/src/lib/services/regular-booking.service.ts
- packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
- apps/web/pages/api/book/recurring-event.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- apps/api/v2/src/lib/services/recurring-booking.service.ts
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- apps/api/v1/pages/api/bookings/_post.ts
- apps/api/v2/src/lib/modules/instant-booking.module.ts
- packages/features/bookings/lib/create-instant-booking.ts
- packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/features/bookings/types.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/handleNewBooking.tsapps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/features/bookings/types.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/handleNewBooking.tsapps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/features/bookings/types.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/handleNewBooking.tsapps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/features/bookings/types.tsapps/web/pages/api/book/event.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/features/bookings/lib/handleNewBooking.tsapps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking.tsapps/web/pages/api/book/instant-event.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
apps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/instant-meeting/handleInstantMeeting.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
packages/lib/di/bookings/containers/RecurringBookingService.container.ts
📚 Learning: 2025-09-18T13:38:50.936Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.936Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/dto/types.d.tspackages/features/instant-meeting/handleInstantMeeting.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
🧬 Code graph analysis (11)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(42-45)
packages/features/bookings/types.ts (2)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(54-54)
apps/web/pages/api/book/event.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (2)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
RecurringBookingService(26-26)recurringBookingServiceModule(10-10)
packages/features/bookings/lib/handleNewBooking.ts (5)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (4)
BookingHandlerInput(40-42)CreateRegularBookingData(15-15)CreateBookingMeta(32-38)BookingDataSchemaGetter(13-13)
apps/web/pages/api/book/instant-event.ts (1)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
packages/features/bookings/lib/dto/types.d.ts (3)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/platform/libraries/bookings.ts (3)
InstantBookingCreateResult(9-9)RegularBookingCreateResult(10-10)RegularBookingService(5-5)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(44-51)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (24)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (8)
9-11: Verify Nest provider wiring for new servicesEnsure InstantBookingCreateService, RecurringBookingService, and RegularBookingService are registered as providers in the corresponding module (bookings.module.ts) so Nest can inject them here.
111-115: LGTM: constructor DI for booking servicesConstructor-based Nest DI aligns with api-v2 guidelines.
456-458: LGTM: Instant bookings routed via serviceCorrectly delegates to InstantBookingCreateService.createBooking with bookingData only.
476-489: LGTM: Recurring bookings pass bookingMeta (incl. noEmail)Good shape and fields forwarded.
526-538: Include noEmail in bookingMeta for regular bookings; consider DRY helperRegular flow currently omits noEmail, diverging from recurring flow. This can trigger emails despite client intent.
Apply this diff:
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },Optional: extract a private buildBookingMeta(bookingRequest) to avoid drift across flows.
(centralization was suggested earlier)
560-571: Include noEmail in bookingMeta for seated regular bookingsSame inconsistency: seated regular bookings omit noEmail, risking unintended notifications.
Apply this diff:
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
501-513: Include noEmail in bookingMeta for seated recurring bookingsnoEmail is passed for non-seated recurring bookings (Lines 476-489) but omitted here. This inconsistency can cause unintended emails in seated recurring flows.
Apply this diff:
bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },
757-769: Use rescheduleBooking API and include noEmail in bookingMeta
- Semantics/readability: prefer RegularBookingService.rescheduleBooking over createBooking during reschedule.
- Behavior: noEmail omitted here; reschedules may send emails unexpectedly.
Apply this diff:
- const booking = await this.regularBookingService.createBooking({ + const booking = await this.regularBookingService.rescheduleBooking({ bookingData: bookingRequest.body, bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, });apps/web/pages/api/book/instant-event.ts (1)
23-28: LGTM: moved to service and kept runtime validation in serviceService retrieval and call shape look correct;
creationSourceset before call is good.If we want parity with event booking’s CF Turnstile gate, confirm whether instant bookings should also enforce it.
packages/features/bookings/types.ts (1)
97-99: LGTM: unify BookingResponse to service result typeAlias to
RegularBookingCreateResultsimplifies typings without behavior change.packages/features/bookings/lib/bookingCreateBodySchema.ts (3)
60-76: Good extraction of recurring fields into a partial schemaClearer separation of concerns; optionality aligns with current shared schema usage.
78-98: LGTM: merged top-level extras with recurring partialThe merge keeps existing callers working while paving way for specialized schemas later.
100-101: Nice: exported input type for Extended schemaImproves reuse across DTOs and services.
packages/features/bookings/lib/handleNewBooking.ts (1)
1609-1613: Bug: attendee lookup uses possibly undefinedbookingData.responsesUse the already parsed
bookerEmail/bookerPhoneNumber. Current code can dereferenceundefinedand fail to match the correct attendee.- const currentAttendee = booking.attendees.find( - (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) - ); + const currentAttendee = booking.attendees.find( + (attendee) => + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) + );packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
57-66: First RR booking result is dropped and series ID not propagatedYou await the first result but never push it, and you don't seed
thirdPartyRecurringEventIdfor later slots. This returns N-1 results and can break third‑party series linkage.Apply:
const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + // include first slot and propagate series id for subsequent slots + createdBookings.push(firstBookingResult); + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + const ref = firstBookingResult.references.find((r) => r.thirdPartyRecurringEventId); + if (ref?.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = ref.thirdPartyRecurringEventId; + } + } + luckyUsers = firstBookingResult.luckyUsers;packages/features/bookings/lib/dto/types.d.ts (6)
2-3: LGTM! Descriptive comment clarifies the purpose.The added comment effectively explains that these are framework-agnostic domain types for booking operations.
7-10: LGTM! Imports are properly aligned with usage.The new imports for
SchedulingType,ExtendedBookingCreateBody, andRegularBookingServiceare correctly sourced and align with their usage in the type definitions.
12-12: LGTM! Consistent with named export preference.Converting
BookingCreateBodyto a type-only export aligns with the coding guidelines that encourage named exports over default exports.
15-21: LGTM! Type unification improves consistency.The migration from
BaseCreateBookingDatatoExtendedBookingCreateBodyprovides better type consistency across the booking services. The addition ofschedulingType?: SchedulingTypetoCreateRecurringBookingDatais logically sound for recurring booking scenarios.
23-42: LGTM! Well-structured metadata types.The new type definitions (
PlatformParams,CreateBookingMeta,BookingHandlerInput) provide clear separation of concerns and improve type safety for booking operations. The structure is logical and the field purposes are evident.
44-51: LGTM! Type rename improves clarity.The rename from
CreateInstantBookingResponsetoInstantBookingCreateResultfollows a consistent naming pattern and better reflects the nature of the type as a result rather than a response. The field types remain appropriate.packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
12-20: Good migration to moduleLoader with explicit deps mapThe DI wiring via bindModuleToClassOnToken and the dependency on RegularBookingService through depsMap looks correct and consistent with the new pattern.
8-9: DI tokens present and unique — no conflicts found
RECURRING_BOOKING_SERVICE and RECURRING_BOOKING_SERVICE_MODULE are defined in packages/lib/di/bookings/tokens.ts and only referenced in packages/lib/di/bookings/modules/RecurringBookingService.module.ts; no other definitions or collisions found.
17-19: Verified — depsMap keys match IRecurringBookingServiceDependenciesIRecurringBookingServiceDependencies declares regularBookingService (packages/features/bookings/lib/handleNewRecurringBooking.ts:127-129), which matches the depsMap entry in RecurringBookingService.module.ts; no changes required.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
376-383: Update skipped test to use the new service contract
RecurringBookingService.createBookingno longer acceptsuserIdat the top level. Passing it here causes a TS compile error, and wrapping the async call in a function means the rejection assertion never runs. Inline the promise and moveuserIdunderbookingMeta.- const recurringBookingService = getRecurringBookingService(); - await expect( - async () => - await recurringBookingService.createBooking({ - bookingData: bookingDataArray, - userId: -1, - }) - ).rejects.toThrow(ErrorCode.NoAvailableUsersFound); + const recurringBookingService = getRecurringBookingService(); + await expect( + recurringBookingService.createBooking({ + bookingData: bookingDataArray, + bookingMeta: { + userId: -1, + }, + }) + ).rejects.toThrow(ErrorCode.NoAvailableUsersFound);packages/features/instant-meeting/handleInstantMeeting.ts (1)
158-169: Guard null eventType before property access.
getEventTypesFromDBcan return null; spreading or accessing.teamwould throw.Apply:
async function handler(bookingData: CreateInstantBookingData) { - let eventType = await getEventTypesFromDB(bookingData.eventTypeId); + let eventType = await getEventTypesFromDB(bookingData.eventTypeId); + if (!eventType) { + throw new Error("Event type not found"); + } const isOrgTeamEvent = !!eventType?.team && !!eventType?.team?.parentId; eventType = { ...eventType, bookingFields: getBookingFieldsWithSystemFields({ ...eventType, isOrgTeamEvent }), }; - if (!eventType.team?.id) { + if (!eventType.team?.id) { throw new Error("Only Team Event Types are supported for Instant Meeting"); }
🧹 Nitpick comments (8)
apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
1-1: Consider using named import for better tree-shaking.Using relative imports with default exports can hurt tree-shaking. Consider using a named export from the service file. As per coding guidelines
-import { InstantBookingCreateService } from "@/lib/services/instant-booking-create.service"; +import { InstantBookingCreateService } from "@/lib/services/instant-booking-create.service";(Note: This assumes the service file exports
InstantBookingCreateServiceas a named export)packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
9-13: Make module load idempotent to avoid repeated bindings.Guard
loadModuleso it runs once per process.Apply:
const container = createContainer(); export function getRecurringBookingService(): RecurringBookingService { - recurringBookingServiceModule.loadModule(container); - - return container.get<RecurringBookingService>(recurringBookingServiceModule.token); + // Load once + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const loaded = (container as any).__recurringBookingLoaded as boolean | undefined; + if (!loaded) { + recurringBookingServiceModule.loadModule(container); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (container as any).__recurringBookingLoaded = true; + } + return container.get<RecurringBookingService>(recurringBookingServiceModule.token); }packages/features/instant-meeting/handleInstantMeeting.ts (1)
259-263: Use Prisma select over include to limit data fetched.Replace
include: { attendees: true }with a minimalselectset.As per coding guidelines:
- const createBookingObj = { - include: { - attendees: true, - }, - data: newBookingData, - }; + const createBookingObj = { + select: { + id: true, + uid: true, + userId: true, + responses: true, + customInputs: true, + metadata: true, + // add other fields only if used below + }, + data: newBookingData, + };As per coding guidelines
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (2)
476-489: BookingMeta consistency: add noEmail where missing.
noEmailis passed for recurring (non-seated) but omitted in other flows. For consistent behavior, include it everywhere if available inbookingRequest.Apply:
@@ createRecurringBooking bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, @@ createRecurringSeatedBooking - bookingMeta: { + bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, @@ createRegularBooking - bookingMeta: { + bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, @@ createSeatedBooking - bookingMeta: { + bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, @@ rescheduleBooking - bookingMeta: { + bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },If this is intentionally omitted for some flows, please confirm and point to tests or specs; otherwise the above keeps behavior aligned.
Also applies to: 501-513, 526-538, 560-572, 757-769
520-539: Optional: centralize bookingMeta construction.Extract a private helper (e.g., buildBookingMeta(bookingRequest)) to avoid drift across flows.
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
194-206: Consider propagating noEmail via bookingMeta for consistencyIf the handler reads noEmail as a top-level flag (not from bookingData), add it to bookingMeta to avoid divergence with other entry points.
Proposed change:
const booking = await this.regularBookingService.createBooking({ bookingData: bookingRequest.body, bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", forcedSlug: orgSlug, platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, + noEmail: !bookingRequest.arePlatformEmailsEnabled, }, });packages/features/bookings/lib/dto/types.d.ts (2)
9-11: Avoid coupling DTOs to service implementationsHaving RegularBookingCreateResult depend on RegularBookingService["createBooking"] ties DTOs to implementation and risks cycles. Prefer a stable, explicit result type exported alongside BookingResponse (or define a dedicated DTO here).
Follow-up: define RegularBookingCreateResult as an explicit interface/type independent of the service signature, then have the service use that type. Based on learnings
53-55: Minor: fix TODO wording and consider defining explicit typeGrammar nit and a reminder to avoid inferring from service signatures.
Proposed change:
-// TODO: In a followup PR, we working on defining the type here itself instead of inferring it. +// TODO: In a follow-up PR, we're working on defining this type here instead of inferring it. export type RegularBookingCreateResult = Awaited<ReturnType<RegularBookingService["createBooking"]>>;
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (36)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(2 hunks)packages/features/bookings/lib/handleNewBooking.ts(10 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(5 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts(1 hunks)packages/lib/di/bookings/containers/RecurringBookingService.container.ts(1 hunks)packages/lib/di/bookings/containers/RegularBookingService.container.ts(1 hunks)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts(1 hunks)packages/lib/di/bookings/modules/RecurringBookingService.module.ts(1 hunks)packages/lib/di/bookings/modules/RegularBookingService.module.ts(2 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- packages/features/bookings/lib/bookingCreateBodySchema.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- apps/web/pages/api/book/event.ts
- apps/api/v2/src/lib/services/regular-booking.service.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- packages/features/bookings/lib/index.ts
- packages/platform/libraries/bookings.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/api/v1/pages/api/bookings/_post.tspackages/lib/di/bookings/containers/RegularBookingService.container.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tspackages/lib/di/bookings/modules/RegularBookingService.module.tsapps/web/lib/types/booking.tspackages/features/bookings/types.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/modules/instant-booking.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/lib/services/instant-booking-create.service.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/create-instant-booking.tsapps/web/pages/api/book/instant-event.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/lib/modules/regular-booking.module.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/web/pages/api/book/recurring-event.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/api/v1/pages/api/bookings/_post.tspackages/lib/di/bookings/containers/RegularBookingService.container.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tspackages/lib/di/bookings/modules/RegularBookingService.module.tsapps/web/lib/types/booking.tspackages/features/bookings/types.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/modules/instant-booking.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/lib/services/instant-booking-create.service.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/create-instant-booking.tsapps/web/pages/api/book/instant-event.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/lib/modules/regular-booking.module.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/web/pages/api/book/recurring-event.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/api/v1/pages/api/bookings/_post.tspackages/lib/di/bookings/containers/RegularBookingService.container.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.tspackages/lib/di/bookings/modules/RegularBookingService.module.tsapps/web/lib/types/booking.tspackages/features/bookings/types.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/modules/instant-booking.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/lib/services/instant-booking-create.service.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tsapps/api/v2/src/lib/services/recurring-booking.service.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/create-instant-booking.tsapps/web/pages/api/book/instant-event.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/lib/modules/regular-booking.module.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/web/pages/api/book/recurring-event.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/services/instant-booking-create.service.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
🧠 Learnings (24)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/lib/di/bookings/containers/InstantBookingCreateService.container.tsapps/api/v1/pages/api/bookings/_post.tspackages/lib/di/bookings/containers/RegularBookingService.container.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/features/bookings/types.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/modules/instant-booking.module.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/lib/di/bookings/containers/RecurringBookingService.container.tspackages/lib/di/bookings/modules/RecurringBookingService.module.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/create-instant-booking.tsapps/web/pages/api/book/instant-event.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v2/src/lib/modules/regular-booking.module.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/web/pages/api/book/recurring-event.ts
📚 Learning: 2025-09-09T08:58:55.970Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/lib/di/containers/InsightsBooking.ts:10-12
Timestamp: 2025-09-09T08:58:55.970Z
Learning: The moduleLoader pattern is being implemented incrementally, focusing only on modules that are directly or indirectly used by Booking modules. Other modules like InsightsBooking are intentionally excluded from this migration phase.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/lib/di/bookings/modules/RegularBookingService.module.tspackages/lib/di/bookings/modules/InstantBookingCreateService.module.tspackages/lib/di/bookings/containers/RecurringBookingService.container.ts
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-27T12:15:43.830Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/testCall.handler.ts:41-44
Timestamp: 2025-08-27T12:15:43.830Z
Learning: In calcom/cal.com, the AgentService.getAgent() method in packages/features/calAIPhone/providers/retellAI/services/AgentService.ts does NOT include authorization checks - it only validates the agentId parameter and directly calls the repository without verifying user/team access. This contrasts with other methods like getAgentWithDetails() which properly use findByIdWithUserAccessAndDetails() for authorization. When reviewing updateToolsFromAgentId() calls, always verify both agent ownership and eventType ownership are checked.
Applied to files:
apps/web/lib/types/booking.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
packages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/create-instant-booking.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.
Applied to files:
packages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-08T09:29:11.681Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts:118-143
Timestamp: 2025-08-08T09:29:11.681Z
Learning: In calcom/cal.com PR #22919, packages/features/calAIPhone/interfaces/AIPhoneService.interface.ts (TypeScript), the AIPhoneServiceAgentListItem is required to include user.email in listAgents responses (per maintainer Udit-takkar). Future reviews should not flag this as unnecessary PII unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-08T09:27:23.896Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22919
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:195-216
Timestamp: 2025-08-08T09:27:23.896Z
Learning: In PR calcom/cal.com#22919, file packages/features/calAIPhone/providers/retellAI/services/AgentService.ts, the updateAgentConfiguration method intentionally does not persist the optional `name` parameter to the repository for now, per maintainer (Udit-takkar). Future reviews should not flag this unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-14T10:48:52.586Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/ai/_router.ts:46-84
Timestamp: 2025-08-14T10:48:52.586Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/ai/_router.ts, the voiceId input parameter in the create endpoint is intentionally not forwarded to aiService.createAgent() as voice customization is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-09-18T13:38:50.958Z
Learnt from: hariombalhara
PR: calcom/cal.com#23913
File: packages/features/bookings/Booker/components/hooks/usePrefetch.ts:43-50
Timestamp: 2025-09-18T13:38:50.958Z
Learning: In usePrefetch hook in packages/features/bookings/Booker/components/hooks/usePrefetch.ts, the !isNaN() checks before comparing monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView are intentional to prevent the NaN !== NaN issue where NaN values would incorrectly be considered different, leading to wrong monthCount calculations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In BookingPaymentInitiatedDTO and other webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking field is a restricted structure containing only specific fields (id, eventTypeId, userId) rather than the full database booking object, so there are no security or PII leakage concerns when passing the booking object to buildEventPayload.
Applied to files:
packages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/create-instant-booking.tspackages/features/instant-meeting/handleInstantMeeting.ts
📚 Learning: 2025-09-12T07:15:58.056Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.056Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.
Applied to files:
packages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/create-instant-booking.tspackages/features/instant-meeting/handleInstantMeeting.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-09-18T08:50:49.925Z
Learnt from: eunjae-lee
PR: calcom/cal.com#23752
File: packages/lib/server/service/InsightsBookingBaseService.ts:340-371
Timestamp: 2025-09-18T08:50:49.925Z
Learning: In the InsightsBookingBaseService (packages/lib/server/service/InsightsBookingBaseService.ts), the startTime date range filter intentionally uses different fields for the lower and upper bounds: `startDate <= "startTime" AND "endTime" <= endDate`. This ensures bookings start within the selected range but don't extend beyond the end date, which is the intended business logic and not an inconsistency.
Applied to files:
packages/features/bookings/lib/create-instant-booking.ts
📚 Learning: 2025-09-08T10:07:30.026Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/larkcalendar/api/callback.ts:109-117
Timestamp: 2025-09-08T10:07:30.026Z
Learning: In office365calendar and zohocalendar callback handlers, vijayraghav-io chose to manually call BookingReferenceRepository.reconnectWithNewCredential() after credential creation instead of using SelectedCalendarRepository.upsert(), to avoid disturbing existing error handling logic in catch blocks while still ensuring booking reference reconnection happens.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-09-23T08:00:07.619Z
Learnt from: hariombalhara
PR: calcom/cal.com#23918
File: packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts:16-23
Timestamp: 2025-09-23T08:00:07.619Z
Learning: In calcom/cal.com test files, particularly packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts, the TIMEZONE_OFFSETS mapping is intentionally limited to only UTC variants and Asia/Kolkata. This is by design and should not be flagged as incomplete in future reviews (confirmed by maintainer hariombalhara).
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
🧬 Code graph analysis (24)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (2)
packages/lib/di/di.ts (1)
createContainer(114-114)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (2)
InstantBookingCreateService(18-18)instantBookingCreateServiceModule(7-7)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/lib/di/bookings/containers/RegularBookingService.container.ts (1)
getRegularBookingService(9-13)
packages/features/instant-meeting/handleInstantMeeting.test.ts (1)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts (1)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (1)
getNewBookingHandler(16-18)
packages/lib/di/bookings/modules/RegularBookingService.module.ts (13)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
moduleLoader(19-22)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (1)
moduleLoader(22-25)packages/lib/di/modules/Attribute.ts (1)
moduleLoader(18-21)packages/lib/di/modules/LuckyUser.ts (1)
moduleLoader(28-31)packages/lib/di/modules/Host.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Ooo.ts (1)
moduleLoader(18-21)packages/lib/di/modules/User.ts (1)
moduleLoader(18-21)packages/lib/di/modules/Booking.ts (1)
moduleLoader(11-16)packages/lib/di/modules/Cache.ts (1)
moduleLoader(14-19)packages/lib/di/modules/Features.ts (1)
moduleLoader(11-16)packages/lib/di/modules/CheckBookingAndDurationLimits.ts (1)
moduleLoader(14-19)packages/lib/di/modules/CheckBookingLimits.ts (1)
moduleLoader(13-18)packages/prisma/prisma.module.ts (1)
moduleLoader(13-19)
apps/web/lib/types/booking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(54-54)packages/platform/libraries/bookings.ts (1)
RegularBookingCreateResult(10-10)
packages/features/bookings/types.ts (5)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/index.ts (1)
BookingResponse(9-9)packages/platform/libraries/index.ts (1)
BookingResponse(49-49)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(54-54)packages/platform/libraries/bookings.ts (1)
RegularBookingCreateResult(10-10)
packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (2)
packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/lib/modules/instant-booking.module.ts (5)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
InstantBookingCreateService(18-18)packages/platform/libraries/bookings.ts (1)
InstantBookingCreateService(7-7)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)
apps/api/v2/src/lib/services/instant-booking-create.service.ts (6)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
Injectable(89-1141)apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
Injectable(6-13)apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/lib/di/bookings/modules/InstantBookingCreateService.module.ts (1)
InstantBookingCreateService(18-18)packages/platform/libraries/bookings.ts (1)
InstantBookingCreateService(7-7)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (2)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/lib/di/bookings/modules/RecurringBookingService.module.ts (2)
RecurringBookingService(26-26)recurringBookingServiceModule(10-10)
apps/api/v2/src/lib/services/recurring-booking.service.ts (2)
apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)
packages/lib/di/bookings/modules/RecurringBookingService.module.ts (3)
packages/lib/di/tokens.ts (1)
DI_TOKENS(3-58)packages/lib/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/lib/di/bookings/modules/RegularBookingService.module.ts (1)
moduleLoader(42-45)
packages/features/bookings/lib/handleNewBooking.ts (3)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1046)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(40-42)CreateRecurringBookingData(19-21)CreateBookingMeta(32-38)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/bookings/lib/create-instant-booking.ts (3)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
createInstantBooking(357-390)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(44-51)packages/lib/fetch-wrapper.ts (1)
post(28-36)
apps/web/pages/api/book/instant-event.ts (1)
packages/lib/di/bookings/containers/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(9-12)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(44-51)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
apps/api/v2/src/lib/modules/regular-booking.module.ts (4)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
Module(5-10)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2422-2451)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)
apps/web/pages/api/book/recurring-event.ts (2)
packages/lib/di/bookings/containers/RecurringBookingService.container.ts (1)
getRecurringBookingService(9-13)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install dependencies / Yarn install & cache
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
45-66: Include the first round-robin booking in the resultsFor round-robin flows we now create the first slot up front, but we never push that result into
createdBookingsnor seedthirdPartyRecurringEventId. As it stands the API returns N‑1 bookings and later slots miss the series identifier. Push the initial result ontocreatedBookingsand capture its recurring reference before iterating the remaining slots.const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + createdBookings.push(firstBookingResult); + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + const recurringRef = firstBookingResult.references.find((ref) => ref.thirdPartyRecurringEventId); + if (recurringRef?.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = recurringRef.thirdPartyRecurringEventId; + } + } + luckyUsers = firstBookingResult.luckyUsers;
♻️ Duplicate comments (4)
apps/api/v1/pages/api/bookings/_post.ts (1)
246-252: Fix unsafe header cast for x-cal-force-slug (can be string[])
req.headers["x-cal-force-slug"]can bestring | string[] | undefined. Casting tostringis unsafe and can leak astring[]to downstream code at runtime. Normalize it.Apply this diff:
+ const forceSlugHeader = req.headers["x-cal-force-slug"]; + const forcedSlug = Array.isArray(forceSlugHeader) ? forceSlugHeader[0] : forceSlugHeader; bookingMeta: { userId, hostname: req.headers.host || "", - forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, + forcedSlug, },apps/web/pages/api/book/event.ts (1)
48-56: The userId: -1 fallback issue remains.As noted in the previous review, passing
userId: -1when the session is missing can lead to confusing downstream errors. The handler should return a 401 response early instead.packages/features/bookings/lib/handleNewBooking.ts (1)
2455-2462: Guard againstbookingMetabeing undefined
bookingMetaremains optional in the method signature, but spreading an undefined value throws (TypeError: Cannot convert undefined or null to object). Any caller that omits meta (and plenty existed before this refactor) will now crash. Default the meta to{}before spreading in both methods.async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); } async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); }apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
324-334: PropagatenoEmailto the recurring service
createNextApiBookingRequeststill setsbookingRequest.noEmail, but we drop it when constructingbookingMeta. BecausehandleNewRecurringBookingtreats an undefined flag as “mute emails for every slot after the first”, this silently disables notifications for the rest of the series. Please wire the flag through (and mirror it in the seated branch).const createdBookings: BookingResponse[] = await this.recurringBookingService.createBooking({ bookingData: bookingRequest.body, bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, }, });
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (33)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/di/InstantBookingCreateService.container.ts(1 hunks)packages/features/bookings/di/InstantBookingCreateService.module.ts(1 hunks)packages/features/bookings/di/RecurringBookingService.container.ts(1 hunks)packages/features/bookings/di/RecurringBookingService.module.ts(1 hunks)packages/features/bookings/di/RegularBookingService.container.ts(1 hunks)packages/features/bookings/di/RegularBookingService.module.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(3 hunks)packages/features/bookings/lib/handleNewBooking.ts(11 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(4 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/di/tokens.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
- apps/api/v2/src/lib/modules/instant-booking.module.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- apps/api/v2/src/lib/modules/regular-booking.module.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- apps/api/v2/src/lib/modules/recurring-booking.module.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- packages/features/bookings/lib/index.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/features/bookings/di/RecurringBookingService.container.tsapps/web/lib/types/booking.tspackages/features/bookings/lib/create-instant-booking.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/di/RecurringBookingService.module.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/types.tsapps/api/v2/src/lib/services/recurring-booking.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/di/InstantBookingCreateService.container.tsapps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tsapps/api/v2/src/lib/services/regular-booking.service.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/di/RegularBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/di/tokens.tspackages/features/bookings/di/RegularBookingService.container.tspackages/features/bookings/di/InstantBookingCreateService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/features/bookings/di/RecurringBookingService.container.tsapps/web/lib/types/booking.tspackages/features/bookings/lib/create-instant-booking.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/di/RecurringBookingService.module.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/types.tsapps/api/v2/src/lib/services/recurring-booking.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/di/InstantBookingCreateService.container.tsapps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tsapps/api/v2/src/lib/services/regular-booking.service.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/di/RegularBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/di/tokens.tspackages/features/bookings/di/RegularBookingService.container.tspackages/features/bookings/di/InstantBookingCreateService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/features/bookings/di/RecurringBookingService.container.tsapps/web/lib/types/booking.tspackages/features/bookings/lib/create-instant-booking.tspackages/features/bookings/lib/bookingCreateBodySchema.tspackages/features/bookings/di/RecurringBookingService.module.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/types.tsapps/api/v2/src/lib/services/recurring-booking.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/di/InstantBookingCreateService.container.tsapps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tsapps/api/v2/src/lib/services/regular-booking.service.tsapps/web/pages/api/book/instant-event.tspackages/features/bookings/di/RegularBookingService.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/di/tokens.tspackages/features/bookings/di/RegularBookingService.container.tspackages/features/bookings/di/InstantBookingCreateService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/lib/services/recurring-booking.service.tsapps/api/v2/src/lib/services/regular-booking.service.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-09-23T08:00:07.619Z
Learnt from: hariombalhara
PR: calcom/cal.com#23918
File: packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts:16-23
Timestamp: 2025-09-23T08:00:07.619Z
Learning: In calcom/cal.com test files, particularly packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts, the TIMEZONE_OFFSETS mapping is intentionally limited to only UTC variants and Asia/Kolkata. This is by design and should not be flagged as incomplete in future reviews (confirmed by maintainer hariombalhara).
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v1/pages/api/bookings/_post.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/bookings/di/RegularBookingService.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/dto/types.d.tsapps/web/pages/api/book/event.tspackages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
🧬 Code graph analysis (21)
packages/features/bookings/di/RecurringBookingService.container.ts (3)
packages/features/di/di.ts (1)
createContainer(114-114)packages/features/bookings/di/RecurringBookingService.module.ts (2)
RecurringBookingService(25-25)recurringBookingServiceModule(9-9)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)
apps/web/lib/types/booking.ts (2)
packages/features/bookings/types.ts (1)
BookingResponse(98-98)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(57-57)
packages/features/bookings/lib/create-instant-booking.ts (3)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
createInstantBooking(357-390)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(47-54)packages/lib/fetch-wrapper.ts (1)
post(28-36)
packages/features/bookings/di/RecurringBookingService.module.ts (4)
packages/features/di/tokens.ts (1)
DI_TOKENS(3-58)packages/features/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/bookings/di/RegularBookingService.module.ts (1)
moduleLoader(39-42)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
packages/features/bookings/di/RecurringBookingService.container.ts (1)
getRecurringBookingService(10-14)
packages/features/bookings/types.ts (2)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(57-57)
apps/api/v2/src/lib/services/recurring-booking.service.ts (2)
apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(47-54)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(43-45)CreateRecurringBookingData(19-21)CreateBookingMeta(35-41)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/bookings/di/InstantBookingCreateService.container.ts (3)
packages/features/di/di.ts (1)
createContainer(114-114)packages/features/bookings/di/InstantBookingCreateService.module.ts (2)
InstantBookingCreateService(16-16)instantBookingCreateServiceModule(5-5)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/features/bookings/di/RegularBookingService.container.ts (1)
getRegularBookingService(10-14)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts (2)
packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(57-57)packages/platform/types/api.ts (1)
ApiSuccessResponse(8-8)
apps/api/v2/src/lib/services/regular-booking.service.ts (5)
apps/api/v2/src/lib/services/instant-booking-create.service.ts (1)
Injectable(5-6)apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
Injectable(6-13)packages/features/bookings/di/RegularBookingService.module.ts (1)
RegularBookingService(44-44)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/platform/libraries/bookings.ts (1)
RegularBookingService(5-5)
apps/web/pages/api/book/instant-event.ts (1)
packages/features/bookings/di/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(10-13)
packages/features/bookings/di/RegularBookingService.module.ts (2)
packages/features/bookings/di/InstantBookingCreateService.module.ts (1)
moduleLoader(17-20)packages/features/bookings/di/RecurringBookingService.module.ts (1)
moduleLoader(21-24)
apps/web/pages/api/book/recurring-event.ts (2)
packages/features/bookings/di/RecurringBookingService.container.ts (1)
getRecurringBookingService(10-14)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
packages/features/bookings/di/InstantBookingCreateService.module.ts (3)
packages/features/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/features/di/tokens.ts (1)
DI_TOKENS(3-58)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)
apps/web/pages/api/book/event.ts (1)
packages/features/bookings/di/RegularBookingService.container.ts (1)
getRegularBookingService(10-14)
packages/features/bookings/lib/handleNewBooking.ts (7)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1049)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/lib/server/repository/host.ts (1)
HostRepository(3-40)packages/lib/server/repository/user.ts (1)
UserRepository(123-1071)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(43-45)CreateRegularBookingData(15-15)CreateBookingMeta(35-41)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Type check / check-types
- GitHub Check: Tests / Unit
- GitHub Check: Linters / lint
🔇 Additional comments (24)
packages/features/di/tokens.ts (1)
1-1: LGTM!The import path change from relative to absolute aligns with the monorepo's absolute import strategy and improves clarity.
packages/features/bookings/di/RecurringBookingService.container.ts (1)
1-14: LGTM!The DI container implementation follows the established pattern used by RegularBookingService.container and InstantBookingCreateService.container, ensuring consistency across booking services.
packages/features/bookings/di/RegularBookingService.module.ts (2)
39-42: LGTM!The export rename to
moduleLoadermaintains consistency with InstantBookingCreateService.module and RecurringBookingService.module, standardizing the DI module pattern across booking services.
24-36: IBookingServiceDependencies matches depsMap The interface now declares all 11 dependencies present in depsMap.packages/features/bookings/di/InstantBookingCreateService.container.ts (1)
1-13: LGTM!The DI container implementation is consistent with the pattern used by RegularBookingService.container and RecurringBookingService.container, maintaining uniformity across all booking service containers.
apps/web/lib/types/booking.ts (1)
1-3: LGTM!The type definition is simplified and correctly aliases RegularBookingCreateResult, aligning with the new service-based booking architecture.
Note: A past review comment flagged that some consumers (e.g., apps/web/pages/api/book/recurring-event.ts) import BookingResponse from the package path instead of this local re-export. Consider standardizing imports across the codebase for consistency.
packages/features/bookings/di/RegularBookingService.container.ts (2)
1-1: LGTM!The import path change to absolute package path improves consistency across the monorepo.
5-6: LGTM!The moduleLoader alias as regularBookingServiceModule maintains backward compatibility while aligning with the updated module export pattern.
apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
1-13: LGTM!The NestJS service implementation correctly extends BaseRecurringBookingService and follows the established DI pattern, consistent with RegularBookingService in the v2 API layer.
apps/web/pages/api/book/instant-event.ts (2)
4-4: LGTM!The import change to use the DI container for InstantBookingCreateService aligns with the broader service-based refactoring pattern.
23-28: LGTM!The service-based approach is correctly implemented. The TODO comment clearly acknowledges the runtime validation trade-off and plans to address the
anytype in a follow-up.packages/features/bookings/di/RecurringBookingService.module.ts (1)
1-25: LGTM!The DI module correctly wires RecurringBookingService with its dependency on RegularBookingService. The depsMap structure aligns with the service's constructor signature shown in the relevant code snippets.
packages/features/bookings/di/InstantBookingCreateService.module.ts (1)
1-20: LGTM!The DI module correctly sets up InstantBookingCreateService with an empty depsMap, which aligns with the service having no constructor dependencies as shown in the relevant code snippets.
apps/web/pages/api/book/event.ts (1)
4-4: LGTM!The import change to use the DI container for RegularBookingService is consistent with the service-based refactoring pattern.
packages/features/bookings/lib/create-instant-booking.ts (2)
3-4: LGTM!The import changes align with the broader DTO type refactoring effort, consolidating types in a dedicated dto/types module.
9-10: Date serialization issue deferred but documented.The TODO clearly acknowledges that
expires: Dateshould be serialized as a string for the HTTP response. While the previous concern about non-existentstartTime/endTimefields is resolved, theexpiresfield serialization remains unaddressed.Consider verifying that downstream consumers properly handle the
expiresfield serialization when the fix is implemented.packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (4)
24-24: LGTM!The import of
getRecurringBookingServicealigns with the service-based testing approach.
27-27: LGTM!Good practice removing unused imports while keeping necessary ones like
BookingStatus.
154-161: LGTM!The test correctly uses the new service-based approach with the
bookingMetastructure. UsinguserId: -1is appropriate in the test context to simulate an anonymous booking scenario.
222-223: Minor formatting adjustment.packages/features/bookings/types.ts (2)
3-4: LGTM!Import changes align with the DTO type consolidation effort and correct enum imports from Prisma.
97-98: LGTM!The type alias provides a clean migration path while maintaining backward compatibility. The TODO clearly documents the plan to consolidate naming in a follow-up PR.
packages/features/bookings/lib/bookingCreateBodySchema.ts (2)
60-76: LGTM!The new
recurringBookingCreateBodyPartialSchemaproperly encapsulates recurring-related fields. The TODO clearly documents the plan to create separate schemas for different booking types. The optionalendfield inallRecurringDatesaligns with the previous comment abouthandleNewRecurringBookingpotentially passing it as undefined.
78-100: LGTM!The schema merge structure is clean and modular. Extracting recurring-related fields into a partial schema and then merging improves maintainability. The new
ExtendedBookingCreateBodytype export provides a useful type alias for consumers.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
45-66: Include the first round‑robin booking in the responseFor round‑robin series we await the first slot but never push it into
createdBookings, so the API returns N‑1 results. We also leavethirdPartyRecurringEventIdunset for later slots. Please add the first result (when defined) and seed the recurring ID from its references before continuing.const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); - luckyUsers = firstBookingResult.luckyUsers; + if (firstBookingResult) { + createdBookings.push(firstBookingResult); + luckyUsers = firstBookingResult.luckyUsers; + if (!thirdPartyRecurringEventId && firstBookingResult.references?.length) { + thirdPartyRecurringEventId = + firstBookingResult.references.find((ref) => ref.thirdPartyRecurringEventId)?.thirdPartyRecurringEventId ?? + null; + } + }
♻️ Duplicate comments (5)
apps/api/v1/pages/api/bookings/_post.ts (1)
242-252: Normalizex-cal-force-slugheader before passing to bookingMeta
req.headers["x-cal-force-slug"]can bestring | string[] | undefined. Casting it straight tostringcan leak astring[]intoCreateBookingMeta, breaking code paths that expect a scalar slug. Normalize the header first.bookingMeta: { userId, hostname: req.headers.host || "", - forcedSlug: req.headers["x-cal-force-slug"] as string | undefined, + forcedSlug: Array.isArray(req.headers["x-cal-force-slug"]) + ? req.headers["x-cal-force-slug"][0] + : req.headers["x-cal-force-slug"], },apps/web/pages/api/book/recurring-event.ts (1)
48-57: Sanitize bookingData and stop leaking sentinel userId
createBookingnow validates the payload against a strict schema; passingcfTokenstraight through causes the Zod parse to fail, and forcing-1intouserIdstill leaks a sentinel into downstream logic. We also losehostname/forcedSlug, so platform flows can no longer resolve the organizer slug. Please stripcfToken, keepuserIdundefined when unauthenticated, and forward the missing meta fields before calling the service.- const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ - bookingData: req.body, - bookingMeta: { - userId: session?.user?.id || -1, - platformClientId: req.platformClientId, - platformCancelUrl: req.platformCancelUrl, - platformBookingUrl: req.platformBookingUrl, - platformRescheduleUrl: req.platformRescheduleUrl, - platformBookingLocation: req.platformBookingLocation, - noEmail: req.noEmail, - }, - }); + const rawBookingData = req.body; + const sanitizedBookingData = Array.isArray(rawBookingData) + ? rawBookingData.map(({ cfToken, ...rest }) => rest) + : rawBookingData; + + const createdBookings: BookingResponse[] = await recurringBookingService.createBooking({ + bookingData: sanitizedBookingData, + bookingMeta: { + userId: session?.user?.id ?? undefined, + hostname: req.hostname, + forcedSlug: req.forcedSlug, + platformClientId: req.platformClientId, + platformCancelUrl: req.platformCancelUrl, + platformBookingUrl: req.platformBookingUrl, + platformRescheduleUrl: req.platformRescheduleUrl, + platformBookingLocation: req.platformBookingLocation, + noEmail: req.noEmail, + }, + });packages/features/bookings/lib/handleNewBooking.ts (1)
2455-2461: GuardbookingMetabefore spreading
createBooking/rescheduleBookingnow spreadinput.bookingMetadirectly; when callers omit the optional meta (the common case) we end up executing{ ...undefined }, which throws. Default the meta to{}before spreading.- return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); @@ - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps);apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
518-526: ForwardnoEmailfor seated recurring bookingsWhen
noEmailis omitted the recurring handler defaults to suppressing emails for every slot after the first one. Seated recurring bookings still need the caller’s email preference, so please passbookingRequest.noEmailthrough.bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, },apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
322-333: PassnoEmailinto recurring bookingMetaWithout forwarding
bookingRequest.noEmail, the recurring service assumesnoEmailis true for every slot after the first, so platform bookings silently drop follow-up mail. Please propagate the flag.bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, },
🧹 Nitpick comments (1)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
154-160: Refresh the comment to match the new service callWe no longer call
handleNewRecurringBookingdirectly; updating the comment keeps the test self-documenting.- // Call handleNewRecurringBooking directly instead of through API + // Call the recurring booking service directly instead of going through the API layer
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (41)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/di/InstantBookingCreateService.container.ts(1 hunks)packages/features/bookings/di/InstantBookingCreateService.module.ts(1 hunks)packages/features/bookings/di/RecurringBookingService.container.ts(1 hunks)packages/features/bookings/di/RecurringBookingService.module.ts(1 hunks)packages/features/bookings/di/RegularBookingService.container.ts(1 hunks)packages/features/bookings/di/RegularBookingService.module.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(3 hunks)packages/features/bookings/lib/handleNewBooking.ts(11 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(4 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/di/bookings/containers/InstantBookingCreateService.container.ts(0 hunks)packages/features/di/bookings/containers/RecurringBookingService.container.ts(0 hunks)packages/features/di/bookings/modules/InstantBookingCreateService.module.ts(0 hunks)packages/features/di/bookings/modules/RecurringBookingService.module.ts(0 hunks)packages/features/di/tokens.ts(1 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (5)
- packages/features/di/bookings/modules/InstantBookingCreateService.module.ts
- packages/features/di/bookings/containers/InstantBookingCreateService.container.ts
- packages/features/di/bookings/containers/RecurringBookingService.container.ts
- packages/features/di/bookings/modules/RecurringBookingService.module.ts
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (15)
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- packages/features/bookings/lib/bookingCreateBodySchema.ts
- packages/features/bookings/di/RecurringBookingService.module.ts
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- apps/web/lib/types/booking.ts
- packages/features/bookings/di/InstantBookingCreateService.container.ts
- packages/features/di/tokens.ts
- packages/features/bookings/di/RecurringBookingService.container.ts
- apps/api/v2/src/lib/modules/regular-booking.module.ts
- packages/features/bookings/lib/create-instant-booking.ts
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/web/pages/api/book/instant-event.ts
- apps/web/pages/api/book/event.ts
- packages/platform/libraries/bookings.ts
- packages/features/bookings/lib/index.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/features/bookings/di/RegularBookingService.module.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/modules/recurring-booking.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/features/bookings/di/InstantBookingCreateService.module.tspackages/features/bookings/di/RegularBookingService.container.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/features/bookings/di/RegularBookingService.module.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/modules/recurring-booking.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/features/bookings/di/InstantBookingCreateService.module.tspackages/features/bookings/di/RegularBookingService.container.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tspackages/features/instant-meeting/handleInstantMeeting.test.tspackages/features/bookings/di/RegularBookingService.module.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tspackages/features/instant-meeting/handleInstantMeeting.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/modules/recurring-booking.module.tsapps/web/pages/api/book/recurring-event.tspackages/features/bookings/types.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tsapps/api/v2/src/ee/bookings/2024-08-13/bookings.module.tspackages/features/bookings/di/InstantBookingCreateService.module.tspackages/features/bookings/di/RegularBookingService.container.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/lib/services/regular-booking.service.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
🧠 Learnings (7)
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/features/bookings/di/RegularBookingService.module.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/dto/types.d.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/di/InstantBookingCreateService.module.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-09-23T08:00:07.619Z
Learnt from: hariombalhara
PR: calcom/cal.com#23918
File: packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts:16-23
Timestamp: 2025-09-23T08:00:07.619Z
Learning: In calcom/cal.com test files, particularly packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts, the TIMEZONE_OFFSETS mapping is intentionally limited to only UTC variants and Asia/Kolkata. This is by design and should not be flagged as incomplete in future reviews (confirmed by maintainer hariombalhara).
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
🧬 Code graph analysis (19)
apps/api/v2/src/lib/modules/instant-booking.module.ts (7)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
Module(5-10)apps/api/v2/src/lib/modules/regular-booking.module.ts (1)
Module(15-32)packages/features/bookings/di/InstantBookingCreateService.module.ts (1)
InstantBookingCreateService(16-16)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/platform/libraries/bookings.ts (1)
InstantBookingCreateService(7-7)
packages/features/instant-meeting/handleInstantMeeting.test.ts (1)
packages/features/bookings/di/InstantBookingCreateService.container.ts (1)
getInstantBookingCreateService(10-13)
packages/features/bookings/di/RegularBookingService.module.ts (2)
packages/features/bookings/di/InstantBookingCreateService.module.ts (1)
moduleLoader(17-20)packages/features/bookings/di/RecurringBookingService.module.ts (1)
moduleLoader(21-24)
apps/api/v2/src/lib/services/regular-booking.service.ts (4)
apps/api/v2/src/lib/services/instant-booking-create.service.ts (1)
Injectable(5-6)apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
Injectable(6-13)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/prisma/index.ts (1)
PrismaClient(84-84)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
packages/features/bookings/di/RecurringBookingService.container.ts (1)
getRecurringBookingService(10-14)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(43-45)CreateRecurringBookingData(19-21)CreateBookingMeta(35-41)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts (2)
packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(57-57)packages/platform/types/api.ts (1)
ApiSuccessResponse(8-8)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(47-54)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/features/bookings/di/RegularBookingService.container.ts (1)
getRegularBookingService(10-14)
packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts (3)
packages/features/bookings/lib/dto/types.d.ts (1)
BookingHandlerInput(43-45)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
BookingHandlerInput(9-11)packages/features/bookings/di/RegularBookingService.container.ts (1)
getRegularBookingService(10-14)
packages/features/bookings/lib/handleNewBooking.ts (6)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1049)packages/platform/libraries/repositories.ts (4)
BookingRepository(4-4)FeaturesRepository(10-10)HostRepository(12-12)UserRepository(9-9)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(43-45)CreateRegularBookingData(15-15)CreateBookingMeta(35-41)
packages/features/bookings/lib/dto/types.d.ts (2)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/lib/modules/recurring-booking.module.ts (5)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
Module(4-8)apps/api/v2/src/lib/modules/regular-booking.module.ts (1)
Module(15-32)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)
apps/web/pages/api/book/recurring-event.ts (1)
packages/features/bookings/di/RecurringBookingService.container.ts (1)
getRecurringBookingService(10-14)
packages/features/bookings/types.ts (2)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(57-57)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(47-54)
packages/features/bookings/di/InstantBookingCreateService.module.ts (3)
packages/features/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/features/di/tokens.ts (1)
DI_TOKENS(3-58)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/lib/services/recurring-booking.service.ts (3)
apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/platform/libraries/bookings.ts (2)
RecurringBookingService(6-6)RegularBookingService(5-5)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: Production builds / Build Docs
- GitHub Check: Tests / Unit
- GitHub Check: Production builds / Build API v1
- GitHub Check: Production builds / Build Web App
- GitHub Check: Production builds / Build API v2
- GitHub Check: Production builds / Build Atoms
- GitHub Check: Type check / check-types
- GitHub Check: Linters / lint
🔇 Additional comments (14)
apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
1-8: LGTM!The module structure is consistent with the existing booking modules (RegularBookingModule, RecurringBookingModule) and follows NestJS conventions. The service is correctly registered as both a provider and an export, making it available for DI in consuming modules.
packages/features/bookings/di/InstantBookingCreateService.module.ts (1)
1-20: LGTM!The DI module setup is correct. The empty
depsMap: {}on line 13 is intentional and valid becauseInstantBookingCreateServicedoesn't require any dependencies in its constructor (it only wraps a handler function). This follows the same DI binding pattern used for other booking services in the codebase.packages/features/bookings/types.ts (2)
3-4: LGTM!The import updates correctly reference the new type location (
RegularBookingCreateResultfrom dto/types) and use the proper enum location (SchedulingTypefrom@calcom/prisma/enums).
97-98: LGTM!The type alias consolidation is a good step toward consistency. The TODO comment appropriately acknowledges that the dual naming (
BookingResponsevsRegularBookingCreateResult) should be unified in a follow-up PR to avoid churn in this already substantial refactoring.packages/features/bookings/lib/dto/types.d.ts (2)
30-32: LGTM!The new optional platform parameters (
skipAvailabilityCheck,skipEventLimitsCheck,skipCalendarSyncTaskCreation) are appropriately typed as optional booleans and provide clear feature flag semantics for platform clients to control booking behavior.
47-57: LGTM!The type definitions are consistent with the service-based architecture:
InstantBookingCreateResultprovides a clear contract for instant booking responsesRegularBookingCreateResultis correctly inferred from the service method, ensuring type safetyNote: The
expires: Datefield (line 52) will serialize to an ISO string in HTTP responses—this is existing behavior that's being preserved, as discussed in previous review comments.packages/features/bookings/di/RegularBookingService.module.ts (3)
3-12: LGTM!The new module loader imports correctly reference the required dependencies for the expanded
RegularBookingServicefunctionality. The additions include repository and service dependencies that align with the service's expanded scope.
31-35: LGTM!The five new dependencies (
luckyUserService,hostRepository,oooRepository,userRepository,attributeRepository) are correctly wired into the DI dependency map, expanding the service's capabilities beyond the original six dependencies noted in the learnings.Based on learnings
39-42: LGTM!The export rename from
regularBookingServiceModuletomoduleLoaderaligns with the consistent naming pattern used in sibling modules (InstantBookingCreateService.module.ts,RecurringBookingService.module.ts), improving consistency across the DI module surface.packages/features/instant-meeting/handleInstantMeeting.test.ts (3)
17-17: LGTM!The import correctly references the new DI container for obtaining the
InstantBookingCreateServiceinstance, aligning the tests with the service-based architecture.
39-115: LGTM!The test correctly updates to use the service-based API (
instantBookingCreateService.createBooking({ bookingData })) instead of the direct handler invocation. The test structure and assertions remain unchanged, confirming API equivalence between the old and new implementations.
138-198: LGTM!The error path test is correctly updated to use the same service-based API, and the expected error message remains consistent with the previous implementation, ensuring no behavioral changes.
packages/features/bookings/di/RegularBookingService.container.ts (1)
1-6: LGTM!The import path update to the absolute import
@calcom/features/di/diimproves maintainability. The alias (moduleLoader as regularBookingServiceModule) preserves the existing container API surface while adopting the newmoduleLoadernaming convention from the module file.apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
1-13: LGTM!The NestJS service implementation correctly extends the platform's
BaseRecurringBookingServiceand follows the established DI pattern used byRegularBookingService. The constructor properly injects the requiredRegularBookingServicedependency and passes it to the base class viasuper().
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
45-123: Include first round‑robin slot and propagate series IDWhen
isRoundRobinis true we await the first slot but never push it intocreatedBookings. With a single-slot series this means we return[], and with multi-slot series we drop the first booking. We also leavethirdPartyRecurringEventIdunset, so subsequent slots generate a fresh ID instead of sharing the first booking’s series. Please push the first result and seedthirdPartyRecurringEventIdfrom its references before looping over the remaining slots.const firstBookingResult = await regularBookingService.createBooking({ bookingData: recurringEventData, bookingMeta: { hostname: input.hostname || "", forcedSlug: input.forcedSlug as string | undefined, ...handleBookingMeta, }, }); + createdBookings.push(firstBookingResult); + if (firstBookingResult.references?.length) { + const recurringRef = firstBookingResult.references.find( + (reference) => reference.thirdPartyRecurringEventId + ); + if (recurringRef?.thirdPartyRecurringEventId) { + thirdPartyRecurringEventId = recurringRef.thirdPartyRecurringEventId; + } + } luckyUsers = firstBookingResult.luckyUsers;
♻️ Duplicate comments (2)
apps/api/v1/pages/api/bookings/_post.ts (1)
242-252: Service integration looks good, but address the header cast issue.The migration to
RegularBookingServicevia DI is correctly implemented. ThebookingDataSchemaGetterparameter is properly passed.However, the unsafe header cast at line 249 remains unaddressed from a previous review.
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (1)
515-526: Add missing noEmail to recurring seated booking.The recurring seated booking call is missing
noEmail: bookingRequest.noEmail,in the bookingMeta. This inconsistency means recurring seated bookings might suppress emails unexpectedly. Add it for consistency with the non-seated recurring booking flow (line 500).Apply this diff:
const bookings = await this.recurringBookingService.createBooking({ bookingData: bookingRequest.body, bookingMeta: { userId: bookingRequest.userId, hostname: bookingRequest.headers?.host || "", platformClientId: bookingRequest.platformClientId, platformRescheduleUrl: bookingRequest.platformRescheduleUrl, platformCancelUrl: bookingRequest.platformCancelUrl, platformBookingUrl: bookingRequest.platformBookingUrl, platformBookingLocation: bookingRequest.platformBookingLocation, + noEmail: bookingRequest.noEmail, areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }, });
🧹 Nitpick comments (3)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
540-551: Consider adding noEmail to regular bookings for consistency.The regular booking flow omits
noEmailfrom bookingMeta, while recurring bookings include it (line 500). IfnoEmailshould be respected for regular bookings, addnoEmail: bookingRequest.noEmail,to maintain consistency across booking types.If this is intentional behavior (recurring bookings handle email differently), consider adding a comment explaining why regular bookings don't pass
noEmail.
574-585: Same noEmail consideration applies to seated bookings.Similar to regular bookings, seated bookings omit
noEmailfrom bookingMeta. Consider adding it if email suppression should be respected for seated bookings.
771-782: Same noEmail consideration applies to reschedule bookings.Reschedule bookings also omit
noEmailfrom bookingMeta. For consistency, consider whether this field should be included across all booking flows that accept bookingMeta.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (41)
apps/api/v1/pages/api/bookings/_post.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts(6 hunks)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts(2 hunks)apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts(8 hunks)apps/api/v2/src/lib/modules/instant-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/recurring-booking.module.ts(1 hunks)apps/api/v2/src/lib/modules/regular-booking.module.ts(1 hunks)apps/api/v2/src/lib/services/instant-booking-create.service.ts(1 hunks)apps/api/v2/src/lib/services/recurring-booking.service.ts(1 hunks)apps/api/v2/src/lib/services/regular-booking.service.ts(1 hunks)apps/web/lib/types/booking.ts(1 hunks)apps/web/pages/api/book/event.ts(2 hunks)apps/web/pages/api/book/instant-event.ts(2 hunks)apps/web/pages/api/book/recurring-event.ts(2 hunks)packages/features/bookings/di/InstantBookingCreateService.container.ts(1 hunks)packages/features/bookings/di/InstantBookingCreateService.module.ts(1 hunks)packages/features/bookings/di/RecurringBookingService.container.ts(1 hunks)packages/features/bookings/di/RecurringBookingService.module.ts(1 hunks)packages/features/bookings/di/RegularBookingService.container.ts(1 hunks)packages/features/bookings/di/RegularBookingService.module.ts(2 hunks)packages/features/bookings/lib/bookingCreateBodySchema.ts(1 hunks)packages/features/bookings/lib/create-instant-booking.ts(1 hunks)packages/features/bookings/lib/dto/types.d.ts(3 hunks)packages/features/bookings/lib/handleNewBooking.ts(11 hunks)packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts(6 hunks)packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts(1 hunks)packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts(4 hunks)packages/features/bookings/lib/handleNewRecurringBooking.ts(4 hunks)packages/features/bookings/lib/index.ts(1 hunks)packages/features/bookings/types.ts(2 hunks)packages/features/di/bookings/containers/InstantBookingCreateService.container.ts(0 hunks)packages/features/di/bookings/containers/RecurringBookingService.container.ts(0 hunks)packages/features/di/bookings/modules/InstantBookingCreateService.module.ts(0 hunks)packages/features/di/bookings/modules/RecurringBookingService.module.ts(0 hunks)packages/features/di/tokens.ts(1 hunks)packages/features/instant-meeting/handleInstantMeeting.test.ts(5 hunks)packages/features/instant-meeting/handleInstantMeeting.ts(3 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (5)
- packages/features/di/bookings/modules/InstantBookingCreateService.module.ts
- packages/features/di/bookings/modules/RecurringBookingService.module.ts
- packages/features/di/bookings/containers/InstantBookingCreateService.container.ts
- packages/platform/libraries/index.ts
- packages/features/di/bookings/containers/RecurringBookingService.container.ts
✅ Files skipped from review due to trivial changes (1)
- packages/features/di/tokens.ts
🚧 Files skipped from review as they are similar to previous changes (14)
- packages/features/bookings/lib/handleNewBooking/test/email-verification-booking.test.ts
- apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts
- apps/api/v2/src/lib/services/instant-booking-create.service.ts
- packages/platform/libraries/bookings.ts
- packages/features/bookings/di/RecurringBookingService.container.ts
- packages/features/bookings/di/RecurringBookingService.module.ts
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts
- apps/web/pages/api/book/event.ts
- apps/web/pages/api/book/recurring-event.ts
- packages/features/bookings/lib/handleNewBooking/test/getNewBookingHandler.ts
- apps/web/pages/api/book/instant-event.ts
- packages/features/bookings/di/RegularBookingService.module.ts
- packages/features/instant-meeting/handleInstantMeeting.test.ts
- apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tspackages/features/bookings/lib/index.tspackages/features/bookings/lib/create-instant-booking.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/di/RegularBookingService.container.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/api/v2/src/lib/modules/regular-booking.module.tspackages/features/bookings/di/InstantBookingCreateService.container.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/bookingCreateBodySchema.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tsapps/web/lib/types/booking.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/lib/modules/recurring-booking.module.tspackages/features/bookings/di/InstantBookingCreateService.module.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tspackages/features/bookings/lib/index.tspackages/features/bookings/lib/create-instant-booking.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/di/RegularBookingService.container.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/api/v2/src/lib/modules/regular-booking.module.tspackages/features/bookings/di/InstantBookingCreateService.container.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/bookingCreateBodySchema.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tsapps/web/lib/types/booking.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/lib/modules/recurring-booking.module.tspackages/features/bookings/di/InstantBookingCreateService.module.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
apps/api/v2/src/lib/modules/instant-booking.module.tspackages/features/bookings/lib/index.tspackages/features/bookings/lib/create-instant-booking.tspackages/features/instant-meeting/handleInstantMeeting.tspackages/features/bookings/di/RegularBookingService.container.tsapps/api/v2/src/lib/services/regular-booking.service.tspackages/features/bookings/types.tspackages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/api/v2/src/lib/modules/regular-booking.module.tspackages/features/bookings/di/InstantBookingCreateService.container.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tspackages/features/bookings/lib/bookingCreateBodySchema.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tsapps/web/lib/types/booking.tspackages/features/bookings/lib/handleNewBooking.tsapps/api/v1/pages/api/bookings/_post.tspackages/features/bookings/lib/handleNewRecurringBooking.tsapps/api/v2/src/lib/modules/recurring-booking.module.tspackages/features/bookings/di/InstantBookingCreateService.module.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
**/*.{service,repository}.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Avoid dot-suffixes like
.service.tsor.repository.tsfor new files; reserve.test.ts,.spec.ts,.types.tsfor their specific purposes
Files:
apps/api/v2/src/lib/services/regular-booking.service.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/lib/services/recurring-booking.service.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
apps/api/v2/src/lib/services/regular-booking.service.tsapps/api/v2/src/lib/modules/regular-booking.module.tsapps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.tspackages/features/bookings/lib/dto/types.d.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/bookings/lib/handleNewRecurringBooking.tspackages/features/bookings/di/InstantBookingCreateService.module.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: The test file packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.test.ts explicitly documents on line 236 that the current behavior of forceRescheduleForCancelledBooking affecting both CANCELLED and REJECTED bookings is known to be incorrect, but is preserved as "Current Behavior" for backward compatibility. The test comment states the expected behavior should be that REJECTED bookings redirect to booking details even when forceRescheduleForCancelledBooking=true.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tsapps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.tspackages/features/bookings/lib/handleNewRecurringBooking.ts
📚 Learning: 2025-09-23T08:00:07.619Z
Learnt from: hariombalhara
PR: calcom/cal.com#23918
File: packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts:16-23
Timestamp: 2025-09-23T08:00:07.619Z
Learning: In calcom/cal.com test files, particularly packages/features/schedules/lib/use-schedule/useTimesForSchedule.test.ts, the TIMEZONE_OFFSETS mapping is intentionally limited to only UTC variants and Asia/Kolkata. This is by design and should not be flagged as incomplete in future reviews (confirmed by maintainer hariombalhara).
Applied to files:
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.
Applied to files:
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts
📚 Learning: 2025-08-17T22:00:16.329Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts:117-126
Timestamp: 2025-08-17T22:00:16.329Z
Learning: In calcom/cal.com PR #22995, packages/trpc/server/routers/viewer/aiVoiceAgent/_router.ts, the enabled input parameter in the update endpoint is intentionally not forwarded to aiService.updateAgentConfiguration() as the enabled/disabled agent functionality is not required at the moment (per maintainer Udit-takkar). Future reviews should not flag this as missing functionality unless requirements change.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
📚 Learning: 2025-09-12T11:23:34.158Z
Learnt from: hariombalhara
PR: calcom/cal.com#23736
File: packages/features/bookings/lib/reschedule/determineReschedulePreventionRedirect.ts:73-84
Timestamp: 2025-09-12T11:23:34.158Z
Learning: In the Cal.com codebase, the forceRescheduleForCancelledBooking flag historically affects both CANCELLED and REJECTED booking statuses, despite its name suggesting it should only affect cancelled bookings. This behavior existed before PR #23736 and was preserved during the refactoring.
Applied to files:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
🧬 Code graph analysis (18)
apps/api/v2/src/lib/modules/instant-booking.module.ts (7)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
Module(5-10)apps/api/v2/src/lib/modules/regular-booking.module.ts (1)
Module(15-32)packages/features/bookings/di/InstantBookingCreateService.module.ts (1)
InstantBookingCreateService(16-16)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/platform/libraries/bookings.ts (1)
InstantBookingCreateService(7-7)
packages/features/bookings/lib/create-instant-booking.ts (3)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (1)
createInstantBooking(357-390)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(47-54)packages/lib/fetch-wrapper.ts (1)
post(28-36)
packages/features/instant-meeting/handleInstantMeeting.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateInstantBookingData(17-17)InstantBookingCreateResult(47-54)packages/features/bookings/lib/interfaces/IBookingCreateService.ts (1)
IBookingCreateService(4-7)
apps/api/v2/src/lib/services/regular-booking.service.ts (4)
apps/api/v2/src/lib/services/instant-booking-create.service.ts (1)
Injectable(5-6)apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
Injectable(6-13)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/prisma/index.ts (1)
PrismaClient(84-84)
packages/features/bookings/types.ts (2)
apps/web/lib/types/booking.ts (1)
BookingResponse(3-3)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(57-57)
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
packages/features/bookings/di/RecurringBookingService.container.ts (1)
getRecurringBookingService(10-14)
apps/api/v2/src/lib/modules/regular-booking.module.ts (5)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
Module(4-8)apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
Module(5-10)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)
packages/features/bookings/di/InstantBookingCreateService.container.ts (3)
packages/features/di/di.ts (1)
createContainer(114-114)packages/features/bookings/di/InstantBookingCreateService.module.ts (2)
InstantBookingCreateService(16-16)instantBookingCreateServiceModule(5-5)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (3)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts (4)
packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)packages/features/bookings/lib/dto/types.d.ts (1)
InstantBookingCreateResult(47-54)
packages/features/bookings/lib/dto/types.d.ts (4)
packages/features/bookings/lib/bookingCreateBodySchema.ts (1)
ExtendedBookingCreateBody(100-100)packages/platform/libraries/bookings.ts (3)
InstantBookingCreateResult(9-9)RegularBookingCreateResult(10-10)RegularBookingService(5-5)packages/features/bookings/di/RegularBookingService.module.ts (1)
RegularBookingService(44-44)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)
apps/web/lib/types/booking.ts (3)
packages/features/bookings/types.ts (1)
BookingResponse(98-98)packages/features/bookings/lib/dto/types.d.ts (1)
RegularBookingCreateResult(57-57)packages/platform/libraries/bookings.ts (1)
RegularBookingCreateResult(10-10)
packages/features/bookings/lib/handleNewBooking.ts (6)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/platform/libraries/bookings.ts (3)
CheckBookingAndDurationLimitsService(4-4)CheckBookingLimitsService(3-3)LuckyUserService(1-1)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1049)packages/lib/server/getLuckyUser.ts (1)
LuckyUserService(193-1133)packages/features/bookings/lib/dto/types.d.ts (4)
BookingHandlerInput(43-45)CreateRegularBookingData(15-15)CreateBookingMeta(35-41)BookingDataSchemaGetter(13-13)
apps/api/v1/pages/api/bookings/_post.ts (1)
packages/features/bookings/di/RegularBookingService.container.ts (1)
getRegularBookingService(10-14)
packages/features/bookings/lib/handleNewRecurringBooking.ts (2)
packages/features/bookings/lib/dto/types.d.ts (2)
CreateRecurringBookingData(19-21)CreateBookingMeta(35-41)packages/features/bookings/types.ts (1)
BookingResponse(98-98)
apps/api/v2/src/lib/modules/recurring-booking.module.ts (5)
apps/api/v2/src/ee/bookings/2024-04-15/bookings.module.ts (1)
Module(29-61)apps/api/v2/src/ee/bookings/2024-08-13/bookings.module.ts (1)
Module(47-98)apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
Module(4-8)apps/api/v2/src/lib/modules/regular-booking.module.ts (1)
Module(15-32)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)
packages/features/bookings/di/InstantBookingCreateService.module.ts (3)
packages/features/di/di.ts (1)
bindModuleToClassOnToken(57-113)packages/features/di/tokens.ts (1)
DI_TOKENS(3-58)packages/features/instant-meeting/handleInstantMeeting.ts (1)
InstantBookingCreateService(338-342)
apps/api/v2/src/lib/services/recurring-booking.service.ts (4)
apps/api/v2/src/lib/services/instant-booking-create.service.ts (1)
Injectable(5-6)apps/api/v2/src/lib/services/regular-booking.service.ts (1)
Injectable(17-46)packages/features/bookings/lib/handleNewRecurringBooking.ts (1)
RecurringBookingService(134-152)packages/features/bookings/lib/handleNewBooking.ts (1)
RegularBookingService(2452-2481)
🔇 Additional comments (17)
packages/features/bookings/di/RegularBookingService.container.ts (1)
1-14: LGTM! Clean DI container setup.The import path update and module loader aliasing are correct. The
getRegularBookingServicefunction properly instantiates the service through the DI container following the established pattern.apps/api/v2/src/lib/modules/instant-booking.module.ts (1)
1-8: LGTM! Well-structured NestJS module.The module correctly declares and exports
InstantBookingCreateService, following NestJS conventions. This aligns with the DI-based booking service pattern introduced in this PR.packages/features/bookings/lib/index.ts (1)
9-9: LGTM! Type export aligns with refactoring.The
BookingResponsetype export centralizes the booking result type, supporting the shift from dynamicReturnTypeto explicitRegularBookingCreateResult.packages/features/bookings/di/InstantBookingCreateService.container.ts (1)
1-13: LGTM! Consistent DI container pattern.The container setup for
InstantBookingCreateServicefollows the same pattern asRegularBookingService, ensuring consistency across the booking service architecture.apps/web/lib/types/booking.ts (1)
1-3: LGTM! Improved type definition.Replacing the dynamic
Awaited<ReturnType<...>>with an explicitRegularBookingCreateResultimproves type clarity and maintainability. This aligns with the service-based refactoring.apps/api/v2/src/lib/services/recurring-booking.service.ts (1)
1-13: LGTM! Proper NestJS service extension.The
RecurringBookingServicecorrectly extends the base class and properly injectsRegularBookingServicethrough NestJS DI. The constructor delegation tosuperfollows the expected pattern.packages/features/bookings/di/InstantBookingCreateService.module.ts (1)
1-20: LGTM! DI module correctly configured.The module setup properly binds
InstantBookingCreateServicewith an empty dependencies map, which is correct since this service has no constructor dependencies. ThemoduleLoaderexport pattern is consistent with other booking service modules.apps/api/v2/src/lib/modules/recurring-booking.module.ts (1)
1-10: LGTM!The module wiring is clean and follows NestJS conventions. The RecurringBookingService correctly depends on RegularBookingModule, which provides the RegularBookingService it needs.
apps/api/v2/src/lib/modules/regular-booking.module.ts (1)
15-31: LGTM!The module correctly wires all dependencies for RegularBookingService. The provider list includes all repositories and services needed, and properly exports RegularBookingService for consumption by other modules. Based on learnings, this aligns with the expected IBookingServiceDependencies pattern and extends it with additional v2-specific dependencies.
Based on learnings.
packages/features/bookings/lib/create-instant-booking.ts (1)
9-10: Acknowledged technical debt for serialization.The TODO correctly identifies that
expires: Datein the type will be serialized to a string over-the-wire. This is acceptable technical debt for a follow-up PR.packages/features/bookings/types.ts (1)
97-98: LGTM!The type alias consolidates BookingResponse to use RegularBookingCreateResult, aligning with the service-based refactor. The TODO appropriately acknowledges the naming inconsistency will be addressed in a follow-up PR.
packages/features/bookings/lib/handleNewBooking/test/handleNewRecurringBooking.test.ts (1)
154-161: LGTM!The test correctly migrates to the service-based approach using
getRecurringBookingService()and the new payload structure withbookingDataandbookingMeta. The-1userId appropriately simulates an anonymous user scenario.packages/features/bookings/lib/bookingCreateBodySchema.ts (2)
60-76: LGTM!The new
recurringBookingCreateBodyPartialSchemaappropriately modularizes recurring-specific fields. The optionalendfield (line 71) is intentional to handle cases wherehandleNewRecurringBookingmay passendas undefined. As per coding guidelines.
78-100: LGTM!The restructured schema cleanly separates recurring-specific fields into the partial schema, improving maintainability. The exported
ExtendedBookingCreateBodytype provides proper typing for consumers.apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts (2)
113-115: LGTM!The three new service dependencies (RegularBookingService, RecurringBookingService, InstantBookingCreateService) are correctly injected via the constructor, replacing the previous platform library handler approach.
470-472: LGTM!Instant bookings correctly use
instantBookingCreateService.createBookingwith onlybookingData(nobookingMeta), which aligns with the instant booking flow that doesn't require metadata like userId or platform URLs.apps/api/v2/src/lib/services/regular-booking.service.ts (1)
17-46: Verify type cast necessity.The service correctly extends
BaseRegularBookingServiceand wires dependencies through NestJS DI. However, the type cast on line 35 (prismaWriteService.prisma as unknown as PrismaClient) suggests a type mismatch between the v2 Prisma service and the base service's expected type.Verify that this type cast is necessary and that there are no type safety concerns. Check if
prismaWriteService.prismaandPrismaClientare compatible:
apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts
Show resolved
Hide resolved
|
@coderabbitai can you please resume where any logic is being changed, if we have any changes. |
|
Tip For best results, initiate chat on the files or code changes. @volnei, based on the AI-generated summaries, this PR is primarily an architectural refactoring with minimal logic changes. Here's a breakdown: 🏗️ Architectural Changes (No Logic Impact)
🔄 Minimal Logic ChangesThe booking creation logic itself appears preserved. The core algorithms, validation, error handling, and booking flow remain unchanged—they're just wrapped in service classes now. One subtle potential change mentioned in the summaries:
📍 Files UpdatedAPI Endpoints (all use new services):
Core Logic (now with DI):
Summary: This is a well-structured refactoring that improves testability and maintainability without altering the booking business logic. The changes are primarily about how the code is organized and invoked, not what it does. |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/features/bookings/lib/handleNewBooking.ts (1)
1635-1640: Fix attendee lookup to use parsed booker variables.The attendee lookup should use the already-parsed
bookerEmailandbookerPhoneNumbervariables instead of accessingbookingData.responsesdirectly, which may have unexpected structure or be undefined.Apply this diff:
const currentAttendee = booking.attendees.find( (attendee) => - attendee.email === bookingData.responses.email || - (bookingData.responses.attendeePhoneNumber && - attendee.phoneNumber === bookingData.responses.attendeePhoneNumber) + attendee.email === bookerEmail || + (bookerPhoneNumber && attendee.phoneNumber === bookerPhoneNumber) );
🧹 Nitpick comments (1)
packages/features/bookings/lib/handleNewBooking.ts (1)
2460-2466: Consider consistent bookingMeta handling for clarity.While spreading
undefinedis safe in JavaScript (it's a no-op), consider explicitly defaultingbookingMetato{}for consistency withcreateBookingForApiV1(line 2476).Apply this diff for consistency:
async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); } async rescheduleBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { - return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); + const bookingMeta = input.bookingMeta ?? {}; + return handler({ bookingData: input.bookingData, ...bookingMeta }, this.deps); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
packages/features/bookings/lib/handleNewBooking.ts(12 hunks)packages/platform/libraries/bookings.ts(1 hunks)packages/platform/libraries/index.ts(0 hunks)
💤 Files with no reviewable changes (1)
- packages/platform/libraries/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/platform/libraries/bookings.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/features/bookings/lib/handleNewBooking.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js
.utc()in hot paths like loops
Files:
packages/features/bookings/lib/handleNewBooking.ts
**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.
Files:
packages/features/bookings/lib/handleNewBooking.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.
Applied to files:
packages/features/bookings/lib/handleNewBooking.ts
🧬 Code graph analysis (1)
packages/features/bookings/lib/handleNewBooking.ts (4)
packages/features/calendar-cache/lib/getShouldServeCache.ts (1)
CacheService(7-15)packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts (1)
CheckBookingAndDurationLimitsService(21-54)packages/lib/server/repository/booking.ts (1)
BookingRepository(124-1049)packages/features/bookings/lib/dto/types.d.ts (3)
BookingHandlerInput(43-45)CreateRegularBookingData(15-15)CreateBookingMeta(35-41)
🪛 Biome (2.1.2)
packages/features/bookings/lib/handleNewBooking.ts
[error] 57-57: Shouldn't redeclare 'enrichHostsWithDelegationCredentials'. Consider to delete it or rename it.
'enrichHostsWithDelegationCredentials' is defined here:
(lint/suspicious/noRedeclare)
[error] 58-58: Shouldn't redeclare 'getFirstDelegationConferencingCredentialAppLocation'. Consider to delete it or rename it.
'getFirstDelegationConferencingCredentialAppLocation' is defined here:
(lint/suspicious/noRedeclare)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (2)
packages/features/bookings/lib/handleNewBooking.ts (2)
418-430: LGTM: DI interface is comprehensive.The
IBookingServiceDependenciesinterface properly defines all required dependencies for the booking service, enabling constructor-based dependency injection.Based on learnings
432-459: LGTM: DI implementation is clean.The handler signature and dependency usage correctly implement the dependency injection pattern, accepting
depsas a parameter and extracting only the dependencies needed in the immediate scope.
What does this PR do?