Skip to content

feat: api v2 event type settings - booker bookings limit, emails, round robin reschedule#24169

Merged
supalarry merged 23 commits intomainfrom
lauris/cal-6470-chore-support-more-event-type-settings-via-api-v2
Oct 15, 2025
Merged

feat: api v2 event type settings - booker bookings limit, emails, round robin reschedule#24169
supalarry merged 23 commits intomainfrom
lauris/cal-6470-chore-support-more-event-type-settings-via-api-v2

Conversation

@supalarry
Copy link
Contributor

@supalarry supalarry commented Sep 30, 2025

@supalarry supalarry requested a review from a team September 30, 2025 10:20
@supalarry supalarry requested review from a team as code owners September 30, 2025 10:20
@linear
Copy link

linear bot commented Sep 30, 2025

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 30, 2025

Walkthrough

Adds booker-level active booking limits and reschedule controls to the API: new input/output DTOs (bookerActiveBookingsLimit, EmailSettings, BookerActiveBookingsLimitOutput), validators (CantHaveRecurrenceAndBookerActiveBookingsLimit, RequiresAtLeastOnePropertyWhenNotDisabled), metadata plumbing in event-type create/update/transform services, output shaping, and OpenAPI schema updates. Expands e2e tests for max-per-booker and reschedule flows, tightens booking test guards from any to unknown, and maps new booking-limit error codes to BadRequestException messages (optionally including a reschedule UID).

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The pull request includes an unrelated change to the example booking page for prefilled form values, which is not part of the linked issues’ objectives around event type settings and should be moved to a separate commit or PR. Extract the example booking page modification into its own pull request or remove it to keep this PR focused solely on the event type settings scope.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and specifically summarises the addition of new API v2 event type settings for booking limits, email configurations, and round-robin rescheduling, which exactly matches the primary focus of the changeset.
Linked Issues Check ✅ Passed The changes fully implement the linked issues’ coding objectives by adding booker active booking limits with validation and error handling, integrating reschedule-with-same-round-robin-host flags for team event types, and supporting email disable settings through inputs, services, outputs, and corresponding tests.
Description Check ✅ Passed The pull request description references the correct linked issues that drive the implementation and is directly related to the changeset by indicating the issues resolved, so it is on-topic.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch lauris/cal-6470-chore-support-more-event-type-settings-via-api-v2

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 30, 2025

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:

No release type found in pull request title "Lauris/cal 6470 chore support more event type settings via api v2". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@graphite-app graphite-app bot requested a review from a team September 30, 2025 10:20
@keithwillcode keithwillcode added core area: core, team members only platform Anything related to our platform plan labels Sep 30, 2025
@supalarry supalarry changed the title Lauris/cal 6470 chore support more event type settings via api v2 feat: api v2 event type settings - booker bookings limit, emails, round robin reschedule Sep 30, 2025
@vercel
Copy link

vercel bot commented Sep 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
cal Ignored Ignored Oct 10, 2025 3:51pm
cal-eu Ignored Ignored Oct 10, 2025 3:51pm

@dosubot dosubot bot added the event-types area: event types, event-types label Sep 30, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
apps/api/v2/src/ee/bookings/2024-08-13/services/errors.service.ts (1)

55-63: Consider stricter type validation for rescheduleUid.

The type cast (error.data as { rescheduleUid: string }) assumes the shape without runtime validation. If error.data.rescheduleUid exists but isn't a string, it could produce an incorrect error message.

Apply this diff to add runtime type validation:

