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
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.
a04e401 to
5ff4ae2
Compare
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
5ff4ae2 to
071c6b2
Compare
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.
071c6b2 to
55c0ba0
Compare
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().
55c0ba0 to
d134d11
Compare
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?