feat: add missing event type fields for advanced settings in api v2 (#25739)

* feat: api v2 add missing event type fields for advanced settings

Add 9 event type fields to API v2 that were available in tRPC but missing from the platform API:

- disableCancelling: disable cancelling for guests/organizer
- disableRescheduling: disable rescheduling for guests/organizer
- canSendCalVideoTranscriptionEmails: send Cal Video transcription emails
- autoTranslateInstantMeetingTitleEnabled: auto-translate instant meeting titles
- interfaceLanguage: preferred booking interface language
- allowReschedulingPastBookings: allow rescheduling past events
- allowReschedulingCancelledBookings: allow booking via reschedule link
- customReplyToEmail: custom reply-to email for confirmations
- showOptimizedSlots: optimize time slot arrangement

Updated output/input schemas, transformation services, and E2E tests.

* fix(api-v2): add proper OpenAPI types for nullable event type fields

Add explicit type and nullable properties to @ApiPropertyOptional decorators
for fields with `boolean | null` or `string | null` types. Without these,
Swagger was generating incorrect "type": "object" instead of the correct types.

Fixed fields:
- disableCancelling: type: Boolean, nullable: true
- disableRescheduling: type: Boolean, nullable: true
- interfaceLanguage: type: String, nullable: true
- allowReschedulingCancelledBookings: type: Boolean, nullable: true
- customReplyToEmail: type: String, nullable: true
- showOptimizedSlots: type: Boolean, nullable: true

* refactor: customReplyToEmail was intentionally excluded from this PR. The web UI
restricts this field to only allow the user's own verified emails via a
dropdown, but implementing the same validation in the API requires additional
business logic. This will be addressed in a separate PR with proper email
ownership validation.

* feat(api-v2): add validation for interfaceLanguage field

Add @IsIn validation to interfaceLanguage field to only accept supported
locales. This ensures API v2 matches the web UI behavior where users can
only select from a predefined dropdown of supported languages.

Changes:
- Add SUPPORTED_LOCALES constant to @calcom/platform-constants
- Add @IsIn([...SUPPORTED_LOCALES]) validation to create/update DTOs
- Add E2E tests for invalid locale rejection (400 error)
- Add cross-reference comments in i18n.json and api.ts to keep in sync

* docs(api): add default values to event type input field documentation

Added default value documentation to @DocsPropertyOptional decorators
for the new event type fields in API v2 (2024_06_14):

- disableCancelling: false
- disableRescheduling: false
- canSendCalVideoTranscriptionEmails: true
- autoTranslateInstantMeetingTitleEnabled: false
- allowReschedulingPastBookings: false
- allowReschedulingCancelledBookings: false
- showOptimizedSlots: false

This improves API documentation by clearly communicating default
values to API consumers in the OpenAPI spec.

* feat(api-v2): refactor event type settings to object types for future extensibility

- Convert disableRescheduling from boolean to object with disabled and minutesBefore properties
- Convert disableCancelling from boolean to object with disabled property
- Move canSendCalVideoTranscriptionEmails into CalVideoSettings as sendTranscriptionEmails
- Remove autoTranslateInstantMeetingTitleEnabled (Enterprise-only feature)
- Add DisableRescheduling_2024_06_14 and DisableCancelling_2024_06_14 input/output types
- Add transformation methods for new object types in input and output services
- Update E2E tests for new API contract

BREAKING CHANGE: disableRescheduling and disableCancelling now accept objects instead of booleans

* fix(api-v2): prevent clearing calVideoSettings when only sendTranscriptionEmails is provided

Only include calVideoSettings in transformed output if it has properties,
avoiding unintentional reset of existing settings during updates.
This commit is contained in:
Dhairyashil Shinde
2026-01-07 16:03:01 +02:00
committed by GitHub
parent 4571215794
commit dcf10935de
17 changed files with 1046 additions and 5 deletions
+453
View File
@@ -19114,6 +19114,31 @@
}
}
},
"DisableRescheduling_2024_06_14": {
"type": "object",
"properties": {
"disabled": {
"type": "boolean",
"description": "If true, rescheduling is always disabled for this event type.",
"example": true
},
"minutesBefore": {
"type": "number",
"description": "Disable rescheduling when less than the specified number of minutes before the meeting. If set, `disabled` should be false or undefined.",
"example": 60
}
}
},
"DisableCancelling_2024_06_14": {
"type": "object",
"properties": {
"disabled": {
"type": "boolean",
"description": "If true, cancelling is always disabled for this event type.",
"example": true
}
}
},
"CalVideoSettings": {
"type": "object",
"properties": {
@@ -19144,6 +19169,11 @@
"disableTranscriptionForOrganizer": {
"type": "boolean",
"description": "If true, the organizer will not be able to receive transcription of the meeting"
},
"sendTranscriptionEmails": {
"type": "boolean",
"description": "Send emails with the transcription of the Cal Video after the meeting ends.",
"default": true
}
}
},
@@ -19417,6 +19447,88 @@
"default": false,
"description": "Boolean to require authentication for booking this event type via api. If true, only authenticated users who are the event-type owner or org/team admin/owner can book this event type."
},
"disableCancelling": {
"description": "Settings for disabling cancelling of this event type.",
"example": {
"disabled": true
},
"allOf": [
{
"$ref": "#/components/schemas/DisableCancelling_2024_06_14"
}
]
},
"disableRescheduling": {
"description": "Settings for disabling rescheduling of this event type. Can be always disabled or disabled when less than X minutes before the meeting.",
"example": {
"disabled": false,
"minutesBefore": 60
},
"allOf": [
{
"$ref": "#/components/schemas/DisableRescheduling_2024_06_14"
}
]
},
"interfaceLanguage": {
"type": "string",
"description": "Set preferred language for the booking interface. Use empty string for visitor's browser language (default).",
"enum": [
"",
"en",
"ar",
"az",
"bg",
"bn",
"ca",
"cs",
"da",
"de",
"el",
"es",
"es-419",
"eu",
"et",
"fi",
"fr",
"he",
"hu",
"it",
"ja",
"km",
"ko",
"nl",
"no",
"pl",
"pt-BR",
"pt",
"ro",
"ru",
"sk-SK",
"sr",
"sv",
"tr",
"uk",
"vi",
"zh-CN",
"zh-TW"
]
},
"allowReschedulingPastBookings": {
"type": "boolean",
"description": "Enabling this option allows for past events to be rescheduled.",
"default": false
},
"allowReschedulingCancelledBookings": {
"type": "boolean",
"description": "When enabled, users will be able to create a new booking when trying to reschedule a cancelled booking.",
"default": false
},
"showOptimizedSlots": {
"type": "boolean",
"description": "Arrange time slots to optimize availability.",
"default": false
},
"locations": {
"type": "array",
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location. Note: Setting a location to a conferencing app does not install the app - the app must already be installed. Via API, only Google Meet (google-meet), Microsoft Teams (office365-video), and Zoom (zoom) can be installed. Cal Video (cal-video) is installed by default. All other conferencing apps must be connected via the Cal.com web app and are not available for Platform plan customers. You can only set an event type location to an app that has already been installed or connected.",
@@ -20528,6 +20640,31 @@
}
}
},
"DisableCancellingOutput_2024_06_14": {
"type": "object",
"properties": {
"disabled": {
"type": "boolean",
"description": "If true, cancelling is always disabled for this event type.",
"example": true
}
}
},
"DisableReschedulingOutput_2024_06_14": {
"type": "object",
"properties": {
"disabled": {
"type": "boolean",
"description": "If true, rescheduling is always disabled for this event type.",
"example": true
},
"minutesBefore": {
"type": "number",
"description": "Rescheduling is disabled when less than the specified number of minutes before the meeting.",
"example": 60
}
}
},
"EventTypeOutput_2024_06_14": {
"type": "object",
"properties": {
@@ -20796,6 +20933,41 @@
"type": "boolean",
"description": "Boolean to require authentication for booking this event type via api. If true, only authenticated users who are the event-type owner or org/team admin/owner can book this event type."
},
"disableCancelling": {
"description": "Settings for disabling cancelling of this event type.",
"allOf": [
{
"$ref": "#/components/schemas/DisableCancellingOutput_2024_06_14"
}
]
},
"disableRescheduling": {
"description": "Settings for disabling rescheduling of this event type. Can be always disabled or disabled when less than X minutes before the meeting.",
"allOf": [
{
"$ref": "#/components/schemas/DisableReschedulingOutput_2024_06_14"
}
]
},
"interfaceLanguage": {
"type": "string",
"nullable": true,
"description": "Set preferred language for the booking interface."
},
"allowReschedulingPastBookings": {
"type": "boolean",
"description": "Enabling this option allows for past events to be rescheduled."
},
"allowReschedulingCancelledBookings": {
"type": "boolean",
"nullable": true,
"description": "When enabled, users will be able to create a new booking when trying to reschedule a cancelled booking."
},
"showOptimizedSlots": {
"type": "boolean",
"nullable": true,
"description": "Arrange time slots to optimize availability."
},
"ownerId": {
"type": "number",
"example": 10
@@ -21162,6 +21334,41 @@
"type": "boolean",
"description": "Boolean to require authentication for booking this event type via api. If true, only authenticated users who are the event-type owner or org/team admin/owner can book this event type."
},
"disableCancelling": {
"description": "Settings for disabling cancelling of this event type.",
"allOf": [
{
"$ref": "#/components/schemas/DisableCancellingOutput_2024_06_14"
}
]
},
"disableRescheduling": {
"description": "Settings for disabling rescheduling of this event type. Can be always disabled or disabled when less than X minutes before the meeting.",
"allOf": [
{
"$ref": "#/components/schemas/DisableReschedulingOutput_2024_06_14"
}
]
},
"interfaceLanguage": {
"type": "string",
"nullable": true,
"description": "Set preferred language for the booking interface."
},
"allowReschedulingPastBookings": {
"type": "boolean",
"description": "Enabling this option allows for past events to be rescheduled."
},
"allowReschedulingCancelledBookings": {
"type": "boolean",
"nullable": true,
"description": "When enabled, users will be able to create a new booking when trying to reschedule a cancelled booking."
},
"showOptimizedSlots": {
"type": "boolean",
"nullable": true,
"description": "Arrange time slots to optimize availability."
},
"teamId": {
"type": "number"
},
@@ -21550,6 +21757,88 @@
"default": false,
"description": "Boolean to require authentication for booking this event type via api. If true, only authenticated users who are the event-type owner or org/team admin/owner can book this event type."
},
"disableCancelling": {
"description": "Settings for disabling cancelling of this event type.",
"example": {
"disabled": true
},
"allOf": [
{
"$ref": "#/components/schemas/DisableCancelling_2024_06_14"
}
]
},
"disableRescheduling": {
"description": "Settings for disabling rescheduling of this event type. Can be always disabled or disabled when less than X minutes before the meeting.",
"example": {
"disabled": false,
"minutesBefore": 60
},
"allOf": [
{
"$ref": "#/components/schemas/DisableRescheduling_2024_06_14"
}
]
},
"interfaceLanguage": {
"type": "string",
"description": "Set preferred language for the booking interface. Use empty string for visitor's browser language (default).",
"enum": [
"",
"en",
"ar",
"az",
"bg",
"bn",
"ca",
"cs",
"da",
"de",
"el",
"es",
"es-419",
"eu",
"et",
"fi",
"fr",
"he",
"hu",
"it",
"ja",
"km",
"ko",
"nl",
"no",
"pl",
"pt-BR",
"pt",
"ro",
"ru",
"sk-SK",
"sr",
"sv",
"tr",
"uk",
"vi",
"zh-CN",
"zh-TW"
]
},
"allowReschedulingPastBookings": {
"type": "boolean",
"description": "Enabling this option allows for past events to be rescheduled.",
"default": false
},
"allowReschedulingCancelledBookings": {
"type": "boolean",
"description": "When enabled, users will be able to create a new booking when trying to reschedule a cancelled booking.",
"default": false
},
"showOptimizedSlots": {
"type": "boolean",
"description": "Arrange time slots to optimize availability.",
"default": false
},
"locations": {
"type": "array",
"description": "Locations where the event will take place. If not provided, cal video link will be used as the location. Note: Setting a location to a conferencing app does not install the app - the app must already be installed. Via API, only Google Meet (google-meet), Microsoft Teams (office365-video), and Zoom (zoom) can be installed. Cal Video (cal-video) is installed by default. All other conferencing apps must be connected via the Cal.com web app and are not available for Platform plan customers. You can only set an event type location to an app that has already been installed or connected.",
@@ -23451,6 +23740,88 @@
"default": false,
"description": "Boolean to require authentication for booking this event type via api. If true, only authenticated users who are the event-type owner or org/team admin/owner can book this event type."
},
"disableCancelling": {
"description": "Settings for disabling cancelling of this event type.",
"example": {
"disabled": true
},
"allOf": [
{
"$ref": "#/components/schemas/DisableCancelling_2024_06_14"
}
]
},
"disableRescheduling": {
"description": "Settings for disabling rescheduling of this event type. Can be always disabled or disabled when less than X minutes before the meeting.",
"example": {
"disabled": false,
"minutesBefore": 60
},
"allOf": [
{
"$ref": "#/components/schemas/DisableRescheduling_2024_06_14"
}
]
},
"interfaceLanguage": {
"type": "string",
"description": "Set preferred language for the booking interface. Use empty string for visitor's browser language (default).",
"enum": [
"",
"en",
"ar",
"az",
"bg",
"bn",
"ca",
"cs",
"da",
"de",
"el",
"es",
"es-419",
"eu",
"et",
"fi",
"fr",
"he",
"hu",
"it",
"ja",
"km",
"ko",
"nl",
"no",
"pl",
"pt-BR",
"pt",
"ro",
"ru",
"sk-SK",
"sr",
"sv",
"tr",
"uk",
"vi",
"zh-CN",
"zh-TW"
]
},
"allowReschedulingPastBookings": {
"type": "boolean",
"description": "Enabling this option allows for past events to be rescheduled.",
"default": false
},
"allowReschedulingCancelledBookings": {
"type": "boolean",
"description": "When enabled, users will be able to create a new booking when trying to reschedule a cancelled booking.",
"default": false
},
"showOptimizedSlots": {
"type": "boolean",
"description": "Arrange time slots to optimize availability.",
"default": false
},
"schedulingType": {
"type": "string",
"enum": [
@@ -23962,6 +24333,88 @@
"default": false,
"description": "Boolean to require authentication for booking this event type via api. If true, only authenticated users who are the event-type owner or org/team admin/owner can book this event type."
},
"disableCancelling": {
"description": "Settings for disabling cancelling of this event type.",
"example": {
"disabled": true
},
"allOf": [
{
"$ref": "#/components/schemas/DisableCancelling_2024_06_14"
}
]
},
"disableRescheduling": {
"description": "Settings for disabling rescheduling of this event type. Can be always disabled or disabled when less than X minutes before the meeting.",
"example": {
"disabled": false,
"minutesBefore": 60
},
"allOf": [
{
"$ref": "#/components/schemas/DisableRescheduling_2024_06_14"
}
]
},
"interfaceLanguage": {
"type": "string",
"description": "Set preferred language for the booking interface. Use empty string for visitor's browser language (default).",
"enum": [
"",
"en",
"ar",
"az",
"bg",
"bn",
"ca",
"cs",
"da",
"de",
"el",
"es",
"es-419",
"eu",
"et",
"fi",
"fr",
"he",
"hu",
"it",
"ja",
"km",
"ko",
"nl",
"no",
"pl",
"pt-BR",
"pt",
"ro",
"ru",
"sk-SK",
"sr",
"sv",
"tr",
"uk",
"vi",
"zh-CN",
"zh-TW"
]
},
"allowReschedulingPastBookings": {
"type": "boolean",
"description": "Enabling this option allows for past events to be rescheduled.",
"default": false
},
"allowReschedulingCancelledBookings": {
"type": "boolean",
"description": "When enabled, users will be able to create a new booking when trying to reschedule a cancelled booking.",
"default": false
},
"showOptimizedSlots": {
"type": "boolean",
"description": "Arrange time slots to optimize availability.",
"default": false
},
"schedulingType": {
"type": "string",
"enum": [