-      } else if (error.message === "booker_limit_exceeded_error_reschedule") {
-        const errorData =
-          "data" in error ? (error.data as { rescheduleUid: string }) : { rescheduleUid: undefined };
-        let message =
-          "Attendee with this email can't book because the maximum number of active bookings has been reached.";
-        if (errorData?.rescheduleUid) {
-          message += ` You can reschedule your existing booking (${errorData.rescheduleUid}) to a new timeslot instead.`;
-        }
-        throw new BadRequestException(message);
+      } else if (error.message === "booker_limit_exceeded_error_reschedule") {
+        let message =
+          "Attendee with this email can't book because the maximum number of active bookings has been reached.";
+        const rescheduleUid =
+          "data" in error &&
+          error.data &&
+          typeof error.data === "object" &&
+          "rescheduleUid" in error.data &&
+          typeof error.data.rescheduleUid === "string"
+            ? error.data.rescheduleUid
+            : undefined;
+        if (rescheduleUid) {
+          message += ` You can reschedule your existing booking (${rescheduleUid}) to a new timeslot instead.`;
+        }
+        throw new BadRequestException(message);
apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (2)

3172-3180: Improved type safety in type guard.

The change from any to unknown and the explicit data !== null check improve type safety. The null check is necessary because typeof null === "object" in JavaScript.

Note: The condition has some redundancy - data !== null && data can be simplified to just data !== null since the subsequent checks would fail for falsy values anyway, but the current form is explicit and clear.

Optional simplification:

-function responseDataIsRecurranceBooking(data: unknown): data is RecurringBookingOutput_2024_08_13 {
-  return (
-    !Array.isArray(data) &&
-    typeof data === "object" &&
-    data !== null &&
-    data &&
-    "id" in data &&
-    "recurringBookingUid" in data
-  );
-}
+function responseDataIsRecurranceBooking(data: unknown): data is RecurringBookingOutput_2024_08_13 {
+  return (
+    !Array.isArray(data) &&
+    typeof data === "object" &&
+    data !== null &&
+    "id" in data &&
+    "recurringBookingUid" in data
+  );
+}

3192-3198: Improved type safety in file-level type guards.

Both type guard functions now use unknown instead of any, which enforces proper type checking at call sites. This is a best practice for type guard implementations.

The same optional simplification mentioned in the previous comment applies to responseDataIsBooking (removing the redundant && data check after data !== null).

apps/api/v2/src/modules/organizations/event-types/services/input.service.ts (1)

178-230: LGTM! EmailSettings handling in update transform mirrors create path.

The implementation correctly handles emailSettings in the update flow with the same logic as the create path. The metadata transformation is properly applied at line 226.

However, there's significant code duplication between lines 135-154 (create) and lines 194-213 (update). Consider extracting the metadata transformation logic into a private helper method to improve maintainability.

Suggested refactor to reduce duplication:

private buildEmailSettingsMetadata(
  emailSettings: { disableStandardEmailsToAttendees?: boolean; disableStandardEmailsToHosts?: boolean } | undefined,
  existingMetadata: any
) {
  if (
    emailSettings?.disableStandardEmailsToAttendees === undefined &&
    emailSettings?.disableStandardEmailsToHosts === undefined
  ) {
    return existingMetadata;
  }

  return {
    ...existingMetadata,
    disableStandardEmails: {
      ...existingMetadata?.disableStandardEmails,
      all: {
        ...existingMetadata?.disableStandardEmails?.all,
        ...(emailSettings?.disableStandardEmailsToAttendees !== undefined && {
          attendee: emailSettings.disableStandardEmailsToAttendees,
        }),
        ...(emailSettings?.disableStandardEmailsToHosts !== undefined && {
          host: emailSettings.disableStandardEmailsToHosts,
        }),
      },
    },
  };
}

Then replace both blocks with:

metadata = this.buildEmailSettingsMetadata(emailSettings, metadata);
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 2ef627b and dbd7b26.

📒 Files selected for processing (16)
  • apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (3 hunks)
  • apps/api/v2/src/ee/bookings/2024-08-13/services/errors.service.ts (1 hunks)
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (5 hunks)
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts (13 hunks)
  • apps/api/v2/src/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.ts (4 hunks)
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts (7 hunks)
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (6 hunks)
  • packages/platform/libraries/event-types.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (6 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/index.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (5 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (5 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/index.ts (1 hunks)
🧰 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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/platform/types/event-types/event-types_2024_06_14/inputs/index.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts
  • apps/api/v2/src/ee/bookings/2024-08-13/services/errors.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts
  • apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/index.ts
  • packages/platform/libraries/event-types.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.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/platform/types/event-types/event-types_2024_06_14/inputs/index.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts
  • apps/api/v2/src/ee/bookings/2024-08-13/services/errors.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts
  • apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/index.ts
  • packages/platform/libraries/event-types.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.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/platform/types/event-types/event-types_2024_06_14/inputs/index.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts
  • apps/api/v2/src/ee/bookings/2024-08-13/services/errors.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts
  • apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/index.ts
  • packages/platform/libraries/event-types.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts
**/*.{service,repository}.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Avoid dot-suffixes like .service.ts or .repository.ts for new files; reserve .test.ts, .spec.ts, .types.ts for their specific purposes

Files:

  • apps/api/v2/src/ee/bookings/2024-08-13/services/errors.service.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
🧠 Learnings (4)
📚 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-08-13/controllers/e2e/user-bookings.e2e-spec.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/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.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/event-types/event-types_2024_06_14/services/input-event-types.service.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.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/platform/libraries/event-types.ts
🧬 Code graph analysis (6)
apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (1)
packages/platform/types/bookings/2024-08-13/outputs/booking.output.ts (2)
  • BookingOutput_2024_08_13 (280-306)
  • RecurringBookingOutput_2024_08_13 (308-323)
packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (3)
packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1)
  • BookerActiveBookingsLimit_2024_06_14 (4-25)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)
  • EmailSettings_2024_06_14 (4-22)
packages/platform/types/event-types/event-types_2024_06_14/inputs/disabled.input.ts (1)
  • Disabled_2024_06_14 (4-13)
apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts (3)
packages/platform/libraries/event-types.ts (1)
  • EventTypeMetadata (21-21)
packages/prisma/zod-utils.ts (1)
  • bookerLayouts (53-58)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (1)
  • CreateEventTypeInput_2024_06_14 (511-530)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (3)
packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1)
  • BookerActiveBookingsLimit_2024_06_14 (4-25)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)
  • EmailSettings_2024_06_14 (4-22)
packages/platform/types/event-types/event-types_2024_06_14/inputs/disabled.input.ts (1)
  • Disabled_2024_06_14 (4-13)
apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (2)
packages/platform/libraries/event-types.ts (1)
  • EventTypeMetadata (21-21)
packages/prisma/zod-utils.ts (1)
  • EventTypeMetadata (135-135)
packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (2)
packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts (1)
  • EmailSettingsOutput_2024_06_14 (4-20)
packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1)
  • BookerActiveBookingsLimit_2024_06_14 (4-25)
🔇 Additional comments (29)
apps/api/v2/src/ee/bookings/2024-08-13/services/errors.service.ts (1)

51-54: LGTM! Clear error handling for booker limit.

The error handling is straightforward and the message clearly communicates the issue to the user.

packages/platform/types/event-types/event-types_2024_06_14/outputs/index.ts (1)

4-4: LGTM!

The re-export of email settings output follows the established pattern and ensures the new EmailSettingsOutput_2024_06_14 type is publicly accessible.

packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (4)

33-33: LGTM!

The new imports for BookerActiveBookingsLimit_2024_06_14 and EmailSettingsOutput_2024_06_14 are correctly added with named imports and appropriate paths.

Also applies to: 62-62


183-184: LGTM!

The additions to @ApiExtraModels correctly register the new types for Swagger documentation, ensuring proper API schema generation.


352-355: LGTM!

The bookerActiveBookingsLimit property is correctly added with appropriate decorators for validation, transformation, and API documentation.


538-552: LGTM with a note on conditional validation.

The emailSettings and rescheduleWithSameRoundRobinHost properties are correctly implemented with appropriate decorators and clear documentation. The rescheduleWithSameRoundRobinHost property is semantically tied to round-robin scheduling—ensure upstream validation or business logic enforces that this field is only meaningful when schedulingType === "roundRobin".

packages/platform/libraries/event-types.ts (1)

21-21: LGTM! Type-only export is appropriate.

The type-only export of EventTypeMetadata is correctly structured and aligns with the PR's goal of exposing metadata types for the new event type settings.

packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)

1-22: LGTM! Email settings DTO is well-structured.

The DTO correctly defines optional boolean flags for disabling standard emails to attendees and hosts, with appropriate validation and API documentation.

packages/platform/types/event-types/event-types_2024_06_14/inputs/index.ts (1)

12-12: LGTM! Export correctly added.

The email settings input is properly re-exported through the module index.

apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts (9)

31-35: LGTM! Imports are correctly added.

The new imports for EventTypeMetadata, EventTypeMetaDataSchema, and validateCustomEventName are properly integrated into the service methods.


74-80: LGTM! Explicit conditional validation is clearer.

The refactoring from short-circuit evaluation to explicit if statements improves readability without changing the validation logic.


102-108: LGTM! Consistent validation pattern.

The update method correctly mirrors the create method's explicit conditional validation approach.


177-190: LGTM! Transformation logic is correct.

The method properly handles both disabled and absent booker active bookings limits, transforming the input DTO to the internal database schema format.


141-172: LGTM! Metadata construction integrates new features correctly.

The create method properly:

  1. Transforms the booker active bookings limit input
  2. Constructs the metadata object with the appropriate fields
  3. Spreads both metadata and max bookings settings into the event type payload

212-256: LGTM! Update method preserves existing metadata correctly.

The update path properly:

  1. Retrieves and parses existing metadata
  2. Merges new metadata fields while preserving unmodified ones
  3. Integrates booker bookings limit settings

359-359: LGTM! Simplified truthiness check.

The change from !!res ? res : {} to res ? res : {} is a minor simplification with no functional difference.


409-410: Verify seats validation behavior when explicitly set to 0.

The condition changed from checking seatsPerTimeSlot !== undefined to just seatsPerTimeSlot, meaning an explicit value of 0 will now fall back to seatsPerTimeSlotDb instead of being used.

If the intent is to allow setting seatsPerTimeSlot: 0 to explicitly disable seats (overriding a DB value), this change would break that. However, if 0 is invalid input (enforced by @Min(1) validation elsewhere), this simplification is correct.

Please confirm whether:

  1. seatsPerTimeSlot: 0 is a valid input to disable seats, or
  2. The validation prevents 0 from reaching this code

If (1), consider reverting to the explicit undefined check:

-    const seatsPerTimeSlotFinal = seatsPerTimeSlot ? seatsPerTimeSlot : seatsPerTimeSlotDb;
+    const seatsPerTimeSlotFinal = seatsPerTimeSlot !== undefined ? seatsPerTimeSlot : seatsPerTimeSlotDb;

434-435: LGTM! ESLint disable is justified.

The any type for transformLocations is necessary because it handles dynamic JSON data from Prisma's JSON type, which is inherently untyped. The method safely validates the structure using InternalLocationSchema.safeParse.

apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (1)

517-520: LGTM! Comprehensive test coverage for bookerActiveBookingsLimit.

The tests properly validate the new bookerActiveBookingsLimit field in both create and update workflows, including the disabled flag scenario for resetting the value.

Also applies to: 595-595, 1212-1214, 1298-1298, 1320-1320

packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (2)

250-270: LGTM! Transform logic correctly discriminates union types.

The Transform decorator properly handles both BookerActiveBookingsLimit_2024_06_14 and Disabled_2024_06_14 by checking for discriminant properties, consistent with existing patterns for recurrence and seats.


515-529: LGTM! Team event type fields properly validated.

The emailSettings and rescheduleWithSameRoundRobinHost fields are correctly decorated with appropriate validators and documentation.

apps/api/v2/src/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.ts (1)

358-362: LGTM! Team event type email settings properly tested.

The tests validate emailSettings and rescheduleWithSameRoundRobinHost in both create and update workflows, including toggling values to ensure the fields are mutable.

Also applies to: 393-393, 609-613, 628-629

packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (2)

303-323: LGTM! Booker active bookings limit properly configured.

The Transform decorator correctly discriminates between BookerActiveBookingsLimit_2024_06_14 and Disabled_2024_06_14, consistent with the update input.


620-634: LGTM! Team event type creation fields properly defined.

The emailSettings and rescheduleWithSameRoundRobinHost fields are correctly decorated. The documentation notes that emailSettings is only available for organization team event types, which should be enforced at the business logic layer.

apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (2)

207-222: LGTM! Email settings transformation logic is sound.

The transformEmailSettings method correctly:

  1. Returns undefined when no email settings are configured in metadata
  2. Checks if at least one field (attendee or host) is explicitly set before constructing the response object
  3. Defaults unset fields to false when the other field is set

This ensures a clear distinction between "no email settings configured" (undefined) and "email settings partially configured" (object with false defaults).


88-88: LGTM! RescheduleWithSameRoundRobinHost properly integrated.

The field is correctly added to the Input type, destructured, and included in the response object.

Also applies to: 104-105, 127-127, 139-139

apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (2)

2497-2497: LGTM! Error message format correction.

The change from escaped quotes to actual quotes ensures the test assertion matches the actual error message format.


3029-3168: LGTM! Comprehensive test coverage for max bookings per booker.

The test suite properly validates:

  • Preventing duplicate bookings when limit is reached
  • Allowing bookings from different attendees
  • Offering reschedule option when configured
  • Appropriate error messages for both scenarios

The tests are well-structured and cover the critical paths for this feature.

apps/api/v2/src/modules/organizations/event-types/services/input.service.ts (1)

117-171: LGTM! Proper handling of emailSettings in create transform.

The implementation correctly:

  • Destructures emailSettings from the input (line 117)
  • Conditionally augments metadata when email settings are provided (lines 135-154)
  • Preserves existing metadata using spread operators
  • Handles attendee and host settings independently
  • Properly assigns the computed metadata to the returned teamEventType (line 166)

The nested spreads ensure that existing metadata is not lost during the transformation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
packages/platform/examples/base/src/pages/booking.tsx (1)

28-28: Consider adding localization for user-facing text.

User-facing strings should use the t() function for localization. The following text should be localized:

  • Line 28: "Public Booking Page"
  • Line 34: "User event types"
  • Line 64: "Team event types"
  • Line 160: "Booking created:"

As per coding guidelines.

Example for line 28:

-        <h1 className="mx-10 my-4 text-2xl font-semibold">{props.calUsername} Public Booking Page</h1>
+        <h1 className="mx-10 my-4 text-2xl font-semibold">{props.calUsername} {t("public_booking_page")}</h1>

Also applies to: 34-34, 64-64, 160-160

docs/api-reference/v2/openapi.json (3)

15281-15294: Consider specifying required fields.

The BookerActiveBookingsLimit_2024_06_14 schema doesn't specify which properties are required. If both maximumActiveBookings and offerReschedule are mandatory for this feature to work correctly, add a required array to the schema definition.

Example:

         "offerReschedule": {
           "type": "boolean",
           "description": "Whether to offer rescheduling the last active booking to the chosen time slot when limit is reached."
         }
-      }
+      },
+      "required": ["maximumActiveBookings"]
     },

19479-19490: Minor description inconsistency.

The description for emailSettings uses "Only available" (capital O) here, while line 19130 uses "only available" (lowercase o). Consider standardizing the capitalization for consistency.

         "emailSettings": {
-          "description": "Email settings for this event type. Only available for organization team event types.",
+          "description": "Email settings for this event type - only available for organization team event types.",
           "allOf": [

19959-19970: Maintain description consistency.

Same capitalization note as the previous comment—"Only available" here versus "only available" on line 19130. Consider standardizing across all three occurrences (lines 19130, 19480, 19960).

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between dbd7b26 and f189e99.

📒 Files selected for processing (2)
  • docs/api-reference/v2/openapi.json (12 hunks)
  • packages/platform/examples/base/src/pages/booking.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • packages/platform/examples/base/src/pages/booking.tsx
**/*.{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/platform/examples/base/src/pages/booking.tsx
**/*.{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/platform/examples/base/src/pages/booking.tsx
docs/api-reference/v2/openapi.json

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

When docs changes are made in /docs/api-reference/v2/openapi.json, ensure 'summary' fields are short, concise, do not end with a period, and are written in proper American English

Files:

  • docs/api-reference/v2/openapi.json
🧠 Learnings (2)
📚 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/platform/examples/base/src/pages/booking.tsx
📚 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/platform/examples/base/src/pages/booking.tsx
🔇 Additional comments (10)
packages/platform/examples/base/src/pages/booking.tsx (1)

97-97: LGTM! Appropriate demo values for example page.

The hardcoded defaultFormValues with placeholder name and email are appropriate for this example/demo page, clearly demonstrating the new prefill capability introduced in this PR.

docs/api-reference/v2/openapi.json (9)

15632-15644: LGTM!

The EmailSettings_2024_06_14 schema is well-structured with clear descriptions for both attendee and host email preferences.


15805-15815: LGTM!

The bookerActiveBookingsLimit property correctly uses oneOf to allow either configured limits or disabled state, with a clear description.


16873-16885: LGTM!

The EmailSettingsOutput_2024_06_14 schema maintains consistency with the input schema, using the same property definitions and descriptions.


17359-17369: LGTM!

Consistent implementation of bookerActiveBookingsLimit with the same oneOf pattern used elsewhere in the input schemas.


18941-18951: LGTM!

Consistent implementation across multiple input schemas.


19128-19142: LGTM!

Both emailSettings and rescheduleWithSameRoundRobinHost are well-defined with clear descriptions. The note about emailSettings being available only for organization team event types is helpful context.


19373-19375: Consistent with other output schemas.

This follows the same pattern as line 17072-17074, directly referencing the limit schema without the oneOf wrapper. Refer to the earlier verification comment about ensuring this approach aligns with the intended API behavior for disabled states.


19778-19788: LGTM!

Consistent implementation maintaining the established pattern for input schemas.


17072-17074: Align bookerActiveBookingsLimit output schema with input schema’s oneOf pattern
The output schema at docs/api-reference/v2/openapi.json (lines 17072–17074) references only #/components/schemas/BookerActiveBookingsLimit_2024_06_14, whereas the input definitions (e.g. around lines 15807, 17361, 18943, 19780) use a oneOf including Disabled_2024_06_14. Confirm whether the disabled state should be representable in responses; if so, update this field to the same oneOf pattern.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
docs/api-reference/v2/openapi.json (4)

15281-15294: Minor inconsistency in description punctuation.

The description for maximumActiveBookings (line 15286) ends with a period, while the description for offerReschedule (line 15291) does not. For consistency across the schema, ensure all descriptions either end with periods or none do.

Apply this diff to maintain consistency:

           "offerReschedule": {
             "type": "boolean",
-            "description": "Whether to offer rescheduling the last active booking to the chosen time slot when limit is reached."
+            "description": "Whether to offer rescheduling the last active booking to the chosen time slot when limit is reached"
           }

Or alternatively, ensure maximumActiveBookings also omits the period if that's the preferred style.


16873-16885: Consider schema reuse if input and output are identical.

EmailSettingsOutput_2024_06_14 is structurally identical to EmailSettings_2024_06_14 (lines 15632-15644). If the input and output schemas will always remain identical, consider having both reference a single base schema to reduce duplication and maintenance burden.

However, if future API evolution might require different input vs. output fields, keeping them separate provides flexibility.


19479-19486: Minor inconsistency in emailSettings description.

The description for emailSettings in the output schema (line 19480) uses a period and "Only" (capitalized), while the input schema version (line 19130) uses a dash and "only" (lowercase). For consistency, these descriptions should be identical since they describe the same field.

Apply this diff to align with the input schema style:

           "emailSettings": {
-            "description": "Email settings for this event type. Only available for organization team event types.",
+            "description": "Email settings for this event type - only available for organization team event types.",
             "allOf": [

19959-19966: Inconsistent emailSettings description across input schemas.

The emailSettings description in this update input schema (line 19960) uses a period and capitalized "Only", matching the output schema style. However, the create input schema (line 19130) uses a dash and lowercase "only". For consistency, all input schemas should use the same description format.

Apply this diff to align with the create input schema style:

           "emailSettings": {
-            "description": "Email settings for this event type. Only available for organization team event types.",
+            "description": "Email settings for this event type - only available for organization team event types.",
             "allOf": [
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between f189e99 and 88877d7.

📒 Files selected for processing (3)
  • docs/api-reference/v2/openapi.json (12 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.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/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.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/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts
docs/api-reference/v2/openapi.json

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

When docs changes are made in /docs/api-reference/v2/openapi.json, ensure 'summary' fields are short, concise, do not end with a period, and are written in proper American English

Files:

  • docs/api-reference/v2/openapi.json
🧬 Code graph analysis (1)
packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts (1)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (2)
  • disableStandardEmailsToAttendeesDescription (4-5)
  • disableStandardEmailsToHostsDescription (6-7)
🔇 Additional comments (9)
packages/platform/types/event-types/event-types_2024_06_14/outputs/email-settings.output.ts (1)

1-23: LGTM! Past review concern has been resolved.

The implementation correctly addresses the previous review feedback by importing differentiated descriptions from the input file. The descriptions now clearly distinguish between attendee-targeted and host-targeted email settings, maintaining DRY principles while improving API documentation clarity.

docs/api-reference/v2/openapi.json (8)

15632-15644: LGTM!

The EmailSettings_2024_06_14 schema is well-structured with clear, consistent descriptions for both properties. The parallel structure between attendee and host settings makes the API intuitive.


15805-15815: LGTM!

The bookerActiveBookingsLimit property correctly uses oneOf to allow either configured limits or a disabled state, providing flexibility in API usage.


17072-17074: LGTM!

The output schema appropriately uses a direct reference to BookerActiveBookingsLimit_2024_06_14 without the oneOf pattern, simplifying the output structure.


17359-17369: LGTM!

Consistent implementation of bookerActiveBookingsLimit using the same pattern as other input schemas.


18941-18951: LGTM!

Consistent implementation maintains API coherence across different schema versions.


19128-19140: LGTM!

Both new properties are well-documented. The constraint that emailSettings is "only available for organization team event types" is clearly stated, helping API consumers understand when this field can be used.


19373-19375: LGTM!

Consistent output schema pattern maintained.


19778-19788: LGTM!

Consistent implementation of the booking limit feature across schema versions.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
apps/api/v2/src/modules/organizations/event-types/services/input.service.ts (1)

135-154: Consider extracting the emailSettings metadata logic into a helper method.

This exact metadata augmentation pattern is duplicated at lines 194-213 in the update path. Extracting it into a private helper method would improve maintainability and reduce the risk of divergence.

Example refactor:

private augmentMetadataWithEmailSettings(
  metadata: any,
  emailSettings?: { disableEmailsToAttendees?: boolean; disableEmailsToHosts?: boolean }
) {
  if (
    emailSettings?.disableEmailsToAttendees === undefined &&
    emailSettings?.disableEmailsToHosts === undefined
  ) {
    return metadata;
  }

  return {
    ...metadata,
    disableStandardEmails: {
      ...metadata?.disableStandardEmails,
      all: {
        ...metadata?.disableStandardEmails?.all,
        ...(emailSettings?.disableEmailsToAttendees !== undefined && {
          attendee: emailSettings.disableEmailsToAttendees,
        }),
        ...(emailSettings?.disableEmailsToHosts !== undefined && {
          host: emailSettings.disableEmailsToHosts,
        }),
      },
    },
  };
}

Then use it in both create and update paths:

-    if (
-      emailSettings?.disableEmailsToAttendees !== undefined ||
-      emailSettings?.disableEmailsToHosts !== undefined
-    ) {
-      metadata = {
-        ...metadata,
-        disableStandardEmails: {
-          ...metadata?.disableStandardEmails,
-          all: {
-            ...metadata?.disableStandardEmails?.all,
-            ...(emailSettings?.disableEmailsToAttendees !== undefined && {
-              attendee: emailSettings.disableEmailsToAttendees,
-            }),
-            ...(emailSettings?.disableEmailsToHosts !== undefined && {
-              host: emailSettings.disableEmailsToHosts,
-            }),
-          },
-        },
-      };
-    }
+    metadata = this.augmentMetadataWithEmailSettings(metadata, emailSettings);
docs/api-reference/v2/openapi.json (3)

15289-15291: Clarify which booking gets rescheduled.

The description "Whether to offer rescheduling the last active booking" is ambiguous. Does "last" mean the most recent, the oldest, or does the user choose? Consider rewording to clarify which booking is offered for rescheduling when the limit is reached.

Suggested alternative:

-          "description": "Whether to offer rescheduling the last active booking to the chosen time slot when limit is reached."
+          "description": "Whether to offer rescheduling an existing active booking to the chosen time slot when the limit is reached."

15635-15642: Consider standard formatting for emphasis.

The use of all-caps "DOES NOT" in both descriptions is unconventional for API documentation. Consider using standard formatting or rephrasing for consistency with typical OpenAPI conventions.

Suggested alternatives:

  • Use italics or bold in rendered documentation
  • Rephrase: "Disables all email communication to attendees for this event type, including booking confirmations, reminders, and cancellations. Custom email workflows are not affected by this setting."

19116-19123: Consider consistent punctuation in description.

The description uses a dash to separate the availability constraint. Consider using a period or parentheses for better readability and consistency with other descriptions in the schema.

Suggested alternative:

-          "description": "Email settings for this event type - only available for organization team event types.",
+          "description": "Email settings for this event type. Only available for organization team event types.",
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 88877d7 and a94fc93.

📒 Files selected for processing (6)
  • apps/api/v2/src/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.ts (4 hunks)
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts (7 hunks)
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (6 hunks)
  • docs/api-reference/v2/openapi.json (11 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts
  • apps/api/v2/src/modules/organizations/event-types/organizations-member-team-admin-event-types.e2e-spec.ts
🧰 Additional context used
📓 Path-based instructions (5)
docs/api-reference/v2/openapi.json

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

When docs changes are made in /docs/api-reference/v2/openapi.json, ensure 'summary' fields are short, concise, do not end with a period, and are written in proper American English

Files:

  • docs/api-reference/v2/openapi.json
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.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:

  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.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:

  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts
  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
**/*.{service,repository}.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Avoid dot-suffixes like .service.ts or .repository.ts for new files; reserve .test.ts, .spec.ts, .types.ts for their specific purposes

Files:

  • apps/api/v2/src/modules/organizations/event-types/services/input.service.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
🧠 Learnings (1)
📚 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/modules/organizations/event-types/services/output.service.ts
🧬 Code graph analysis (2)
packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (2)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)
  • EmailSettings_2024_06_14 (4-20)
packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1)
  • BookerActiveBookingsLimit_2024_06_14 (4-25)
apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (2)
packages/platform/libraries/event-types.ts (1)
  • EventTypeMetadata (21-21)
packages/prisma/zod-utils.ts (1)
  • EventTypeMetadata (135-135)
🔇 Additional comments (12)
docs/api-reference/v2/openapi.json (1)

15805-15815: LGTM!

The property definition correctly uses oneOf to allow either enabling the feature with specific settings or disabling it. The description is clear and concise.

apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (6)

7-7: LGTM: Clean import of EventTypeMetadata.

The import is properly sourced from the platform libraries package.


88-88: LGTM: Input type correctly extended.

The rescheduleWithSameRoundRobinHost field is appropriately added to the Input type Pick.


100-102: LGTM: Metadata transformation properly invoked.

The metadata is correctly transformed using the existing service method, and the emailSettings derivation follows logically.


104-105: LGTM: Destructuring includes new field.

The rescheduleWithSameRoundRobinHost field is properly destructured alongside existing fields.


127-127: LGTM: New fields properly included in response.

Both emailSettings and rescheduleWithSameRoundRobinHost are correctly added to the return object.

Also applies to: 139-139


207-222: transformEmailSettings logic is correct
The guard ensures an object is only returned when at least one flag is explicitly set, and explicit false values correctly yield { disableEmailsToAttendees: false, disableEmailsToHosts: false }. No changes needed.

packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (5)

33-33: LGTM: Imports properly added.

Both BookerActiveBookingsLimit_2024_06_14 and EmailSettings_2024_06_14 are correctly imported from their respective input files.

Also applies to: 39-39


183-184: LGTM: EmailSettings registered in ApiExtraModels.

The EmailSettings_2024_06_14 is correctly added to the @ApiExtraModels decorator to ensure OpenAPI schema generation includes this nested type.


352-355: LGTM: bookerActiveBookingsLimit properly defined.

The field is correctly decorated with @IsOptional(), @Type(), and @ApiPropertyOptional(). The type transformation is appropriate for nested object validation.


538-545: LGTM: emailSettings properly defined.

The field is correctly decorated with @IsOptional(), @ValidateNested(), @Type(), and @ApiPropertyOptional(). The description clearly indicates this is only available for organization team event types.


547-552: LGTM: rescheduleWithSameRoundRobinHost properly defined.

The boolean field is correctly decorated with @IsBoolean(), @IsOptional(), and @ApiPropertyOptional(). The description is clear and concise.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)

4-4: Use a type-only import to avoid a runtime dependency cycle

BaseCreateEventTypeInput is referenced purely in a type assertion, yet the value import forces Node to execute create-event-type.input while that same file already imports this validator. Switching to a type-only import drops the redundant runtime require, keeps tree-shaking intact, and sidesteps the circular dependency at load time.

-import { BaseCreateEventTypeInput } from "../create-event-type.input";
+import type { BaseCreateEventTypeInput } from "../create-event-type.input";
apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (1)

209-224: Consider safer navigation in transformEmailSettings.

The method assumes metadata.disableStandardEmails.all is an object with attendee and host properties when it exists. If the metadata structure is malformed (e.g., all is null or a non-object), the destructuring on line 214 could fail.

Consider adding a type guard or additional check:

  private transformEmailSettings(metadata: EventTypeMetadata) {
-   if (!metadata?.disableStandardEmails?.all) {
+   if (!metadata?.disableStandardEmails?.all || typeof metadata.disableStandardEmails.all !== 'object') {
      return undefined;
    }

    const { attendee, host } = metadata.disableStandardEmails.all;

Alternatively, if the EventTypeMetadata type guarantees that all is always an object when present, this is safe as-is.

apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (1)

1449-1620: LGTM: Comprehensive test coverage for bookerActiveBookingsLimit.

The test suite thoroughly covers both negative (invalid combinations) and positive (valid creation/update) scenarios. Error message assertions use imported constants, ensuring consistency.

However, note that eventTypeWithBookerActiveBookingsLimitId is not cleaned up in the afterAll hook. If the test creates event types that persist, consider adding cleanup to avoid test pollution:

afterAll(async () => {
  // Existing cleanup...
  try {
    if (eventTypeWithBookerActiveBookingsLimitId) {
      await eventTypesRepositoryFixture.delete(eventTypeWithBookerActiveBookingsLimitId);
    }
  } catch (e) {
    console.log(e);
  }
  await app.close();
});
packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (1)

38-38: Verify intentional sharing of EmailSettings_2024_06_14 between input and output.

EmailSettings_2024_06_14 is imported from the inputs directory ("../inputs/email-settings.input"). While this is valid if the structure is identical for both input and output, it's unusual. Typically, output types are defined separately in the outputs directory.

If the structure is the same for both directions, this is acceptable. Otherwise, consider creating a separate EmailSettingsOutput_2024_06_14 type in the outputs directory for clarity.

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between ec563dc and bce6062.

📒 Files selected for processing (9)
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (2 hunks)
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts (7 hunks)
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformed/event-type.tranformed.ts (1 hunks)
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (6 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (9 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (8 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/booker-active-bookings-limit.output.ts (1 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (5 hunks)
🧰 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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformed/event-type.tranformed.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/booker-active-bookings-limit.output.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.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/ee/event-types/event-types_2024_06_14/transformed/event-type.tranformed.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/booker-active-bookings-limit.output.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.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/ee/event-types/event-types_2024_06_14/transformed/event-type.tranformed.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/booker-active-bookings-limit.output.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts
**/*.{service,repository}.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Avoid dot-suffixes like .service.ts or .repository.ts for new files; reserve .test.ts, .spec.ts, .types.ts for their specific purposes

Files:

  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
🧠 Learnings (2)
📚 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/event-types/event-types_2024_06_14/services/output-event-types.service.ts
  • apps/api/v2/src/modules/organizations/event-types/services/output.service.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.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/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
🧬 Code graph analysis (7)
apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts (2)
packages/platform/libraries/index.ts (1)
  • parseRecurringEvent (77-77)
apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/recurrence.ts (1)
  • transformRecurrenceInternalToApi (4-12)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (4)
packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1)
  • BookerActiveBookingsLimit_2024_06_14 (4-25)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)
  • EmailSettings_2024_06_14 (4-20)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)
  • CantHaveRecurrenceAndBookerActiveBookingsLimit (12-49)
packages/platform/types/event-types/event-types_2024_06_14/inputs/disabled.input.ts (1)
  • Disabled_2024_06_14 (4-13)
apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (2)
packages/platform/libraries/event-types.ts (1)
  • EventTypeMetadata (21-21)
packages/prisma/zod-utils.ts (1)
  • EventTypeMetadata (135-135)
packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (5)
packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1)
  • BookerActiveBookingsLimit_2024_06_14 (4-25)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)
  • EmailSettings_2024_06_14 (4-20)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (2)
  • CantHaveRecurrenceAndBookerActiveBookingsLimit (183-512)
  • Host (541-561)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)
  • CantHaveRecurrenceAndBookerActiveBookingsLimit (12-49)
packages/platform/types/event-types/event-types_2024_06_14/inputs/disabled.input.ts (1)
  • Disabled_2024_06_14 (4-13)
packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (2)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)
  • EmailSettings_2024_06_14 (4-20)
packages/platform/types/event-types/event-types_2024_06_14/outputs/booker-active-bookings-limit.output.ts (1)
  • BookerActiveBookingsLimitOutput_2024_06_14 (4-21)
apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (2)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (2)
  • FAILED_RECURRING_EVENT_TYPE_WITH_BOOKER_LIMITS_ERROR_MESSAGE (6-7)
  • HAS_MISSING_ACTIVE_BOOKER_LIMIT_ERROR_MESSAGE (9-10)
packages/platform/types/api.ts (1)
  • ApiSuccessResponse (8-8)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (1)
  • CantHaveRecurrenceAndBookerActiveBookingsLimit (183-512)
🔇 Additional comments (12)
apps/api/v2/src/modules/organizations/event-types/services/output.service.ts (4)

7-7: LGTM: Centralized import improves maintainability.

The import of EventTypeMetadata from @calcom/platform-libraries/event-types centralizes type definitions and aligns with the PR's goal of consolidating event-type types.


102-107: LGTM: Metadata transformation and field extraction are clear.

The delegation of metadata transformation to outputEventTypesService.transformMetadata is appropriate, and the new transformEmailSettings method cleanly derives email settings. The destructuring of rescheduleWithSameRoundRobinHost is straightforward.


129-141: LGTM: New fields correctly added to the output.

The emailSettings and rescheduleWithSameRoundRobinHost fields are correctly added to the response object. Both are appropriately optional/nullable based on their derivation.


88-90: Verified Prisma schema includes new fields: rescheduleWithSameRoundRobinHost, maxActiveBookingPerBookerOfferReschedule, and maxActiveBookingsPerBooker are defined in the EventType model.

apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (1)

34-47: LGTM: Type-only imports and error message constants improve maintainability.

The use of type modifiers for imports is good practice, improving tree-shaking. Importing validator error messages from the validator module ensures consistency and reduces magic strings in tests.

packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (3)

183-184: LGTM: EmailSettings_2024_06_14 added to ApiExtraModels.

Adding EmailSettings_2024_06_14 to ApiExtraModels ensures it's correctly included in the OpenAPI schema for nested objects in API responses.


352-355: LGTM: bookerActiveBookingsLimit correctly added to output.

The bookerActiveBookingsLimit property is correctly defined as optional, with proper decorators for class transformation (@Type) and OpenAPI documentation (@ApiPropertyOptional).


538-552: LGTM: New team event type output properties are well-defined.

The emailSettings and rescheduleWithSameRoundRobinHost properties are correctly added to TeamEventTypeOutput_2024_06_14 with:

  • Proper decorators for validation and transformation
  • Clear API documentation describing their purpose and availability

The note that emailSettings is "only available for organization team event types" is helpful for API consumers.

packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (4)

24-130: LGTM: Imports and ApiExtraModels correctly updated.

All new imports (BookerActiveBookingsLimit_2024_06_14, EmailSettings_2024_06_14, CantHaveRecurrenceAndBookerActiveBookingsLimit) are from the correct locations, and the new types are properly added to ApiExtraModels for OpenAPI schema generation.


183-184: LGTM: Class-level validator ensures valid input combinations.

The @CantHaveRecurrenceAndBookerActiveBookingsLimit() decorator correctly enforces business rules at the class level:

  • Prevents enabling both recurrence and bookerActiveBookingsLimit simultaneously
  • Validates that when bookerActiveBookingsLimit.disabled is false, at least one of maximumActiveBookings or offerReschedule is provided

This is the appropriate place for cross-property validation.


305-325: LGTM: bookerActiveBookingsLimit transformation follows existing patterns.

The @Transform logic correctly coerces objects into either BookerActiveBookingsLimit_2024_06_14 or Disabled_2024_06_14 based on the presence of specific keys. This pattern is consistent with similar properties (recurrence, seats) elsewhere in the file.

The transformation handles the following cases:

  • Objects with maximumActiveBookings or offerRescheduleBookerActiveBookingsLimit_2024_06_14
  • Objects with disabledDisabled_2024_06_14
  • Other values → pass through unchanged

If a value is an object but doesn't match either case, it will pass through unchanged and likely fail validation, which is the expected behavior.


598-637: LGTM: New team event input properties are well-defined.

The new properties for CreateTeamEventTypeInput_2024_06_14 are correctly implemented:

  • emailSettings: Properly decorated with @ValidateNested() and @Type() for nested validation and transformation. The description clearly indicates it's only for organization team event types.
  • rescheduleWithSameRoundRobinHost: Simple boolean property with clear description.

The minor formatting improvement in the assignAllTeamMembers description also enhances readability.

@supalarry supalarry enabled auto-merge (squash) October 3, 2025 08:06
@github-actions github-actions bot added api area: API, enterprise API, access token, OAuth Medium priority Created by Linear-GitHub Sync reactive⚡︎ ✨ feature New feature or request labels Oct 7, 2025
@graphite-app graphite-app bot requested a review from a team October 7, 2025 10:30
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)

9-40: Prefer returning false over throwing inside validators; attach error to a real property

  • Don’t throw HttpException in validators; return false and rely on defaultMessage. This integrates with ValidationPipe and prior review already requested this.
  • Attach the constraint to an actual property (e.g., "recurrence") instead of a synthetic name for clearer error paths.
   return function (object: any) {
     registerDecorator({
       name: "cantHaveRecurrenceAndBookerActiveBookingsLimit",
-      target: object,
-      propertyName: "recurrence or bookerActiveBookingsLimit",
+      target: object,
+      propertyName: "recurrence",
       options: validationOptions,
       constraints: [],
       validator: {
         validate(_: unknown, args: ValidationArguments) {
           const obj = args.object as BaseCreateEventTypeInput;
@@
-          if (hasActiveRecurrence && hasActiveBookerLimit) {
-            throw new BadRequestException(FAILED_RECURRING_EVENT_TYPE_WITH_BOOKER_LIMITS_ERROR_MESSAGE);
-          }
+          if (hasActiveRecurrence && hasActiveBookerLimit) {
+            return false;
+          }
           return true;
         },
         defaultMessage(): string {
           return FAILED_RECURRING_EVENT_TYPE_WITH_BOOKER_LIMITS_ERROR_MESSAGE;
         },
packages/platform/types/utils/RequiresOneOfPropertiesWhenNotDisabled.ts (1)

37-39: Return false instead of throwing inside validators

Align with class-validator patterns and previous feedback: don’t throw HttpException here; return false and let defaultMessage handle the error text.

-          if (!hasAtLeastOneOtherProperty) {
-            throw new BadRequestException(REQUIRES_AT_LEAST_ONE_PROPERTY_ERROR);
-          }
+          if (!hasAtLeastOneOtherProperty) {
+            return false;
+          }
🧹 Nitpick comments (2)
packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (1)

248-269: Use strict boolean check for disabled in Transform

Avoid truthiness to prevent misclassification (e.g., "false" string). Check for disabled === true explicitly.

   @Transform(({ value }) => {
     if (value && typeof value === "object") {
-      if ("disabled" in value && value.disabled) {
+      if ("disabled" in value && value.disabled === true) {
         return Object.assign(new Disabled_2024_06_14(), value);
       } else {
         return Object.assign(new BookerActiveBookingsLimit_2024_06_14(), value);
       }
     }
     return value;
   })
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (1)

306-327: Use strict boolean check for disabled in Transform

Prefer disabled === true to avoid truthy pitfalls from malformed inputs.

 @RequiresAtLeastOnePropertyWhenNotDisabled()
 @Transform(({ value }) => {
   if (value && typeof value === "object") {
-    if ("disabled" in value && value.disabled) {
+    if ("disabled" in value && value.disabled === true) {
       return Object.assign(new Disabled_2024_06_14(), value);
     } else {
       return Object.assign(new BookerActiveBookingsLimit_2024_06_14(), value);
     }
   }
   return value;
 })
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between bce6062 and 0aabe63.

📒 Files selected for processing (5)
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (2 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (9 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (8 hunks)
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1 hunks)
  • packages/platform/types/utils/RequiresOneOfPropertiesWhenNotDisabled.ts (1 hunks)
🧰 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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • packages/platform/types/utils/RequiresOneOfPropertiesWhenNotDisabled.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.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/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • packages/platform/types/utils/RequiresOneOfPropertiesWhenNotDisabled.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.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/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts
  • packages/platform/types/utils/RequiresOneOfPropertiesWhenNotDisabled.ts
  • packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts
  • apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
🧠 Learnings (2)
📚 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/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.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/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts
🧬 Code graph analysis (4)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (1)
  • CantHaveRecurrenceAndBookerActiveBookingsLimit (184-514)
packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (6)
packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1)
  • BookerActiveBookingsLimit_2024_06_14 (4-25)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)
  • EmailSettings_2024_06_14 (4-20)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (2)
  • CantHaveRecurrenceAndBookerActiveBookingsLimit (184-514)
  • Host (543-563)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)
  • CantHaveRecurrenceAndBookerActiveBookingsLimit (9-40)
packages/platform/types/event-types/event-types_2024_06_14/inputs/disabled.input.ts (1)
  • Disabled_2024_06_14 (4-13)
packages/platform/types/utils/RequiresOneOfPropertiesWhenNotDisabled.ts (1)
  • RequiresAtLeastOnePropertyWhenNotDisabled (13-49)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (5)
packages/platform/types/event-types/event-types_2024_06_14/inputs/booker-active-booking-limit.input.ts (1)
  • BookerActiveBookingsLimit_2024_06_14 (4-25)
packages/platform/types/event-types/event-types_2024_06_14/inputs/email-settings.input.ts (1)
  • EmailSettings_2024_06_14 (4-20)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)
  • CantHaveRecurrenceAndBookerActiveBookingsLimit (9-40)
packages/platform/types/utils/RequiresOneOfPropertiesWhenNotDisabled.ts (1)
  • RequiresAtLeastOnePropertyWhenNotDisabled (13-49)
packages/platform/types/event-types/event-types_2024_06_14/inputs/disabled.input.ts (1)
  • Disabled_2024_06_14 (4-13)
apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (6)
packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (1)
  • CreateEventTypeInput_2024_06_14 (515-534)
packages/platform/types/event-types/event-types_2024_06_14/inputs/validators/CantHaveRecurrenceAndBookerActiveBookingsLimit.ts (1)
  • FAILED_RECURRING_EVENT_TYPE_WITH_BOOKER_LIMITS_ERROR_MESSAGE (6-7)
packages/platform/types/utils/RequiresOneOfPropertiesWhenNotDisabled.ts (1)
  • REQUIRES_AT_LEAST_ONE_PROPERTY_ERROR (10-11)
packages/platform/types/api.ts (1)
  • ApiSuccessResponse (8-8)
packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts (1)
  • EventTypeOutput_2024_06_14 (483-492)
packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (1)
  • UpdateEventTypeInput_2024_06_14 (457-476)
⏰ 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 (4)
apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts (2)

34-45: LGTM!

The type-only imports follow TypeScript best practices, and importing error message constants from their source modules ensures test assertions stay in sync with validation logic.


1447-1499: LGTM!

The negative test coverage is comprehensive and correctly validates:

  1. Mutual exclusivity of enabled recurrence and bookerActiveBookingsLimit
  2. Required properties when disabled: false is specified

Error assertions using imported constants ensure tests stay in sync with validation logic.

packages/platform/types/event-types/event-types_2024_06_14/inputs/update-event-type.input.ts (1)

518-533: LGTM: email settings and RR reschedule flags

Field shapes, validation, and docs look good.

packages/platform/types/event-types/event-types_2024_06_14/inputs/create-event-type.input.ts (1)

625-639: LGTM: team email settings and RR reschedule flag

Looks good; validations and docs are clear.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (2)

3176-3185: Type guard improved, consider simplifying redundant checks.

The change from implicit any to unknown is excellent for type safety. However, the null check at line 3180 and the truthy check at line 3181 are redundant.

Consider this simpler version:

 function responseDataIsRecurranceBooking(data: unknown): data is RecurringBookingOutput_2024_08_13 {
   return (
-    !Array.isArray(data) &&
-    typeof data === "object" &&
-    data !== null &&
-    data &&
-    "id" in data &&
-    "recurringBookingUid" in data
+    typeof data === "object" &&
+    data !== null &&
+    !Array.isArray(data) &&
+    "id" in data &&
+    "recurringBookingUid" in data
   );
 }

3196-3198: Type guard improved, consider simplifying redundant checks.

The change from implicit any to unknown improves type safety. The redundant checks (data !== null && data) can be simplified.

Consider this simpler version:

 function responseDataIsBooking(data: unknown): data is BookingOutput_2024_08_13 {
-  return !Array.isArray(data) && typeof data === "object" && data !== null && data && "id" in data;
+  return typeof data === "object" && data !== null && !Array.isArray(data) && "id" in data;
 }
📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 0aabe63 and 1835016.

📒 Files selected for processing (1)
  • apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (3 hunks)
🧰 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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.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/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.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/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts
🧠 Learnings (1)
📚 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/controllers/e2e/user-bookings.e2e-spec.ts
🧬 Code graph analysis (1)
apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (1)
packages/platform/types/bookings/2024-08-13/outputs/booking.output.ts (2)
  • BookingOutput_2024_08_13 (280-306)
  • RecurringBookingOutput_2024_08_13 (308-323)
⏰ 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)
apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (2)

2497-2497: LGTM! Error message formatting improved.

The change from escaped quotes to actual quotes improves readability in the test assertion.


3200-3202: LGTM! Type guard properly updated.

The change from implicit any to unknown improves type safety. The simple array check is appropriate for this guard.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (1)

3172-3180: Approve type safety improvements; consider fixing function name typo.

The change from any to unknown and the explicit null check improve type safety.

However, the function name typo (responseDataIsRecurranceBooking vs. responseDataIsRecurringBooking at line 3196) makes these similar functions harder to distinguish. One checks for a single recurring booking object, the other for an array. Consider renaming to responseDataIsRecurringBooking (fixing the typo) in a follow-up to reduce confusion.

📜 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 1835016 and 9e37ab2.

📒 Files selected for processing (1)
  • apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (3 hunks)
🧰 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 use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.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/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.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/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts
🧠 Learnings (2)
📚 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/controllers/e2e/user-bookings.e2e-spec.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-08-13/controllers/e2e/user-bookings.e2e-spec.ts
🧬 Code graph analysis (1)
apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (1)
packages/platform/types/bookings/2024-08-13/outputs/booking.output.ts (2)
  • BookingOutput_2024_08_13 (280-306)
  • RecurringBookingOutput_2024_08_13 (308-323)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Production builds / Build Docs
  • GitHub Check: Production builds / Build Web App
  • GitHub Check: Production builds / Build Atoms
  • GitHub Check: Production builds / Build API v1
  • GitHub Check: Production builds / Build API v2
  • GitHub Check: Tests / Unit
  • GitHub Check: Type check / check-types
  • GitHub Check: Linters / lint
🔇 Additional comments (3)
apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/user-bookings.e2e-spec.ts (3)

2497-2497: LGTM: Error message improved.

The removal of escaped quotes improves readability of the user-facing error message.


3030-3168: LGTM: Comprehensive tests for max bookings per booker.

The tests appropriately verify:

  • Limit enforcement per attendee email
  • Different attendees can still book independently
  • Error messaging with and without reschedule offer
  • Reschedule UID inclusion when maxActiveBookingPerBookerOfferReschedule is enabled

The debug artifacts flagged in the previous review have been cleaned up.


3192-3198: LGTM: Type guard improvements enhance type safety.

Changing from any to unknown and adding explicit null checks aligns with TypeScript best practices and provides better type safety for runtime type narrowing.

Copy link
Contributor

@ThyMinimalDev ThyMinimalDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

@supalarry supalarry merged commit bb9d99c into main Oct 15, 2025
40 checks passed
@supalarry supalarry deleted the lauris/cal-6470-chore-support-more-event-type-settings-via-api-v2 branch October 15, 2025 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api area: API, enterprise API, access token, OAuth core area: core, team members only event-types area: event types, event-types ✨ feature New feature or request Medium priority Created by Linear-GitHub Sync platform Anything related to our platform plan reactive⚡︎ ready-for-e2e size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: support more event type settings via api v2

4 participants