Compare commits

..
Author SHA1 Message Date
khushal-winnerandSahitya Chandra 1c193cca86 docs: document Windows setup fix for prisma .env symlink error (#28101)
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
* docs: add Windows fix for prisma .env symlink issue

* Remove 'link-as-an-app' from redirect apps list

Removed 'link-as-an-app' from the list of apps.

* Update README.md

removed option 2

* Update README.md

* Update README.md

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-03-01 12:42:42 +00:00
17af50bbdc feat: add per-host locations seed data in Acme Org for QA (#27832)
* fix: host location option

* feat: add per-host locations seed data for Round Robin event type

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: move per-host locations seed to Acme Org with dedicated event type

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: check app existence before creating credentials in per-host location seed

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: remove credential-based app seeding, use simple location types instead

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2026-02-26 18:51:11 +00:00
5242e419d9 feat: Calendar Sync (#24124)
* feat: calendar cache and sync - wip

* Add env.example

* refactor on CalendarCacheEventService

* remove test console.log

* Fix type checks errors

* chore: remove pt comment

* add route.ts

* chore: fix tests

* Improve cache impl

* chore: update recurring event id

* chore: small improvements

* calendar cache improvements

* Fix remove dynamic imports

* Add cleanup stale cache

* Fix tests

* add event update

* type fixes

* feat: add comprehensive tests for new calendar subscription API routes

- Add tests for /api/cron/calendar-subscriptions-cleanup route (9 tests)
- Add tests for /api/cron/calendar-subscriptions route (10 tests)
- Add tests for /api/webhooks/calendar-subscription/[provider] route (11 tests)
- Add missing feature flags for calendar-subscription-cache and calendar-subscription-sync
- All 30 tests pass with comprehensive coverage of authentication, feature flags, error handling, and service instantiation

Tests cover:
- Authentication scenarios (API key validation, Bearer tokens, query parameters)
- Feature flag combinations (cache/sync enabled/disabled states)
- Success and error handling (including non-Error exceptions)
- Service instantiation with proper dependency injection
- Provider validation for webhook endpoints

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* feat: add comprehensive tests for calendar subscription services, repositories, and adapters

- Add unit tests for CalendarSubscriptionService with subscription, webhook, and event processing
- Add unit tests for CalendarCacheEventService with cache operations and cleanup
- Add unit tests for CalendarSyncService with Cal.com event filtering and booking operations
- Add unit tests for CalendarCacheEventRepository with CRUD operations
- Add unit tests for SelectedCalendarRepository with calendar selection management
- Add unit tests for GoogleCalendarSubscriptionAdapter with subscription and event fetching
- Add unit tests for Office365CalendarSubscriptionAdapter with placeholder implementation
- Add unit tests for AdaptersFactory with provider management and adapter creation
- Fix lint issues by removing explicit 'any' type casting and unused variables
- All tests follow Cal.com conventions using Vitest framework with proper mocking

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: improve calendar-subscriptions-cleanup test performance by adding missing mocks

- Add comprehensive mocks for defaultResponderForAppDir, logger, performance monitoring, and Sentry
- Fix slow test execution (933ms -> <100ms) caused by missing dependency mocks
- Ensure consistent test performance across different environments

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Fix tests

* Fix tests

* type fix

* Fix coderabbit comments

* Fix types

* Fix test

* Update apps/web/app/api/cron/calendar-subscriptions/route.ts

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Fixes by first review

* feat: add database migrations for calendar cache and sync fields

- Add CalendarCacheEventStatus enum with confirmed, tentative, cancelled values
- Add new fields to SelectedCalendar: channelId, channelKind, channelResourceId, channelResourceUri, channelExpiration, syncSubscribedAt, syncToken, syncedAt, syncErrorAt, syncErrorCount
- Create CalendarCacheEvent table with foreign key to SelectedCalendar
- Add necessary indexes and constraints for performance and data integrity

Fixes database schema issues causing e2e test failures with 'column does not exist' errors.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* only google-calendar for now

* docs: add Calendar Cache and Sync feature documentation

- Add comprehensive feature overview and motivation
- Document feature flags with SQL examples
- Include SQL examples for enabling features for users and teams
- Reference technical documentation files

Addresses PR #23876 documentation requirements

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* docs: update calendar subscription README with comprehensive documentation

- Undo incorrect changes to main README.md
- Update packages/features/calendar-subscription/README.md with:
  - Feature overview and motivation
  - Environment variables section
  - Complete feature flags documentation with SQL examples
  - SQL examples for enabling features for users and teams
  - Detailed architecture documentation

Addresses PR #23876 documentation requirements

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix docs

* Fix test to available calendars

* Fix test to available calendars

* add migration and sync boilerplate

* fix typo

* remove double log

* sync boilerplate

* remove console.log

* only subscribe for google calendar

* adjust for 3 months fetch

* only subscribe for teams that have feature enabled

* adjust tests

* chore: safe increment error count

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* calendar sync

* test: add comprehensive tests for CalendarSyncService

- Add comprehensive test coverage for CalendarSyncService methods
- Test handleEvents, cancelBooking, and rescheduleBooking functionality
- Cover edge cases like missing UIDs, malformed UIDs, and error handling
- Fix dynamic import usage in CalendarSyncService to use .default
- Remove invalid properties from handleNewBooking call to fix type errors

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add skipCalendarSyncTaskCreation flag to handleCancelBooking to prevent infinite loops

- Add skipCalendarSyncTaskCreation field to bookingCancelSchema in zod-utils.ts
- Update handleCancelBooking to skip EventManager.cancelEvent when flag is true
- Update CalendarSyncService.cancelBooking to pass skipCalendarSyncTaskCreation: true
- Update CalendarSyncService.rescheduleBooking to pass skipCalendarSyncTaskCreation: true
- Update tests to verify the flags are passed correctly

This prevents infinite loops when calendar events are cancelled/rescheduled from
external calendars (Google/Office365) which trigger webhooks to Cal.com, which
would otherwise try to update the external calendar again.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: rename flag to skipCalendarSyncTaskCancellation and use static imports

- Rename skipCalendarSyncTaskCreation to skipCalendarSyncTaskCancellation in handleCancelBooking
- Convert dynamic imports to static imports in CalendarSyncService
- Update tests to use vi.hoisted for proper mock hoisting with static imports

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* feat: add error handling and static import for handleNewBooking

- Create index.ts entry point for handleNewBooking directory
- Add try-catch error handling to cancelBooking and rescheduleBooking
- Log errors but don't block calendar sync operations
- Update tests to verify errors are caught and logged, not thrown

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: use RegularBookingService directly and fix safeStringify usage

- Remove handleNewBooking/index.ts and call getRegularBookingService().createBooking() directly in CalendarSyncService
- Fix safeStringify usage: apply to error itself, not wrapper object
- Update tests to mock getRegularBookingService instead of handleNewBooking

Addresses PR comments from Volnei and Cubic-dev-ai

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: restore handleNewBooking/index.ts and fix bookingData structure for calendar sync

- Restore handleNewBooking/index.ts as entry point for static imports
- Fix CalendarSyncService.rescheduleBooking to use correct bookingData structure
  with required fields (eventTypeId, start, end, timeZone, language, metadata)
- Use rescheduleUid to indicate this is a reschedule operation
- Fix safeStringify usage in error logging (wrap only the error, not the whole object)
- Update tests to match new bookingData structure

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: address PR comments - use RegularBookingService directly, remove unnecessary flags, fix booking reference update

- Remove handleNewBooking/index.ts wrapper and use getRegularBookingService().createBooking() directly in CalendarSyncService
- Remove allRemainingBookings and cancelSubsequentBookings flags from cancelBooking (only cancel the specific booking, not the entire series)
- Move bookingReference update outside skipCalendarSyncTaskCancellation block for data consistency
- Update tests to match new implementation

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: remove unnecessary comment from zod-utils.ts

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* feat: add Sentry metrics telemetry and fix null assertions in CalendarSyncService

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: use dynamic import for getRegularBookingService to avoid RAQB import in server context

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: use dynamic import for findTeamMembersMatchingAttributeLogic to avoid RAQB import in server context

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* improve booking update

* add more tests and edge cases

* fix: add required actionSource and Sentry mocks to calendar sync

Add actionSource: "SYSTEM" to handleCancelBooking call after it became
required, and mock @sentry/nextjs in test files.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-02-26 13:12:52 -03:00
5d65a0f091 fix: hide cal branding for orgs/teams (#27643)
* fix: hide branding for teams

* fix: remove unused organizationId and username fields from profiles select

Addresses Cubic AI review feedback (confidence 9/10) to select only
the profile fields that are actually used. The organizationId and
username fields were fetched but never referenced in this function.

Co-Authored-By: unknown <>

* fix: unit tests

* fix: add prisma named export to test mock

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* Add tests: packages/features/profile/lib/hideBranding.test.ts

Generated by Paragon from proposal for PR #27643

* chore: implement cubic feedback

* fix: merge conflicts

* fix: unit tests

* fixup

* refactor: implement DI pattern for event type service

* fix: atoms build

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-25 20:53:01 +09:00
4081d11fbe feat: workflow auto translation (#27087)
* feat: workflow auto translation

* tests: add unit tests

* refactor: tests and workflow

* fix: type err

* fix: type err

* fix: remove redundant index on WorkflowStepTranslation

The @@index on [workflowStepId, field, targetLocale] duplicates the @@unique
constraint on the same columns. A unique index already provides efficient
lookups, so the separate @@index adds storage overhead and write latency
without benefit.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* fix: correct locale mapping when translation API returns null

Map translations with their corresponding locales before filtering to
preserve correct locale-to-translation associations. Previously, filtering
out null translations would reindex the array, causing incorrect locale
mappings when any translation in the batch failed.

Also fixes pre-existing lint warnings:
- Move exports to end of file
- Add explicit return type to processTranslations
- Replace ternary with if-else for upsertMany selection

Co-Authored-By: udit@cal.com <udit222001@gmail.com>

* fix: address review feedback for workflow auto-translation

- Add change detection before creating translation tasks
- Rename userLocale to sourceLocale in task props for clarity
- Show source language in UI with new translation key
- Extract SUPPORTED_LOCALES to shared translationConstants.ts
- Fix locale mapping bug in translateEventTypeData.ts
- Add WhatsApp translation support
- Abstract translation lookup into shared translationLookup.ts helper
- Restore if-else readability for SCANNING_WORKFLOW_STEPS

Co-authored-by: Udit Takkar <udit.takkar@cal.com>
Co-Authored-By: unknown <>

* fix: update test to use sourceLocale instead of userLocale

Co-Authored-By: unknown <>

* refactor: feedback

* fix: handle first time

* fix: tests

* fix: tests

* fix: address Cubic AI review feedback (confidence 9/10 issues)

- WhatsApp translation: Apply variable substitution using getSMSMessageWithVariables
  and clear contentSid when using translated body to ensure Twilio uses the
  translated text instead of the original template

- update.handler.ts: Change sourceLocale assignment from ?? to || for consistency
  with tasker payload behavior (line 481)

- ITranslationService.ts: Rename methods from plural to singular naming:
  - getWorkflowStepTranslations -> getWorkflowStepTranslation
  - getEventTypeTranslations -> getEventTypeTranslation
  Updated all call sites and tests accordingly

Co-Authored-By: unknown <>

* fix: address Cubic AI review feedback (confidence 9/10+ issues)

- Fix getSMSMessageWithVariables to handle WHATSAPP_ATTENDEE action for
  locale and timezone (confidence 9/10)
- Remove WhatsApp translation feature that set contentSid to undefined
  since Twilio ignores body parameter for WhatsApp and requires
  pre-approved Message Templates (confidence 10/10)

Co-Authored-By: unknown <>

* fix: translatio

* Add tests: packages/features/eventTypeTranslation/repositories/EventTypeTranslationRepository.test.ts

Generated by Paragon from proposal for PR #27087

* Add tests: packages/features/tasker/tasks/translateWorkflowStepData.test.ts

Generated by Paragon from proposal for PR #27087

* chore: nit

* chore: verfied atg

* fix: set sourceLocale for new steps, add shouldDirty to checkbox, remove spec docs

- Set sourceLocale fallback in addedSteps mapping to fix stale detection mismatch
- Add { shouldDirty: true } to autoTranslateEnabled checkbox onChange
- Remove specs/workflow-translation/ directory (planning docs, not for repo)

Co-authored-by: Udit Takkar <udit.07.takkar@gmail.com>
Co-Authored-By: unknown <>

* chore: add specs back

* fix: type error

* fix: type error

* fix: type err

* fix: tests

* refactor: feedback

* fix: type err

* refactor

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <udit.takkar@cal.com>
Co-authored-by: Udit Takkar <udit.07.takkar@gmail.com>
2026-02-25 01:03:55 +05:30
f883dee084 perf: improve getTotalBookingDuration query (#27383)
* perf: improve getTotalBookingDuration query

* perf: improve getTotalBookingDuration query

* test: add unit tests for getTotalBookingDurationForUsers and yearly duration pre-fetching

Co-Authored-By: udit@cal.com <udit222001@gmail.com>

* fix: integration tests

* fix: update tests

* fix: use vi.stubEnv instead of direct process.env modification for test isolation

Replace direct deletion of process.env variables with vi.stubEnv() to ensure
automatic restoration after tests, preventing flaky tests and side effects
in parallel execution.

Issue identified by Cubic AI (confidence: 9/10)

Co-Authored-By: unknown <>

* chore: add log

* refactor: imports

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-24 22:55:33 +05:30
e3a9f54ba5 feat: Configure cancellation reason (#26872)
* feat: Configure cancellation reason

* fix: use enums

* tests: add unit tests

* fix: type error

* chore: remove duplicate dialog

* fix: type erro

* refator: improvements

* refator: improvements

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-24 13:35:51 -03:00
c9abc556ba fix: improve getIP header resolution for CF → Vercel setup (#28152)
Co-Authored-By: unknown <>

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-24 14:47:14 +00:00
Benny Joo 9855176948 refactor: Remove all TrpcSessionUser usages in @calcom/features (#27853)
* sessionUser in features

* update sessionMiddleware

* update

* format changes

* update import paths

* fix

* fix ts errors

* refactor

* fix

* fix

* fix

* fix

* rename

* rename

* rename

* use error with code objs
2026-02-24 09:29:54 +00:00
48cbb94af2 feat: add webhook trigger when routing form fallback route is hit (#27588)
* feat: add no users found fallback action for routing forms

- Add NoUsersFoundFallbackActionType enum with CustomPageMessage and ExternalRedirectUrl options
- Add noUsersFoundFallbackAction field to zodNonRouterRoute schema
- Add NoUsersFoundFallback UI component in RouteBuilder for configuring fallback action
- Update handleResponse to return noUsersFoundFallbackAction when no team members match
- Add i18n translation keys for new UI strings

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: change fallback to use same action options as main route

- Replace noUsersFoundFallbackAction with fallbackAction that has same structure as main action
- Add action dropdown and input fields to fallback attributes query builder section
- Support Event redirect, External URL, and Custom page options in fallback
- Remove separate NoUsersFoundFallback toggle component
- Update handleResponse to return fallbackAction

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: ensure fallbackAction type is always defined in onChange handlers

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add guards for route.fallbackAction in onChange handlers

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: only return fallbackAction when no users are found

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: restructure fallback section to mirror main route structure

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: ensure backwards compatibility for existing routes with fallbackAttributesQueryValue

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: initialize fallbackAction with main event type for backwards compatibility

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: include fallbackAction in getRoutesToSave to persist changes

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use fallbackAction in getRoutedUrl when no team members found

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use i18n for fallback label and add tests for fallback action

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: do not trigger fallback action when CRM contact owner is found

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: prioritize fallbackAction over fallbackAttributesQueryValue

When a route has a fallbackAction configured, skip the
fallbackAttributesQueryValue to ensure the fallbackAction is triggered
when no team members are found. This maintains backwards compatibility
by only using fallbackAttributesQueryValue when fallbackAction is not set.

Also treats teamMemberIdsMatchingAttributeLogic being null (routing couldn't
run, e.g., missing orgId) the same as an empty array for the purpose of
triggering the fallbackAction.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: extract RouteActionSelector shared component for action selection UI

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add i18n string for default custom page message

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add webhook trigger when routing form fallback route is hit

- Add ROUTING_FORM_FALLBACK_HIT to WebhookTriggerEvents enum in Prisma schema
- Add new trigger to routing-forms webhook triggers in constants
- Add translation string for the new webhook trigger
- Implement triggerFallbackWebhook function in formSubmissionUtils.ts
- Call webhook trigger from handleResponse.ts when fallback action is used

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove webhook object from error log to avoid exposing secrets

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* revert: remove webhook trigger changes (to be moved to separate PR)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add webhook trigger when routing form fallback route is hit

- Add ROUTING_FORM_FALLBACK_HIT to WebhookTriggerEvents enum in Prisma schema
- Add new trigger to routing-forms webhook triggers in constants
- Add translation string for the new webhook trigger
- Implement triggerFallbackWebhook function in formSubmissionUtils.ts
- Call webhook trigger from handleResponse.ts when fallback action is used

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove webhook object from error log to avoid exposing secrets

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add ROUTING_FORM_FALLBACK_HIT to PayloadBuilderFactory trigger mapping

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* style: apply biome formatting fixes

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: restore removed comments in RouteBuilder

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: add prisma migration for ROUTING_FORM_FALLBACK_HIT enum value

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add ROUTING_FORM_FALLBACK_HIT to FormTriggerEvents type union

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: add test coverage for triggerFallbackWebhook function

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: consolidate fallback webhook firing with form submission webhooks

Move ROUTING_FORM_FALLBACK_HIT webhooks into the same Promise.all() batch
as FORM_SUBMITTED / FORM_SUBMITTED_NO_EVENT, eliminating redundant
getWebhooks/getWebhookTargetEntity/getOrgIdFromMemberOrTeamId calls.

- Add fallbackAction parameter to _onFormSubmission and onSubmissionOfFormResponse
- Remove triggerFallbackWebhook function and all its usages/imports
- Move getFallbackAction() earlier in handleResponse.ts and pass result through
- Update all tests to verify batched webhook behavior

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Add UI option for trigger

* feat: persist fallbackAction on queued form responses

When a routing form response is queued, the fallbackAction determined
during routing is now stored on the QueuedFormResponse record. When
the queued response is later converted to a real FormResponse, the
stored fallbackAction is passed to onSubmissionOfFormResponse so the
ROUTING_FORM_FALLBACK_HIT webhook fires correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add coverage for fallbackAction in queued form response flow

Verify that fallbackAction is persisted when queuing and passed through
to onSubmissionOfFormResponse when the queued response is converted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-23 16:44:41 -05:00
8238d4ffcd fix: use WEBAPP_URL for booking confirmation redirects to fix localhost behind proxy (#28144)
Replace request.url with WEBAPP_URL from @calcom/lib/constants as the base URL
for NextResponse.redirect() in booking confirmation API routes. Behind a reverse
proxy, request.url resolves to http://localhost:3000 instead of the public domain.

Fixes #20358

Co-Authored-By: unknown <>

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-23 14:19:54 -03:00
0a84ce5c73 fix: use smsReminderNumber fallback for attendee phone in SMS reminders (#27942)
* SMS reminders not trigger

* addressed devin review

* Add tests: packages/features/ee/workflows/lib/service/scheduleLazySMSWorkflow.test.ts

Generated by Paragon from proposal for PR #27942

* Add tests: packages/features/ee/workflows/lib/reminders/reminderScheduler.smsLazy.test.ts

Generated by Paragon from proposal for PR #27942

* Add tests: packages/features/tasker/tasks/sendWorkflowSMS.test.ts

Generated by Paragon from proposal for PR #27942

* Add tests: packages/features/ee/workflows/lib/reminders/smsReminderManager.test.ts

Generated by Paragon from proposal for PR #27942

* Delete packages/features/ee/workflows/lib/reminders/reminderScheduler.smsLazy.test.ts

* fix: update sendWorkflowSMS tests to match refactored implementation

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: use smsReminderNumber fallback for attendee phone in SMS workflows

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* revert: keep only scheduleSMSReminders.ts changes, revert all other files

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: restore reminderScheduler.ts and smsReminderManager.ts to original branch state

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: use smsReminderNumber fallback for attendee phone in WhatsApp reminders

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-23 17:35:51 +01:00
7e73d675d7 refactor: improve invoice.upcoming logging and add strategyName to billing strategies (#28143)
- Add strategyName property to ISeatBillingStrategy interface and all implementations
- Log which strategy handled the invoice.upcoming webhook (not just whether it applied)
- Always log strategy result (not just when applied=true) for better observability
- Rename highWaterMarkApplied to strategyApplied since applied covers multiple strategies

Co-Authored-By: unknown <>

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-23 15:57:13 +00:00
Benny Joo 648ad72a54 refactor: extract dedicated @calcom/i18n package (#28141) 2026-02-23 13:30:12 +00:00
f00be08e8c fix: order custom questions by event type bookingFields in BookingDetailsSheet (#28140)
Co-Authored-By: unknown <>

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-23 22:25:02 +09:00
Yuvraj Angad SinghandAnik Dhabal Babu f1e8e3fa58 fix(caldav): consistent UIDs and VTIMEZONE in iCalendar output (#28115)
* fix(caldav): use consistent UIDs and inject VTIMEZONE in iCalendar output

Two remaining CalDAV interop issues from #9485:

1. UID consistency: use the booking's canonical UID (event.uid) instead
   of always generating a new random UUID. CalDAV servers use UID as the
   event identifier — different UIDs cause duplicate calendar entries.

2. VTIMEZONE injection: the ics library generates UTC times with no
   VTIMEZONE block. CalDAV servers like Fastmail read this as UTC and
   send scheduling emails with wrong times. Per RFC 5545 §3.6.5,
   DTSTART with TZID requires a matching VTIMEZONE component. We now
   build a proper VTIMEZONE using binary-searched DST transitions for
   the event's year, handling Northern/Southern hemisphere correctly.

* fix: use pre-transition offset for VTIMEZONE DTSTART per RFC 5545

The DTSTART in VTIMEZONE components must represent the local time
interpreted with the pre-transition offset (TZOFFSETFROM), not the
post-transition offset. For example, US Eastern spring forward DTSTART
should be 02:00 (EST), not 03:00 (EDT).

* Remove comments on UID handling in createEvent

Removed comments about UID handling for calendar events.

* Revise injectVTimezone documentation

Update injectVTimezone function documentation to clarify UTC handling.

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-02-21 14:38:56 +00:00
Anirban SinghaandRomit 4dbe044ecc refactor: remove unused imports and stale TODO comment from caleventparser.ts (#28096)
* refactor: replace manual provider logic with getAppFromLocationValue

* chore: revert changes and remove stale comment

---------

Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-21 19:38:14 +05:30
Romit f1ae5f727a fix: update fast-xml-parser and ignore audit 1113407 (#28117) 2026-02-21 12:22:57 +00:00
Romit 7ee01c0487 fix (#28119) 2026-02-21 09:16:13 -03:00
05537780b8 fix: add biome overrides for embed-core to prevent auto-import of node:process (#27387)
* fix: use import.meta.env instead of process.env in embed.ts

Using import.meta.env is Vite's native way to handle environment variables
in browser bundles. This prevents biome from auto-adding 'import process
from node:process' which breaks the embed.js in browsers.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Remove unncessar comment

* fix: migrate remaining process.env to import.meta.env in embed.ts

Complete the migration started by @hariombalhara by also converting
process.env usages at lines 1681, 1682, and 1700 to import.meta.env.
Update env.d.ts to include EMBED_PUBLIC_EMBED_FINGER_PRINT,
EMBED_PUBLIC_EMBED_VERSION, and INTEGRATION_TEST_MODE types.

This ensures no process.env references remain in embed.ts, fully
preventing Biome from auto-adding import process from node:process.

Co-Authored-By: unknown <>

* fix: add biome overrides for embed-core to prevent auto-import of node:process

Reverts import.meta.env back to process.env since API V2's tsconfig uses
module: commonjs which doesn't support import.meta. Instead, adds biome
overrides for embed-core to disable useNodejsImportProtocol, noProcessEnv,
and noProcessGlobal rules that were causing biome to auto-add
'import process from node:process' on save.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-20 14:38:11 -03:00
Hariom BalharaandDevin AI 3e29904d7d test: add tests for __reloadInitiated behavior to ensure correct bookerViewed vs bookerReloaded events (#27379)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-20 14:35:18 -03:00
06f4b25080 fix: update routing form identifier hint text with learn more link (#27837)
* fix: update routing form identifier hint text with learn more link

Co-Authored-By: carina@cal.com <c.wollendorfer@me.com>

* UI improvements

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-02-20 13:09:09 +01:00
Deepanshu 79fc0c8437 fix: toolbar dropdown toggle (#28097) 2026-02-20 11:20:38 +00:00
a2b25fa615 fix: prevent deselecting active option in booker layout toggle (#27748)
* fix: prevent deselecting active option in ToggleGroup

Radix UI's single-type ToggleGroup allows deselection by default,
calling onValueChange("") when the active item is clicked.

Fix by converting to controlled mode with proper dual-mode support:
- Controlled (value prop): parent owns state, component just filters
  empty values from onValueChange. Parent can still reject changes.
- Uncontrolled (defaultValue prop): internal useState prevents
  deselection by only updating state for non-empty values.

* Update ToggleGroup.tsx

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2026-02-20 10:41:54 +00:00
14c151be76 fix: add CSRF protection to OAuth callback via HMAC-signed nonce (#28083)
* fix: add CSRF protection to OAuth callback via HMAC-signed nonce

The OAuth state parameter was used only for passing application data
(returnTo, teamId) with no cryptographic binding to the user session.
An attacker could authorize their own account on a provider, capture the
authorization code, and trick a logged-in user into visiting the callback
URL to link the attacker's account to the victim's Cal.com profile.

Changes:
- encodeOAuthState: generate a random nonce and HMAC-sign it with
  NEXTAUTH_SECRET + userId, injecting both into the OAuth state
- decodeOAuthState: verify the HMAC on callback using timingSafeEqual;
  skip verification when nonce is absent (backwards compatible with apps
  that don't yet use encodeOAuthState)
- Stripe callback: replace raw state.returnTo redirect with
  getSafeRedirectUrl to prevent open redirect, remove redundant
  getReturnToValueFromQueryState, add missing return on access_denied

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: make CSRF nonce verification mandatory with allowlist for exempt apps

Makes nonce/HMAC verification mandatory by default in decodeOAuthState,
preventing attackers from bypassing CSRF protection by omitting nonce
fields from the state parameter.

Apps not yet migrated to encodeOAuthState (stripe, basecamp3, dub,
webex, tandem) are explicitly allowlisted and pass their slug to
decodeOAuthState to skip verification.

Addresses review feedback (identified by cubic) about the conditional
check being trivially bypassable.

Co-Authored-By: unknown <>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-20 10:35:01 +00:00
1aae57daae refactor(booking-audit): discriminated union for displayFields and i18n param support (#27373)
* feat: Add infrastructure for no-show audit integration

- Add Prisma migrations for SYSTEM source and NO_SHOW_UPDATED audit action
- Add NoShowUpdatedAuditActionService with array-based attendeesNoShow schema
- Update BookingAuditActionServiceRegistry to include NO_SHOW_UPDATED
- Update BookingAuditTaskConsumer and BookingAuditViewerService
- Add AttendeeRepository methods for no-show queries
- Update IAuditActionService interface with values array support
- Update locales with no-show audit translation keys

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add NO_SHOW_UPDATED to BookingAuditAction and SYSTEM to ActionSource types

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED from BookingAuditAction type to match Prisma schema

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update BookingAuditActionSchema to use NO_SHOW_UPDATED instead of HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Remove deprecated no-show audit services and unify to NoShowUpdatedAuditActionService

- Delete HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService
- Update BookingAuditProducerService.interface.ts to use queueNoShowUpdatedAudit
- Update BookingAuditTaskerProducerService.ts to use queueNoShowUpdatedAudit
- Update BookingEventHandlerService.ts to use onNoShowUpdated
- Add integration tests for NoShowUpdatedAuditActionService

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add data migration step for deprecated no-show enum values

Addresses Cubic AI review feedback (confidence 9/10): The migration now
includes an UPDATE statement to convert existing records using the
deprecated 'host_no_show_updated' or 'attendee_no_show_updated' enum
values to the new unified 'no_show_updated' value before the type cast.
This prevents migration failures if any existing data uses the old values.

Co-Authored-By: unknown <>

* fix: Use CASE expression in USING clause for enum migration

Fixes PostgreSQL error 'unsafe use of new value of enum type' by avoiding
the ADD VALUE statement and instead using a CASE expression in the ALTER
TABLE USING clause to convert deprecated enum values (host_no_show_updated,
attendee_no_show_updated) to the new unified value (no_show_updated) during
the type conversion.

Co-Authored-By: unknown <>

* fix: Replace hardcoded color with semantic text-success class

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove color class completely from display fields

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: Add valuesWithParams support for translatable complex field values

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor(booking-audit): use discriminated union for displayFields and update consumers

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: add explicit return type to getBookingHistoryHandler to bust stale tRPC build cache

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: replace $t() nested interpolation with separate translation keys and add translationsWithParams tests

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-20 14:34:12 +05:30
Abir RoyandSahitya Chandra 12e95a1f47 feat: Add meta pixel conversion events (#25638)
* feat(meta-pixel): add trackingEvent to zod schema

* fix: do not allow trackingEvent to be optional

* feat(meta-pixel): add trackingEvent selection dropdown to UI

* feat(meta-pixel): add trackingEvent to Event Type App Data

* fix(meta-pixel): implement history API hook for SPA conversion tracking

* fix(meta-pixel): check for cancel in URL and prevent Re-wrapping of pushState

* Update EventTypeAppSettingsInterface.tsx

* fix: make trackingEvent optional in zod schema to fix type-check

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-20 00:17:42 +05:30
60b6086221 feat: add keyboard shortcuts and tooltips to booking slideover buttons (#27428)
* feat: add keyboard shortcuts and tooltips to booking slideover buttons

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: remove duplicate useBookingLocation import and fix import ordering

- Removed duplicate import of useBookingLocation from non-existent
  @calcom/web/modules/bookings/hooks/useBookingLocation path
- Fixed import ordering to satisfy biome organizeImports rules
- Removed unnecessary code comment
- Original feature by @PeerRich via Devin AI

Co-Authored-By: unknown <>

* use same style arrows for both button and remove bydefault focus from them

* fix join button tooltip hover

* fix: disable keyboard shortcuts when overlays/dialogs are open on BookingDetailsSheet

Co-Authored-By: unknown <>

* fix: use focus-based detection instead of selector-based overlay detection for keyboard shortcuts

Co-Authored-By: unknown <>

* fix: allow keyboard shortcuts when focus is on sheet ancestors

Co-Authored-By: unknown <>

* fix: use capture phase for keyboard handler to prevent Enter from activating focused buttons

Co-Authored-By: unknown <>

* fix: allow shortcuts when focus is on page elements outside any Radix portal

Co-Authored-By: unknown <>

* fix: handle calendar event clicks in onInteractOutside to prevent sheet close/reopen

Co-Authored-By: unknown <>

* fix: stop arrow key propagation to prevent Radix dropdown from opening during booking navigation

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: always stop arrow key propagation when sheet is active, even at first/last booking

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: extract keyboard handler into testable utility with tests

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: resolve type errors in keyboard handler config and test mocks

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* test: add e2e tests for booking sheet keyboard shortcuts

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: replace text= locators with data-testid selectors in e2e tests

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* made 3 fixes: Fix 1 — Stabilize handleNext/handlePrevious/handleClose with useCallback
In BookingDetailsSheet.tsx, all three handler functions were plain arrow functions recreated on every render, causing the useEffect to tear down and re-attach the document keydown listener unnecessarily. Wrapped all three in useCallback with proper dependency arrays (the Zustand store functions they call).
Fix 2 — data-booking-list-item verified (no change needed)
Confirmed that data-booking-list-item is rendered on BookingListItem.tsx and data-booking-calendar-event is rendered on Event.tsx. The onInteractOutside handler in the final merged state correctly checks both selectors. No code change required.
Fix 3 — Removed dead code from JoinMeetingButton
Reverted JoinMeetingButton back to a plain function component:
Removed forwardRef wrapping (no caller passes a ref)
Removed showTooltip prop (unused — tooltip is handled by the parent BookingDetailsSheet)
Removed ref prop from the inner Button
Removed unused Tod forwardRef imports

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: eunjae@cal.com <hey@eunjae.dev>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2026-02-19 22:32:43 +05:30
5d65df9c05 chore: migrate booking requested webhook trigger (#27546)
* init

* wiring up

* fix type

* feat: implement DI pattern for webhook producer in API v2

- Export IWebhookProducerService and getWebhookProducer from platform-libraries
- Add WEBHOOK_PRODUCER token and useFactory provider in RegularBookingModule
- Inject webhookProducer in RegularBookingService and pass to base class

This follows the composition root pattern where only the NestJS module
knows about getWebhookProducer(), and all consumers depend only on the
IWebhookProducerService interface via constructor injection.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* test: migrate BOOKING_REQUESTED tests to new webhook architecture

- Remove failing BOOKING_REQUESTED tests from fresh-booking.test.ts (4 tests)
- Remove failing BOOKING_REQUESTED tests from reschedule.test.ts (2 tests)
- Remove failing BOOKING_REQUESTED test from collective-scheduling.test.ts (1 test)
- Replace WebhookTaskConsumer.test.ts with placeholder (constructor changed)
- Create new webhook architecture test suite:
  - producer/WebhookTaskerProducerService.test.ts (14 tests)
  - consumer/WebhookTaskConsumer.test.ts (8 tests)
  - consumer/triggers/booking-requested.test.ts (8 tests)

The new test suite is organized by trigger type for extensibility as more
triggers are migrated to the producer/consumer pattern.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* test: remove paid events BOOKING_REQUESTED test (moved to new architecture)

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* wrap webhook in own try-catch

* wire datafetcher

* fix

* fix v2

* fix circular dependency

* --

* merge-conflict-resolve

* mreg-conflict-resolve

* remove early return

* test: add integration tests for BOOKING_REQUESTED webhook producer invocation

Cover all 8 scenarios verifying the booking flow correctly invokes
the webhook producer for BOOKING_REQUESTED:

1. Basic confirmation → queueBookingRequestedWebhook called
2. Booker-is-organizer + confirmation → still called
3. Confirmation threshold NOT met → not called (BOOKING_CREATED instead)
4. Confirmation threshold IS met → called
5. Paid event + confirmation → called after payment succeeds
6. Reschedule + confirmation (non-organizer) → called (not BOOKING_RESCHEDULED)
7. Reschedule + confirmation (organizer) → not called (BOOKING_RESCHEDULED instead)
8. Collective scheduling + confirmation → called

Adds reusable MockWebhookProducer helper in @calcom/testing for
extendable use as more webhook triggers migrate to the new architecture.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix bug

* fix conditional check

* remove unnecessary comment

* add missing expect

* remove empty test

* clean up

* tasker config

* --

* fix missing metadata

* remove faulty if else

* test: add payload content verification tests for BOOKING_REQUESTED webhook

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* remove unnecessary tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <1780212+hariombalhara@users.noreply.github.com>
2026-02-19 20:21:26 +04:00
Peer RichelsenandDevin AI 66ce20245c docs: declare credentials and environment variables in calcom-api skill (#28047)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-19 14:32:41 +00:00
c321a6c07a feat: owner can test non accepted OAuth client (#27525)
* refactor: combine exchange and refresh into token endpoint

* refactor: controller error handling

* refactor: use snake_case

* refactor: use snake_case

* refactor: use snake case

* refactor: token endpoint accepts application/x-www-form-urlencoded

* refactor: token endpoint accepts application/x-www-form-urlencoded

* refactor: flat token response data

* refactor: error structure

* refactor: client_id in the body

* fix: address Cubic AI review feedback on OAuth2 endpoints

- Fix getClient endpoint to use proper REST API error format instead of OAuth token error format (confidence 9/10)
- Add missing space after comma in error format string in token.input.pipe.ts (confidence 9/10)
- Support both camelCase and snake_case inputs in authorize endpoint for backward compatibility (confidence 10/10)
- Restore legacy /exchange and /refresh endpoints alongside new /token endpoint for backward compatibility (confidence 10/10)
- Add OAuth2TokensResponseDto for legacy endpoint wrapped responses
- Add OAuth2LegacyExchangeInput and OAuth2LegacyRefreshInput for legacy endpoints

Co-Authored-By: unknown <>

* fix: address additional Cubic AI feedback on OAuth2 endpoints

- Log errors when status code >= 500 in handleClientError (confidence 9/10)
- Add Cache-Control: no-store and Pragma: no-cache headers to legacy /exchange and /refresh endpoints (confidence 9/10)

Co-Authored-By: unknown <>

* docs

* Revert "fix: address additional Cubic AI feedback on OAuth2 endpoints"

This reverts commit 39cc4aa3ebb9e59a171541d7010398425995ed89.

* Revert "fix: address Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 97bf593186db04c0859f9ca30950c9e3e524019d.

* docs

* fix: address Cubic AI review feedback on OAuth2 endpoints

- Fix getClient to use handleClientError instead of handleTokenError (confidence 10)
- Restore legacy /exchange and /refresh endpoints for backward compatibility (confidence 9)
- Fix RFC 6749 error format: use human-readable messages in error_description (confidence 9)
- Fix errorDescription in OAuthService to use OAUTH_ERROR_REASONS mapping (confidence 9)

Co-Authored-By: unknown <>

* fix: address additional Cubic AI feedback on OAuth2 endpoints

- Fix security issue: Replace 'CALENDSO_ENCRYPTION_KEY is not set' with generic 'Internal server configuration error' message (confidence 10/10)
- Fix backward compatibility: Create OAuth2LegacyTokensDto with camelCase properties for legacy /exchange and /refresh endpoints (confidence 9/10)
- Skipped: RFC 6749 error field issue (confidence 8/10, below threshold)

Co-Authored-By: unknown <>

* e2e

* Revert "fix: address additional Cubic AI feedback on OAuth2 endpoints"

This reverts commit a080e93f07aaf5a7dcf81fe605012cb7ebcdc192.

* Revert "fix: address Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 04986a16c981521ca97069152457bf521a9ee45f.

* fix: re-apply Cubic AI review feedback on OAuth2 endpoints

- Restore OAuth2LegacyExchangeInput and OAuth2LegacyRefreshInput classes
- Restore legacy /exchange and /refresh endpoints in OAuth2Controller
- Restore OAuth2LegacyTokensDto and OAuth2TokensResponseDto classes
- Restore OAUTH_ERROR_DESCRIPTIONS mapping in oauth2-error.service.ts
- Restore OAUTH_ERROR_REASONS lookup in OAuthService.ts mapErrorToOAuthError
- Fix encryption_key_missing error to not expose internal env var name

Addresses Cubic AI feedback with confidence >= 9/10:
- Comment 32 (9/10): Legacy endpoints and input classes
- Comment 34 (9/10): Error description mapping in OAuthService
- Comment 35 (10/10): OAUTH_ERROR_DESCRIPTIONS in error service

Skipped (confidence < 9/10):
- Comment 33 (8/10): getClient handleTokenError vs handleClientError

Co-Authored-By: unknown <>

* Revert "fix: re-apply Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 416bef9c931d9a7ed78c65a70a3425550d61b151.

* delete unused file

* fix: e2e tests

* address cubic review

* fix: address Cubic AI review feedback on OAuth2 exception filter

- Fix header case sensitivity: use lowercase 'x-request-id' instead of 'X-Request-Id' since Express lowercases all request headers
- Redact request body in error logs to prevent exposing sensitive OAuth2 credentials like client_secret, password, and refresh_token

Co-Authored-By: unknown <>

* docs: api v2 oauth controller docs

* chore: remove authorize endpoint

* feat: owner can test non accepted OAuth client

* fix: remove sensitive data from OAuth2 exception logs

Remove Authorization header and userEmail from error logs in
OAuth2HttpExceptionFilter to avoid logging sensitive information.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* fix: e2e

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-19 08:11:46 -03:00
0eb2c15b39 fix: handle JSON string name field from URL prefill for firstAndLastName variant (#28039)
* fix: handle JSON string name field from URL prefill for firstAndLastName variant

* refactoring logic

* improve test coverage

* remove unnecessary comment

---------

Co-authored-by: Maks Pikov <mixelburg@users.noreply.github.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-19 05:14:51 +05:30
9d29055808 feat: replace admin API settings page with link to API docs (#28046)
* feat: replace admin API settings page with link to API docs

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: remove unused AdminAPIView component

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: rename admin API tab to API Docs

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-18 17:12:24 -05:00
74f3608b42 fix: Billings page reorganised (#28053)
* billings page reorganised

* Update redirect-apps.generated.ts

* small border update

* udpate for organization billing page

---------

Co-authored-by: Romit <romitgabani1.work@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-18 21:50:38 +00:00
9bfa4165b9 fix: prevent sending raw errors in responses (#24282)
* fix: prevent sending raw errors in responses

* correct already existing typo

* style: fix import ordering per biome lint

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-19 02:43:14 +05:30
cal-com-ci[bot]andLingo.dev 8a96a45424 feat: update translations via @LingoDotDev (#27639)
Co-authored-by: Lingo.dev <support@lingo.dev>
2026-02-18 16:32:10 -03:00
Deepanshu 0787c4890e fix: add toggle in workflow form (#27983) 2026-02-18 18:39:11 +01:00
Eunjae Lee 51e902f03e chore: pause syncing rules to devin (#28041)
* chore: pause syncing rules to devin

* Revert "chore: pause syncing rules to devin"

This reverts commit dd0e55322fe079b62207c9a4b58c9d24ce1c0dda.

* disable temporarily
2026-02-18 16:35:45 +00:00
Anirban SinghaandSahitya Chandra 9b1bf29ecf chore: remove stale Vitest workspace TODO (#27667)
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-18 14:50:58 +00:00
Hariom BalharaandDevin AI ad65fbbd81 fix: change URL prefill behavior to skip only invalid fields (#26982)
* fix: change URL prefill behavior to skip only invalid fields

Previously, when prefilling booking form fields from URL query parameters,
if any single field failed validation, all prefilling was skipped and an
empty object was returned.

This change modifies the behavior so that only invalid fields are skipped,
while valid fields are still prefilled. The implementation:

- Adds validateSingleFieldForPrefill() to validate individual fields
- Adds parseFieldByField() to collect valid fields when full parse fails
- Modifies getBookingResponsesPartialSchema to use field-by-field parsing
  as a fallback when full schema validation fails
- Logs which specific fields were skipped and why

This improves user experience by preserving valid prefill data even when
some fields have invalid values.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: reduce code duplication in partial prefill validation

Simplify the implementation by integrating field-by-field error handling
directly into the existing preprocess() function instead of using separate
helper functions.

Changes:
- Remove validateSingleFieldForPrefill() and parseFieldByField() functions
- Simplify getBookingResponsesPartialSchema to directly use preprocess()
- Add try-catch wrapper in preprocess() when isPartialSchema=true
- Continue processing other fields even if one fails during preprocessing
- Log skipped fields with reasons at debug level

This reduces code duplication while maintaining the same behavior of
skipping only invalid fields during URL prefill.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fixes

* refactor: rename getRefinedValue to superRefineField and add edge case tests

- Rename getRefinedValue to superRefineField for clarity
- Remove duplicate multiselect test block
- Add test for empty object name field during partial prefill
- Add test for invalid URL format during partial prefill
- Add test for null responses during partial prefill

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Simplifu

* Simplif more

* Enhance booking responses schema tests to validate required fields and name variants. Updated error handling for empty names and added tests for first and last name requirements. Refactored schema validation logic to improve clarity and maintainability.

* fix types

* test: add test for email validation behavior during partial prefill

Documents that email validation is relaxed to z.string() during partial prefill,
consistent with phone field behavior where partial values like '+91' are accepted.
This addresses Cubic AI feedback (confidence 9/10) to verify email handling.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix

* Add tests: packages/features/bookings/lib/getBookingResponsesSchema.test.ts

Generated by Paragon from proposal for PR #26982

* Revert "Add tests: packages/features/bookings/lib/getBookingResponsesSchema.test.ts"

This reverts commit fc2b7ad7ca8099bc4f68e97b383ea16b41cdd772.

* Simplify

* fix: sanitize partial prefill log to avoid exposing user input data

Replaced raw Zod issues array in console.warn with a count of
validation errors to prevent sensitive user data from being logged.

Issue identified by cubic (confidence 9/10).

Co-Authored-By: unknown <>

* fix

* Remove throw Error

* Refactor booking responses schema tests to use helper functions for assertions

- Introduced `expectResponsesToBe` and `expectParsingToFail` helper functions to streamline test assertions.
- Replaced direct assertions with these helper functions for improved readability and maintainability.
- Removed redundant error handling code to simplify test logic.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-18 20:01:23 +05:30
eef47ddefd feat: add duplicate functionality for managed event types (#26792)
* feat: add duplicate functionality for managed event types

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat: add disclaimer and redirect for managed event type duplication

- Add info alert disclaimer in duplicate modal for managed event types
- Pass schedulingType to duplicate dialog via query params
- Redirect to assignment tab after duplicating managed event types
- Add translation key for managed event type duplicate disclaimer

Co-Authored-By: peer@cal.com <peer@cal.com>

* test: add tests for managed event type duplication

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: replace PrismaMock unit test with Prisma integration test for duplicate handler (#27973)

* refactor: replace PrismaMock unit test with Prisma integration test for duplicate handler

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: re-throw TRPCErrors in duplicate handler catch block and assert specific error codes in tests

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <1780212+hariombalhara@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2026-02-18 16:49:23 +04:00
8908a66c23 fix: allow booking rejection via GET for email clients that do not support forms (#28029)
* fix: allow booking rejection via GET for email clients that do not support forms

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Refactor test cases for GET handler in route.test.ts

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-18 17:23:42 +05:30
Alex van AndelandDevin AI a78a3ffe39 refactor: optimize team booking limits query with in-app filtering (#28021)
Replace 3 sequential queries (with expensive attendee email IN clauses)
with 2 parallel queries using indexed eventType.teamId filtering and
in-application user filtering with Sets for O(1) lookups.

Fix managed events booking-limit behavior: managed bookings now only
match by organizer userId (not attendee email), preserving the original
query semantics where managed bookings used userId-only matching.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-18 11:47:30 +00:00
a6a428c8cb feat: make actionSource required with ValidActionSource type across booking handlers (#27869)
* feat: make actionSource required with ValidActionSource type across booking handlers

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: update getAuditActionSource to return ValidActionSource, default to SYSTEM

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: revert getAuditActionSource, handleSeats, RegularBookingService back to ActionSource

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2026-02-18 07:34:25 -03:00
Pasquale Vitiello 217c6e6a76 chore: re-pull coss-ui components (#28032) 2026-02-18 10:08:35 +00:00
b1eb5a2809 feat: api v2 POST booking attendees endpoint (#27759)
* feat: add booking attendee endpoint

* chore: add attendee added email for add guests handler

* cleanup

* fix: restore BookingPbacGuard to prevent IDOR vulnerability in booking attendees endpoint

Co-Authored-By: unknown <>

* chore: implement review feedback, add a core service for booking attendees endpoint

* chore: implement PR feedback

* fix: dont reuse add guests handler instead add logic to add attendee function

* fix: revert previous changes

* chore: implement cubic feedback

* fix: e2e tests

* fix: e2e tests

* fix: remove convertTRPCErrorToErrorWithCode not needed

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-17 20:46:18 +00:00
Anirban Singha bd5d94a4ba fix: localize remaining hardcoded strings in PayPal setup (#27908)
* chore: add en locale key-value for paypal setup

* fix: add translation function for paypal setup

* chore: avoid merge conflicts
2026-02-17 17:36:45 +00:00
Shrey-SutariyaandRomit 3cfe295ed5 Commit 1 (#28011)
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-17 16:51:21 +00:00
20dcef6680 fix: validate schedule title input to block invalid characters (#27818)
* fix(availability): validate schedule title input to block invalid characters

* fix: add english translation for invalid_characters_in_name

* fix(schedule): allow Unicode characters in schedule name validation

* fix(schedule): update validation message to match regex

* fix: tsconfig target

* fix(schedule): add required validation in NewScheduleButton using translation

* fix(schedule): allow ASCII apostrophe in schedule name validation

* Update ScheduleListItem.tsx

* fix: remove unused @ts-expect-error directives

* fix: remove tsconfig target change

* Revert "fix: remove tsconfig target change"

This reverts commit d4992caf9b71cdfe32ac9db9a509128548097a30.

* Revert "fix: remove unused @ts-expect-error directives"

This reverts commit 913eda500aeccdd67b15cf1898f6db376bf3dda9.

* fix: update validation regex to support unicode characters

* fix: remove es6 from tsconfig

* Update NewScheduleButton.tsx

---------

Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-17 22:12:38 +05:30
11b65b295b test: add missing negation operator tests for TEXT, NUMBER, and compound rules (#27690)
* Fix exclusion filter - include all team members

* Fix display when members aren't saved in the DB

* Update tests

* test: add missing negation operator tests for TEXT, NUMBER, and compound rules

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: revert non-intentional changes to AddMembersWithSwitch.tsx

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2026-02-17 15:45:36 +00:00
4c73695d3a fix: refresh slots on timezone change for booker timezone restrictions (#27491)
* fix: refresh slots on timezone change for booker timezone restrictions

* refactor: use useMemo for timezone change detection

* revert: remove unnecessary formatting changes

* feat: add timezone refresh for platform components

Add timezone change detection and slot refresh to BookerPlatformWrapper
and EventTypeCalendarViewComponent to handle restriction schedules with
useBookerTimezone enabled.

* refactor: extract timezone slot refresh logic into reusable hook

* Update packages/platform/atoms/calendar-view/EventTypeCalendarViewComponent.tsx

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>

* Update packages/platform/atoms/calendar-view/EventTypeCalendarViewComponent.tsx

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>

* fix

* fix: prevent unnecessary getSchedule calls when useBookerTimezone is disabled

* fix: add timezone fields to BookerEvent type

* fix: add missing properties to BookerEvent and BookerEventProfile types

* trying to fix type errors

* Add restrictionScheduleId and useBookerTimezone fields

* fix: correct import path for useBookerTime hook

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: explicitly include restrictionScheduleId and useBookerTimezone in getPublicEvent return

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* chore: trigger fresh CI build

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: cast event.data to BookerEvent for timezone fields access

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: address review feedback for timezone slot refresh

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: add explicit return type to event handler to ensure type propagation

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: extract useStableTimezone hook and remove dead timezone detection code

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

---------

Co-authored-by: hackice20 <yashkam431@gmail.com>
Co-authored-by: Yash <116657771+hackice20@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-17 07:46:40 -03:00
Raihanullah Shamsi ab4eff1fe1 fix: translate hardcoded 'mins' on payment page (#27998) 2026-02-17 09:26:25 +00:00
38b43f75ba refactor: remove circular dependencies from CalendarView atom (#27850)
* fix: decouple large calendar from features

* fix: move calendar to features since this is the better approach

* chore: move OOO slots to features

* feat: add DefaultOutOfOfficeSlot fallback for calendar OOO rendering

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* chore: cleanup unused LargeCalendar component

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-17 08:14:33 +00:00
Hariom Balhara 9603831def refactor: update BookingHistory component to use date-fns for timestamp formatting (#27851)
Replaced dayjs with date-fns for better performance and consistency in date handling. Added Tooltip for displaying formatted timestamps and improved search functionality by translating field labels and values. Cleaned up code for better readability.
2026-02-17 13:22:16 +05:30
2bc17313fd fix: deep link reschedule audit log to booking drawer history tab (#27709)
* fix: deep link reschedule audit log to booking drawer history tab

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: make booking drawer tab-agnostic for cross-tab deep links

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use status-agnostic /bookings URL for audit log deep links

- Update audit service URLs from /bookings/upcoming?uid=... to /bookings?uid=...
- Add /bookings/page.tsx redirect that routes to /bookings/upcoming preserving query params
- Update tests to expect new URL format

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fixes

* refactor: use client-side replaceState instead of server redirect for booking deep links

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use router.replace instead of replaceState to update tab and booking list

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* improvements

* refactor: extract deep link logic from BookingListContainer into usePreSelectedBooking hook

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use proper BookingOutput status type in test helper

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: decouple getTabForBooking from BookingOutput type for simpler testing

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: accept Date | string for endTime in BookingForTabResolution interface

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: eliminate initialBookingUid prop drilling and revert formatting-only changes

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use AuditDeepLink wrapper to preserve target=_blank through ServerTrans cloneElement

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Improve code organization

* refactor: rename usePreSelectedBooking to useSwitchToCorrectStatusTab

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: push preSelectedBooking into store so drawer opens on direct navigation

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fixes

* fixes

* fixes

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2026-02-17 13:20:06 +05:30
3a7122d613 fix: revert assignmentReason breaking change in webhook payloads (#27891)
* fix: revert assignmentReason breaking change in webhook payloads

Remove the new { category, details } format from EventPayloadType to
maintain backward compatibility for webhook consumers. The new format
is stripped at all webhook payload construction sites by destructuring
assignmentReason out of CalendarEvent before spreading into the payload.

A sanitizeAssignmentReasonForWebhook function provides an additional
safety net in sendPayload itself. Emails and booking single view
continue to use the new format via CalendarEvent.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: strip assignmentReason from handlePaymentSuccess webhook payload

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: strip assignmentReason from triggerWebhooks and handleSeats webhook payloads

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: use zod safeParse instead of type assertion in sanitizeAssignmentReasonForWebhook

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-16 21:55:10 -03:00
Eunjae LeeandClaude Opus 4.6 21d28c9747 refactor: apply biome formatting to packages/trpc (#27928)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:46:42 -03:00
Volnei MunhozandDevin AI f8a93414a5 chore: remove companion app (moved to calcom/companion) (#27957)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-16 10:08:24 -03:00
DeepanshuandDeepanshu Verma 85e1ed3ab5 refactor: move cancel logic from inline onClick handler to dedicated function (#27972)
* refactor: move cancel booking logic into handleCancel function

* chore: remove unused comments per review feedback

---------

Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
2026-02-16 09:46:42 +00:00
emrysal 4647333839 chore: release v6.2.0 2026-02-16 01:36:08 +00:00
Aritra Dey 9d4cb08c55 fix: Correct hours-to-days conversion in convertToNewDurationType (#27964)
Signed-off-by: Aritra Dey <adey01027@gmail.com>
2026-02-15 21:01:00 +05:30
Peer RichelsenandDevin AI 773fab858f fix: hide bookings opt-in banner on mobile viewport (#27965)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-15 14:24:21 +00:00
Aritra DeyandRomit ea0c92a267 fix: use maxLength parameter in truncateOnWord instead of hardcoded value (#27961)
Signed-off-by: Aritra Dey <adey01027@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-15 09:51:53 +00:00
Dhairyashil Shinde 2abefc412c update version (#27952) 2026-02-14 14:36:43 +00:00
Volnei MunhozandDevin AI 9d4b12b8d3 fix: lazy-load companion iframe to avoid requests on every page visit (#27946)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-14 11:41:43 +01:00
Anik Dhabal Babu c21281a55c preserve customReplyToEmail (#27941) 2026-02-13 18:09:39 +00:00
sean-brydon f5a813f531 Revert "revert (#27933)" (#27938)
This reverts commit 227ed64b49.
2026-02-13 23:36:50 +05:30
Dhairyashil Shinde fa53f54815 feat(companion): add configurable landing page (#27267)
* feat(companion): add configurable landing page feature

- Add useUserPreferences hook for persistent storage of landing page preference
- Add LandingPagePicker component for both iOS and Android/web platforms
- Update tabs index to redirect based on user preference
- Update bookings index to accept initial filter from URL params
- Add App Settings section in More screen with landing page selector
- Clear user preferences on logout for fresh state

* fix(companion): remove try-finally for React Compiler compatibility

* fix(companion): use router.replace for dynamic landing page redirect

Replace Redirect component with router.replace() to fix TypeScript
strict typing issue with expo-router's Href type for dynamic routes.

* fix(companion): use literal route strings for TypeScript strict typing

Use switch statement with literal route strings instead of dynamic
string variable to satisfy expo-router's strict Href type checking.

* working fix

* better css
2026-02-13 11:28:42 -03:00
Pedro Castro f07bed1a2a chore(deps): bump axios to 1.13.5 (#27864)
* chore: bump axios to 1.13.5

* chore: bump axios in apps/api/v2

* chore: dedupe follow-redirects to 1.15.11
2026-02-13 22:08:49 +09:00
sean-brydon 227ed64b49 revert (#27933) 2026-02-13 12:14:08 +00:00
Alex van AndelandDevin AI 237d7e95c4 fix: inline package.json descriptions in app-store _metadata.ts to fix Vitest RPC errors (#27931)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-13 08:41:39 -03:00
Eunjae LeeandDevin AI 896dfd50fd fix: prevent BookingDetailsSheet flicker when switching bookings (#27894)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-13 11:53:22 +01:00
Eunjae LeeandClaude Opus 4.6 e2119879ae refactor: apply biome formatting to packages/sms, prisma, emails, lib (#27880)
* refactor: apply biome formatting to small packages + packages/lib

Format packages/sms, packages/prisma, packages/platform/libraries,
packages/platform/examples, packages/platform/types, packages/emails,
and packages/lib.

Excludes packages/platform/examples/base/src/pages/[bookingUid].tsx
due to pre-existing lint errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* revert: remove packages/platform formatting changes

Revert biome formatting for packages/platform as requested.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 07:39:01 -03:00
7aefefc31f feat: enable onboarding-v3 globally and update e2e tests (#27922)
* feat: enable onboarding-v3 globally and update e2e tests

- Add migration to set onboarding-v3 feature flag enabled=true
- Rewrite onboarding.e2e.ts for v3 flow (Plan Selection → Personal Settings → Calendar)
- Update URL assertions in signup, team-invitation, org-invitation, ab-tests-redirect, and auth tests to accept both old and new onboarding paths

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: use pathname-only matching in waitForURL to prevent false matches on callbackUrl query param

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* use test IDs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-02-13 10:37:47 +00:00
1b6b91b0ad fix: display phone numbers and localized timezone in BookingDetailsSheet (#27909)
* fix: display phone numbers and localized timezone in BookingDetailsSheet

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: replace selectAll with explicit column selects for Attendee query

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Update apps/web/modules/bookings/components/BookingDetailsSheet.tsx

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Add tests: packages/lib/dayjs/formatToLocalizedTimezone.test.ts

Generated by Paragon from proposal for PR #27909

* Revert "refactor: replace selectAll with explicit column selects for Attendee query"

This reverts commit f810ba801c900c8f065e5e1ce1d02a1700322257.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-13 10:27:01 +00:00
50c7210d6b fix: resolve signup watchlist review issues and auto-unlock on SIGNUP entry removal (#27923)
* fix: resolve signup watchlist review issues with deleteEntry, email verification ordering, and unlock flow

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: scope sendEmailVerification to non-invite signups only

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* feat: auto-unlock users when SIGNUP-source watchlist entries are removed

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: remove PII from error logging in unlockSignupUser

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-13 10:13:33 +00:00
Eunjae LeeandDevin AI 1bb4b206c6 fix: default icon size to 16px in createIcon wrapper and fix download button alignment (#27924)
* fix: resolve insights page UI regressions for plus button size and download alignment

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: default icon size to 16px in createIcon wrapper

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-13 10:00:16 +00:00
Anik Dhabal Babu 6386b2ec95 fix: add e2e-spec pattern to CODEOWNERS test file exclusions (#27926)
* add e2e-spec pattern to CODEOWNERS

* Add pattern for test-suite files in CODEOWNERS
2026-02-13 15:18:32 +05:30
RomitandAnik Dhabal Babu 68abc63fe4 fix (#27902)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-02-13 09:46:37 +00:00
Syed Ali ShahbazandDevin AI bdeb4b1dc9 fix: use randomString() for booking uid in slots e2e tests to avoid unique constraint flake (#27916)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-13 06:18:52 -03:00
Devanshu SharmaandSahitya Chandra 1541730886 fix(app-store): preserve existing enabled state during seed (#27918)
* fix(app-store): preserve existing enabled state during seed

* Update seed-app-store.ts

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-13 08:34:06 +00:00
4c6af5659a fix: exclude test files from CODEOWNERS foundation approval (#27919)
* fix: exclude test files from CODEOWNERS foundation approval

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: add *.test.* to CODEOWNERS test file exclusions

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: add *.integration-test.* to CODEOWNERS test file exclusions

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-13 14:01:51 +05:30
Anik Dhabal Babu a9951df501 show invite link settings modal (#27917) 2026-02-13 04:13:17 +00:00
emrysal 68663231d8 chore: release v6.1.16
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-02-12 23:27:31 +00:00
d3bbed01f6 feat: add signup watchlist review mode (#27912)
* feat: add signup watchlist review feature flag and handler logic

- Add 'signup-watchlist-review' global feature flag
- Add SIGNUP to WatchlistSource enum in Prisma schema
- When flag enabled, lock new signups and add email to watchlist
- Show 'account under review' message on signup page
- Add i18n strings for review UI
- Create seed migration for the feature flag

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* test: add isAccountUnderReview tests to fetchSignup test suite

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: address Cubic AI review feedback (confidence >= 9/10)

- Remove 'import process from node:process' in signup-view.tsx (P0 bug in 'use client' component)
- Move watchlist review check before checkoutSessionId early return in calcomSignupHandler (P1 premium bypass)
- Revert selfHostedHandler to original state (out of scope per user request)
- Add test mocks for FeaturesRepository and GlobalWatchlistRepository

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: remove node:process import from useFlags.ts (client-side file)

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: remove !token condition from watchlist review check

Token is present in normal email-verified signups, so the !token
condition was incorrectly skipping watchlist review for verified users.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor: move user lock to UserRepository.lockByEmail

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* refactor: use cached getFeatureRepository() instead of deprecated FeaturesRepository

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* refactor: remove user locking, keep only watchlist addition on signup review

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* feat: lock user on signup review, remove watchlist entry on unlock

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-12 23:14:31 +00:00
Volnei MunhozandDevin AI 9dfcb0d482 fix: include locale-prefixed paths in botid client-side protection (#27910)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-12 20:13:01 +00:00
Madhav KumarandAnik Dhabal Babu 240405f849 fix: Trimmed License Section in README (#27903)
* Pruned the 'License' section and Pushed it before 'Acknowledgement' to avoid confusion and Clarity

* Improves README file by pruning License Section and Aligning Properly

* Remove License section from README.md

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-02-12 17:46:20 +00:00
bc9a9c0c24 fix: Organised the OOO page (#27865)
* fixed text issue

* matched style of api keys page

* organised the out of office page

* Clean up unused imports in OutOfOfficeEntriesList

Removed unused imports from OutOfOfficeEntriesList.tsx

* fixed import issues

* remove unused imports

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-12 22:35:43 +05:30
Eunjae LeeandClaude Opus 4.6 f8abce44cb fix: update data-table hook imports missed in #27833 refactor (#27900)
* fix: update data-table hook imports after refactor (#27833)

The data-table hooks (useDataTable, useFilterValue) were moved from
@calcom/features/data-table to ~/data-table/hooks/ in #27833 but this
file was missed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update DataTableProvider import path in insights-wrong-routing-view

Another import missed in #27833 refactor — DataTableProvider moved from
@calcom/features/data-table/ to ~/data-table/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:05:12 +00:00
Eunjae LeeandDevin AI 1368ffe55d refactor: move data-table hooks/contexts/provider from features to web modules (#27833)
* refactor: move data-table hooks/contexts/provider from features to web modules

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: update broken useColumnResizing import path in DataTable.tsx

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: update remaining broken import paths for moved hooks

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: update GUIDE.md import paths and file references for moved modules

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-13 00:00:40 +09:00
Carina WollendorferandCarinaWolli 397bf3cc0c fix: use personal credits if no more team credits (#27518)
* use personal credits if team has no more credits

* clean up

* adjust comment

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-02-12 20:02:12 +05:30
sean-brydon 98ec38aeaa feat: add annual plans for teams/organizations (#27896)
* wip: add annual plan priceId support

* fix type errors

* type cast
2026-02-12 14:05:24 +00:00
d52e2d9fad feat: active user billing (#27867)
* factory and statergie

* chore: use correct method of DI

* feat: add onchagne

* add logic to HWM stat

* add webhook resolver methods to each statergy

* move seat tracking + webhooks over to own statergy

* Move to factory base approach

* move logic to correct class

* rename create -> createByTeamId

* fix: remove debug `true ||` overrides from IS_STRIPE_ENABLED and IS_TEAM_BILLING_ENABLED

Remove accidentally committed debug overrides that short-circuited
IS_STRIPE_ENABLED and IS_TEAM_BILLING_ENABLED to always be true,
bypassing Stripe credential checks. This would break self-hosted
instances without Stripe configured.

Identified by cubic (https://cubic.dev)

Co-Authored-By: unknown <>

* feat: active user billing

* add tests

* UI side for users on active billing

* use correct period of stripe sub

* feat: claude feedback

* fix: skip Stripe sync for canceled/expired subscriptions to prevent repeated API calls

Co-Authored-By: unknown <>

* feat: feedback

* feat: only render when active users mode is set

* fix type error

* fix: constants + feature flags

* fix: default to null in tests

* chore: use seats in test

* fix: use node:crypto protocol for Node.js builtin imports

Co-Authored-By: sean@cal.com <Sean@brydon.io>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-12 13:57:32 +00:00
bf348ee209 refactor: migrate Icon to component icons from @coss/ui/icons (#27458)
* feat: add @coss/ui/icons package and migrate static icon usages

Create a new icon system in @coss/ui/icons that wraps lucide-react icons
with controlled props (size and className only). Migrate 44 component
files from <Icon name="xxx" /> to <XxxIcon /> pattern.

This is Phase 1 of the icon migration, covering only static icon names.
Dynamic icon usages (e.g., name={variable}) are skipped for now.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate more static icons to @coss/ui/icons (batch 2)

Migrated 18 files from <Icon name="xxx" /> to <XxxIcon /> pattern:
- Event meta, insights, shell, user table bulk actions
- Webhooks, blocklist, form-builder, form components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate more static icons to @coss/ui/icons (batch 3)

Migrated 7 files:
- CancelBooking, AddGuestsDialog, ChargeCardDialog
- ReassignDialog, RescheduleDialog
- Categories, Slider

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate more static icons to @coss/ui/icons (batch 4)

Migrated 6 files:
- Organizations: AboutOrganizationForm, PaymentStatusView, profile
- Workflows: CallDetailsSheet, SkeletonLoaderList, TimeTimeUnitInput

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate more static icons to @coss/ui/icons (batch 5)

Migrated 4 files:
- TwoFactorModalHeader
- App setups: alby, make, btcpayserver

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 6)

- confirmDialog.tsx: clock icon
- ics-feedcalendar/Setup.tsx: trash, plus icons
- hitpay/Setup.tsx: info icon
- paypal/Setup.tsx: circle-alert icons

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 7)

- webhook-edit-view.tsx: external-link icon
- webhook-new-view.tsx: external-link icon
- UserDropdown.tsx: chevron-down, user, settings, moon, map, circle-help, download, blocks, log-out icons
- TopNav.tsx: settings icon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 8)

- EmailInviteForm.tsx: x icon
- InviteOptions.tsx: mail, upload, link icons
- SkeletonLoader.tsx: search, clock, user icons
- Embed.tsx: sun, arrow-left icons
- CalendarSwitch.tsx: arrow-left, rotate-cw icons

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 9)

- apps-view.tsx: search icon
- categories-view.tsx: arrow-left, arrow-right icons
- DatePicker.tsx: calendar icon
- EditLocationDialog.tsx: map-pin icon
- AppPage.tsx: circle-alert, book-open, external-link, mail, file, shield, flag icons

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 10)

- LicenseSelection.tsx: loader, check icons
- AppConnectionItem.tsx: circle-alert, arrow-right icons
- oauth-client-form/index.tsx: info icons (x2)
- auth/error/page.tsx: x icon
- troubleshoot/layout.tsx: loader icon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 11)

- UpgradeTipWrapper.tsx: users, refresh-ccw, user-plus icons
- PbacOptInModal.tsx: shield-check, lock, users, shield icons
- AdvancedPermissionGroup.tsx: chevron-right, info icons

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 12)

- AdminAppsList.tsx: pencil icon
- AvailableTimes.tsx: calendar-x-2 icon
- BookingDetailsSheet.tsx: external-link (x2), repeat icons
- BookingCalendarContainer.tsx: chevron-left, chevron-right icons

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 13)

- videos-single-view.tsx: chevron-right icon
- TroubleshooterSidebar.tsx: arrow-left icon
- RuleBuilder.tsx: filter icon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 14)

- FieldMappingBuilder.tsx: arrow-right, link icons
- IntegrationAttributeSyncCard.tsx: key icon
- onboarding-view.tsx: loader icon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static icons to @coss/ui/icons (batch 15)

- team-profile-view.tsx: copy icon
- DateRangeFilter.tsx: check icon
- ColumnVisibilityButton.tsx: check icon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static Icon to @coss/ui/icons (batch 16)

- EventWorkflowsTab.tsx: lock
- event-types-listing-view.tsx: search
- onboarding-migrate-members-browser-view.tsx: arrow-left, arrow-right, rotate-cw, lock, ellipsis-vertical, check, user-plus
- onboarding-migrate-teams-browser-view.tsx: arrow-left, arrow-right, rotate-cw, lock, ellipsis-vertical, check, arrow-right, users
- EventAvailabilityTab.tsx: globe, user
- onboarding-teams-browser-view.tsx: arrow-left, arrow-right, rotate-cw, lock, ellipsis-vertical, check, arrow-right, users
- FormBuilder.tsx: mail, phone, arrow-up, arrow-down
- AIEventController.tsx: info
- EventTeamAssignmentTab.tsx: x

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static Icon to @coss/ui/icons (batch 17)

- EventAdvancedTab.tsx: pencil, info
- HostLocations.tsx: triangle-alert, loader
- EventTypeLayout.tsx: loader
- Locations.tsx: x, corner-down-right, check
- EditWeightsForAllTeamMembers.tsx: upload, search, info, chevron-down
- WorkflowPage.tsx: pencil

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static Icon to @coss/ui/icons (batch 18)

- TestPhoneCallDialog.tsx: phone
- WorkflowListPage.tsx: link
- UsersTable.tsx: building, lock
- TeamList.tsx: building, paintbrush, chart-line, user-plus, users, pencil
- bookings-single-view.tsx: chevron-left, check, calendar, x, external-link

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate static Icon to @coss/ui/icons (batch 19)

- TeamsListing.tsx: users, refresh-ccw, user-plus, mail, video, eye-off, info
- ConnectionInfo.tsx: clipboard
- IntercomContactForm.tsx: message-circle, loader, send

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: migrate static Icon to @coss/ui/icons in teams components

- EventTypesList.tsx: check → CheckIcon
- MemberInvitationModal.tsx: user, users, building → UserIcon, UsersIcon, BuildingIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: migrate static Icon to @coss/ui/icons in workflow components

- ImportNumberDialog.tsx: info → InfoIcon
- VoiceSelector.tsx: user → UserIcon
- IncomingCallsTab.tsx: info, phone-incoming → InfoIcon, PhoneIncomingIcon
- PhoneNumberTab.tsx: loader, phone → LoaderIcon, PhoneIcon
- VoiceSelectionDialog.tsx: pause, play, user → PauseIcon, PlayIcon, UserIcon
- WebCallDialog.tsx: loader, phone, phone-off, triangle-alert, trash, message-circle → new icons (kept Icon import for dynamic mic icon)
- WorkflowDetailsPage.tsx: zap, arrow-right → ZapIcon, ArrowRightIcon
- AddActionDialog.tsx: info → InfoIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: migrate static Icon to @coss/ui/icons in WorkflowStepContainer

- info → InfoIcon (2 instances)
- phone → PhoneIcon (2 instances)
- circle-help → CircleHelpIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: migrate static Icon to @coss/ui/icons in data-table and org components

- attributes-list-view.tsx: tags → TagsIcon
- AddFilterButton.tsx: plus, eye-off → PlusIcon, EyeOffIcon
- BaseSelectFilterOptions.tsx: check → CheckIcon
- DataTable.tsx: arrow-up, arrow-down, check, chevrons-up-down, eye-off → new icons
- booking-dry-run-success-view.tsx: check → CheckIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: migrate static Icon to @coss/ui/icons in username and routing components

- UsernameTextfield.tsx: check → CheckIcon
- PremiumTextfield.tsx: check, external-link → CheckIcon, ExternalLinkIcon (kept Icon for star with fill prop)
- Header.tsx (routing-forms): pencil, menu, waypoints → PencilIcon, MenuIcon, WaypointsIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate Icon to component icons in routing-forms pages

Batch 25: Migrate static Icon usages to @coss/ui/icons components.

Files changed:
- Forms.tsx: file-text, shuffle, chart-bar, circle-check, mail, download → FileTextIcon, ShuffleIcon, ChartBarIcon, CircleCheckIcon, MailIcon, DownloadIcon
- FormEdit.tsx: chevron-down, menu → ChevronDownIcon, MenuIcon
- IncompleteBooking.tsx: globe → GlobeIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate Icon to component icons in UI package

Batch 26: Migrate static Icon usages to @coss/ui/icons components.

Files changed:
- ProgressToast.tsx: file-down, x → FileDownIcon, XIcon
- showToast.tsx: check, info, x → CheckIcon, InfoIcon, XIcon
- InfoBadge.tsx: info → InfoIcon
- MeetingTimeInTimezones.tsx: globe → GlobeIcon
- InputError.tsx: info → InfoIcon
- ConfirmationDialogContent.tsx: circle-alert, check → CircleAlertIcon, CheckIcon
- CalendarSwitch.tsx: arrow-left, rotate-cw → ArrowLeftIcon, RotateCwIcon
- ArrowButton.tsx: arrow-up, arrow-down → ArrowUpIcon, ArrowDownIcon
- FileUploader.tsx: upload → UploadIcon (kept Icon for dynamic)
- Checkbox.tsx: check → CheckIcon
- EditableHeading.tsx: pencil → PencilIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate Icon to component icons in UI and app-store packages

Batch 27: Migrate static Icon usages to @coss/ui/icons components.

Files changed:
- MultiEmail.tsx: x → XIcon (converted width to size)
- AppListCard.tsx: circle-alert → CircleAlertIcon
- SplitButton.tsx: chevron-down → ChevronDownIcon (kept Icon for dynamic)
- Calendar.tsx: chevron-left, chevron-right → ChevronLeftIcon, ChevronRightIcon
- AppDependencyComponent.tsx: check, circle-x, arrow-right → CheckIcon, CircleXIcon, ArrowRightIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate Icon to component icons in form input components

Batch 28: Migrate static Icon usages to @coss/ui/icons components.

Files changed:
- TextField.tsx: info → InfoIcon (kept Icon for x with onClick)
- Input.tsx: eye, eye-off, search → EyeIcon, EyeOffIcon, SearchIcon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use @coss/ui/src/icons in packages with legacy moduleResolution

Packages like packages/ui and packages/app-store use a legacy moduleResolution
setting that doesn't support subpath exports. This changes the import path from
@coss/ui/icons to @coss/ui/src/icons for these packages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate Icon to component icons in UI form and editor components

Migrates static Icon usages:
- MultiOptionInput: x (2x), arrow-up, arrow-down
- components (select): check
- AddVariablesDropdown: chevron-down (3x)
- ToolbarPlugin: chevron-down

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: migrate Icon to component icons in settings and platform atoms

Migrates static Icon usages:
- SettingsLayoutAppDirClient: chevron-down (2x), chevron-right (2x), arrow-left
- platform/atoms dialog: x
- platform/atoms toast: x

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: resolve @coss/ui/icons module resolution for legacy moduleResolution

Add typesVersions to @coss/ui package.json to help TypeScript resolve
subpath exports even with legacy moduleResolution: "node" setting.

Change imports from @coss/ui/src/icons to @coss/ui/icons to avoid
double-src path issue when Next.js applies import maps.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: localize 'Select field type' fallback label in FormEdit

Address Cubic AI review feedback (confidence 9/10) by using t() for
the hardcoded 'Select field type' string to ensure proper i18n support.

Co-Authored-By: unknown <>

* fix: add typesVersions wildcards for @coss/ui subpath imports

Add lib/*, components/*, and hooks/* to typesVersions to support
legacy moduleResolution with all package subpath patterns.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: resolve missing Icon references in settings and workflows

- Add Icon import for dynamic icon usages in SettingsLayoutAppDirClient
- Replace static Icon usages with component icons (InfoIcon, PhoneIcon)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: resolve icon component type errors

- Add onClick prop support to IconProps
- Fix size prop type (use number instead of string)
- Rename local MailOpenIcon to MailOpenIconWrapper to avoid shadowing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add data-testid to icon components for test compatibility

- Add testId parameter to createIcon function
- Auto-generate data-testid for all icons (e.g., "check-icon", "search-icon")
- Remove outdated mock for @calcom/ui/components/icon in tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update package.json

* Update package.json

* fix: migrate Icon to CalendarDaysIcon in videos-single-view.tsx

Co-Authored-By: unknown <>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-12 14:30:27 +01:00
Hariom Balhara 635c1febb0 fix: Booking Drawer - text overlap in footer (#27897)
## What does this PR do?

Fixes footer text overlap in the Booking Details drawer where action buttons covered the last content items on smaller screens.

**Root cause:** `sm:-my-6` on `SheetFooter` applied both negative top and bottom margins. The negative top margin pulled the footer up into the body content area, causing the overlap.

**Fix:**
- Removed `-mb-4` and `sm:-my-6` from `SheetFooter`, keeping only horizontal negative margins (`-mx-4` / `sm:-mx-6`) for edge-to-edge stretch
- Added `pb-0` to `SheetContent` to remove bottom padding so the footer sits flush at the bottom on all breakpoints

<img width="1098" height="1362" alt="image" src="https://github.com/user-attachments/assets/0418df56-a432-4edf-8e5b-664a5e8c18ac" />

- Fixes #XXXX (GitHub issue number)
- Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

## Visual Demo (For contributors especially)

#### Image Demo (if applicable):

See screenshot above showing the overlap bug. The footer actions ("..." button) overlap with the last booking history entry.

## Mandatory Tasks (DO NOT REMOVE)

- [ ] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Open any booking in the bookings list to open the details drawer
2. Scroll to the bottom of the drawer content
3. Verify the footer actions (buttons, dropdown) do not overlap with the last content item
4. Test on both mobile and desktop viewport sizes — footer should sit flush at the bottom with no extra gap on either

## Human Review Checklist

- [ ] Verify footer appearance on **mobile** (below `sm` breakpoint) — no gap below footer, no overlap with content
- [ ] Verify footer appearance on **desktop** (`sm+` breakpoint) — same checks
- [ ] Confirm the footer still stretches edge-to-edge horizontally on both breakpoints

## Checklist

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my changes generate no new warnings
- My PR is too large (>500 lines or >10 files) and should be split into smaller PRs

---

Link to Devin run: https://app.devin.ai/sessions/b9d130b8a7a54f039b90b53921b19c78
Requested by: @hariombalhara
2026-02-12 18:50:33 +05:30
emrysal 8beb629b07 chore: release v6.1.15
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-02-12 13:09:31 +00:00
7cfb053026 feat: add wrong routing tab under Insights for reviewing assignment reports (#27423)
* Add DB table for wrong assignment reports

* When report is submitted write to the db

* Prevent duplicate reportings

* test: add migration and tests for WrongAssignmentReport table

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add unique constraint on bookingUid and booking access check for hasWrongAssignmentReport

- Add @unique constraint on bookingUid in WrongAssignmentReport model to prevent duplicate reports at DB level
- Add booking ownership check using BookingAccessService in hasWrongAssignmentReport endpoint
- Refactor hasWrongAssignmentReport into separate handler and schema files

Addresses Cubic AI review feedback on PR #27405

Co-Authored-By: unknown <>

* feat: add routingFormId to WrongAssignmentReport and fix Select clearing

- Add routingFormId field to WrongAssignmentReport model in schema.prisma
- Add relation to App_RoutingForms_Form with SetNull on delete
- Update WrongAssignmentReportRepository.createReport to accept routingFormId
- Update BookingRepository.findByUidIncludeEventTypeAndTeamAndAssignmentReason to include routedFromRoutingFormReponse
- Extract routingFormId from booking in reportWrongAssignment handler
- Fix Select clearing issue: handle null case when user clears team member selection
- Update tests to include routingFormId field

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: add migration for routingFormId in WrongAssignmentReport

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add wrong assignment reports dashboard under routing tab

- Add reviewedById and reviewedAt fields to WrongAssignmentReport model
- Add repository methods for listing reports by status and updating status
- Create tRPC endpoints for fetching reports and updating status
- Create dashboard UI with pending/reviewed tabs showing routing form name
- Add translation keys for dashboard UI
- Integrate dashboard into routing insights page

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: move hooks before early return and fix indentation

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: address Udit's review comments

- hasWrongAssignmentReport: throw UNAUTHORIZED error instead of returning false
- reportWrongAssignment: add try-catch for Prisma P2002 unique constraint error
- WrongAssignmentReport: add Team relation to teamId field
- WrongAssignmentReportRepository: use findUnique instead of findFirst
- reportWrongAssignment: use i18n for error messages

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: revert hasWrongAssignmentReport to return false when user lacks access

Per PR checklist, hasWrongAssignmentReport should return { hasReport: false }
when user lacks access to booking, not throw an error. This allows the UI
to gracefully treat 'no access' as 'no report exists'.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: update mocks for findUnique and i18n in unit tests

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: throw UNAUTHORIZED in hasWrongAssignmentReport and squash migrations

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: move wrong assignment reports to its own tab under Insights

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Use data table for wrong reports

* Add option to view routing trace

* feat: add view routing form submission action to wrong assignment reports

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add RoutingFormResponseSheet component for viewing form submissions

- Create slide-out sheet to display routing form responses
- Map option IDs to display labels for select/multiselect fields
- Handle both legacy and modern option formats
- Add i18n strings: form_submission, no_responses_found

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: improve wrong assignment reports UX

- Integrate RoutingFormResponseSheet as slide-out panel instead of new tab
- Fix dropdown padding by using StartIcon prop instead of manual Icon
- Allow direct status changes for reviewed reports (no need to reopen first)
- Remove unused Icon import

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: change User relation onDelete from Cascade to SetNull in WrongAssignmentReport

Address Hariom's review feedback:
- Changed reportedById from Int to Int? (nullable)
- Changed reportedBy relation from onDelete: Cascade to onDelete: SetNull
- Updated migration SQL to reflect these changes

This preserves wrong assignment reports even when the reporting user is deleted,
as the data is still useful for analysis.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add missing i18n strings for wrong assignment reports dashboard

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: move form response display value resolution server-side

Replace client-side option ID to label resolution in
RoutingFormResponseSheet with a new lean tRPC endpoint
(getFormResponseDisplay) that resolves values server-side using
the existing getHumanReadableFieldResponseValue utility. This
enforces DTO boundaries by returning a clean pre-resolved payload
instead of leaking internal option format details to the client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add report wrong assignment button to routing trace sheet

Wire up the WrongAssignmentDialog from the routing trace sheet header
so users can flag wrong assignments directly while viewing the trace.
The report button is disabled with a tooltip when a report already
exists.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: reuse existing WrongAssignmentDialog from parent

Replace the duplicate WrongAssignmentDialog in RoutingTraceSheet with
a callback to the existing instance in BookingActionsDropdown. This
reduces the prop surface from a 6-field reportContext object to an
onReport callback and hasExistingReport boolean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: use repository instead of direct Prisma in getFormResponseDisplay

Replace direct Prisma query with PrismaRoutingFormResponseRepository's
findByIdIncludeForm method. Extend the method to also select form name,
description, userId, and teamId needed for display and auth checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: replace direct Prisma calls with repository methods

Use MembershipRepository.hasMembership() for auth checks and
TeamRepository.findAllByParentId() for child team queries instead
of direct Prisma calls. Replace direct user query with
UserRepository.getTimeZoneAndDefaultScheduleId(). Remove unused
seed script.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: use PBAC services for wrong assignment report auth

Replace manual MembershipRepository.hasMembership() checks with
PBAC-aware permission checking. getWrongAssignmentReports uses
createTeamPbacProcedure middleware since teamId is in input.
updateWrongAssignmentReportStatus uses PermissionCheckService
directly since teamId is discovered from the report entity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve type errors in RoutingFormResponseSheet and wrong-routing view

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add seed script for wrong assignment reports test data

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Revert "feat: add seed script for wrong assignment reports test data"

This reverts commit 0bd60e9661858a59aab1573d14d57d81733b7991.

* Only update reviewed fields when not pending

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: wrap handleStatusChange in useCallback to fix useMemo recalculation

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Fix routing sheet UI

* fix: use appropriate error message in getFormResponseDisplay handler

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: extract WrongAssignmentReportService from tRPC handlers

Move business logic (booking lookup, duplicate check, report creation,
webhook dispatch, org-level team resolution) into a dedicated service
in packages/features. Handlers become thin controllers that only handle
auth checks and delegate to the service.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restrict report status updates to admin/owner roles

Remove MembershipRole.MEMBER from fallbackRoles in
updateWrongAssignmentReportStatus permission check. Updating report
status is an administrative action that should be limited to team
admins and owners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: localize hard-coded success message in WrongAssignmentReportService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: rename reviewed tab to handled and add missing translations

Rename the "Reviewed" tab to "Handled" since it groups three distinct
statuses (Reviewed, Resolved, Dismissed). Also add missing translation
keys for "resolved" and "dismissed" status badges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* merge: resolve conflicts with main branch

Merge main into devin/1769747741-wrong-assignment-dashboard, resolving conflicts in:
- BookingActionsDropdown.tsx: use main's booking prop with PR's fragment structure
- reportWrongAssignment.handler.ts: keep PR's service-based approach
- reportWrongAssignment.handler.test.ts: use main's class-based mocks with PR's additions
- WrongAssignmentReportService.ts: align with main's repo method and field names

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Add guard when accessing assignmentReasonSortedByCreatedAt

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: address Cubic AI review feedback - select projection and useLocale refactor

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove stale TRPCError assertion in test (service throws ErrorWithCode)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: remove unused findByTeamIdAndStatus and findByTeamIdAndStatuses methods

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* perf: add composite index on WrongAssignmentReport and narrow findByIdIncludeForm select

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* perf: use lightweight findTeamIdById in update-status handler instead of findById

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: hariom@cal.com <hariombalhara@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: alex@cal.com <me@alexvanandel.com>
2026-02-12 13:02:33 +00:00
Hariom Balhara 50c5423ba7 fix: support underscores in workflow template variables with backward compatibility (#27571)
## What does this PR do?

Fixes an issue where underscores in form field identifiers were being stripped when converting to workflow template variables. According to the documentation, users should be able to use variables like `{COMPANY_NAME}` or `{MONTHLY_INFRASTRUCTURE_SPEND}`, but the regex in `formatIdentifierToVariable` was removing underscores, causing these variables to not match.

**The problem:**
- Form field identifier: `Company_Name` or `Monthly_Infrastructure_Spend`
- Expected variable: `{COMPANY_NAME}` or `{MONTHLY_INFRASTRUCTURE_SPEND}`
- Actual variable (before fix): `{COMPANYNAME}` or `{MONTHLYINFRASTRUCTURESPEND}`

**The fix:**
- Updated the regex from `[^a-zA-Z0-9 ]` to `[^a-zA-Z0-9_ ]` to preserve underscores in `formatIdentifierToVariable`
- Added a private `formatIdentifierToVariableLegacy` function that maintains the old behavior (strips underscores)
- Added `getVariableFormats` helper that returns both current and legacy formats for backward compatibility
- Added `convertResponsesToVariableFormats` helper in `executeAIPhoneCall.ts` to convert form responses to both variable formats
- Updated `customTemplate.ts` matching logic to support both variable formats
- Updated `executeAIPhoneCall.ts` to include both variable formats when building dynamic variables

This ensures existing templates using `{COMPANYNAME}` continue to work while new templates can use the documented `{COMPANY_NAME}` format.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A - no docs changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Create a routing form with a field identifier containing underscores (e.g., `Company_Name`)
2. Create a workflow with a template using `{COMPANY_NAME}` (with underscore)
3. Submit the form and verify the variable is replaced correctly
4. Also test with `{COMPANYNAME}` (without underscore) to verify backward compatibility

**Automated tests added:**
- `customTemplate.test.ts` - 15 tests covering `formatIdentifierToVariable`, `getVariableFormats`, and template variable replacement
- `executeAIPhoneCall.test.ts` - 6 tests covering `convertResponsesToVariableFormats` function for form responses

## Human Review Checklist

- [ ] Verify the regex change `[^a-zA-Z0-9_ ]` correctly preserves underscores
- [ ] Verify backward compatibility: both `{COMPANY_NAME}` and `{COMPANYNAME}` should work for the same form field
- [ ] Verify `convertResponsesToVariableFormats` correctly generates both variable formats
- [ ] Review test coverage for edge cases (empty responses, undefined values)

---

Link to Devin run: https://app.devin.ai/sessions/9d5d90178714493086d94691865c3e07
Requested by: @hariombalhara
<!-- devin-review-badge-begin -->

---

<a href="https://app.devin.ai/review/calcom/cal.com/pull/27571">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
    <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin">
  </picture>
</a>
<!-- devin-review-badge-end -->
2026-02-12 17:21:42 +05:30
Anirban Singha 7716f8c0a1 feat: add list formatting options to profile and event description editor (#27838) 2026-02-12 10:42:03 +00:00
8a3944f987 chore: Remove /api/ routes from proxy (#27883)
* chore: Remove /api/ routes from proxy

* Update apps/web/proxy.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Add tests: apps/web/proxy.test.ts

Generated by Paragon from proposal for PR #27883

* Update proxy.test.ts

* fix: update proxy tests to account for /api/auth/signup in matcher

Co-Authored-By: unknown <>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-12 07:33:47 -03:00
Dhairyashil Shinde be0b707296 style: take feedback dialog little right (#27892) 2026-02-12 14:32:36 +05:30
fad64a012a fix(form-builder): correct value of selection box behavior in Edit of new Added Question dialog (#27890)
* fix/SelectionBox Issue

* comment removed

* remove empty lines

---------

Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
2026-02-12 13:36:05 +05:30
Eunjae LeeandDevin AI 14563f664e feat: re-render bookings page after feature opt-in without full refresh (#27873)
* feat: re-render bookings page after feature opt-in without full refresh

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: make onOptInSuccess a required prop

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-12 10:41:40 +05:30
c7e66a3aa9 fix: maintain uid parameter in BookingDetailsSheet URL (#27872)
* fix: maintain uid parameter in BookingDetailsSheet URL

Move the isSyncedFromUrlToStoreRef guard from the effect level to inside
the Zustand subscription callback. This ensures the Store→URL subscription
is always created while still preventing premature URL overwrites during
URL→Store sync.

Also adds an E2E test verifying the uid parameter appears in the URL
after clicking a booking item in the v3 bookings view.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Update apps/web/playwright/bookings-list.e2e.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: clean up bookings-v3 feature flag after E2E test

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-02-12 10:39:08 +05:30
Pedro Castro 0d55939d13 chore(deps): resolve fast-xml-parser to 5.3.4 for @lingo.dev/_compiler (#27887) 2026-02-12 01:26:59 +00:00
06bb994145 fix: Improve wrong assignment report (#27162)
* Pass already fetched booking

* Fetch the assignment reason

* Update tests

* Label as first assignment reason

* Pass single booking object

* Remove unused repository method

* Only pass bookingUid to handler

* Rename booking `assignmentReason` to `assignmentReasonSortedByCreatedAt`

* fix: use renamed assignmentReasonSortedByCreatedAt property

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Remove take statement

* fix: address Udit's review comments

- Restore BookingAccessService for access control checks
- Rename repository method from findByUidForWrongAssignmentReport to findByUidIncludeUserAndEventTypeTeamAndAttendeesAndAssignmentReason

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: update tests to use BookingAccessService mock

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use latest assignment reason in BookingDetailsSheet for consistency

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-11 13:12:21 -05:00
Udit Takkar b185cd231b feat: login overlay re design (#27800) 2026-02-11 15:12:10 +00:00
Anik Dhabal Babu 4c804cdb00 fix flakes (#27849) 2026-02-11 14:51:34 +00:00
Eunjae LeeandClaude Opus 4.6 98b6d63164 refactor: apply biome formatting to packages/features (#27844)
* refactor: apply biome formatting to packages/features (batch 1 - small subdirs)

Format small subdirectories in packages/features: di, flags, holidays, oauth,
settings, users, assignment-reason, selectedCalendar, hashedLink, host, form,
form-builder, availability, data-table, pbac, schedules, troubleshooter,
eventtypes, calendar-subscription, and root-level files.

Also includes straggler apps/web BookEventForm.tsx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 2 - medium subdirs)

Format medium subdirectories in packages/features: auth, credentials,
calendars, routing-forms, routing-trace, attributes, watchlist, calAIPhone,
tasker, and webhooks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 3 - bookings + insights)

Format bookings and insights subdirectories in packages/features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 4 - ee)

Format packages/features/ee subdirectory covering billing, workflows,
organizations, teams, managed-event-types, round-robin, dsync,
integration-attribute-sync, and payments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 5 - booking-audit part 1)

Format booking-audit di, actions, common, dto, repository, and types
subdirectories in packages/features/booking-audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 6 - booking-audit part 2)

Format booking-audit service subdirectory in packages/features/booking-audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 15:47:14 +01:00
Keith WilliamsandDevin AI bc8ebb9213 perf: use UNION ALL with DISTINCT for bookings query optimization (#27841)
* perf: use UNION ALL with DISTINCT for bookings query optimization

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: add unionAll and distinct to kysely test mocks

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: add integration tests for getBookings query

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: add totalCount deduplication test for multi-branch union scenario

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: fix totalCount assertion to be exact instead of gte

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Apply suggestion from @keithwillcode

* perf: restore COUNT(DISTINCT id) for totalCount query

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Add tests: packages/trpc/server/routers/viewer/bookings/get.handler.integration-test.ts

Generated by Paragon from proposal for PR #27841

* Add tests: packages/trpc/server/routers/viewer/bookings/get.handler.test.ts

Generated by Paragon from proposal for PR #27841

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-11 11:33:11 -03:00
6089f47d24 feat: add fallback action options to routing form fallback section (#27449)
* feat: add no users found fallback action for routing forms

- Add NoUsersFoundFallbackActionType enum with CustomPageMessage and ExternalRedirectUrl options
- Add noUsersFoundFallbackAction field to zodNonRouterRoute schema
- Add NoUsersFoundFallback UI component in RouteBuilder for configuring fallback action
- Update handleResponse to return noUsersFoundFallbackAction when no team members match
- Add i18n translation keys for new UI strings

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: change fallback to use same action options as main route

- Replace noUsersFoundFallbackAction with fallbackAction that has same structure as main action
- Add action dropdown and input fields to fallback attributes query builder section
- Support Event redirect, External URL, and Custom page options in fallback
- Remove separate NoUsersFoundFallback toggle component
- Update handleResponse to return fallbackAction

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: ensure fallbackAction type is always defined in onChange handlers

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add guards for route.fallbackAction in onChange handlers

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: only return fallbackAction when no users are found

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: restructure fallback section to mirror main route structure

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: ensure backwards compatibility for existing routes with fallbackAttributesQueryValue

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: initialize fallbackAction with main event type for backwards compatibility

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: include fallbackAction in getRoutesToSave to persist changes

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use fallbackAction in getRoutedUrl when no team members found

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use i18n for fallback label and add tests for fallback action

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: do not trigger fallback action when CRM contact owner is found

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: prioritize fallbackAction over fallbackAttributesQueryValue

When a route has a fallbackAction configured, skip the
fallbackAttributesQueryValue to ensure the fallbackAction is triggered
when no team members are found. This maintains backwards compatibility
by only using fallbackAttributesQueryValue when fallbackAction is not set.

Also treats teamMemberIdsMatchingAttributeLogic being null (routing couldn't
run, e.g., missing orgId) the same as an empty array for the purpose of
triggering the fallbackAction.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: extract RouteActionSelector shared component for action selection UI

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add i18n string for default custom page message

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add webhook trigger when routing form fallback route is hit

- Add ROUTING_FORM_FALLBACK_HIT to WebhookTriggerEvents enum in Prisma schema
- Add new trigger to routing-forms webhook triggers in constants
- Add translation string for the new webhook trigger
- Implement triggerFallbackWebhook function in formSubmissionUtils.ts
- Call webhook trigger from handleResponse.ts when fallback action is used

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove webhook object from error log to avoid exposing secrets

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* revert: remove webhook trigger changes (to be moved to separate PR)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: only show fallback query builder when fallbackAction is explicitly set

The fallback attributes query builder was being shown for new routes
when fallbackAction was not set, causing an extra 'Add rule' button
to appear. This broke e2e tests that relied on the button index.

Now the fallback query builder is only shown when fallbackAction is
explicitly set to EventTypeRedirectUrl, which happens after the route
is saved and reloaded (via auto-initialization in useRoutes).

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use data-testid for attribute query builder selectors in e2e tests

- Add data-testid='attributes-query-builder' to the main attributes query builder div
- Update addAttributeRoutingRule and addAttributeRoutingRuleWithOperator to use the data-testid selector instead of nth() indices
- This makes the tests more robust and independent of DOM structure changes

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: initialize fallbackAction for new routes in useCreateRoute hook

- New routes created via useCreateRoute now initialize fallbackAction
- This ensures new routes have a valid fallbackAction when saved
- Matches the initialization logic for existing routes in useRoutes

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: initialize fallbackAction at save time when action is EventTypeRedirectUrl

- When saving routes, if fallbackAction is undefined but action is EventTypeRedirectUrl,
  initialize fallbackAction from the main action
- This handles the case where user creates a new route and changes action to an event type
- Fixes e2e test failures where form save was failing due to undefined fallbackAction

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: initialize fallbackAction when main action changes to EventTypeRedirectUrl

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: only show fallback section when main action has valid event type selected

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: check for valid fallbackAction event type before preserving existing value

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Give more structure to main and fallback routes

* Update comment

* Rename fallbackAttributesQueryBuilder to matchingMembersFallbackRoute

* Display custom event redirect input

* fix: address Cubic AI review feedback for routing form fallback

- Simplify getFallbackAction logic to use checkedFallback flag instead of
  manually parsing attributesQueryValue (confidence 9/10)
- Add i18n translation for 'And connect with specific team members' string
  using t('connect_with_specific_team_members') (confidence 9/10)

Co-Authored-By: unknown <>

* fix: update getFallbackAction to use checkedFallback and handle missing orgId case

- Use checkedFallback flag as primary indicator for triggering fallback action
- Also handle edge case where attribute routing was configured but couldn't run
  due to missing orgId (teamMemberIdsMatchingAttributeLogic is null)
- Update test to mock checkedFallback: true when expecting fallback action

Co-Authored-By: unknown <>

* Address UI comment

* fix: Use fallbackAttributesQueryValue when fallback action is event redirect

Only use fallbackAttributesQueryValue when:
1. fallbackAction is EventTypeRedirectUrl (attribute routing applies)
2. fallbackAction is not set (backwards compatibility)

Skip it for CustomPageMessage and ExternalRedirectUrl fallback actions
since attribute routing doesn't apply to those action types.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: correct JSX syntax error in matchingMembersFallbackRoute

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: extract getCustomSlug helper to deduplicate custom event type slug logic

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: only show fallback attribute filtering for teams under orgs

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: show fallback action for all team forms, gate attribute filtering on isOrganization

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2026-02-11 09:15:16 -05:00
saptarshi-bose f6fa24de2b adjusted zoho Token expiry time to miliseconds. (#27855)
The Date.now() method returns time in epoch miliseconds, adding 60 * 60 = 3.6seconds leads to a bug that results in expiring the access token in 3.6 seconds, although it been valid. It creates unnecessary api calls to the zoho servers before most the api calls.
2026-02-11 12:49:44 +00:00
Shrey-SutariyaandRomit b75000ea7b feat(form-builder): format field labels with spaces (#27858)
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-11 11:37:45 +00:00
Benny Joo dc7b9d91ae chore: add agent rules to prevent circular dependencies between packages (#27860) 2026-02-11 12:00:57 +01:00
36713fc12e feat: add UTM parameter data to insights bookings CSV download (#27854)
* feat: add UTM parameter data to insights bookings CSV download

Co-Authored-By: carina@cal.com <c.wollendorfer@me.com>

* test: add UTM data tests and update snapshots for csvDataTransformer

Co-Authored-By: carina@cal.com <c.wollendorfer@me.com>

* fix: use Tracking relation for UTM data instead of flat fields on Booking

Co-Authored-By: carina@cal.com <c.wollendorfer@me.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-11 15:28:54 +05:30
Anik Dhabal Babu 285f6d54a3 fix: unable to add and remove org banner (#27848) 2026-02-11 06:58:20 +00:00
Peer Richelsen 1e0cf3d0f6 feat: caretta.so app (#27840)
* new caretta.so app

* added logo and screenshots

* nit
2026-02-11 06:45:34 +00:00
681d191537 fix: ensure metadata key is always present in BOOKING_CREATED webhook payload (#27300)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-02-11 06:05:51 +00:00
Anik Dhabal BabuandDevin AI 269ed87db4 fix: use unique UIDs in seated slots E2E tests to prevent flaky uid collisions (#27847)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-11 00:55:38 -03:00
Madhav KumarandVolnei Munhoz 0191f54519 Populated Contributing Section with a welcoming summary (#27830)
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-02-11 03:02:54 +00:00
Everton Resende dc3e681e01 fix: hide cancel/reschedule links in emails when disabled (#27637)
When disableCancelling or disableRescheduling is enabled on an event type,
the confirmation email still showed non-functional cancel/reschedule links.

The ManageLink email component already had correct conditional logic to
hide these links, but two flows constructed the CalendarEvent manually
without including the flags: the booking confirmation handler and the
payment booking flow. This caused the flags to be undefined, which
ManageLink interpreted as enabled.

Added disableCancelling and disableRescheduling to the Prisma select and
CalendarEvent object in both confirm.handler.ts and getBooking.ts.

Closes #22906
2026-02-10 18:57:54 -03:00
Romit 30bba3da15 fix (#27478) 2026-02-10 18:56:45 -03:00
Udit Takkar cfa0783ebc feat: add claude specs (#26852)
* feat: claude templates

* refactor: new file

* feat: symlink
2026-02-10 19:06:31 +00:00
81e4241f85 refactor: apply biome formatting to apps/web (#27692)
* refactor: apply biome formatting to apps/web (batch 1)

Formats apps/web non-modules directories:
- apps/web/app
- apps/web/lib
- apps/web/pages
- apps/web/styles
- apps/web/server
- apps/web/test
- Root-level .ts and .mjs files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web/modules (batch 2)

Formats smaller apps/web/modules directories:
- onboarding, data-table, users, apps, auth
- integration-attribute-sync, shell, availability
- feature-flags, team, webhooks, getting-started
- feature-opt-in, troubleshooter, schedules, notifications
- signup-view.tsx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web/modules (batch 3)

Formats medium apps/web/modules directories:
- bookings
- event-types
- insights
- embed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web/modules/ee (batch 4)

Formats apps/web/modules/ee directory.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web (batch 5)

Formats remaining apps/web directories:
- apps/web/modules/settings
- apps/web/modules/booking-audit
- apps/web/playwright

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to apps/web/components (batch 6)

Formats remaining apps/web/components files.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to new apps/web files from main

Formats newly added/modified files from main merge:
- WorkflowStepContainer.tsx (resolved merge conflicts)
- Newly moved files (blocklist, form-builder, schedules, etc.)
- Other files modified in main

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: apply biome formatting to new apps/web files from main

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 23:25:24 +05:30
f4abbb2de1 feat: refactor billing to strategy implemention (#27828)
* factory and statergie

* chore: use correct method of DI

* feat: add onchagne

* add logic to HWM stat

* add webhook resolver methods to each statergy

* move seat tracking + webhooks over to own statergy

* Move to factory base approach

* move logic to correct class

* rename create -> createByTeamId

* fix: remove debug `true ||` overrides from IS_STRIPE_ENABLED and IS_TEAM_BILLING_ENABLED

Remove accidentally committed debug overrides that short-circuited
IS_STRIPE_ENABLED and IS_TEAM_BILLING_ENABLED to always be true,
bypassing Stripe credential checks. This would break self-hosted
instances without Stripe configured.

Identified by cubic (https://cubic.dev)

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 13:11:36 -03:00
3908cda372 perf: optimize getBusyTimesForLimitChecks with batched parallel queries (#27399)
* perf: optimize getBusyTimesForLimitChecks with batched parallel queries and raw SQL

Co-Authored-By: udit@cal.com <udit222001@gmail.com>

* test: add unit tests for getBusyTimesForLimitChecks batched query optimization

Co-Authored-By: udit@cal.com <udit222001@gmail.com>

* refactor: use Prisma findMany instead of raw SQL for better testability

The batching (50 user chunks) and parallel execution (Promise.all) provide
the main performance optimization. Using findMany instead of $queryRaw
maintains the same performance characteristics while being compatible
with prismock for testing.

Co-Authored-By: udit@cal.com <udit222001@gmail.com>

* fix: type error

* refactor: add integration test

* chore: remove log

* chore: remove log

* fix: avoid logging PII (userId) in busyTimes debug log

Replace JSON.stringify(busyTimes) with count to avoid exposing userId
in logs. Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* chore: undo

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 15:56:30 +00:00
Rajiv Sahal db76980644 fix: API v2 @GetWebhook() decorator doesn't generate OpenAPI path (#27612)
* fix: openapi spec for GetWebhook decorator

* fix: openapi spec
2026-02-10 11:56:55 -03:00
sean-brydon d8e6ecc7a0 fix: add i18n + migration (#27836) 2026-02-10 14:44:19 +00:00
16eb96e27d fix: update booking page terms text to use APP_NAME instead of "our" (#27834)
* fix: update booking page terms text to use APP_NAME instead of 'our'

Co-Authored-By: carina@cal.com <c.wollendorfer@me.com>

* remove changes for platform booker

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-02-10 14:41:00 +00:00
Pedro Castro 83c42cfb2b chore: resolve @modelcontextprotocol/sdk to 1.26.0 (#27640) 2026-02-10 22:28:21 +09:00
Udit TakkarandHariom Balhara 589260a7c7 fix: host location option (#27807)
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
Co-authored-by: Hariom Balhara <1780212+hariombalhara@users.noreply.github.com>
2026-02-10 13:21:57 +00:00
emrysal ff076d2394 chore: release v6.1.14 2026-02-10 13:18:45 +00:00
Alex van Andel ee1748dbee Revert "fix: prevent layout shift in sticky navbar (#27256)"
This reverts commit 38492d5839.
2026-02-10 13:09:04 +00:00
Alex van Andel 0a68a189f2 Revert "fixed header (#27794)"
This reverts commit 6f6c27b47d.
2026-02-10 13:09:01 +00:00
Alex van Andel abbc8bbb7b Revert "fix: availability page UI (#27825)"
This reverts commit 267686704d.
2026-02-10 13:05:50 +00:00
Hariom Balhara 11f336811b feat: add non-interactive mode to app-store CLI (#27831) 2026-02-10 13:59:00 +01:00
Keith Williams 3fd922664f chore: Update CODEOWNERS for Shell.tsx (#27835) 2026-02-10 18:18:25 +05:30
ae31e05bec refactor: decouple @calcom/features from @calcom/trpc/server [2] (#27821)
* inviteMemberUtils in featuers

* update imports

* wip

* wip

* fix: remove PII from log statements in inviteMemberUtils

- Remove email (usernameOrEmail) from error log in sendSignupToOrganizationEmail
- Replace full user object with userId in debug log in sendExistingUserTeamInviteEmails

Co-Authored-By: unknown <>

* revert: restore original code for pure relocation (no formatting/logic changes)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix: update test mocks to use new import path for inviteMemberUtils

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* revert: restore original formatting in proration test and handleGroupEvents

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 09:29:32 -03:00
Benny JooandDevin AI 431fbe44fc refactor: decouple @calcom/features from @calcom/trpc/server (#27751)
* make GetPublicEventInput

* space

* mv feature flags router to trpc

* remove trpc imports

* wip

* mv OrgMembershipLookup to features

* fix

* fix

* update

* fix

* revert formatting-only changes to improve PR reviewability

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 09:28:37 -03:00
c0504993a6 feat: Write wrong assignment reports to the database (#27405)
* Add DB table for wrong assignment reports

* When report is submitted write to the db

* Prevent duplicate reportings

* test: add migration and tests for WrongAssignmentReport table

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add unique constraint on bookingUid and booking access check for hasWrongAssignmentReport

- Add @unique constraint on bookingUid in WrongAssignmentReport model to prevent duplicate reports at DB level
- Add booking ownership check using BookingAccessService in hasWrongAssignmentReport endpoint
- Refactor hasWrongAssignmentReport into separate handler and schema files

Addresses Cubic AI review feedback on PR #27405

Co-Authored-By: unknown <>

* feat: add routingFormId to WrongAssignmentReport and fix Select clearing

- Add routingFormId field to WrongAssignmentReport model in schema.prisma
- Add relation to App_RoutingForms_Form with SetNull on delete
- Update WrongAssignmentReportRepository.createReport to accept routingFormId
- Update BookingRepository.findByUidIncludeEventTypeAndTeamAndAssignmentReason to include routedFromRoutingFormReponse
- Extract routingFormId from booking in reportWrongAssignment handler
- Fix Select clearing issue: handle null case when user clears team member selection
- Update tests to include routingFormId field

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: add migration for routingFormId in WrongAssignmentReport

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: address Udit's review comments

- hasWrongAssignmentReport: throw UNAUTHORIZED error instead of returning false
- reportWrongAssignment: add try-catch for Prisma P2002 unique constraint error
- WrongAssignmentReport: add Team relation to teamId field
- WrongAssignmentReportRepository: use findUnique instead of findFirst
- reportWrongAssignment: use i18n for error messages

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: revert hasWrongAssignmentReport to return false when user lacks access

Per PR checklist, hasWrongAssignmentReport should return { hasReport: false }
when user lacks access to booking, not throw an error. This allows the UI
to gracefully treat 'no access' as 'no report exists'.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: update mocks for findUnique and i18n in unit tests

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: throw UNAUTHORIZED in hasWrongAssignmentReport and squash migrations

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: change User relation onDelete from Cascade to SetNull in WrongAssignmentReport

Address Hariom's review feedback:
- Changed reportedById from Int to Int? (nullable)
- Changed reportedBy relation from onDelete: Cascade to onDelete: SetNull
- Updated migration SQL to reflect these changes

This preserves wrong assignment reports even when the reporting user is deleted,
as the data is still useful for analysis.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 08:00:01 -03:00
c3a8301b0c fix: hide feature opt-in feedback dialog during impersonation (#27802)
* fix: hide feature opt-in banner and feedback forms during impersonation

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: keep opt-in banner visible during impersonation, only hide feedback forms

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: allow feedback form during impersonation in development mode

Co-Authored-By: sean@cal.com <Sean@brydon.io>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 10:28:03 +00:00
c58e1f4ae5 feat: add filter segment validation with useActiveFiltersValidator hook and refactor DataTableProvider (#27208)
* feat: add activeFilters validator to DataTableProvider for filter segment validation

- Add validateActiveFilters prop to DataTableProvider to filter out inaccessible values
- Create useActiveFiltersValidator hook in bookings module to validate filter values
- Integrate validator in bookings-view.tsx to validate userId, eventTypeId, teamId filters
- Add comprehensive tests for the filter validation logic

This provides a scalable solution for handling stale filter segment data by validating
filters at the caller level using already-fetched accessible resource IDs.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add type guard for eventTypeIds to ensure number[] type

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: delay segment filter application until validator is ready

- Change useActiveFiltersValidator to return 'loading' state while data is fetching
- Add pending segment handling in DataTableProvider to delay filter application
- Expose isValidatorPending in context for consumers to disable queries
- Update BookingListContainer to disable bookings query while validator is pending

This prevents both errors from invalid filters and flash from fetching without filters.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: extract useSegmentManagement hook from DataTableProvider

- Extract segment management logic into dedicated useSegmentManagement hook
- Reduces DataTableProvider from ~500 lines to ~330 lines
- Use NuqsSetter type to match nuqs useQueryState setter signatures
- Maintains all existing functionality and type safety

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: export ActiveFiltersValidator types from data-table lib/types

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: import ActiveFiltersValidatorState from lib/types instead of hook

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "refactor: extract useSegmentManagement hook from DataTableProvider"

This reverts commit dd588ac4cfb1d709c71d1f621994a7e8f3118f33.

* refactor: split DataTableProvider into fine-grained context providers

- Create DataTableStateContext for raw nuqs state management
- Create DataTableSegmentContext for segment management
- Create DataTableFiltersContext for filter manipulation
- DataTableProvider now composes all providers with a bridge component
- Maintains backward compatibility via combined DataTableContext

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: apply segment filters when navigating back to page with existing URL state

When navigating back to a page with a segment already selected in the URL,
the segment was being marked as selected but its filters were not being
applied. This caused non-deterministic behavior where the filter segment
would sometimes not take effect.

The fix ensures that when segmentIdRaw exists in the URL and segments are
fetched, we also call applySegmentFilters() (with validator timing support)
instead of just setting the selectedSegment state.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: simplify filter validator to only handle multi-select

These filters are always multi-select, so remove unnecessary
single-select handling code and tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: cancel debounced search term on unmount

Cancel the debounced search term on unmount/dependency change to avoid
queued updates firing after the provider unmounts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 10:38:12 +01:00
Udit TakkarandDevin AI 267686704d fix: availability page UI (#27825)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 09:06:21 +00:00
83354fbe18 fix(readme): correct 'therefor' typo to 'therefore' (#27816)
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:04:35 +00:00
sean-brydon 892d53917d fix: pass onboardingfalse (#27806) 2026-02-10 09:03:17 +00:00
Dhairyashil Shinde 6f6c27b47d fixed header (#27794) 2026-02-10 14:10:13 +05:30
sean-brydonandDevin AI 9424649d6f fix: add isCompanyEmail check to organization upgrade path (#27813)
Users with personal emails (e.g. Gmail) could enter the org creation flow
at /settings/organizations/new but only hit the company email error at
checkout, with no way to fix it from the form. After changing their email
in settings, the cached store email was still used.

- Add server-side isCompanyEmail check in page.tsx to redirect early
- Add client-side check in CreateANewOrganizationForm with clear messaging
- Always use current session email for non-admin users (not cached store)
- Add tests for isCompanyEmail utility

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 06:15:28 +00:00
Carina WollendorferandDevin AI b03c00aded fix: remove duplicate label on team name input in team creation page (#27803)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 04:48:49 +00:00
Keith Williams e2e1ba096c chore: Use IF NOT EXISTS for index of App_RoutingForms_FormResponse (#27814) 2026-02-09 22:56:55 +00:00
Keith WilliamsandDevin AI 6a9b1ec3a8 perf: add composite index on (formId, createdAt) for App_RoutingForms_FormResponse (#27252)
* perf: add composite index on (formId, createdAt) for App_RoutingForms_FormResponse

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: add migration for formId, createdAt composite index

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update migration.sql

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 15:49:35 -03:00
Keith WilliamsandDevin AI 8b17df4621 refactor: Stop using Unkey for IP-based rate limiting (#27674)
* refactor: migrate IP-based rate limiting from Unkey to Cloudflare

Remove Unkey rate limiting for IP-based endpoints that will now be
handled by Cloudflare Enterprise Advanced Rate Limiting:

- Regular booking creation (createBooking:{hashedIP})
- Recurring booking creation (createRecurringBooking:{hashedIP})
- Instant meeting creation (instant.event-{hashedIP})
- Booking cancellation for unauthenticated users (api:cancel-ip:{hashedIP})
- Forgot password (forgotPassword:{hashedIP})
- Reset password (api:reset-password:{hashedIP})
- Signup (api:signup:{hashedIP})
- API v1 requests ({userId} with auto-lock)
- Global proxy rate limiting (common namespace)

Rate limiting that remains in Unkey (user/entity-based):
- Login (hashedEmail)
- Booking cancellation for authenticated users (api:cancel-user:{userId})
- 2FA setup/enable/disable (api:totp-*:{userId})
- SMS sending (team/org/user based)
- Email verification (various patterns)
- Team member operations (userId based)
- Routing forms (formId:responseHash)
- AI phone calls (userId based)

Also includes Cloudflare configuration proposal document with
recommended rules using JA4 fingerprinting for enhanced protection.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: remove cloudflare proposal doc from PR

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: remove cloudflare comments and keep common rate limiting type

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: revert global middleware from PR #25080 and restore core rate limits

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: restore instantMeeting rate limiting

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: restore email fallback in forgot-password rate limiting

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Remove the static file check

* refactor: add POST_METHODS_ALLOWED_API_ROUTES to proxy matcher

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* revert: restore API v1 rate limiting to original state

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* revert: restore reset-password, cancel, book/event, book/recurring-event to original state

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: use POST_METHODS_ALLOWED_API_ROUTES spread in matcher instead of hardcoded routes

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* revert: restore signup route to original state

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: update proxy matcher tests for POST_METHODS_ALLOWED_API_ROUTES spread

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Rename var

* refactor: revert matcher to static strings, add sync-check test for POST_METHODS_ALLOWED_API_ROUTES

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* removed dead routing forms rewrite code

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 15:49:26 -03:00
Lauris Skraucis edf9cd70dd fix: hide cal branding on platform workflows (#27385)
* fix: hide cal branding on platform workflows

* refactor: rely on existing with platform variables code

* revert: comment

* fix e2e

* chore: remove unit results
2026-02-09 13:46:52 -03:00
f66fffd13b feat: add routing trace seeding to seed-insights (#27782)
* feat: add routing trace seeding to seed-insights and standalone seed script

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* chore: remove standalone seed-routing-trace.ts (now in seed-insights)

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: track skipped routing trace creates for accurate log output

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 21:46:25 +05:30
82a4780145 feat: show routing trace dialog on assignment reason badge click (#27629)
* feat: show routing trace dialog on assignment reason badge click

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove duplicate RoutingTraceSheet rendering

- Remove RoutingTraceSheet from BookingListItem.tsx to avoid duplicate rendering
- Move RoutingTraceSheet in BookingActionsDropdown.tsx outside of isBookingFromRoutingForm condition
- Use booking.assignmentReason.length > 0 condition for RoutingTraceSheet rendering
- Remove unused isOpenRoutingTraceSheet getter and RoutingTraceSheet import from BookingListItem.tsx

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 10:39:34 -05:00
0a2d0854e7 fix: allow unmarking host as no-show (#27694)
* fix: allow unmarking host as no-show and filter invalid attendees in updateAttendees

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* revert: remove updateAttendees change per review feedback

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 13:14:53 +00:00
e04a394e1c fix: (booking-audit) Remove IS_PRODUCTION gate and add feature flag check in producer (#26524)
* fix: remove IS_PRODUCTION gate from BookingAuditProducer

Remove the IS_PRODUCTION check that was preventing booking audits from
being queued in production. Audits are still properly gated by:

1. Organization check: Audits are skipped for non-organization bookings
   (organizationId === null)
2. Feature flag: The BookingAuditTaskConsumer checks if the 'booking-audit'
   feature is enabled for the organization via featuresRepository.checkIfTeamHasFeature()

The IS_PRODUCTION gate was intentionally added to prevent logs from being
created in production while the action data versioning was being actively
reviewed and finalized. Without proper versioning handling, the Booking
History UI could crash when encountering unversioned data. Now that the
versioning system is in place, this gate can be safely removed.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: revert formatting, keep only IS_PRODUCTION removal

Reverts the unintended formatting changes from the previous commit.
Only removes the IS_PRODUCTION gate without changing indentation.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: add booking-audit feature flag check in producer to avoid unnecessary task creation

- Query booking-audit and booking-email-sms-tasker flags in parallel before fireBookingEvents
- Pass isBookingAuditEnabled through BookingEventHandler to producer's queueTask method
- Add conditional check in queueTask with debug log when skipping audit
- Reuse pre-queried isBookingEmailSmsTaskerEnabled flag instead of querying again

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: make isBookingAuditEnabled required and pass it through all booking audit flows

- Make isBookingAuditEnabled a required property in BookingAuditProducerService interface
- Update all BookingEventHandler methods to require isBookingAuditEnabled
- Add feature flag check in all flows that call booking audit:
  - handleSeats (seat booking/rescheduling)
  - RecurringBookingService (bulk bookings)
  - handleCancelBooking (booking cancellation)
  - handleConfirmation (booking acceptance)
  - roundRobinReassignment (automatic reassignment)
  - roundRobinManualReassignment (manual reassignment)
  - trpc handlers: addGuests, confirm, editLocation, requestReschedule
- Skip queueing audit tasks when feature is disabled with debug logging

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: add featuresRepository dependency to RecurringBookingService DI module

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: make isBookingAuditEnabled optional for non-main flows

Keep feature flag check only in main flows (handleSeats, RegularBookingService, RecurringBookingService) which are frequently triggered. For other flows (handleCancelBooking, handleConfirmation, roundRobinReassignment, etc.), rely on the existing consumer-level check.

Changes:
- Revert feature flag check from non-main flows
- Make isBookingAuditEnabled optional in interface for non-main flow methods
- Keep isBookingAuditEnabled required for main flow methods (queueCreatedAudit, queueRescheduledAudit, queueSeatBookedAudit, queueSeatRescheduledAudit, queueBulkCreatedAudit, queueBulkRescheduledAudit)
- Update BookingEventHandlerService to use required params for main flows and optional for non-main flows

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: remove isBookingAuditEnabled from non-main flow methods

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: make isBookingAuditEnabled required in all BookingEventHandlerService methods

- Add isBookingAuditEnabled as required parameter in all BookingAuditProducerService interface methods
- Update BookingAuditTaskerProducerService to use simplified check (!params.isBookingAuditEnabled)
- Update BookingEventHandlerService to require isBookingAuditEnabled in all methods
- Update all callers to query booking-audit feature flag and pass isBookingAuditEnabled:
  - handleCancelBooking
  - handleConfirmation
  - roundRobinReassignment
  - roundRobinManualReassignment
  - addGuests.handler
  - confirm.handler
  - editLocation.handler
  - requestReschedule.handler
- Inject featuresRepository in API V2's booking-location.service.ts

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* test: update roundRobinReassignment tests to include isBookingAuditEnabled

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* test: update roundRobinManualReassignment tests to include isBookingAuditEnabled

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: inject featuresRepository in API V2 RecurringBookingService

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: import PrismaWorkerModule for PrismaFeaturesRepository dependency

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use booking's organization for feature flag check in addGuests handler

Use booking.user?.profiles?.[0]?.organizationId instead of user.organizationId
to check the booking-audit feature flag. This ensures the feature flag is
checked against the booking's organization rather than the actor's organization,
which is consistent with other handlers in this PR.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* Add comment

* fix: use user.organizationId for feature flag check in addGuests handler

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use booking's organizationId for feature flag check in addGuests handler

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: revert to user.organizationId for feature flag check in addGuests handler

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: add isBookingAuditEnabled to onNoShowUpdated calls after main merge

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: add isBookingAuditEnabled to onNoShowUpdated calls and update tests

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 09:25:33 -03:00
emrysal b1b73f7fcc chore: release v6.1.13
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-02-09 11:56:07 +00:00
Benny JooandDevin AI 6287026638 fix: prevent 500 error when deleting calendar events with empty uid (#27500)
* fix: prevent 500 error when deleting calendar events with empty uid

This fix addresses a 500 error that occurs when trying to delete a Google
Calendar event with an empty event ID, which results in a malformed API URL.

Root cause: When calendar event creation fails or returns without an ID,
booking references were being created with empty uids. Later, when trying
to delete these events (e.g., during reschedule), the empty uid caused
a 404 from Google Calendar API which was then thrown as a 500 error.

Changes:
1. CalendarManager.deleteEvent: Added validation to skip deletion if
   bookingRefUid is empty, with appropriate error logging. This is a
   safety net for existing bad data in the database.

2. EventManager.create: Added filtering to exclude booking references
   with empty uids from being stored, with error logging to help
   diagnose the root cause of missing event IDs.

3. EventManager.updateLocation: Same filtering applied for consistency.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: revert EventManager filtering to preserve existing behavior

The test expects that booking references with empty uids are still created
when calendar event creation fails. This is intentional behavior to track
failed calendar syncs. The CalendarManager.deleteEvent fix handles the
deletion case gracefully by skipping the API call when uid is empty.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: throw ErrorWithCode instead of silently returning when bookingRefUid is empty

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: validate uid before calling calendar.deleteEvent to prevent 500 error

- Add uid check in lastAttendeeDeleteBooking.ts before calling calendar.deleteEvent
- Add uid check in EventManager.updateAllCalendarEvents before calling calendar.deleteEvent
- Revert CalendarManager.deleteEvent changes (validation at call sites is the proper fix)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add error logging safeguard in CalendarManager.deleteEvent for empty bookingRefUid

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: move bookingRefUid check before getCalendar call

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: prevent storing booking references with empty uid when calendar event creation fails

Root cause fix: Change the check from 'if (createdEvent)' to 'if (createdEvent.createdEvent)'
in createAllCalendarEvents to prevent failed calendar events from being added to results.

This prevents empty uids from being stored in the database in the first place, which
was causing 500 errors when trying to delete non-existent calendar events later.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* test: update test to expect no calendar reference when calendar event creation fails

The root cause fix changes behavior so that failed calendar events no longer
create booking references with empty uids. This test now expects an empty
references array when calendar event creation fails, which is the correct
behavior that prevents 500 errors later when trying to delete non-existent
calendar events.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: use createdEvent.success instead of createdEvent.createdEvent

Using success is more semantically clear since it explicitly checks the
success status rather than checking if the nested object exists.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: use optional chaining for createdEvent?.success

Using optional chaining is safer in case createdEvent is somehow undefined.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* revert: remove root cause fix to preserve backfilling script compatibility

The root cause fix (checking createdEvent?.success instead of createdEvent)
would break the backfilling script that relies on booking references with
empty uids to identify which bookings need backfilling.

This PR now only includes defensive checks to prevent 500 errors when
deleting calendar events with empty uids.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* revert

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 08:42:14 -03:00
Benny JooandDevin AI 96bec9f7b9 refactor: Move repositories from @calcom/lib to @calcom/features domain folders (#27570)
* refactor: move repositories from lib to features domain folders

- Move HolidayRepository to features/holidays/repositories
- Move PrismaTrackingRepository to features/bookings/repositories
- Move PrismaBookingPaymentRepository to features/bookings/repositories
- Move PrismaRoutingFormResponseRepository to features/routing-forms/repositories
- Move PrismaAssignmentReasonRepository to features/assignment-reason/repositories
- Move VerificationTokenRepository to features/auth/repositories
- Move WorkspacePlatformRepository to features/workspace-platform/repositories
- Move DTO files to their respective feature domains
- Merge lib DestinationCalendarRepository into features version
- Merge lib SelectedCalendarRepository into features version
- Update all import paths across the codebase

This follows the vertical slice architecture pattern by organizing
repositories by domain rather than by technical layer.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update VerificationTokenService import path to new location

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update test file imports to use new repository locations

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* mv

* fix structure

* fix

* refactor: merge unit tests for SelectedCalendarRepository into single file

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 08:41:04 -03:00
Rajiv SahalandDevin AI d4a059033e fix: restore listWithTeam query to include team events with userId set and add comprehensive tests (#27752)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 11:40:47 +00:00
Benny Joo eba0635a07 refactor: eliminate all @calcom/trpc/react imports and tRPC hooks from @calcom/features (#27728)
* migrate booker layout selector

* move schedule hooks and types

* migrate feature opt in components

* migrate feedback dialog

* update

* migrate schedule hooks

* migrate useSegments

* update

* update import paths

* fix import paths

* mv useTimesForSchedule back to features

* fix

* add useEvent to web

* remove the old file

* update imports

* clean up

* migrate Segment

* update imports

* update imports

* fix name

* fix tests

* fix

* fix

* update imports

* remove trpc/react

* remove trpc dependency from package.json

* rm

* wip

* wip

* fix types

* fix

* migrate PhoneInput

* mv LocationInput

* remove dead file

* update import paths

* rm dead import

* rm useApp hook

* cleanup

* wip

* restore

* wip

* remove dead code

* fix

* simplify

* fix

* fix

* fix

* fix

* fix

* fix

* format

* format

* restore

* remove prop
2026-02-09 08:39:28 -03:00
Anik Dhabal Babu 7b9168e3f2 fix: prevent "Closing rpc while fetch was pending" error in unit tests (#27725)
* test: prevent Closing rpc while

* update
2026-02-09 10:33:27 +00:00
9172fe6b1b fix: disable save button when workflow has no changes (#25973)
* fix: disable save button when workflow has no changes

* test: wait for save button to be enabled before clicking

* test: ensure input value is set before pressing Enter

* test fix

* fix: add shouldDirty to enable save button on name change

* test: clean up workflow test fixtures

* fix: disable save button when workflow has no changes

* test: update workflow E2E tests

* test: fix workflow E2E

* fix: enable save button when workflow form fields change

* fix tests

* fix: disable save button when workflow has no changes

* remove comments

* chore: improve fixture logic

* cleanup: remove unnecessary changes

* update workflow fixture to handle team workflow creation

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Romit <romitgabani@icloud.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-09 08:55:49 +00:00
Aditya Vyas 19366700b3 fix: broken style on availability delete button (#27779)
* fix: broken style on availability delete button

* fix/final
2026-02-09 08:49:37 +00:00
b6916df671 test: add E2E tests for assignAllTeamMembers with attribute segment filters (#27680)
* test: add E2E tests for assignAllTeamMembers with attribute segment filters

Cover all 4 attribute types (SINGLE_SELECT, MULTI_SELECT, TEXT, NUMBER)
with booking flow verification plus edge cases (no match, all match).

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use auto-retrying assertion for no-match edge case test

Replace flaky waitForTimeout(2000) + count check with Playwright's
toHaveCount(0, { timeout: 15000 }) which retries until availability
settles, preventing CI timing issues.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: add exclusion tests for members without attribute assigned

Add 4 new E2E tests covering the case where team members have no
attribute assigned at all (not just a different value). Each attribute
type (SINGLE_SELECT, MULTI_SELECT, TEXT, NUMBER) is tested to verify
that members without the attribute are excluded from the booking pool.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: add negation operator tests and restructure exclusion tests

- Restructure 'Members without attribute assigned' tests: assign
  matching attribute to teammate-1 (not owner) so round-robin can't
  coincidentally pass when the bug exists
- Add 4 negation operator tests (select_not_any_in, multiselect_not_some_in,
  not_equal for TEXT and NUMBER) that verify unassigned members should
  match negation filters. Marked with test.fail() as they confirm a
  known bug where getLogicResultForAllMembers skips members without
  attribute assignments entirely.
- Add edge case: no members have attribute assigned -> no available slots

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: remove test.fail() markers from negation tests after bug fix

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 14:07:49 +05:30
f819f6488e test: add E2E tests for routing form attribute conditions (#27681)
* feat: add comprehensive E2E tests for routing form attribute conditions

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: assert routedTeamMemberIds in URL instead of email in results

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: assert both routedTeamMemberIds in URL and email in results

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: include users without attribute assignments in exclusion condition evaluation

Users with no attribute assigned were excluded from the team members list
entirely, causing exclusion operators (not_equals, not_some_in, not_like,
not_between, etc.) to never match them. Now getAttributesAssignmentData
includes all team members, even those without attribute assignments.

Also adds unit tests and E2E tests for this scenario.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: update getAttributes test to reflect new behavior for empty attributes

Users without attribute assignments are now included with empty attributes
so exclusion operators can match them. Updated test expectation accordingly.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: remove redundant usersWithAssignments code (fix already in _prepareAssignmentData from main)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 14:02:22 +05:30
Benny Joo 29bb4fd497 refactor: remove 3 @calcom/web imports from @calcom/features by relocating blocklist UI and useEvent hook (#27775)
* migrate blocklist components to web

* migrate useEvent

* fix

* fix

* rm barrel file

* dead code
2026-02-09 08:02:42 +00:00
Ahmad YasserandDhairyashil cdf901fee3 fix: defer email validation to after first blur on signup form (#27765)
* fix: defer email validation to after first blur on signup form

Change react-hook-form validation mode from "onChange" to "onTouched"
so that the "Invalid email" error only appears after the user has
interacted with the field and moved away, not on every keystroke.
Password strength hints still update in real-time since onTouched
validates on change after the field has been touched (blurred once).

Fixes #19163

* test: add unit tests for signup email validation mode

Verify the onTouched form validation behavior:
- No error shown while user is typing
- Error appears only after blur with invalid email
- No error for valid email after blur
- Revalidation on each keystroke after first blur

* remove eslint comment

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-02-09 06:40:11 +00:00
Ahmad Yasser 3052cf5157 feat: add ARIA labels to time format and layout toggle controls (#27760)
Add aria-label to the TimeFormatToggle and LayoutToggle components
on the booking page so screen readers can identify these radio groups.
Uses existing translation keys "time_format" and "layout".

Fixes #20703
2026-02-09 06:13:27 +00:00
Hariom BalharaandDevin AI 0ec07b0005 fix: resolve flaky no-show-updated-action integration test (#27772)
- Remove unused attendeeIds field and unnecessary prisma.booking.findUnique from beforeEach
- Store booking.id in testData to avoid re-querying booking in test body
- Track additional attendee emails via additionalAttendeeEmails array for proper afterEach cleanup
- Remove fragile prisma.attendee.delete (throws P2025 on missing record) from test body
- Use deleteMany-based cleanupTestData for second attendee cleanup instead

The test was flaky because:
1. It used prisma.attendee.delete (singular) which throws if record is already gone
2. It re-queried the booking via findUnique mid-test which could fail if cascade-deleted
3. The second attendee email was not tracked in afterEach cleanup

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 05:10:37 +00:00
Ahmad Yasser e940aac2f1 fix: remove duplicate translation keys in common.json (#27769)
Remove 4 duplicate keys that existed in the English translations file:
- routing_forms: identical duplicate removed
- submit_feedback: kept "Submit feedback" (consistent casing)
- skip_trial: kept "Skip trial" (used as button label)
- availability_schedule: kept "Availability schedule" (sentence case),
  removed duplicate with inconsistent capitalization

Fixes #23478
2026-02-09 04:12:15 +00:00
Benny Joo 7ba749e496 fix: Atom build failing due to dependency on @calcom/web (#27757) 2026-02-08 20:31:18 +00:00
Ahmad YasserandSahitya Chandra 794046cf05 fix: prevent textarea resize overlapping buttons in rejection dialog (#27749)
* fix: prevent textarea resize overlapping buttons in rejection dialog

The rejection reason textarea in the booking rejection dialog allows
manual resizing via the drag handle, which can cause it to expand over
the dialog footer buttons. Adding resize-none prevents this overlap.

Fixes #17536

* Update RejectionReasonDialog.tsx

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-08 20:10:58 +00:00
60188bc66e fix(booking): make provider label and location link visible on mobile (#27463)
* fix(booking): make provider label and location link visible on mobile

* correct order

* remove comments

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-02-08 19:22:50 +00:00
an_ifrah24andRomit 466e7f2fa7 fix: removed extra scrollbar when selected checkbox field for booking form questions (#27592)
* fix: css property for the scroll bar and label for multi select

* chore

---------

Co-authored-by: Romit <romitgabani1.work@gmail.com>
2026-02-08 11:27:13 +00:00
Abhay MishraandDhairyashil 0b0a5478fb feat: Add action‑item support to mobile “More” page and added navigation to refer page (#26431)
* Add action‑item support to mobile “More” page and hide arrow on copy‑link button

* updated code

* fix code

* updated code

* remove unused import and formatting

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-02-07 13:57:24 +00:00
Abhay MishraandSahitya Chandra 0beadfa80b fix: allow deleting first time slot in availability schedule (#26448) (#27569)
* fix: allow deleting first time slot in availability schedule (#26448)

* code updated

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-07 13:18:25 +00:00
Eunjae LeeandDevin AI a57fac7a78 docs: add code comment guidelines to AGENTS.md and update rule (#27729)
* docs: add code comment guidelines to AGENTS.md

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: extract comment guidelines into agents/rules and reference from AGENTS.md

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-07 18:06:30 +05:30
22167d28b8 fix: prevent auto-install for OAuth apps in installation flow (#27567)
* fix: resolve organizer default conferencing app credential for location update

- Fix Google Meet credential lookup in EventManager to properly map 'google:meet' to 'google_video' type
- Add automatic credential ID resolution when selecting 'Organizer Default App' as location
- Fixes 'Location update failed' error when editing round-robin team event location to organizer default app (Google Meet) with multiple Google Calendar connections

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix update

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-07 12:27:16 +00:00
Udit Takkar 129ea8d1f1 chore: enable agent teams feature (#27682) 2026-02-07 17:55:08 +05:30
Benny Joo e64fad8e34 refactor: remove 6 @calcom/trpc imports from packages/features (#27727)
* migrate booker layout selector

* move schedule hooks and types

* migrate feature opt in components

* migrate feedback dialog

* update

* migrate schedule hooks

* migrate useSegments

* update

* update import paths

* fix import paths

* mv useTimesForSchedule back to features

* fix
2026-02-07 09:05:09 -03:00
Sparky_AutonomousandSparky Autonomous aa5e90ab2a chore: Bail earlier when an invalid session is found (Fixes #15982) (#27609)
Co-authored-by: Sparky Autonomous <sparky@openclaw.ai>
2026-02-07 07:37:33 +00:00
Rajiv Sahal 321b07ab8b chore: troubleshooter atom docs (#27717) 2026-02-06 19:39:28 +00:00
3abde55b05 fix: Auth page in settings design fixed (#27294)
* fixed text issue

* matched style of api keys page

* o auth design fixed

---------

Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Romit <romitgabani@icloud.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-07 00:52:11 +05:30
b45d7c15db fix: optional email validation (#27329)
* fix: validate optional email fields when input is provided #27299

* fix: validate optional email fields when input is provided

* fix: validate optional email fields when input is provided

* refactor: move empty value handling out of zod-utils

* fix: remove PII from error logs

* test: verify optional email allows empty submission

* test: e2e validation for optional email using url state

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2026-02-06 18:39:47 +00:00
68022f369c test: [Stacked] migrate findTeamMembersMatchingAttributeLogic to integration tests (#27697)
* Fix exclusion filter - include all team members

* Fix display when members aren't saved in the DB

* Update tests

* Use integration tests for findTeamMembersMatchingAttributeLogic for better behaviour testing

* Add test that verifies that it was working earlier and broken in b/w and not working again

* Revert changes to AddMembersWithSwitch.tsx

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 12:48:48 -05:00
Eunjae LeeandDevin AI b9c54f6661 docs: add Trigger.dev task implementation rule (#27712)
* docs: add Trigger.dev task implementation rule

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: add specific file path references for CalendarsTasker and config examples

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-07 00:43:07 +09:00
Rajiv Sahal 8a17ebc2ef feat: Troubleshooter atom (#27497) 2026-02-06 17:34:58 +02:00
Everton Resende a71d62dc33 fix(ui): change phone booking display from Organizer Phone Number to Phone Call (#27636)
* fix(ui): change phone booking display from Organizer Phone Number to Phone Call

The label \"Organizer Phone Number\" was confusing for attendees on the
booking page, as it exposed internal terminology. Replaced with the
more user-friendly \"Phone Call\" label across the booking UI, companion
app, and test assertions.

Closes #13010

* fix: remove duplicate phone_call i18n key

The phone_call key already existed in en/common.json (line 1685,
Cal.ai Voice Agent section). Removed the duplicate entry we added.

Found by ai-codex review.
2026-02-06 15:28:38 +00:00
Benny JooandDevin AI a8ede7761f fix: use LOGO_DARK constant for generic OG image instead of hardcoded value (#27705)
* fix: use LOGO constant for generic OG image instead of hardcoded value

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* test: add unit tests for OgImages module

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: remove unused LOGO import from OgImages test

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* test: update OgImages tests to reflect LOGO_DARK constant

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* add comment

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 14:19:00 +00:00
Peer RichelsenandDevin AI 6a162e47c0 fix: remove unnecessary border from availability list view (#27683)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 15:15:49 +01:00
Joe Au-Yeung bc0ff0da8e fix: Exclusion attribute filter (#27669)
* Fix exclusion filter - include all team members

* Fix display when members aren't saved in the DB

* Update tests

* Undo change to member switch
2026-02-06 14:06:31 +00:00
38492d5839 fix: prevent layout shift in sticky navbar (#27256)
* fix navbar layout shift

* fix: adjust layout for iPad breakpoints

* fix: respect disableSticky for md+ header positioning

* Fix sticky header condition in Shell component

* Update apps/web/modules/event-types/components/EventTypeLayout.tsx

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update apps/web/modules/shell/Shell.tsx

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update apps/web/components/apps/layouts/AppsLayout.tsx

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update apps/web/modules/event-types/components/EventTypeLayout.tsx

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update packages/app-store/_components/AppCategoryNavigation.tsx

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Fix formatting in ShellMainAppDir component

* Update apps/web/modules/shell/Shell.tsx

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Adjust layout styles for Shell component

* Add dynamic header style based on banners height

* fix respect disableSticky and add spacing to navbar elements

* Refactor JSX structure in Shell component

* Refactor header div and sticky behavior

* Update AppsLayout.tsx

* remove sticky navbar from app store

* fix alignment

---------

Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-02-06 13:21:06 +00:00
d80ee83da7 feat: redesign team creation flow to match onboarding (#27698)
* Revert "Revert "feat: redesign team creation flow to match onboarding-v3 design (#26733)""

This re-applies the team creation redesign from PR #26733 which was
previously reverted. Cherry-picked from 2540423ba3.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: check org/username slug when in org context

* fix: use expect(page).toHaveURL() instead of page.waitForURL() in team e2e test

Co-Authored-By: unknown <>

* fix: redirect URL

* fix: flag import

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 13:19:39 +00:00
369ec831fe feat: add comprehensive booking audit logs seed script (#27699)
* feat: add comprehensive booking audit logs seed script

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: remove dead code and use real UUID for impersonation context

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: seed audit logs for org user booking to enable UI testing

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: create dedicated booking for audit logs, only seed for org user

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: use realistic names and emails in audit log seed data

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: enable bookings-v3 global flag and booking-audit team flag in seed

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix or gcheck

* fix: add guard for empty profiles array in audit seed script

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 13:09:48 +00:00
sean-brydon bb6b99d9b1 feat: move platform active billing logic to services (#27704)
* wip

* feat: migrate from v2

* format

* remove plan
2026-02-06 12:45:40 +00:00
8a7cf24f90 feat(companion): add upcoming bookings widget for iOS and Android (#27199)
* feat(companion): add upcoming bookings widget for iOS and Android

- Add iOS widget using @bacons/apple-targets with SwiftUI
- Add Android widget using react-native-android-widget
- Configure App Groups for iOS data sharing between app and widget
- Create widget sync hook to update widget data when bookings change
- Widget displays up to 5 upcoming bookings with title, time, and attendee
- Widget refreshes every 15 minutes and when app goes to background

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix(companion): refactor useWidgetSync to avoid React Compiler limitation

Move conditional logic outside of try/catch block to fix React Compiler
error: 'Support value blocks (conditional, logical, optional chaining,
etc) within a try/catch statement'

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix(companion): fix widget data sync issues

- Fix Swift widget to read data as JSON string (format used by react-native-shared-group-preferences)
- Add fallback to read as raw Data for compatibility
- Fix query key mismatch by checking multiple common filter combinations
- Ensure widget finds cached bookings regardless of which filter the app used

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix(companion): use ExtensionStorage from @bacons/apple-targets for widget data

- Replace react-native-shared-group-preferences with ExtensionStorage
- ExtensionStorage properly stores data in iOS App Groups
- Add ExtensionStorage.reloadWidget() call to trigger widget refresh
- This ensures the widget picks up new data immediately

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat(companion): add upcoming bookings widget for ios - all shapes (#27564)

* ios working widget

* fix(companion): remove sensitive data logging from widget storage

Remove console.log statements that were logging full widgetData payload
and formatted widget bookings containing attendee names and booking
details. This addresses security concerns identified by Cubic AI review
(confidence 9/10).

Co-Authored-By: unknown <>

* dark mode

* new look

* fix deeplink

* fix biome lint

* fix(companion): remove booking titles from console logs to avoid PII exposure

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* lock the versions and dev mode logging

* remove dynamic imports

* feat(companion): upcoming bookings widget android (#27689)

* companion-upcoming-bookings-widget-android

* fix(companion): remove stale relative countdowns and fix past-time clamping in Android widget

- Remove relative countdown text (In 15m, In 1h, Now) that becomes stale
  due to Android widget 30+ min update interval (Cubic violation 2)
- Remove Math.max(0, minutes) clamping that caused ended meetings to
  display as 'Now' indefinitely (Cubic violation 1)
- Simplify accent color logic to use startTimeISO directly
- Keep absolute time display (date + startTime) which remains accurate

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-02-06 12:32:46 +00:00
Anik Dhabal Babu 617cdea683 fix: fallback to cal video when Google Meet used without Google Calendar as default app (#27630)
* fallback to daily video

* add tests
2026-02-06 09:29:26 -03:00
Anik Dhabal Babu c6125f359d fix: event is not created on the Zoho Calendar when hideOrganizerEmail is enabled (#27675)
* fix: event not created

* Update CalendarManager.ts

* Add tests: packages/features/calendars/lib/CalendarManager.ts

Generated by Paragon from proposal for PR #27675

* Add tests: packages/features/calendars/lib/CalendarManager.test.ts

Generated by Paragon from proposal for PR #27675

* Export processEvent for testing and refactor logic

* Fix missing newline at end of CalendarManager.test.ts

Add missing newline at the end of the file.

* fix test
2026-02-06 12:28:22 +00:00
4a6d608b19 refactor: simplify link-as-an-app template and migrate 24 existing apps (#27215)
* refactor: simplify link-as-an-app template to config.json only

- Remove api/, components/, index.ts, package.json from link-as-an-app template
- Add externalLink field to AppMetaSchema for external URL configuration
- Update API handler to dynamically create handlers for external link apps
- External link apps no longer create credentials (just redirect to URL)
- Update CLI to handle externalLinkUrl field for link-as-an-app template
- CLI now skips package.json update for apps without package.json

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: simplify external link handler to bypass credential creation

External link apps now directly return the redirect URL without going
through the AppDeclarativeHandler type, avoiding type conflicts with
the createCredential return type requirement.

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: migrate 24 external link apps to simplified structure

Migrated the following apps to use config.json with externalLink field
instead of api/add.ts handlers:

- amie, autocheckin, baa-for-hipaa, bolna, chatbase, clic, cron, deel
- elevenlabs, fonio-ai, framer, granola, greetmate-ai, lindy, millis-ai
- monobot, n8n, pipedream, raycast, retell-ai, synthflow, telli, vimcal
- wordpress

Each app now only contains: config.json, DESCRIPTION.md, static/
Removed: api/, components/, index.ts, package.json

Co-Authored-By: peer@cal.com <peer@cal.com>

* nit

* Fix merge conflict issue

* refactor: generate REDIRECT_APPS dynamically during app-store build

- Add logic to build.ts to detect apps with externalLink field
- Generate redirect-apps.generated.ts with list of redirect app slugs
- Update redirectApps.ts to import from generated file
- Revert [...]args].ts to original state (Flow 1 is preferred)

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: cast REDIRECT_APPS to readonly string[] for includes check

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Fix error with React

* Take exteral link URL as input

* deleted bun.lockb

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2026-02-06 12:28:11 +00:00
54da93ab02 chore: Integrate mark-no-show booking audit (#26570)
* chore: Integrate mark-no-show booking audit

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Simplify host no-show audit and add comment for attendee actor

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Make actionSource required with ValidActionSource type and remove unnecessary comments

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove merge conflict markers from bookings.service.ts

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: implement SYSTEM as a booking audit source for background tasks, including no-show triggers.

* refactor: Move prisma query to BookingRepository for audit logging

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Conflict resolution

* refactor: introduce `handleMarkHostNoShow` for public viewer and standardize actor and action source parameters for no-show actions.

* refactor: Combine HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService into NoShowUpdatedActionService

- Create new NoShowUpdatedAuditActionService with combined schema supporting both noShowHost and noShowAttendee as optional fields
- Update BookingAuditActionServiceRegistry to use combined service with NO_SHOW_UPDATED action type
- Update BookingAuditTaskerProducerService with single queueNoShowUpdatedAudit method
- Update BookingAuditProducerService.interface.ts with combined method
- Update BookingEventHandlerService with single onNoShowUpdated method
- Update handleMarkNoShow.ts to use combined audit service
- Update tasker tasks (triggerGuestNoShow, triggerHostNoShow) to use combined service
- Add NO_SHOW_UPDATED to Prisma BookingAuditAction enum
- Remove old separate HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService files

This allows a single API action (e.g., API V2 markAbsent) that updates both host and attendee no-show status to be logged as a single audit event.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* chore: Add migration for NO_SHOW_UPDATED audit action enum value

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Update no-show audit schema to use host and attendees array

- Rename noShowHost to host and noShowAttendee to attendees (remove redundant prefix)
- Change attendees from single value to array to support multiple attendees in single audit entry
- Update handleMarkNoShow.ts to create single audit entry for all attendees
- Update tasker tasks (triggerGuestNoShow, triggerHostNoShow) to use new schema
- Update display data types to reflect new schema structure

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Update schema to be more clear. Call onNoShowUpdated immediately after DB update as audit only cares about DB update, and this would avoid any accidental Audit update on DB change

* chore: accommodate schema changes and fix type errors for no-show audit

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update migration to remove old no-show enum values

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Use updated attendees in webhook payload for guest no-show

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove duplicate imports and fix actor parameter in bookings.service.ts

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Move booking query to BookingRepository and remove unused method

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: centralize no-show audit event firing and attendee fetching within `handleMarkNoShow` for improved clarity.

* fix: Build attendeesNoShow as Record with attendee IDs as keys

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Fix and add tests for handleMarkBoShow

* refactor: Move prisma queries to AttendeeRepository and BookingRepository

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Correct return type for updateNoShow method (noShow can be null)

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update handleMarkNoShow tests to mock new repository methods

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix triggerGuestNoShow

* refactor: Move triggerGuestNoShow queries to AttendeeRepository and add unit tests

- Add new methods to AttendeeRepository:
  - findByBookingId: Get attendees with id, email, noShow
  - findByBookingIdWithDetails: Get full attendee details
  - updateManyNoShowByBookingIdAndEmails: Update specific attendees
  - updateManyNoShowByBookingIdExcludingEmails: Update all except specific emails
- Refactor triggerGuestNoShow.ts to use AttendeeRepository instead of direct Prisma calls
- Add comprehensive unit tests for triggerGuestNoShow following handleMarkNoShow.test.ts pattern:
  - Mock repositories and external services
  - In-memory DB simulation
  - Test core functionality, audit logging, webhook payload, error handling, and edge cases

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Move triggerHostNoShow queries to repositories and delete unit test file

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Convert repository methods to use named parameters objects

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Enhance no-show handling by consolidating audit logging and updating repository interactions

- Refactor `buildResultPayload` to accept a structured argument for better clarity.
- Update `updateAttendees` to use a named parameter object for improved readability.
- Introduce `fireNoShowUpdatedEvent` to centralize no-show audit logging for both hosts and guests.
- Remove redundant methods and streamline attendee retrieval in `AttendeeRepository`.
- Add comprehensive unit tests for no-show event handling, ensuring accurate audit logging and webhook triggering.

* test: Add tests for handleMarkHostNoShow guest actor and unmarking host no-show

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: update attendeesNoShow validation to handle numeric keys

- Changed attendeesNoShow schema to use z.coerce.number() for key validation, ensuring string keys are correctly coerced to numbers.
- Updated test to validate attendeesNoShow data using numeric key comparison, improving robustness of the audit data checks.

* test: Add integration tests for NoShowUpdatedAuditActionService coerce fix

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: add graceful error handling for audit log enrichment

- Add hasError field to EnrichedAuditLog type
- Create buildFallbackAuditLog() method for failed enrichments
- Wrap enrichAuditLog() in try-catch to handle errors gracefully
- Add booking_audit_action.error_processing translation key
- Update BookingHistory.tsx to show warning icon for error logs
- Hide 'Show details' button for logs with hasError
- Add comprehensive test cases for error handling scenarios

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: Enhance booking audit action services with new display fields and improved validation

- Added "attendee_no_show_updated" and "no_show_updated" translations to common.json.
- Updated IAuditActionService to include new methods for handling display fields and migration.
- Enhanced NoShowUpdatedAuditActionService to differentiate between host and attendee no-show updates.
- Improved ReassignmentAuditActionService to ensure consistent handling of audit data.
- Refactored BookingAuditViewerService for better clarity and maintainability.

* refactor: Use attendeeEmail instead of attendeeId as key in audit data and store host's userUuid

- Updated schema to use attendee email as key instead of attendee ID because attendee records can be reused with different person's data
- Store host's userUuid in audit data with format: host: { userUuid, noShow: { old, new } }
- Updated fireNoShowUpdated to accept hostUserUuid parameter
- Added uuid field to BookingRepository.findByUidIncludeEventTypeAttendeesAndUser
- Updated NoShowUpdatedAuditActionService getDisplayFields to work with email-based keys
- Added attendeeRepository to DI modules for BookingAuditTaskConsumer
- Updated tests to match new schema format

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* test: Update integration tests to use new schema format with host.userUuid and email keys

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: correct audit schema for SYSTEM source and ensure attendee lookup by bookingId

- Fix schema inconsistency: use host.userUuid format instead of hostNoShow
- Add user.uuid to getBooking select for audit logging
- Log warning when hostUserUuid is undefined but host no-show is being updated
- Use email as key for attendeesNoShow (not attendee ID) to match schema
- Fetch attendees by bookingId before updating to ensure correct scoping
- Remove unused safeStringify import

* refactor: Change attendeesNoShow schema from Record to Array format

- Update NoShowUpdatedAuditActionService schema to use array format:
  attendeesNoShow: Array<{attendeeEmail: string, noShow: {old, new}}>
- Update handleMarkNoShow.ts to build attendeesNoShow as array
- Update common.ts fireNoShowUpdatedEvent to convert Map to array
- Update all tests to use new array format with attendeeEmail property

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Update attendeesNoShow schema to use array format in triggerNoShow tasks

- Refactor `triggerGuestNoShow` and `triggerHostNoShow` to replace Map with array for `attendeesNoShowAudit`.
- Update `fireNoShowUpdatedEvent` to handle the new array format for attendees.
- Ensure consistent data structure across no-show audit logging for better clarity and maintainability.

* fix: Update ReassignmentAuditActionService to use GetDisplayFieldsParams interface

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update ReassignmentAuditActionService tests to use GetDisplayFieldsParams interface

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Use handleMarkAttendeeNoShow for API v2 mark absent endpoint

- Export handleMarkAttendeeNoShow from platform-libraries
- Update API v2 bookings service to use handleMarkAttendeeNoShow with actionSource
- Add validation for userUuid before calling handleMarkAttendeeNoShow

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Enhance display fields structure in booking audit components

- Updated `BookingHistory.tsx` to allow for more flexible display fields, including optional raw values and arrays of values.
- Introduced `DisplayFieldValue` component for rendering display fields, improving clarity and maintainability.
- Adjusted `IAuditActionService` and `NoShowUpdatedAuditActionService` to align with the new display fields structure.
- Ensured consistent handling of display fields across the booking audit service for better data representation.

* fix: Remove debug code that duplicated first attendee in display fields

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Update attendee repository methods to use structured parameters

- Modified `updateNoShow`, `updateManyNoShowByBookingIdAndEmails`, and `updateManyNoShowByBookingIdExcludingEmails` methods to accept structured `where` and `data` parameters for better clarity and maintainability.
- Updated calls to these methods throughout the codebase to reflect the new parameter structure.
- Removed unused `findByIdWithNoShow` method and adjusted related logic to streamline attendee data retrieval.

* feat: Add infrastructure for no-show audit integration

- Add Prisma migrations for SYSTEM source and NO_SHOW_UPDATED audit action
- Add NoShowUpdatedAuditActionService with array-based attendeesNoShow schema
- Update BookingAuditActionServiceRegistry to include NO_SHOW_UPDATED
- Update BookingAuditTaskConsumer and BookingAuditViewerService
- Add AttendeeRepository methods for no-show queries
- Update IAuditActionService interface with values array support
- Update locales with no-show audit translation keys

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add NO_SHOW_UPDATED to BookingAuditAction and SYSTEM to ActionSource types

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED from BookingAuditAction type to match Prisma schema

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update BookingAuditActionSchema to use NO_SHOW_UPDATED instead of HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Remove deprecated no-show audit services and unify to NoShowUpdatedAuditActionService

- Delete HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService
- Update BookingAuditProducerService.interface.ts to use queueNoShowUpdatedAudit
- Update BookingAuditTaskerProducerService.ts to use queueNoShowUpdatedAudit
- Update BookingEventHandlerService.ts to use onNoShowUpdated
- Add integration tests for NoShowUpdatedAuditActionService

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update test mock to match new AttendeeRepository.updateNoShow signature

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: rename handleMarkAttendeeNoShow to handleMarkNoShow and update related types

- Renamed `handleMarkAttendeeNoShow` to `handleMarkNoShow` for clarity.
- Updated type definitions to reflect the new naming convention.
- Modified the `markNoShow` handler to require `userUuid` and adjusted related logic.
- Enhanced the `fireNoShowUpdatedEvent` to accommodate changes in event type structure.
- Updated references across various files to ensure consistency with the new function name.

* handle null value

* fix: add explicit parentheses for operator precedence clarity

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Fix cubic reported bug

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 09:27:25 -03:00
08a5edd464 feat: nav item dropdown animation implemented (#26534)
* Nav Item dropdown animation Implemented

* minor issue resolved

* Dropdown

* fix: remove inert property from NavigationItem to resolve type check error

* add inert

* replace inert with visible/invisible class

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
Co-authored-by: Romit <romitgabani@icloud.com>
2026-02-06 17:37:19 +05:30
66fc0465bd fix: Form Builder Name Field Shows Default Label When Custom Label is Empty (#24201)
* removed previious pr ommit from thi sone

* fixed addressed issues

* fallback to non-empty label for variant fields

* fallback to default label

* normalize empty labels and fallback to default when label equals field name

* fix: initially use empty label for name field (fullName variant)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: remove normalization of empty field labels in FormBuilder

* fix: enhance label handling in getTranslatedConfigVariants function

* Update apps/web/modules/event-types/components/tabs/advanced/FormBuilder.tsx

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 16:58:31 +05:30
b74dd3227c perf: Optimize DB calls and avoid N+1 queries in BookingAuditViewer (#26544)
* Integrate creation/rescheduling booking audit

* fix: add missing hostUserUuid to booking audit test data

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix-ci

* feat: enhance booking audit with seat reference

- Added support for seat reference in booking audit actions.
- Updated localization for booking creation to include seat information.
- Modified relevant services to pass attendee seat ID during booking creation.

* fix: update test data to match schema requirements

- Add seatReferenceUid: null to default mock audit log data
- Add seatReferenceUid: null to multiple audit logs test case
- Convert SEAT_RESCHEDULED test data to use numeric timestamps instead of ISO strings

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Allow nullish seatReferenceUid

* feat: enhance booking audit to support rescheduledBy information

- Updated booking audit actions to include rescheduledBy details, allowing tracking of who rescheduled a booking.
- Refactored related services to accommodate the new rescheduledBy parameter in booking events.
- Adjusted type definitions and function signatures to reflect the changes in the booking audit context.

* Avoid possible run time issue

* Fix imoport path

* fix failing test due to merge from main\

* Pass useruuid

* Refactor getDisplayTitle method signatures to use _params for consistency across audit action services. Update IAuditActionService to include dbStore in GetDisplayTitleParams for improved data handling during title retrieval.

* fix: extend bulk-fetching optimization to actor and impersonator enrichment

- Collect actor userUuids (for USER type actors) in collectDataRequirements
- Collect impersonator UUIDs from log.context.impersonatedBy
- Update enrichActorInformation to use dbStore.getUserByUuid() for USER actors
- Update enrichImpersonator to use dbStore.getUserByUuid()
- Update tests to verify findByUuids is called with correct aggregated UUIDs

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: Add infrastructure for no-show audit integration

- Add Prisma migrations for SYSTEM source and NO_SHOW_UPDATED audit action
- Add NoShowUpdatedAuditActionService with array-based attendeesNoShow schema
- Update BookingAuditActionServiceRegistry to include NO_SHOW_UPDATED
- Update BookingAuditTaskConsumer and BookingAuditViewerService
- Add AttendeeRepository methods for no-show queries
- Update IAuditActionService interface with values array support
- Update locales with no-show audit translation keys

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add NO_SHOW_UPDATED to BookingAuditAction and SYSTEM to ActionSource types

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED from BookingAuditAction type to match Prisma schema

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update BookingAuditActionSchema to use NO_SHOW_UPDATED instead of HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Remove deprecated no-show audit services and unify to NoShowUpdatedAuditActionService

- Delete HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService
- Update BookingAuditProducerService.interface.ts to use queueNoShowUpdatedAudit
- Update BookingAuditTaskerProducerService.ts to use queueNoShowUpdatedAudit
- Update BookingEventHandlerService.ts to use onNoShowUpdated
- Add integration tests for NoShowUpdatedAuditActionService

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add data migration step for deprecated no-show enum values

Addresses Cubic AI review feedback (confidence 9/10): The migration now
includes an UPDATE statement to convert existing records using the
deprecated 'host_no_show_updated' or 'attendee_no_show_updated' enum
values to the new unified 'no_show_updated' value before the type cast.
This prevents migration failures if any existing data uses the old values.

Co-Authored-By: unknown <>

* fix: Use CASE expression in USING clause for enum migration

Fixes PostgreSQL error 'unsafe use of new value of enum type' by avoiding
the ADD VALUE statement and instead using a CASE expression in the ALTER
TABLE USING clause to convert deprecated enum values (host_no_show_updated,
attendee_no_show_updated) to the new unified value (no_show_updated) during
the type conversion.

Co-Authored-By: unknown <>

* fix: Remove dbStore usage from audit action services after merge

- Update CreatedAuditActionService to use userRepository.findByUuid directly
- Remove unused dbStore parameter from RescheduledAuditActionService
- Sync test file with prepare-for-no-show-audit branch

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Restore dbStore bulk-fetching optimization pattern

- Add dbStore parameter and getDataRequirements method to IAuditActionService interface
- Update CreatedAuditActionService to use dbStore.getUserByUuid() for bulk-fetched data
- Update RescheduledAuditActionService to accept dbStore parameter
- Update BookingAuditViewerService to:
  - Collect data requirements from all audit logs
  - Bulk-fetch users with findByUuids() before enrichment
  - Pass dbStore to action services and enrichment methods
- Update tests to verify findByUuids is called for bulk-fetching optimization

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove duplicate fireBookingEvents method in RecurringBookingService

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* revert: Remove formatting-only changes in audit action services

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: Make getDataRequirements required and fetch rescheduled logs early

- Make getDataRequirements a required method in IAuditActionService interface
- Add getDataRequirements to all action services that didn't have it
- Fetch rescheduled logs early to include their data requirements in bulk fetch
- Update ReassignmentAuditActionService to use dbStore pattern instead of repository
- Update NoShowUpdatedAuditActionService to use dbStore pattern
- Update tests to use new dbStore pattern
- Handle invalid data gracefully in collectDataRequirements

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Remve unncessary variable

* feat: Implement Actor Strategy pattern for bulk-fetching attendees and credentials

- Add ActorStrategies.ts with strategy pattern for all 5 actor types
- Extend EnrichmentDataStore with StoredAttendee and StoredCredential types
- Add findByIds method to CredentialRepository for bulk-fetching
- Update BookingAuditViewerService to use strategy pattern:
  - Replace switch statement in enrichActorInformation with strategy dispatch
  - Update collectDataRequirements to collect attendeeIds and credentialIds
  - Update buildEnrichmentDataStore to bulk-fetch in parallel
- Update tests to use findByIds mock and reflect graceful handling of missing data

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Restore error-throwing for actors with missing required IDs

- USER actor now throws error when userUuid is missing
- ATTENDEE actor now throws error when attendeeId is missing
- Updated tests to expect hasError: true for fallback logs

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Restore original test assertions, only update mocks for bulk methods

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* test: Add contract verification tests for getDataRequirements

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Clean up imports and improve type definitions in BookingAuditTaskConsumer and BookingAuditViewerService

- Consolidated import statements for better readability
- Enhanced type definitions for clarity and consistency
- Updated method signatures to use destructured parameters for improved maintainability

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* test: Split contract verification tests into separate files per action service

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* test: Rename contract test files to .test.ts and merge into existing test file

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: Add runtime validation to EnrichmentDataStore for undeclared data access

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Make declaredRequirements required and add ensureFetched helper

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Simplify EnrichmentDataStore with constructor + fetch() pattern

- Remove unused userIds and bookingUids from DataRequirements
- Remove unused getUserById and getBookingByUid methods
- Refactor constructor to accept requirements and repositories
- Add fetch() method that fetches data and populates maps
- Use Map keys as source of truth for declared requirements
- Update getters to throw when accessing undeclared data
- Add comprehensive unit tests for EnrichmentDataStore
- Update BookingAuditViewerService to use new API
- Update contractVerification.ts to remove unused tracking

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Clean up imports and improve type definitions in BookingAuditTaskConsumer and BookingAuditViewerService

- Consolidated import statements for better readability
- Enhanced type definitions for clarity and consistency
- Updated method signatures to use destructured parameters for improved maintainability

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Include contextRequirements in mergeDataRequirements and add accessedData assertions

- Fix bug where contextRequirements (impersonator UUIDs) were not merged
- Add accessedData assertions to CreatedAuditActionService.test.ts
- Add accessedData assertions to ReassignmentAuditActionService.test.ts

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 16:08:38 +05:30
39135f84ef fix: call history to free users (#27473)
* fix: call history to free users

Signed-off-by: Jagadish Madavalkar <jagadish.me07@gmail.com>

* bypass paywall for insights/call-history

* improve naming

---------

Signed-off-by: Jagadish Madavalkar <jagadish.me07@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
Co-authored-by: Romit <romitgabani@icloud.com>
2026-02-06 15:41:01 +05:30
Eunjae LeeandClaude Opus 4.5 512002aaef refactor: replace FeaturesRepository with DI-based feature repositories (#27200)
* refactor: replace FeaturesRepository with DI-based feature repositories

Migrate from the legacy FeaturesRepository pattern to separate DI-based repositories:
- Add checkIfFeatureIsEnabledGlobally to IFeatureRepository
- Add getTeamsWithFeatureEnabled to ITeamFeatureRepository
- Update CalendarSubscriptionService to use featureRepository, teamFeatureRepository, and userFeatureRepository
- Update SelectedCalendarRepository.findNextSubscriptionBatch to filter by teamIds instead of featureIds
- Update OnboardingPathService to use DI via getFeatureRepository()
- Remove prisma parameter from OnboardingPathService callsites

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: update tests to use new DI-based feature repositories

Update CalendarSubscriptionService and SelectedCalendarRepository tests
to use the new separate repository interfaces:
- featureRepository for global feature checks
- teamFeatureRepository for team-level feature checks
- userFeatureRepository for user-level feature checks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update API routes to use DI-based feature repositories

Update cron and webhook routes to use the new separate repository
interfaces instead of the combined FeaturesRepository.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: remove prisma arg from getGettingStartedPathWithParams call

The OnboardingPathService method no longer requires a prisma argument
as it now uses DI containers internally.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: update route tests to expect new DI-based feature repositories

Update service instantiation tests to expect featureRepository,
teamFeatureRepository, and userFeatureRepository instead of the
old featuresRepository.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: optimize global feature check and add guard in checkForNewSubscriptions

- Use targeted select for only `enabled` field in checkIfFeatureIsEnabledGlobally
- Add global feature flag guard in checkForNewSubscriptions to avoid unnecessary
  DB queries and API calls when the cache feature is globally disabled

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* remove redundant comment

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 09:34:03 +00:00
Pedro CastroandDevin AI cb36fc201f fix: add URL validation to webhook endpoints (#26593)
Validates webhook URLs on create and update:
- HTTPS required (HTTP allowed for self-hosted and E2E)
- Blocks private IP ranges and localhost
- Blocks cloud metadata endpoints

Existing webhooks are preserved: validation only applies when URL is created or changed.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 16:18:10 -03:00
Anik Dhabal Babu c57b517555 optimize organization member removal (#27660) 2026-02-05 17:11:57 +00:00
7226f1e4c0 fix: ux audit changes (#26875)
* fix: ux audit changes

* fix: remove locale-insensitive toLowerCase() on translation

Remove .toLowerCase() call on t('minutes') translation as it is
locale-insensitive and can corrupt translations (e.g., Turkish
dotted/dotless 'i'). The translation itself should provide the
desired casing.

Addresses Cubic AI review feedback with confidence 9/10.

Co-Authored-By: unknown <>

* fix: redirect url tool tip not working

* fix: type check

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 13:37:59 -03:00
Keith WilliamsandDevin AI b0835e8ae3 perf: reduce team page client payload with minimal data serialization (#27656)
* perf: optimize team page data fetching by reducing host user data

For team view pages (/team/[slug]), event type hosts only need minimal
user data for avatar display (id, name, username, avatarUrl).

Previously, the full userSelect was used which included:
- teams (with nested team data)
- credentials (with app and destinationCalendars)
- email, bio

This optimization reduces data transfer significantly for teams with
many event types and hosts. With 441K requests and 54GB outgoing data
(~128KB per request), even small reductions per request add up.

The full userSelect is still used when !isTeamView to support the
connectedApps feature.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* perf: optimize team page serialization to reduce data transfer

- Replace spread operators with explicit field selection for eventTypes
- Only send minimal user data needed for UserAvatarGroup: name, username, avatarUrl, profile
- Override eventTypes in return props with minimalEventTypes
- Reduces per-request data transfer by excluding unnecessary fields like email, bio, teams, credentials

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add missing fields needed by EventTypeDescription component

Add metadata, seatsPerTimeSlot, requiresConfirmation to minimalEventTypes
Add id to user object for proper key handling

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* revert: remove serialization changes that broke TypeScript types

Keep only the query-level optimization in queries.ts which reduces
database load by fetching minimal user data for event type hosts
when isTeamView=true.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* perf: reduce team page client payload with explicit DTO types

- Create TeamPage.types.ts with explicit DTO types for minimal data
- Update getServerSideProps.tsx to return only fields needed by the UI
- Update team-view.tsx to use explicit types instead of inferSSRProps

This reduces the data sent to the client by:
- Event types: only id, title, slug, description, length, schedulingType,
  recurringEvent, metadata, requiresConfirmation, seatsPerTimeSlot
- Event type users: only id, name, username, avatarUrl, avatar, profile
- Members: only fields needed by Team component
- Children: only slug and name
- Parent: only id, slug, name, isOrganization, isPrivate, logoUrl

Combined with the query-level optimization, this should significantly
reduce the ~128KB average payload per request.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Revert: explicit DTO approach due to type compatibility issues

The explicit DTO types broke compatibility with existing components
(EventTypeDescription, UserAvatarGroup) which expect specific type
structures. Keeping only the query-level optimization.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* perf: reduce team page client payload with minimal data serialization

- Update EventTypeDescription to accept minimal type (only fields actually used)
- Update UserAvatarGroup to accept minimal user type
- Update UserAvatar to accept minimal profile type
- Update Team component to accept minimal member type
- Update getServerSideProps to explicitly select only needed fields

This reduces the ~128KB client payload by removing unused fields from:
- Event types: removed hidden, price, currency, lockTimeZoneToggleOnBookingPage, etc.
- Event type users: only send name, username, avatarUrl, avatar, profile.username, profile.organization.slug
- Team members: only send fields needed by Team component
- Team parent/children: only send fields needed for display

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: revert component type changes, keep serialization optimization

- Revert EventTypeDescription, UserAvatarGroup, UserAvatar, Team component types to original
- Keep serialization optimization in getServerSideProps.tsx
- Add missing fields (price, currency, hidden, etc.) for EventTypeDescription compatibility
- Add full profile structure for UserAvatarGroup compatibility

This reduces client payload by explicitly selecting only needed fields while
maintaining type compatibility with existing component usages.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add missing fields for component type compatibility

- Add lockedTimeZone and canSendCalVideoTranscriptionEmails for EventTypeDescription
- Add organizationId to members for Team component MemberType
- Add name, calVideoLogo, bannerUrl to organization for UserProfile type
- Reorder fields to match baseEventTypeSelect structure

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 12:03:37 -03:00
MorganandDevin AI 295058d123 fix: use Object.prototype.hasOwnProperty.call for safe property checks (#27661)
The error 'TypeError: value.hasOwnProperty is not a function' can occur
when objects are created without the standard Object prototype (e.g., via
Object.create(null) or certain parsing methods). Using
Object.prototype.hasOwnProperty.call() is the safe way to check for
property existence on any object.

Fixed in:
- GetSlotsInputPipe (isById, isByUsernameAndEventTypeSlug, isByTeamSlugAndEventTypeSlug)
- CancelBookingInputPipe (isCancelSeatedBookingInput)
- CreateBookingInputPipe (isRecurringBookingInput, isInstantBookingInput)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 11:11:43 -03:00
2e9191fcad fix: open Join button in default browser instead of in-app browser (#27455)
* fix: open Join button in default browser instead of in-app browser

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat(companion): open join in default browser (#27655)

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2026-02-05 17:39:26 +05:30
an_ifrah24 75cd509106 fix: cleaned the extra space in description before saving to avoid word break (#27632) 2026-02-05 12:20:07 +01:00
Eunjae Lee de24e0a232 fix: show bookings-v3 opt-in banner (#27653) 2026-02-05 11:13:15 +00:00
2364cff54d feat: custom feedback dialog for feature opt-in (#27578)
* feat: add delayed formbricks tracking for feature opt-in

Adds delayed Formbricks survey tracking for feature opt-in. When a user
opts into a feature, this allows triggering a Formbricks action after a
configurable delay (e.g., 24 hours later) to collect feedback once
they've had time to use the feature.

Key changes:
- Added `formbricks` config option to `OptInFeatureConfig` interface
  with `actionName` and `delayMs` properties
- Created `useFormbricksOptInTracking` hook that handles the delayed
  tracking logic
- Added `isFeatureTracked` / `setFeatureTracked` storage helpers to
  prevent duplicate tracking
- Integrated the tracking hook into `useFeatureOptInBanner`

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* upgrade formbricks

* feat: replace formbricks popup with custom feedback dialog

Instead of using Formbricks' built-in popup, we now show a custom
Cal.com-styled feedback dialog that submits responses directly to
Formbricks API via tRPC mutation.

- Add FeedbackDialog component with emoji rating selector
- Add feedback tRPC router for server-side Formbricks submission
- Update useFormbricksOptInTracking to return dialog state
- Add survey config fields (surveyId, questions) to config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: position feedback dialog at bottom-right corner

- Use base-ui Dialog primitives for custom positioning
- Position dialog at bottom-right to avoid Intercom overlap
- Use z-index 10000 (below Intercom's high z-index)
- Keep blocking backdrop for modal behavior
- Use i18n keys for title/description
- Add survey IDs for bookings-v3 feedback

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add i18n keys for feedback dialog title/description

Allow each feature to specify custom i18n keys for the feedback dialog
title and description via the formbricks config.

- Add titleKey/descriptionKey to formbricks config interface
- Pass i18n keys through feedbackDialogProps
- Add bookings_v3_feedback_title/description translation keys

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: move FeedbackDialog into FeatureOptInBannerWrapper

Better encapsulation - consumers of the feature opt-in banner
no longer need to handle the feedback dialog separately.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add 5 second delay before showing feedback dialog

Ensures the page has time to finish loading before showing
the feedback dialog, avoiding showing it while skeletons
are still visible.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: simplify feedback dialog UI

- Remove redundant question labels
- Add "(optional)" to comment placeholder

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: remove emoji button borders and add footer gap

- Remove borders from rating emoji buttons
- Add proper gap between textarea and footer (pb-4)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: delayMs is opt-in waiting period, not setTimeout delay

delayMs represents the minimum time that must pass since opt-in
before showing the feedback form (e.g., 3 days). If not enough
time has passed, we skip showing the form entirely instead of
setting a long setTimeout.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: custom feedback dialog for feature opt-in

- Replace Formbricks popup with Cal.com-styled dialog
- Add configurable delay (waitAfterDays) before showing feedback
- Position dialog at bottom-right, non-blocking
- Add localStorage tracking to prevent duplicate feedback
- Add device targeting (showOn: desktop/mobile/all)
- Create tRPC endpoint for Formbricks API submission
- Use proper logger for error handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: rename tracking terminology to feedback

- Rename useFormbricksOptInTracking → useOptInFeedback
- Rename FormbricksOptInTrackingResult → OptInFeedbackState
- Rename formbricksTracking property → feedback
- Rename FormbricksTrackingState → FeedbackState

We no longer "track" events to Formbricks. Instead, we show
our custom feedback dialog when conditions are met.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: set waitAfterDays to 3 for production feedback delay

Co-Authored-By: unknown <>

* fix: update formbricks JS SDK usage for v3.0.0

The @formbricks/js SDK v3.0.0 changed its API:
- setup() no longer accepts debug, userId, or attributes
- Use setUserId() and setAttributes() after setup instead
- track() now expects { hiddenFields: ... } or undefined

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 11:01:14 +00:00
80e07a8d35 fix: add oauth client owner email to admin view (#27243)
* add owner email to admin oauth view

* fix type error

* fix oauth flow with sign up

* improve e2e tests

* fix: use dynamic user email in OAuth client e2e test

The test 'editing redirect uri of an approved client triggers reapproval'
creates a new user and assigns the OAuth client to that user, but was
incorrectly expecting 'admin@example.com' as the owner email. Changed to
use user.email to correctly validate the owner email matches the created
user.

Addresses Cubic AI review feedback (confidence: 9/10)

Co-Authored-By: unknown <>

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 10:39:29 +00:00
Eunjae LeeandDevin AI 357c2882ad refactor: apply biome formatting to several packages (#27439)
* refactor: apply biome formatting to Phase 1 packages

Packages formatted:
- packages/app-store-cli
- packages/config
- packages/dayjs
- packages/debugging
- packages/embeds/embed-react
- packages/embeds/embed-snippet
- packages/kysely
- packages/platform/constants
- packages/platform/utils
- packages/testing
- packages/tsconfig

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: restore non-null assertions in embed-snippet to fix type error

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: remove ESM import from CommonJS config file

Biome incorrectly added 'import process from node:process' to a CommonJS
file that uses require(). This breaks Jest which expects CommonJS syntax.
The process global is already available in Node.js without explicit import.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: exclude packages/embeds from Phase 1 formatting

Per user request, reverting all biome formatting changes in packages/embeds
to handle separately.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: restore const enum for BookingLocations

Biome changed 'const enum' to 'enum' which is a semantic change.
Reverting to keep the PR purely formatting-only.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 07:24:34 -03:00
c652c61e0c feat: refactor UI to use coss + coupons UI (#27647)
* feat: refactor UI to use coss + coupons UI

* fix: use TRPCError and remove sensitive logging in createCoupon handler

- Replace plain Error with TRPCError for consistent tRPC error handling
- Use INTERNAL_SERVER_ERROR for missing env configuration
- Use UNAUTHORIZED for permission denied errors
- Use BAD_REQUEST for API failure errors
- Remove console.warn that logged username (sensitive info)

Co-Authored-By: unknown <>

* feat: add copy button and fix 0 on % off

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 10:05:57 +00:00
1ad4ad6e4e feat: High Water Mark (HWM) billing for monthly subscriptions (#27559)
* wip

* fix: claue reveiew commentsd

* add seed test

* fix: seed test plus subscriptin undefined in webhook

* chore: udpate triggr

* Integration test + HWM seed script

* add feature flag for hmw

* Remove redudant docs

* feat: add hwm-seating feature flag for high water mark billing

- Add new hwm-seating feature flag to control HWM billing logic
- Update HighWaterMarkService to use hwm-seating flag
- Update SeatChangeTrackingService to use hwm-seating flag
- Update BillingPeriodService to use hwm-seating flag
- Add flag to migration SQL
- Enable flag in seed script and integration test

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add hwm-seating to useFlags and fix test mocks

- Add hwm-seating to useFlags.ts initial data
- Add shouldApplyHighWaterMark mock to TeamBillingService tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix test

* feat: move to invoice paid subscription

* fix: transactions for transiants updates + reusable util

* fix: address Cubic AI review feedback for HWM billing

- Fix dotenv import hoisting in seed-hwm-test.ts by using side-effect import
- Remove logging of sensitive information (password/emails) in seed script
- Fix incorrect newHighWaterMark return value when update is not performed

Co-Authored-By: unknown <>

* add additional unit tests

* improve DI

* fix migration + restore package.json trigger update

* feat:move to featurerepo+update tests

* fix mocks

* fix DI calls

* revert faeturerepo to featuresrepository

* fix: pass featureRepository to BillingPeriodService and HighWaterMarkService

- Fix TeamBillingService.ts: pass featureRepository to BillingPeriodService constructor
- Fix _invoice.upcoming.ts: pass featureRepository to HighWaterMarkService constructor
- Fix hwm-webhook-utils.ts: pass featureRepository to HighWaterMarkService constructor

These services require featureRepository for feature flag checks but production
call sites were missing this required dependency, causing runtime errors.

Addresses Cubic AI review feedback on PR #27559

Co-Authored-By: unknown <>

* fix import

* update feature repo usage to features

* remove test thats mocking the wrong stuff

* revert RegularBookingService changes

* remove hide branding

* remove change in redudant file

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 09:56:31 +00:00
Benny Joo 249065851b refactor: Break useCreateEventType hook into web-specific and platform-specific ones (#27522)
* migrate useCreateEventType hook to web

* fix

* fix

* fix import
2026-02-05 15:06:05 +05:30
Morgan cf55b5b462 fix: ensure default calendars domain (#27645)
* fix: ensure default calendars delegation credential domain

* fix: ensure default calendars delegation credential domain
2026-02-05 09:22:29 +00:00
bd25cba89c refactor: OAuth 2.0 endpoints (#27442)
* refactor: combine exchange and refresh into token endpoint

* refactor: controller error handling

* refactor: use snake_case

* refactor: use snake_case

* refactor: use snake case

* refactor: token endpoint accepts application/x-www-form-urlencoded

* refactor: token endpoint accepts application/x-www-form-urlencoded

* refactor: flat token response data

* refactor: error structure

* refactor: client_id in the body

* fix: address Cubic AI review feedback on OAuth2 endpoints

- Fix getClient endpoint to use proper REST API error format instead of OAuth token error format (confidence 9/10)
- Add missing space after comma in error format string in token.input.pipe.ts (confidence 9/10)
- Support both camelCase and snake_case inputs in authorize endpoint for backward compatibility (confidence 10/10)
- Restore legacy /exchange and /refresh endpoints alongside new /token endpoint for backward compatibility (confidence 10/10)
- Add OAuth2TokensResponseDto for legacy endpoint wrapped responses
- Add OAuth2LegacyExchangeInput and OAuth2LegacyRefreshInput for legacy endpoints

Co-Authored-By: unknown <>

* fix: address additional Cubic AI feedback on OAuth2 endpoints

- Log errors when status code >= 500 in handleClientError (confidence 9/10)
- Add Cache-Control: no-store and Pragma: no-cache headers to legacy /exchange and /refresh endpoints (confidence 9/10)

Co-Authored-By: unknown <>

* docs

* Revert "fix: address additional Cubic AI feedback on OAuth2 endpoints"

This reverts commit 39cc4aa3ebb9e59a171541d7010398425995ed89.

* Revert "fix: address Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 97bf593186db04c0859f9ca30950c9e3e524019d.

* docs

* fix: address Cubic AI review feedback on OAuth2 endpoints

- Fix getClient to use handleClientError instead of handleTokenError (confidence 10)
- Restore legacy /exchange and /refresh endpoints for backward compatibility (confidence 9)
- Fix RFC 6749 error format: use human-readable messages in error_description (confidence 9)
- Fix errorDescription in OAuthService to use OAUTH_ERROR_REASONS mapping (confidence 9)

Co-Authored-By: unknown <>

* fix: address additional Cubic AI feedback on OAuth2 endpoints

- Fix security issue: Replace 'CALENDSO_ENCRYPTION_KEY is not set' with generic 'Internal server configuration error' message (confidence 10/10)
- Fix backward compatibility: Create OAuth2LegacyTokensDto with camelCase properties for legacy /exchange and /refresh endpoints (confidence 9/10)
- Skipped: RFC 6749 error field issue (confidence 8/10, below threshold)

Co-Authored-By: unknown <>

* e2e

* Revert "fix: address additional Cubic AI feedback on OAuth2 endpoints"

This reverts commit a080e93f07aaf5a7dcf81fe605012cb7ebcdc192.

* Revert "fix: address Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 04986a16c981521ca97069152457bf521a9ee45f.

* fix: re-apply Cubic AI review feedback on OAuth2 endpoints

- Restore OAuth2LegacyExchangeInput and OAuth2LegacyRefreshInput classes
- Restore legacy /exchange and /refresh endpoints in OAuth2Controller
- Restore OAuth2LegacyTokensDto and OAuth2TokensResponseDto classes
- Restore OAUTH_ERROR_DESCRIPTIONS mapping in oauth2-error.service.ts
- Restore OAUTH_ERROR_REASONS lookup in OAuthService.ts mapErrorToOAuthError
- Fix encryption_key_missing error to not expose internal env var name

Addresses Cubic AI feedback with confidence >= 9/10:
- Comment 32 (9/10): Legacy endpoints and input classes
- Comment 34 (9/10): Error description mapping in OAuthService
- Comment 35 (10/10): OAUTH_ERROR_DESCRIPTIONS in error service

Skipped (confidence < 9/10):
- Comment 33 (8/10): getClient handleTokenError vs handleClientError

Co-Authored-By: unknown <>

* Revert "fix: re-apply Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 416bef9c931d9a7ed78c65a70a3425550d61b151.

* delete unused file

* fix: e2e tests

* address cubic review

* fix: address Cubic AI review feedback on OAuth2 exception filter

- Fix header case sensitivity: use lowercase 'x-request-id' instead of 'X-Request-Id' since Express lowercases all request headers
- Redact request body in error logs to prevent exposing sensitive OAuth2 credentials like client_secret, password, and refresh_token

Co-Authored-By: unknown <>

* docs: api v2 oauth controller docs

* chore: remove authorize endpoint

* refactor: remove scope from docs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 10:16:15 +02:00
DeepanshuandDeepanshu Verma bcbb714ea9 fix: toggle chevron icon direction in filter segment dropdown (#27641)
* fix: chevron toggle in filter segment dropdown

* fix: restore disabled state behavior for filter segment dropdown

---------

Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
2026-02-05 06:57:09 +00:00
9a5323bbb6 feat: add delete confirmation dialog to webhook list items (#26305)
* feat: add delete confirmation dialog to webhook list items

* adds appname for translation key used in alert

* extract delete wehook dialog into separate component

* add e2e test

* chore update e2e locator

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
Co-authored-by: Romit <romitgabani@icloud.com>
2026-02-05 08:32:51 +05:30
Alex van Andel 9a287ac876 Revert "fix: add input validation to analytics app schemas (#26976)"
This reverts commit c43c48b1a8.
2026-02-05 01:01:33 +00:00
Alex van Andel a8e1cbeeb5 Revert "fix: handle null/undefined tracking IDs in analytics schemas (#27625)"
This reverts commit 04e828358a.
2026-02-05 01:00:42 +00:00
emrysal aef96e214f chore: release v6.1.12
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-02-05 00:37:49 +00:00
MorganandDevin AI 2f16758de3 fix: improve error handling in delegation credential workspace configuration (#26985)
- Changed checkIfSuccessfullyConfiguredInWorkspace to throw detailed errors instead of returning boolean
- Updated testDelegationCredentialSetup in Google Calendar and Office365 Calendar services to throw specific errors
- Updated assertWorkspaceConfigured to let errors propagate naturally
- Updated Calendar interface type to reflect Promise<void> return type
- Updated CalendarCacheWrapper and CalendarTelemetryWrapper to match new interface

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 21:48:56 +00:00
04e828358a fix: handle null/undefined tracking IDs in analytics schemas (#27625)
* fix(analytics): handle null/undefined tracking IDs in embed endpoint

PR 26976 introduced strict validation for analytics app schemas,
but this broke the embed endpoint when apps are installed with
null tracking IDs (apps enabled but not yet configured)

Changes:
- Add nullishToEmpty preprocessor to convert null/undefined to ""
- Update all analytics schemas to handle null gracefully
- Change GTM to allowEmpty: true for consistency
- Fix createPrefixedIdSchema to not add prefix to empty strings
- Add tests for null handling

* fix(analytics): add optional() to schemas for type compatibility

The preprocess schemas output string type but BookerEvent has
trackingId?: string | undefined. Adding .optional() makes the
types compatible while preserving null → "" conversion at runtime

* refactor: use z.union+transform for proper type inference

Replace z.preprocess() with z.union([string, null, undefined]).transform()
pattern. This ensures TypeScript correctly infers:
- Input: string | null | undefined
- Output: string (always)

Remove .optional() from tracking ID fields to output string, not string | undefined

* fix(analytics): make trackingId optional in metapixel and plausible schemas

Address Cubic AI review feedback (confidence 9/10) to keep trackingId
optional in the schema to avoid breaking existing payloads that omit
the field entirely. The union with null/undefined handles the value
transformation, but the property itself must be optional to allow
payloads without the key.

Co-Authored-By: unknown <>

* fix: restore .optional() for missing tracking fields

* fix: revert safeUrlSchema to maintain databuddy type compat

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 21:02:27 +00:00
Pedro Castro 5d7738e39d fix: use SMS-specific rate limits for verification code (#27635)
Replace core rate limit with sms + smsMonth types to align with sendSMS handler and move check before billing gate for early rejection
2026-02-04 17:42:21 -03:00
sean-brydon 1a0bf47bc5 fix: verification code perf (#27631) 2026-02-04 18:41:41 +00:00
9de621eb23 perf: replace O(n*m) array lookups with O(1) Map lookups in attribute routing (#27599)
* Replace n x m array functions with maps

* test: add tests and benchmark for Map-based attribute lookup optimization

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: add real-world enterprise scenario (14 attrs x 6,530 opts) to benchmark

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: remove benchmark file

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Rename function

* Pass built maps to functions

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 12:43:16 -05:00
sean-brydon b3c3b4277c feat: use cache (#27627) 2026-02-04 17:02:10 +00:00
Benny Joo 31c6bbb5ba Revert "init: hide cal branding on user level (#27594)" (#27626)
This reverts commit 2c28c9c028.
2026-02-04 17:00:52 +00:00
Anik Dhabal Babu c183223b8d fix: prevent attendee phone number from overriding organizer default app location (#27620)
* se organizer default app

* nit

* Add tests: packages/features/bookings/lib/handleNewBooking/getBookingData.test.ts

Generated by Paragon from proposal for PR #27620
2026-02-04 16:55:17 +00:00
8d79209e74 perf: Optmize DB queries around attribute routing (#27600)
* Replace n x m array functions with maps

* feat: add attributeIds filter to findManyByOrgMembershipIds

Allow filtering attribute-to-user assignments by specific attribute IDs.
This enables querying only the attributes needed for a routing rule
instead of fetching all attributes for all team members.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: extract attribute IDs from routing rules and filter queries

Add extractAttributeIdsFromQueryValue helper to parse routing rules
and identify which attributes are referenced. Pass these IDs through
getAttributesAssignmentData to _queryAllData to only fetch the
attribute assignments that are actually needed for evaluation.

For a team with 785 members and 14 attributes, if a routing rule
only references 2-3 attributes, this reduces the query from ~3500
rows to ~500 rows.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: use attribute filtering in findTeamMembersMatchingAttributeLogic

Extract attribute IDs from the routing rules (main + fallback) and
pass them to getAttributesForLogic to only fetch necessary data.

This completes the optimization to reduce database load when
evaluating routing rules that only reference a subset of attributes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: filter attributes query by attribute IDs

Also filter the attributes query (not just attributeToUser assignments)
by the attribute IDs referenced in routing rules.

For a routing rule that references 2 out of 14 attributes with 6524
total options, this reduces:
- Attributes fetched: 14 → 2
- Options fetched: 6524 → ~930 (proportional reduction)
- Fewer regex replacements in replaceAttributeOptionIdsWithOptionLabel

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add comprehensive test coverage for attribute routing query optimization

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Revert "Replace n x m array functions with maps"

This reverts commit 312eeb03bd1aba19760f093c798861a23b5fc66f.

* fix: re-establish extractAttributeIdsFromQueryValue mock after resetAllMocks

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 11:28:46 -05:00
Keith WilliamsandDevin AI 1da2edb9e2 perf: optimize myStats tRPC call to only trigger when Intercom session is created (#27623)
* fix: optimize myStats tRPC call to only trigger when Intercom is enabled

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: fetch myStats on-demand when Intercom session is created, not upfront

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: remove unnecessary comments

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 16:18:46 +00:00
a99b63dcfc feat: update translations via @LingoDotDev (#27532)
Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-02-04 11:46:40 -03:00
Eunjae LeeandDevin AI 3f4109d8a9 test: add integration test for FeatureRepository with @Memoize decorator (#27613)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 14:43:41 +00:00
Eunjae LeeandDevin AI 8dde579d93 chore: add deprecated comment to FeaturesRepository (#27611)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 14:37:33 +00:00
Anik Dhabal Babu 99f0cf6189 fix: initiate OAuth flow in setup page instead of redirecting to dashboard for stripe (#27608)
* fix stripe setup

* fix type error

* address cubic

* Add tests: packages/app-store/stripepayment/pages/setup/__tests__/_getServerSideProps.test.ts

Generated by Paragon from proposal for PR #27608
2026-02-04 13:45:40 +00:00
Eunjae Lee a7f4aebaaa chore: add react grab (#27598) 2026-02-04 13:40:11 +00:00
2a30ba9d3c feat: skip platform billing for non-platform-managed users in 2024-08-13 API (#27586)
* feat: skip platform billing for non-platform-managed users in 2024-08-13 API

- Add isPlatformManaged check in billBooking() to skip billing for regular users
- Add isPlatformManaged check in billRescheduledBooking() to skip billing for regular users
- Add isPlatformManagedUserBooking check in cancelBooking() to skip billing cancellation for regular users
- Add E2E tests to verify billing behavior for both regular and platform-managed users

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: reuse booking data for isPlatformManaged instead of fetching user

- Capture isPlatformManagedUserBooking from raw booking data returned by regularBookingService.createBooking() and recurringBookingService.createBooking()
- Pass the flag through the output booking objects
- Update billBooking() and billRescheduledBooking() to use the flag instead of fetching user from database
- Matches the pattern used in 2024-04-15 controller

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: skip platform billing in booking service for non platform

* fix: use double negation for boolean type safety in isPlatformManagedUserBooking

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 10:26:38 -03:00
Rajiv Sahal 2c28c9c028 init: hide cal branding on user level (#27594) 2026-02-04 21:52:40 +09:00
fc602d3b03 feat: OAuth 2.0 support for atoms (#27158)
* fix: useOAuthClient support OAuth 2.0

* fix: cannot read properties of undefined (reading NEXT_PUBLIC_IS_E2E)

* fix: allow OAuth 2.0 token to connect gcal or ms calendar

* fix: allow OAuth 2.0 token to save gcal or ms calendar credentials

* refactor: dont set oauth id header for OAuth 2.0

* fix: calendar events not showing and emails not sent

* feat: CalOAuth2Provider

* chore: make OAuth 2.0 work in examples app

* chore: refresh OAuth 2.0 tokens

* docs: running examples app with oauth 2.0

* fix: remove sensitive console.log statements that leak secrets

Remove logging of:
- OAuth authorization codes (oauth2-user.ts)
- Token-bearing exchange responses (oauth2-user.ts)
- /me response data containing PII (oauth2-user.ts)
- OAuth2 refresh response with tokens (refresh.ts)
- Response payload with access tokens (_app.tsx)

Addresses Cubic AI review feedback for issues with confidence >= 9/10

Co-Authored-By: unknown <>

* docs: update readme

* fix: implemente cubic feedback

* fix: seed script import

* fix: seed script pkce

* fix: correct typos and SQLite capitalization in OAuth2 README (#27176)

Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor: dont return name in public oauth endpoint

* docs: CalOAuthProvider

* chore: add NEXT_PUBLIC_IS_E2E constant to test

* docs: fix duplicated 'or' in Cal OAuth Provider documentation (#27177)

Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>

* revert: is e2e constant

* fix: typecheck

* refactor: example app users select

* update readme

* chore: update oauth atoms readme

* refactor: enable booking managed event types with user.username instead of profile.username

* fix: EventTypeSettings when viewing round robin

* test: add e2e tests for atoms-oauth2 controller

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* fix: correct error message path in atoms-oauth2 e2e test

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-02-04 12:54:15 +01:00
Anik Dhabal Babu 0776bdf5fe show Google Meet link in location (#27508) 2026-02-04 08:45:12 -03:00
DeepanshuandDeepanshu Verma a1124edec1 fix availability action btn overflow (#27607)
Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
2026-02-04 16:55:33 +05:30
af230f919b fix: ensure default calendars api v2 (#27603)
* fix: ensure default calendars

* test: add E2E tests for delegation credential controller and update tasker config

- Add E2E tests to verify ensureDefaultCalendars is called when enabling delegation credentials
- Update calendars tasker config to use medium-1x machine for retry on OOM
- Set minimum retry backoff to 60 seconds (1 minute between retries)

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update tasker config to use small-2x machine with outOfMemory retry on medium-1x

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update E2E tests to properly spy on service instance and use valid workspace platform slug

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* ci: add CALCOM_SERVICE_ACCOUNT_ENCRYPTION_KEY to E2E API v2 workflow

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add encryption key to E2E test file for delegation credentials

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* revert: remove CALCOM_SERVICE_ACCOUNT_ENCRYPTION_KEY from workflow (moved to test file)

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: move encryption key to setEnvVars.ts for E2E tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use valid format for service account encryption key

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: encrypt service account key in E2E test for delegation credentials

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: mock updateDelegationCredentialEnabled to bypass Google API call in E2E tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: get service from app.get() after initialization for proper spy setup in E2E tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use jest.mock() to mock toggleDelegationCredentialEnabled and bypass Google API calls in E2E tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use Service.prototype pattern for spying on ensureDefaultCalendars in E2E tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: move spy setup to beforeAll before app.init() for proper NestJS interception

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 13:08:28 +02:00
Benny Joo a28ab042ad refactor: move admin and filter components out of packages/features (#27604)
* migrate CreateLicenseKeyForm

* refactor

* migrate

* migrate filters components

* fix import
2026-02-04 12:50:36 +02:00
Eunjae LeeandDevin AI 5804cc4fb0 feat: add PostHog event tracking for feature opt-in banner and dialog (#27579)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 09:32:35 +00:00
4367028492 feat(api-v2): add GET /v2/bookings/by-seat/{seatUid} endpoint (#26786)
* feat(api-v2): add GET /v2/bookings/by-seat/{seatUid} endpoint

- Add new endpoint to retrieve a booking by its seat reference UID
- Add getByReferenceUidIncludeBookingWithAttendeesAndUserAndEvent method to BookingSeatRepository
- Add getBookingBySeatUid method to BookingsService
- Add e2e tests for the new endpoint

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use Object.prototype.hasOwnProperty.call for ES compatibility in e2e tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use select instead of include in BookingSeatRepository for security and performance

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add teamId and userId to eventType select for access check

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: return seatUid attendee when not admin and seatsShowAttendees is false

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use select for eventType in repository and fetch full eventType for access check

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 17:54:10 +09:00
Morgan 49a2fcaf65 feat: allow users to provide custom apiUrl prop to BookerEmbed (#27576) 2026-02-04 17:53:03 +09:00
5e77e34439 fix: users not joining org/team when signing up with API v2 invite tokens (#27526)
* users not joining org/team

* fix: address Cubic AI review feedback for E2E tests

- Replace waitForURL with expect(page).toHaveURL() for fail-fast URL checks
- Replace Prisma include with select to fetch only needed fields

Both issues had confidence score 9/10 from Cubic AI review.

Co-Authored-By: unknown <>

* fix: add select to Prisma query in getServerSideProps

Address Cubic AI review feedback - use select to fetch only the id field
instead of retrieving all user columns, following project guidelines to
avoid over-fetching and exposing sensitive data.

Co-Authored-By: unknown <>

* refactor: remove comments from newly added E2E tests

Clean up the E2E tests by removing unnecessary comments as requested.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-04 12:29:01 +04:00
Pedro Castro b21719b995 chore(deps): resolve @isaacs/brace-expansion to 5.0.1 (#27596)
* chore(deps): resolve @isaacs/brace-expansion to 5.0.1

* fix: pin brace-expansion version
2026-02-03 21:00:30 +00:00
Pedro Castro 5dfa1dfd74 fix: sanitize event type text in Gmail dropdown (#27533)
- Add shared escapeHtml utility function
 - Apply text sanitization to title/description in content.ts
 - Refactor linkedin.ts to use shared utility
2026-02-04 02:10:04 +05:30
Rajiv Sahal efcbc3a07b fix: avatar URL breaking for team/orgs in BookerEmbed atom (#27424)
* fix: avatar URL breaking for team/orgs in booker embed

* fix: api v2 breaking because of type mismatch

* fix: atoms build

* chore: implement PR feedback
2026-02-03 17:19:48 +00:00
Shivangi Sharma 2ccff0aead fix(docs): correct env copy command in local-development.mdx (#27274) 2026-02-03 21:49:33 +05:30
Keith WilliamsandDevin AI 2231530a4a fix: use step output for PR number in Cubic review workflow (#27577)
The checkout step deletes the review-context.json file that was extracted
from the artifact. The 'Post comment with Devin session link' step was
trying to read this file after checkout, causing ENOENT errors.

Fixed by using the PR number from the extract-prompt step output instead
of reading the deleted file.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 15:55:22 +00:00
Yash Garg d2d6d32bcf fix: misalignment in rows per page select in bookings page (#27512)
* set min height to make sure the alignment does not get weird

* fix: makes sure "100" label does not get truncated in smaller devices
2026-02-03 15:49:56 +00:00
10dd0e2af2 feat: add GitHub workflows to sync agents/ to Devin Knowledge (#26994)
* feat: add GitHub workflows to sync agents/ to Devin Knowledge

- Add parse-to-devin-knowledge.ts to convert agents/ markdown to Devin Knowledge JSON
- Add validate-format.ts to validate rules have frontmatter and knowledge-base sections start with 'When...'
- Add sync-to-devin.ts to sync knowledge entries to Devin API
- Add export-devin-knowledge.sh to backup existing Devin knowledge
- Add validate-agents-format.yml workflow to validate format on PRs
- Add sync-agents-to-devin.yml workflow to sync on merge to main
- Add devin-knowledge.json to .gitignore (generated file)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use tsx instead of ts-node for better ESM support in CI

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: add missing knowledge entries from Devin backup

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move agents scripts to scripts/ folder

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename scripts to devin-knowledge-* for clarity

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move scripts to scripts/devin/ with clearer names

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* rename DEVIN_API_TOKEN to DEVIN_API_KEY

* docs: fix usage comment script path

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: remove folder creation from sync script (API doesn't support it)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add -S flag to shebang for proper env execution

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* use pull_request_target

* fix: add -S flag to shebang in sync-knowledge-to-devin.ts for proper env execution

Co-Authored-By: unknown <>

* restructure workflows

* refactor: consolidate agent docs and split knowledge-base into modular rules

- Delete knowledge-base.md, migrate content to 17 new rule files
- Delete coding-standards.md (content duplicated in AGENTS.md and rules)
- Add ci- and reference- prefixes to rules/_sections.md
- Update AGENTS.md to reference new rule files
- Update agents/README.md as rules index
- Clean up parse-local-knowledge.ts (remove deleted file references)

New rule files:
- testing-playwright, testing-mocking, testing-timezone
- ci-check-failures, ci-type-check-first, ci-git-workflow
- data-prisma-migrations, data-prisma-feature-flags
- quality-error-handling, quality-imports, quality-pr-creation, quality-code-comments
- architecture-features-modules
- patterns-workflow-triggers, patterns-app-store
- reference-file-locations, reference-local-dev

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Revert "refactor: consolidate agent docs and split knowledge-base into modular rules"

This reverts commit 8251b6b214c7c01a3bfe2137c6aa9292dd72427e.

* refactor: reorganize agent docs - extract coding rules, keep domain knowledge

- Slim down knowledge-base.md (356 → 96 lines) to domain knowledge only
- Add Business rules section (managed events, orgs/teams, OAuth clients)
- Delete coding-standards.md (content moved to rules)
- Create 19 new rule files for coding guidelines:
  - quality-*: PR creation, error handling, imports, comments, code review
  - testing-*: playwright, mocking, timezone, incremental
  - ci-*: check failures, type-check-first, git workflow
  - data-prisma-*: migrations, feature flags
  - patterns-*: workflow triggers, app store
  - architecture-features-modules, reference-file-locations, reference-local-dev
- Update agents/README.md as rules index (43 total rules)
- Update _sections.md with CI/CD and Reference sections
- Clean up parse-local-knowledge.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: rename knowledge-base sections to start with "When..."

Update section headers to pass validation rules:
- "Business Rules" → "When working with managed events, organizations, or OAuth clients"
- "Product & Codebase Knowledge" → "When you need product or codebase context"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: split knowledge-base business rules into separate sections

Split the combined "When working with managed events, organizations, or OAuth clients"
section into three distinct ## sections for better Devin triggering:
- When working with managed event types
- When working with organizations and teams
- When working with OAuth clients

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: simplify trigger description logic in parse-local-knowledge.ts

Since validate-local-knowledge.ts enforces that all section titles must start
with "When...", we can remove the manual fallback logic and just use the
title directly as the trigger description.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: simplify knowledge-base section validation

Simplify the validation to only check that section titles start with "When..."
since we've standardized on that pattern. Remove the special cases for error,
file naming, PR, and repo note sections.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add script to delete all Devin knowledge entries

Add delete-all-devin-knowledge.ts script that:
- Lists all knowledge entries before deletion
- Requires interactive confirmation (Y) to proceed
- Blocks execution in non-TTY environments (CI, piped input)
- Shows progress while deleting entries

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: add API reference links to delete-all-devin-knowledge script

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: replace NOW() with CURRENT_TIMESTAMP in feature flag migration example

Co-Authored-By: unknown <>

* add -S

* docs: consolidate agent documentation and add AI setup guide

- Remove duplicated Project Structure & Tech Stack from agents/README.md
- Condense Commands section in AGENTS.md, link to agents/commands.md
- Add AI-Assisted Development section to root README.md explaining
  the agents/ folder structure and symlink configuration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: remove incorrect CLAUDE.md symlink claim from README

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 15:40:04 +00:00
Pedro Castro 51b3f5c74d Revert b3430c8efc: fix Atoms build failures on CI (#27575) 2026-02-03 15:39:46 +00:00
Anik Dhabal Babu 40e5b739d6 fix: prevent video redirect when booking additional seats (#27574)
* seated event fix

* fix type error
2026-02-03 12:36:13 -03:00
2ad3abd909 test: replace text locators with data-testid selectors in team filter tests (#27148)
* test: add e2e tests for team filter in bookings list

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: replace text locators with data-testid selectors in team filter tests

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: apply formatting to resolved merge conflict

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 11:54:38 -03:00
Keith WilliamsandDevin AI c9b4143f57 feat: support Cubic feedback workflow for external forked PRs (#26910)
Use workflow_run pattern to enable the Cubic AI to Devin review workflow
for PRs from external forks. The pull_request_review event doesn't have
access to secrets when triggered from forks, so we split into two workflows:

1. cubic-devin-review-trigger.yml - Lightweight workflow that triggers on
   pull_request_review and saves the review context as an artifact
2. cubic-devin-review.yml - Main workflow that triggers on workflow_run,
   downloads the artifact, and processes it with full permissions/secrets

This follows the same pattern used by on-changes-requested.yml and re-draft.yml.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 11:41:06 -03:00
Anik Dhabal Babu 5b1751c80b hubspot issue (#27555) 2026-02-03 14:03:35 +00:00
Pedro Castro 629346060e chore(deps): bump tar resolution to 7.5.7 (#27538) 2026-02-03 10:53:17 -03:00
emrysal 8f8d199e8f chore: release v6.1.11
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-02-03 13:43:26 +00:00
12abc316e6 refactor: consolidate agent config into agents directory (#27427)
* refactor: consolidate agent config folders into agents directory

- Move .claude/skills and .claude/rules content to agents/
- Remove duplicate .cursor/ and .goose/ folders
- Create symlinks from .claude/ and .cursor/ to agents/
- Convert review.mdc to quality-review-checklist.md with proper frontmatter

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* feat: add Cal.com APIv2 skills to agents directory

Move the Cal.com API v2 skills from PR #27445 into the consolidated
agents/skills/ directory structure. This includes:
- SKILL.md - Main skill file with API overview
- references/authentication.md - Authentication methods
- references/bookings.md - Bookings API reference
- references/calendars.md - Calendars API reference
- references/event-types.md - Event types API reference
- references/schedules.md - Schedules API reference
- references/slots-availability.md - Slots and availability API reference
- references/webhooks.md - Webhooks API reference

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: update calcom-api skill to use Claude Code frontmatter format

Remove non-standard frontmatter fields (license, metadata) and keep only
the Claude Code supported fields (name, description) as per the
Claude Code skills specification.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: restructure calcom-api SKILL.md as index file

Convert SKILL.md from a comprehensive API doc (317 lines) to a concise
index file (108 lines) that references the detailed documentation in
the references/ folder. This follows the Claude Code skills pattern of
keeping SKILL.md focused with supporting files for detailed content.

The SKILL.md now:
- Provides a quick start guide with essential examples
- References all 7 detailed reference docs in a table
- Lists common workflows and best practices
- Points to external resources

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: preserve deleted content in reference files

Move content that was removed from SKILL.md to appropriate reference files:
- Add Error Handling and Pagination sections to authentication.md
- Add Organization endpoints to event-types.md
- Add Core Concepts section back to SKILL.md

This ensures no useful API documentation is lost during the restructuring.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 14:14:41 +01:00
Joe Au-YeungandDevin AI f7381d1b6d Parallelize calls (#27486)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 17:31:22 +05:30
Udit Takkar d997be2a3c chore: add npm audit in CI (#27182)
* chore: add npm audit in CI

* chore: add npm audit in CI
2026-02-03 17:26:36 +05:30
GyanandAnik Dhabal Babu 8a3074fbe7 fix(cal-video): make toggle switch visible in mic settings (#27558)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-02-03 17:16:33 +05:30
fde41977dd fix: Navbar hiding unexpectedly on Workflow page scroll (#27557)
* prevent navbar hiding unexpectedly on scroll

* update z-5 to z-10 for consistency

---------

Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
Co-authored-by: Romit <romitgabani@icloud.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-03 10:57:42 +00:00
6eafb4b4bc feat: skip platform billing for non-platform-managed users (#27521)
* feat: skip platform billing for non-platform-managed users

- Add isPlatformManaged to user select in saveBooking and findBookingQuery
- Update 2024-04-15 booking controller to check isPlatformManaged before billing
- Update 2024-08-13 bookings service billBooking methods to check isPlatformManaged
- Update buildDryRunBooking to include isPlatformManaged in user object

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: update buildDryRunBooking test to include uuid and isPlatformManaged fields

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: simplify to only check isPlatformManaged in normal booking flow

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: add E2E tests for billing behavior based on isPlatformManaged flag

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: only trigger platform billing for platform user bookingd

* test: add E2E tests for cancel and recurring booking billing behavior

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: correct expected status code for cancel booking endpoint (201 instead of 200)

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 12:51:29 +02:00
19e89dfcd5 fix: clear oversized images from onboarding store during migration (#27560)
* fix: clear oversized images from onboarding store during migration

This fixes the 429 errors caused by large images stored in IndexedDB
before PR #27285 added cropping functionality.

Changes:
- Add version 1 to zustand persist config with migration function
- Migration clears images exceeding thresholds:
  - Logos/avatars: 500KB (properly cropped are ~50-150KB)
  - Banners: 1.5MB (properly cropped are ~200-500KB)
- Add comprehensive tests for migration logic

When users refresh the page, the migration runs automatically and
clears any oversized images, requiring them to re-upload using the
new cropping flow.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fixes

* chore: remove migration test file

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 10:48:35 +00:00
Romit 7840cc3a9d fix: correct LearnMoreLink import path in BillingCredits 2026-02-03 10:32:13 +00:00
Rajiv SahalandMorgan 078b3935eb chore: update atoms retry mechanism (#27450)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-02-03 15:18:17 +05:30
Morgan b5eda9c57e chore: use trigger.dev task to ensure default calendars (#27556) 2026-02-03 14:44:28 +05:30
Carina WollendorferandCarinaWolli fc3815a150 fix: show personal credits even when user is on teams plan (#27511)
* show personal credits even if on team plan

* show personal credits even when on teams plan

* fix learn more link

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-02-03 10:02:14 +01:00
MorganandDevin AI 336295c0ab fix: suppress alerts for expected billing errors in increment-usage task (#27535)
- Skip retrying and alerting for temp/sandbox subscription IDs
- Skip retrying and alerting for non-usage-based subscriptions
- Log expected errors at info level instead of error level

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 08:42:35 +00:00
52f3ddaf74 feat: add tasker integration for proration email notifications (#27247)
* feat: add proration invoice and reminder email templates

Add email templates for monthly proration billing notifications:

- ProrationInvoiceEmail: Sent when invoice is created for additional seats
- ProrationReminderEmail: Sent 7 days later if invoice remains unpaid

Includes:
- React email templates using V2BaseEmailHtml
- BaseEmail classes for rendering
- Billing email service functions
- Translation keys for email content

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add tasker integration for proration email notifications

Add task handlers for proration billing email flow:

- sendProrationInvoiceEmail: Sends invoice email and schedules reminder
- sendProrationReminderEmail: Sends reminder if invoice still unpaid
- cancelProrationReminder: Cancels scheduled reminder on payment success

The calling job should trigger these tasks after:
1. MonthlyProrationService.createProrationForTeam() succeeds with invoice
2. handleProrationPaymentSuccess() is called (to cancel reminder)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: i18n + feedback from cubic + morgan

* fix: use default tasker import instead of non-existent getTasker

Co-Authored-By: unknown <>

* fix: add trigger tasks plus DI

* use for await

* fix query

* fix: remove duplicate JOIN alias in findTeamMembersWithPermission query

The raw SQL query had two INNER JOINs using the same alias 'u':
- INNER JOIN "users" u ON m."userId" = u.id
- INNER JOIN "User" u ON m."userId" = u.id

This would cause a SQL error at runtime. Removed the duplicate JOIN
with incorrect table name ("User" instead of "users").

Fixes issue identified by Cubic AI review.

Co-Authored-By: unknown <>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-03 08:29:36 +00:00
Veronica Prilutskaya 3c1d906808 feat: enable @lingodotdev concurrency (#27529)
* feat: translation review by @LingoDotDev team

* feat: enable @LingoDotDev concurrency

* feat: translation review by @lingodotdev team
2026-02-02 20:33:33 +00:00
c0f6a1b088 feat: add redirect option for non-routed visits to event types (#27468)
* feat: add redirect option for non-routing form bookings

Add a new event type option that redirects to a custom URL when the booking
was not made through a routing form (no cal.routingFormResponseId or
cal.queuedFormResponseId query parameters).

Changes:
- Add redirectUrlOnNoRoutingFormResponse field to EventType schema
- Add UI toggle in Advanced tab to configure the redirect URL
- Implement redirect logic in bookingSuccessRedirect hook
- Add translations for new UI strings

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add redirectUrlOnNoRoutingFormResponse to test builder

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add redirectUrlOnNoRoutingFormResponse to BookerEvent type

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add redirectUrlOnNoRoutingFormResponse to getPublicEventSelect

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add redirect logic to getServerSideProps for non-routing form bookings

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove redirectUrlOnNoRoutingFormResponse from booking success flow

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use 'in' operator for type narrowing on redirectUrlOnNoRoutingFormResponse

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: exclude redirectUrlOnNoRoutingFormResponse from test assertions

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: include redirectUrlOnNoRoutingFormResponse in test assertions and update description

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add redirectUrlOnNoRoutingFormResponse to mockUpdatedEventType

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove redirect logic from instant meetings

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add redirectUrlOnNoRoutingFormResponse to EventTypeRepository select

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add redirectUrlOnNoRoutingFormResponse to form default values

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Reword string

* fix: bust tRPC cache for redirectUrlOnNoRoutingFormResponse

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: guard redirect when rescheduleUid or bookingUid is present

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add redirectUrlOnNoRoutingFormResponse to dynamicEvent defaults

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add bookingUid guard to team getServerSideProps redirect

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 15:48:23 -03:00
mintlify[bot]andSyed Ali Shahbaz 7062887632 chore: Remove developing/introduction page and make Local Development the landing page (#27492)
* Update docs/mint.json

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Delete docs/developing/introduction.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Add redirects for developing introduction

Added redirects for the developing introduction page.

* Delete docs/mint.json

* Add redirects for developing introduction page

* Remove introduction page from Getting Started group

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2026-02-02 18:11:15 +00:00
Pedro Castro 1ff307bb44 fix: instant booking location lookup (#27517)
Use booking uid instead of numeric id for instant booking location
  endpoint, aligning with existing booking endpoint patterns
2026-02-02 14:19:52 -03:00
Pedro CastroandDevin AI c43c48b1a8 fix: add input validation to analytics app schemas (#26976)
* fix(analytics): add input validation to analytics app schemas

Add strict input validation for tracking IDs and URLs in analytics
app integrations to ensure data conforms to expected formats

* fix: remove optional/default to fix type inference

Remove .optional() and .default("") from schemas with transform/refine
chains to preserve correct TypeScript type inference

* fix: restore .optional() for type compatibility

* fix(e2e): use valid GTM container ID format in analytics test

Co-Authored-By: pedro@cal.com <pedro.castro@ideware.com.br>

* fix(analytics): address Cubic AI review feedback

- Tighten Meta Pixel ID regex from {1,20} to {15,16} digits (confidence 9.5/10)
- Fix PostHog error message to mention underscores are allowed (confidence 9/10)

Co-Authored-By: unknown <>

* fix(analytics): enforce domain label boundaries and prevent consecutive dots

Co-Authored-By: pedro@cal.com <pedro.castro@ideware.com.br>

* refactor: extract shared validation schemas

- Create analytics-schemas.ts with reusable safeUrlSchema, alphanumericIdSchema, and numericIdSchema
- Update databuddy, insihts, matomo, plausible, posthog, and umami to use shared schemas
- Keep app-specific schemas local (domain validation, UUID patterns, etc.)

* fix(analytics): enforce exactly 10 characters for GA4 Measurement ID

Tighten GA4 regex from {1,20} to {10} to match the documented format
G-XXXXXXXXXX. This addresses Cubic AI review feedback (confidence 9/10)
that the regex was too permissive compared to the error message.

Co-Authored-By: unknown <>

* refactor: add createPrefixedIdSchema factory for GTM/GA4/Fathom

- Add factory function to handle prefixed IDs with configurable options
(prefix, addPrefixIfMissing, allowEmpty)
- Consolidate GTM, GA4, and Fathom schemas using the shared factory
- Standardize imports to use @calcom/app-store alias

* fix: reject prefix-only IDs like "G-" or "GTM-" without content

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 14:19:43 -03:00
Syed Ali Shahbaz 1a0f70ea65 chore: Update Mintlify to V2 (#27523)
* update mintlify

* remove mint.json
2026-02-02 14:13:42 -03:00
Anik Dhabal Babu 7611e0ea39 fix: filter attendees in emails when seatsShowAttendees is disabled (#27520)
* seated event

* Reorder imports in attendee-scheduled-email.ts
2026-02-02 17:07:35 +00:00
4b7ea0c98f feat: update current time indicator on page refocus (#27503)
Add updateCurrentTimeOnFocus prop to Calendar component that enables
the current time indicator to update when the page is refocused.
This helps users see the accurate current time after switching tabs.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2026-02-02 14:40:20 +00:00
Lauris Skraucis d743c92479 fix: trpc build (#27516) 2026-02-02 14:38:06 +00:00
Joe Au-YeungandDevin AI 1d5228ef38 fix: skip duplicate CRM lookup when router already performed it (#27487)
When the routing form redirects to an event type, it now passes
cal.crmLookupDone=true to indicate that the CRM contact owner lookup
was already performed. The event type SSR checks for this flag and
skips the duplicate CRM lookup, improving performance.

This fixes the scenario where no CRM contact owner exists - previously
the lookup would be performed twice (once in the router, once in SSR),
but now it's only performed once.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 14:28:34 +00:00
emrysal 4ad82d1a9f chore: release v6.1.10
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-02-02 13:56:00 +00:00
bc392584b2 fix: reset embed iframe queue consistently to preserve UI commands (#27419)
* Reset queue correctly all places

* test: verify UI config persists on second modal open (#27422)

* test: verify UI config persists on second modal open

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: update iframe selection logic in getEmbedIframe function

Refactor the getEmbedIframe function to improve iframe selection by using a more specific selector and ensuring the last iframe is targeted in cases of repeated modal openings. This change enhances reliability in iframe handling during tests.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix test

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 13:51:25 +00:00
sean-brydonandDevin AI 4f0a1d0f9b feat: show invoices on team/org (#27120)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 13:37:25 +00:00
29ec2b9cb6 refactor: split flag repositories into Prisma and Cached layers (#27186)
* refactor: split flag repositories into Prisma and Cached layers

- Rename FeatureRepository to PrismaFeatureRepository (raw DB access)
- Rename TeamFeatureRepository to PrismaTeamFeatureRepository (raw DB access)
- Rename UserFeatureRepository to PrismaUserFeatureRepository (raw DB access)
- Create CachedFeatureRepository with @Memoize wrapping PrismaFeatureRepository
- Create CachedTeamFeatureRepository with @Memoize/@Unmemoize wrapping PrismaTeamFeatureRepository
- Create CachedUserFeatureRepository with @Memoize/@Unmemoize wrapping PrismaUserFeatureRepository
- Update DI tokens, modules, and containers for all 6 repositories
- Update imports in FeatureOptInService and related modules
- Update tests to use new repository structure

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: simplify @Memoize key patterns and delegate batch methods to Prisma

- Use direct function references for @Memoize key (e.g., KEY.all instead of () => KEY.all())
- Simplify batch methods in Cached repositories to delegate to Prisma repository
- Update tests to reflect the new delegation pattern

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add orderBy to TeamRepository.findAllByParentId for deterministic results

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* test: update TeamRepository test to expect orderBy in findAllByParentId

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: cleanup features repository and add specialized repository methods (#27195)

* refactor: cleanup features repository and add findBySlug, update methods

- Remove unused methods from FeaturesRepository (keep getTeamsWithFeatureEnabled)
- Add findAll(), findBySlug(), update() to IFeatureRepository interface
- Add findAll() with caching to CachedFeatureRepository
- Add findBySlug() with caching to CachedFeatureRepository
- Add update() with Unmemoize to CachedFeatureRepository
- Add checkIfFeatureIsEnabledGlobally() to CachedFeatureRepository
- Update toggleFeatureFlag.handler.ts to use repository instead of raw Prisma
- Add comprehensive unit tests for all new methods

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: update updatedAt timestamp in feature update method

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move feature check methods to specialized repositories

- Replace getUserFeaturesStatus with two checkIfUserHasFeature calls in bookings page
- Move checkIfTeamHasFeature to PrismaTeamFeatureRepository with pass-through in CachedTeamFeatureRepository
- Move checkIfUserHasFeature and checkIfUserHasFeatureNonHierarchical to PrismaUserFeatureRepository with pass-throughs in CachedUserFeatureRepository
- Add getEnabledFeatures to PrismaTeamFeatureRepository with caching in CachedTeamFeatureRepository
- Keep FeaturesRepository methods as pass-throughs for backward compatibility
- Update test to expect updatedAt in feature update

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove getUserFeaturesStatus and unused methods from FeaturesRepository

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* restore comment

* fix: invalidate all-features cache on update and enabledFeatures cache on upsert/delete

- CachedFeatureRepository: Add KEY.all() to @Unmemoize keys in update() to prevent stale findAll() results
- CachedTeamFeatureRepository: Add KEY.enabledFeatures(teamId) to @Unmemoize keys in upsert() and delete() to prevent stale getEnabledFeatures() results

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: add CachedUserFeatureRepository tests

Add comprehensive tests for CachedUserFeatureRepository covering:
- findByUserIdAndFeatureId (cache hit, cache miss, not found)
- findByUserIdAndFeatureIds (empty input, multiple features)
- upsert (with cache invalidation)
- delete (with cache invalidation)
- findAutoOptInByUserId (cache hit, cache miss, not found)
- setAutoOptIn (with cache invalidation)

Co-Authored-By: unknown <>

* test: remove tests for methods removed from FeaturesRepository

Remove integration tests for methods that were intentionally removed:
- getUserFeatureStates
- getTeamsFeatureStates
- getUserAutoOptIn
- getTeamsAutoOptIn
- setUserAutoOptIn
- setTeamAutoOptIn

Co-Authored-By: unknown <>

* avoid N+1 query

* refactor: add select clauses to PrismaFeatureRepository queries

- Add explicit select clauses to findAll, findBySlug, and update methods
- Only fetch fields needed for FeatureDto (slug, enabled, description, type, stale, lastUsedAt, createdAt, updatedAt, updatedBy)
- Update tests to expect select clauses
- Fix UserFeatureRepository test to use findMany mock

Co-Authored-By: unknown <>

* fix bad conflict resolved

* use userId

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 14:26:23 +01:00
8c123ece25 refactor: move shared components from apps/web to packages/features (#27490)
* refactor: move shared components from apps/web to packages/features

Move components that don't require dependency injection:
- DisconnectIntegrationModal
- Booking components (Header, Section, TimeFormatToggle, PayIcon, Price)
- useInitializeWeekStart hook
- TeamEventTypeForm
- Event type components (AssignAllTeamMembers, BulkEditDefaultForEventsModal, etc.)
- Event type dialogs (HostEditDialogs, ManagedEventDialog)
- Location components (LocationInput, types)
- Tab components (EventLimitsTab, EventRecurringTab, etc.)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: update import paths to use @calcom/features

Update imports in apps/web and packages/platform/atoms to reference
the moved components from @calcom/features instead of @calcom/web.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: delete original files from apps/web/modules

Complete the file move by deleting the original files that were
copied to packages/features. This makes it a proper move instead
of a copy, reducing the PR size significantly.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update import paths to use @calcom/features for moved files

Update import paths in apps/web files that reference components
that were moved from apps/web/modules to packages/features:
- LearnMoreLink
- ChildrenEventTypeSelect
- AssignAllTeamMembers
- WeightDescription
- LocationCustomClassNames (types)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update additional import paths for moved components

Update import paths in apps/web files that reference components
moved from apps/web/modules to packages/features:
- AppList.tsx: BulkEditDefaultForEventsModal
- schedule-view.tsx: BulkUpdatParams type
- AddMembersWithSwitch.tsx: AssignAllTeamMembers, CheckedTeamSelect
- EventTypeWebWrapper.tsx: ChildrenEventType, ManagedEventDialog
- DefaultLocationSettings.tsx: LocationCustomClassNames, LocationInput
- Locations.tsx: LocationCustomClassNames, LocationInput

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: resolve circular dependency by adding isPlatform prop to Header

This fixes the circular dependency where @calcom/atoms (CalendarViewComponent)
was importing Header from @calcom/features, but Header was importing
useIsPlatform from @calcom/atoms.

The fix adds an isPlatform prop to the Header component so it no longer
needs to import useIsPlatform from @calcom/atoms. Callers now pass the
isPlatform value directly:
- atoms components pass isPlatform={true}
- web components pass the isPlatform prop they receive

Fix confidence: 9/10 (Cubic AI)

Co-Authored-By: unknown <>

* fix

* fix

* fix

* fix

* fix

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 10:25:41 -03:00
Romit e29662b173 fix (#27506) 2026-02-02 18:04:48 +05:30
Morgan 36e477cebf fix: platform billing reschedule usage increment via trigger.dev (#27483) 2026-02-02 09:10:23 -03:00
9cb16e3260 fix: improve French translations and handle email invites (#27286)
* fix: handle email invites in team event-type assignment by preventing NaN userId.

* fix(i18n): improve French translation for login and identifier

Updating 'Connexion' to 'Se connecter' for consistency with Google/SAML login buttons and improving the identifier label.

* Update apps/web/public/static/locales/fr/common.json

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* revert: remove team assignment logic fix to focus on translations.

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-02 17:16:18 +05:30
Carina WollendorferandCarinaWolli ebf0508d9a fix icon on button (#27502)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-02-02 11:40:42 +00:00
sean-brydonandDevin AI 3adb9c2dda feat: enable username editing during personal onboarding for social sign-in users (#27495)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 11:38:53 +00:00
vishwajeett007 c3459ad1a0 fix: toggle user dropdown chevron on open/close 2026-02-02 16:41:31 +05:30
Keith WilliamsandDevin AI b28b337f67 feat: add devin-finish-pr label as trigger for PR completion workflow (#27504)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 11:00:07 +00:00
Anik Dhabal BabuandDevin AI 888a8d806d fix: correct incrementDate function in E2E tests to properly calculate next month date (#27501)
The incrementDate function was using .day() incorrectly, which sets the day
of the week for the CURRENT week rather than finding the same weekday in
the next month. This caused the function to return dates in the previous
month when the target date fell early in the week.

For example, when incrementing March 2, 2026 (Monday) by a month:
- Old behavior: April 2 (Thursday) + .day(1) = March 30 (wrong month!)
- New behavior: First Monday in April = April 6 (correct)

This bug caused flaky E2E test failures in booking-limits and duration-limits
tests because the 'year limit with multiple limits set' test would try to
book on a date that was still in the same month, which was blocked by the
month limit (3 bookings already existed in that month).

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 07:23:15 -03:00
sean-brydonandAnik Dhabal Babu 8f6d580233 fix: monthly integration (#27498)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-02-02 12:13:17 +02:00
d29c8a4fa2 fix: add guest limits and rate limiting to booking-guests endpoint (#27494)
* fix: add guest limits and rate limiting to booking-guests endpoint

- Add ArrayMaxSize(10) validation to limit guests per request to 10
- Add aggressive rate limiting (5 requests/minute) via @Throttle decorator
- Add total guest limit check (max 30 guests per booking) to prevent abuse
- Update API documentation to reflect new limits

This prevents scammers from using the endpoint to send spam emails
to hundreds of guests through our system.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* docs: update openapi.json with guest limits and rate limiting info

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 11:49:25 +02:00
f91511b927 feat(salesforce): add field rules for round robin routing (#27402)
* feat(salesforce): add field rules for round robin skip

- Add rrSkipFieldRules schema to appDataSchema in zod.ts
- Implement applyFieldRules method in CrmService.ts for post-query filtering
- Integrate field rules into getContacts method when forRoundRobinSkip=true
- Add UI component for configuring field rules in EventTypeAppCardInterface
- Add translations for new UI strings
- Add comprehensive tests for field rules functionality

Field rules allow users to specify conditions based on Salesforce record fields
with 'ignore' or 'must_include' actions. Rules are evaluated with AND logic
and gracefully handle missing fields by skipping those rules.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add children prop to Section.SubSectionHeader for field rules

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat(salesforce): add edit button for field rules

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat(salesforce): apply field rules to GraphQL results

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat(salesforce): add Redis caching for field validation

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix(salesforce): remove Redis caching to fix ERR_INVALID_THIS error

- Removed Redis caching for field validation that was causing ERR_INVALID_THIS errors
- Simplified field rules filtering to try query directly and skip filtering if it fails
- Restored ensureFieldsExistOnObject method for other uses (write to record)
- Field rules now gracefully handle invalid fields by skipping filtering

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: reformat getAttributes.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(salesforce): dynamically build GraphQL query for field rules with multi-edge iteration

- Add buildDynamicAccountQuery to inject field rule fields into GraphQL query
- Add passesFieldRules to evaluate ignore/must_include rules against UIAPI nodes
- Validate field rules via getObjectFieldNames (in-memory + Redis cache) before branching
- Remove applyFieldRulesToGraphQLRecords (used jsforce conn in GraphQL path)
- Iterate all edges in Tiers 1 and 2 instead of only the first result
- Rank Tier 3 accounts by contact count and fallback to next on field rule failure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(salesforce): add field rule routing trace steps

Add trace calls alongside field rule info logs for routing visibility:
- fieldRulesValidated: records validation result in CrmService
- fieldRuleFilteredRecord: records when account is filtered at each tier
- fieldRuleEvaluated: records individual rule evaluation details
- allRecordsFilteredByFieldRules: records when SOQL records are all filtered

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(salesforce): remove duplicate field validation and fix disabled Select options

applyFieldRules now receives pre-validated rules from the early
validation block instead of re-validating internally. Also adds
the missing options prop to the disabled Select in the field rules UI.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(salesforce): include failed rule details in field rule trace steps

Rename passesFieldRules to getFailingFieldRule so the caller receives
the specific rule that caused filtering. The fieldRuleFilteredRecord
trace step now includes failedRule with field, value, and action.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(salesforce): add GraphQL path tests for field rules

Cover field rule filtering across all three GraphQL resolution tiers
(contact, account, related contacts) with ignore and must_include
actions, multi-edge fallback, case-insensitivity, and dynamic query
selection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Abstract new field rules settings

* Reduce extra SOQL call

* fix(salesforce): fix type errors in CrmService and GraphQL client

- Add missing import for getRedisService from @calcom/features/di/containers/Redis
- Fix ensureFieldsExistOnObject to properly return Field[] instead of incomplete function
- Use Array.from() instead of spread operator for Set and Map iterators to fix downlevelIteration errors

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 23:03:19 -05:00
Peer RichelsenandDevin AI 3f053b4e22 feat: add Cal.com APIv2 skills for AI agents (#27445)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-31 12:14:23 +00:00
73f51920c5 refactor: move Booker hooks from packages/features to apps/web/modules (#27343)
* refactor: move Booker hooks from packages/features to apps/web/modules

Migrate the following Booker hooks:
- useOverlayCalendar
- useSkipConfirmStep
- useInitializeWeekStart
- useIsQuickAvailabilityCheckFeatureEnabled
- useDecoyBooking

These hooks are only imported by apps/web files, making them safe to move
without creating circular dependencies.

Part of the tRPC-driven UI migration from packages/features to apps/web/modules.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: revert useIsQuickAvailabilityCheckFeatureEnabled move and fix import paths

- Reverted useIsQuickAvailabilityCheckFeatureEnabled.ts back to packages/features since it's imported by useSlots.ts in packages/features (would create circular dependency)
- Fixed import paths in useOverlayCalendar.ts to use @calcom/features paths
- Fixed import paths in useSkipConfirmStep.ts to use @calcom/features paths
- Updated Booker.tsx to import useIsQuickAvailabilityCheckFeatureEnabled from original location

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use @calcom/web alias for hook imports to fix vitest resolution

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor

* migrate more hooks

* fix

* mv types

* fix

* fix

* fix

* fix

* revert: remove formatting-only changes to make PR easier to review

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix

* revert: restore original import ordering in moved hooks

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix imports

* fix

* fix

* wip

* wip

* wip

* wip

* wip

* wip

* fix: add isBrowser guard to useSlotsViewOnSmallScreen hook

Address Cubic AI review feedback (confidence 9/10) by adding the isBrowser
guard to the useSlotsViewOnSmallScreen hook to follow the file's client-only
contract and avoid executing during SSR/prerendering.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-31 07:33:33 -03:00
Peer RichelsenandDevin AI 5476c38f3b fix: filter KBar bookings to show only current user's upcoming bookings (#27447)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-30 21:49:15 +00:00
Eunjae Lee 5a7ce63d38 fix: show bookings shell headings when v3 disabled (#27433)
* fix: show bookings shell headings when v3 disabled

* remove unused hook
2026-01-30 15:09:51 +00:00
Eunjae LeeandClaude Opus 4.5 b51a0b0847 fix: cache already-enabled feature opt-in status in local storage (#27393)
When the eligibility check returns "already_enabled", store this in
local storage to prevent repeated API calls on subsequent page loads.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:43:00 +00:00
Eunjae LeeandClaude Haiku 4.5 1e048648ce feat: add tooltip for disabled Cancel button on past bookings (#27431)
* feat: Add tooltip for disabled Cancel button on past bookings

Show a tooltip explaining "You cannot cancel a past booking" when hovering over the disabled Cancel dropdown item for bookings that have already occurred.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* refactor: Extract tooltip condition into named variable

Improves readability by extracting the tooltip open condition into a descriptive variable `showPastBookingCancelTooltip`.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-30 14:07:24 +00:00
be4bb3fcde feat: TOUTOC in handleSeats (#27389)
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
* feat: TOUTOC in handleSeats

* fix type check

* refactor: replace Prisma include with select in integration tests

Address Cubic AI review feedback (confidence 9/10) to use select instead
of include in Prisma queries to limit returned fields and avoid pulling
full related records.

Co-Authored-By: unknown <>

* fix seat count

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-30 13:38:31 +00:00
Amit SharmaandClaude Opus 4.5 cf2bf9bb8d fix: ooo reason select dropdown opening in wrong direction (#27426)
Add menuPlacement="bottom" to the reason Select in the OOO modal
to ensure dropdown opens downwards consistently with other selects.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 13:27:52 +00:00
MorganandDevin AI 72307b13c7 fix: skip retry when Trigger.dev deployment is already current (#27430)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-30 13:12:16 +00:00
devin-ai-integration[bot]andali@cal.com 101cef72ac fix: query Host table directly to determine isCurrentUserHost flag (#27268)
The previous implementation relied on the hosts array returned from
findTeamEventTypes, which is limited to 5 hosts for display purposes.
This caused the 'Assigned' badge to not show for users who were hosts
but not in the first 5 returned by the query.

This fix queries the Host table directly with a single batch query to
get all event type IDs where the current user is a host, ensuring the
badge shows correctly regardless of how many hosts an event type has.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
2026-01-30 13:02:16 +00:00
emrysal de02a96525 chore: release v6.1.9 2026-01-30 12:50:35 +00:00
Alex van Andel fc9c26e8dd feat: add encryptedKey column to Credential table for calendar integrations (#27154)
Adds encrypted credential storage using a new keyring system:
  - New `encryptedKey` column with AES-256-GCM encryption
  - Decryption in getCalendarsEvents with fallback to legacy `key`
  - buildCredentialCreateData service for credential creation
  - Phase 1: Google Calendar only, other integrations follow
2026-01-30 09:15:13 -03:00
Hariom BalharaandDevin AI 80e4b1af1f fix: Update search filter to check value and values fields in displayFields (#27386)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-30 10:12:12 +00:00
Eunjae Lee c1f52c219d fix: align feature opt-in toggle labels with enable/disable wording (#27425) 2026-01-30 10:11:19 +00:00
Benny JooandDevin AI b3430c8efc refactor: remove 10 trpc imports from features package by moving 16 tRPC-driven components to apps/web/modules (#27336)
* refactor: move Segment, BookerLayoutSelector, CreateLicenseKeyForm from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update relative imports to absolute paths in moved files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: move useBookingLocation and blocklist components from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: move EmbedTabs and embed hooks from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* migrate useBookerUrl

* migrate embed tabs

* fix

* fix

* fix

* mv ThemeLabel

* mv settings headers to webn

* update imports

* clean up

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-30 04:55:50 -03:00
Hariom Balhara ea0d9cbbeb fix: unncesary border in case event type details are hidden (#27421) 2026-01-30 06:47:57 +00:00
0e6bf54fa2 feat(companion): dark mode (#27305)
* feat(companion): add dark mode support using NativeWind system preference

- Set userInterfaceStyle to 'automatic' in app.json to follow system preference
- Add useColorScheme hook from NativeWind to detect color scheme
- Update root layout with dynamic colors for StatusBar, containers, and modals
- Update tabs layout with dynamic colors for tab bar and icons
- Update all Stack.Screen options to use dynamic background colors and blur effects
- Support both iOS and Android with appropriate dark mode colors

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix(companion): use NativeWind dark: variant classes for automatic dark mode

Use dark: Tailwind variant classes instead of conditional logic based on
useColorScheme for the container background. This ensures NativeWind
automatically applies dark mode styles based on system preference.

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix(companion): use darkMode 'media' for automatic dark mode detection

- Changed darkMode from 'class' to 'media' in tailwind.config.js
- Updated global.css to use @media (prefers-color-scheme: dark) instead of .dark selector
- This ensures NativeWind properly detects system color scheme on iOS/Android

Co-Authored-By: peer@cal.com <peer@cal.com>

* dark mode starting

* feat(companion): add dark mode support to core infrastructure (Phase 1)

* feat(companion): add dark mode support to tab pages (Phase 2)

* fix(companion): add dark mode support to booking list components for font visibility

* fix(companion): add dark mode support to EventTypeListItem components

* event types and bookings page

* Availability list page

* more page, and some ui fixes

* feat(companion): add dark mode support to detail screens and modals

- BookingDetailScreen (iOS & Android): dynamic colors for all UI elements
- AvailabilityDetailScreen (iOS & Android): dark mode backgrounds and text
- profile-sheet (iOS & Android): dark mode support for profile modal
- RescheduleScreen (all platforms): dark mode for date/time pickers
- EditLocationScreen (iOS & Android): dark mode for location editor
- AddGuestsScreen: partial dark mode implementation (in progress)

Uses iOS system colors: #000000 (black), #1C1C1E (secondary), #FFFFFF (white), #38383A (border), #8E8E93 (text secondary)

* fix typecheck and lint

* feat(companion): add dark mode support to remaining screens

- ScreenWrapper: Fix hardcoded #800020 color with dynamic destructive color
- EditAvailabilityDayScreen: Add dark mode for Android/Web and iOS
- EditAvailabilityHoursScreen: Add dark mode for Android/Web and iOS
- EditAvailabilityNameScreen: Add dark mode for Android/Web and iOS
- EditAvailabilityOverrideScreen: Add dark mode for Web, iOS, and Android
- MarkNoShowScreen: Add dark mode with dynamic colors for no-show states
- MeetingSessionDetailsScreen: Add dark mode for session details
- ViewRecordingsScreen: Add dark mode for recordings list

Uses iOS system colors (#000000, #1C1C1E, #38383A, #8E8E93) and
useColorScheme hook for automatic theme detection.

* fix(companion): fix iOS modal dark mode backgrounds for transparent glass UI

* fix(companion): fix dark mode for booking action screens in transparent background mode

* fix(companion): fix Android dark mode for transparent background in EditAvailabilityOverrideScreen

* refactor(companion): centralize dark mode colors and align with main website

- Update tailwind.config.js with centralized color definitions
- Create constants/colors.ts for inline style color references
- Replace iOS system colors with main website neutral grays:
  - #1C1C1E -> #171717 (secondary dark background)
  - #38383A -> #4D4D4D (dark border)
  - #8E8E93 -> #A3A3A3 (secondary text dark)
- Keep pure black (#000000) for main backgrounds (OLED friendly)
- Add semantic color mappings for consistent UI styling

* feat(companion): complete dark mode implementation across all priority files

- Priority 1: Updated SettingsUI.tsx, BasicsTab.tsx, LimitsTab.tsx, AdvancedTab.tsx, RecurringTab.tsx, AvailabilityTab.tsx, event-type-detail.tsx
- Priority 2: Updated edit-availability-hours/name/override/day.tsx, oauth/callback.tsx
- Priority 3: Updated AvailabilityListScreen.tsx with dark mode for modals and list items
- Priority 4: Updated BookingActionsModal.tsx, BookingActionsModal.ios.tsx, GlassModalHeader.tsx, LoginScreen.tsx, LocationsList.tsx, SearchHeader.tsx, toast.tsx

Dark mode colors used:
- Main bg: #000000 (cal.bg.dark)
- Secondary bg: #171717 (cal.bg.secondaryDark)
- Muted bg: #262626 (cal.bg.mutedDark)
- Borders: #4D4D4D (cal.border.dark)
- Secondary text: #A3A3A3 (cal.text.secondaryDark)

* fix(companion): add dark mode support to iOS header, GlassView modals, and main content background

* fix(companion): add dark mode support to toggle/switch components

* fix(companion): use iOS green (#34C759) for toggle ON state in dark mode

* fix(companion): use white track + black thumb for dark mode toggles

* fix(companion): add dark mode support to login page logo and button

* dark mode to many pages, centralize the colors

* dark mode skelaton

* Availability pages android

* toggles

* headers

* red color for dark mode

* copy button

* white flash on bottom ui native ios sheet

* bottom sheet buttons

* bottom sheet in gray color

* bottom sheet again.. yeahh

* toggle green

* toggle green

* fix lint and typechecks

* fix exntension error

* Update companion/components/event-type-detail/tabs/LimitsTabDatePicker.android.tsx

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* address cubic comments

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: peer@cal.com <peer@cal.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-30 05:54:18 +01:00
Alex van Andel 39f97e7326 chore: Reduce circular dependencies in tsconfig resoluttion (#27416) 2026-01-30 02:24:02 +00:00
Alex van AndelandDevin AI 5c2382d296 fix: allow wildcard prefix in domain validation (#27413)
* fix: allow wildcard prefix in normalizeDomain function

The normalizeDomain function now accepts domains with *. prefix
(e.g., *.cal.com) for wildcard domain matching in the watchlist.
The domain part after *. is validated using the existing regex.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: allow wildcard domains in validation checks

Update WatchlistOperationsService and CreateBlocklistEntryModal to
accept wildcard domain prefixes (*.) in domain validation. This ensures
wildcard domains like *.cal.com can be added through both the API and UI.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 21:56:55 -03:00
Volnei Munhoz f0ca3bbbfd chore: remove unused env vars and duplicates from turbo.json globalEnv (#27400)
Remove 7 environment variables no longer referenced in the codebase:
- NEXT_PUBLIC_CONSOLE_URL
- NEXT_PUBLIC_STRIPE_PRICING_TABLE_PUBLISHABLE_KEY
- NEXT_PUBLIC_PLAIN_CHAT_EXCLUDED_PATHS
- NEXT_PUBLIC_VERCEL_ENV
- NEXT_PUBLIC_VERCEL_BRANCH_URL
- PRISMA_FIELD_ENCRYPTION_KEY
- PRISMA_GENERATE_DATAPROXY

Deduplicate 6 entries that appeared twice in globalEnv:
- CALCOM_CREDENTIAL_SYNC_SECRET
- INTERCOM_SECRET
- NEXT_PUBLIC_ORG_SELF_SERVE_ENABLED
- ORG_MONTHLY_CREDITS
- STRIPE_ORG_PRODUCT_ID
- VAPID_PRIVATE_KEY

Also removes the unused vars from .env.example.

Reduces globalEnv from 321 to 308 entries, lowering the surface
for unnecessary Turbo cache invalidation.
2026-01-29 21:27:22 -03:00
Alex van AndelandDevin AI c662a76277 feat: add configurable wildcard domain matching to watchlist (#27409)
* feat: add wildcard domain matching to watchlist

When a domain is blocked in the watchlist (e.g., cal.com), all subdomains
are now also blocked (e.g., app.cal.com, sub.app.cal.com).

Changes:
- Add getParentDomains() utility to extract all parent domains
- Update GlobalBlockingService.isBlocked() and areBlocked() for wildcard matching
- Update OrganizationBlockingService.isBlocked() and areBlocked() for wildcard matching
- Add comprehensive tests for wildcard domain matching
- More specific subdomain matches take precedence over parent domain matches
- Email matches still take precedence over domain matches

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* feat: make wildcard domain matching configurable

- *.cal.com blocks all subdomains (app.cal.com, sub.app.cal.com, etc.)
- cal.com only blocks exact matches (not subdomains)
- Updated getWildcardPatternsForDomain to generate wildcard patterns
- Added domainMatchesWatchlistEntry for configurable matching logic
- Updated GlobalBlockingService and OrganizationBlockingService
- Updated tests to verify new behavior

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* refactor: simplify wildcard pattern generation to strip only first part

- Only strips the first part before the first dot
- Handles multi-part TLDs correctly (e.g., .co.uk)
- Returns empty array for two-part domains (e.g., cal.com -> no pattern)
- app.cal.com -> *.cal.com
- bloody-hell.cal.co.uk -> *.cal.co.uk

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 23:59:51 +00:00
Keith WilliamsandDevin AI 81a656930a perf: increase Office365 calendarView page size to 999 to minimize pagination (#27407)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 19:30:48 -03:00
Volnei Munhoz 47becd416d feat: add index on channelId for SelectedCalendar (#27403)
Add database index on the channelId column in the SelectedCalendar
table to improve lookup performance for watched calendar channels.
2026-01-29 20:36:40 +00:00
7abbc8c22c feat: Routing trace presenter (#27372)
* feat: Add routing trace presenters

Add domain-specific presenters (SalesforceRoutingTracePresenter,
RoutingFormTracePresenter) that format trace steps into human-readable
strings, and a core RoutingTracePresenter that delegates to them based
on step domain. Includes unit tests for all presenters.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add findByBookingUid to RoutingTraceRepository

Add method to look up a routing trace by booking UID, needed by the
routing trace presenter tRPC endpoint.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add getRoutingTrace tRPC endpoint

Expose routing trace data for a booking via viewer.bookings.getRoutingTrace.
Tries the permanent RoutingTrace first (round robin bookings), then falls
back to PendingRoutingTrace via the booking's form response relation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add routing trace side sheet to booking list item

Add a route icon button on booking list items that came from routing
forms. Clicking it opens a side sheet displaying the full routing trace
as human-readable steps. Adds RoutingTraceSheet component, store state,
and translation key.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Move routing trace action to dropdown menu

Move the routing trace button from a standalone icon on the booking list
item into the actions dropdown menu alongside "Report wrong assignment".
The RoutingTraceSheet is now rendered from BookingActionsDropdown.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Improve routing trace UI and handle unnamed routes

- Redesign RoutingTraceSheet with vertical timeline layout, domain badges,
  skeleton loading state, and millisecond timestamps
- Use Salesforce app-store icon for Salesforce steps
- Fall back to "Unnamed route" when route name is missing or matches route ID
- Fix dropdown menu icon to git-merge (valid icon, unique in menu)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Add tests for getRoutingTrace handler and findByBookingUid repository method

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Abstract functions

* Fix build error

* Add permission check

* fix: Update getRoutingTrace tests to include ctx and mock BookingAccessService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 15:26:44 -03:00
Eunjae Lee e7d38755dd refactor: use DI-ed cached FeaturesRepository in flags router (#27394)
## What does this PR do?

Replaces direct instantiation of `FeaturesRepository` with the dependency-injected version using `getFeaturesRepository()` from the DI container in the feature flags router.

**Key improvement:** The DI-ed version uses Redis caching, replacing the previous in-memory 5-minute cache implementation which was not ideal. This follows the established DI pattern in the codebase for loose coupling, better testability, and more robust caching across instances.

## Type of change

- [x] Refactor (non-breaking change that improves code quality)

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Verify feature flags functionality works as expected:
   - Feature flag list endpoint should return all features
   - Team feature check should work correctly
2. No environment variables needed beyond standard setup

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

## Human Review Checklist

- [ ] Verify `getFeaturesRepository()` returns a properly configured instance from the DI container
- [ ] Confirm the DI container properly injects the Prisma client
- [ ] Verify Redis caching is working as expected for feature flag data

---

**Link to Devin run:** https://app.devin.ai/sessions/2ff6e4551c8649e4b6178b31a2195327
**Requested by:** @eunjae-lee
2026-01-29 16:47:46 +01:00
emrysal 0e8dde843d chore: release v6.1.8
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-29 15:01:13 +00:00
Benny JooandDevin AI c7ee3984ef refactor: move feature-flags, calendars, and schedules components from packages/features to apps/web/modules (#27222)
* refactor: move feature-flags, calendars, and schedules components from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix

* fix: move DatePicker and DateOverrideInputDialog to apps/web/modules and update imports

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* rename

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* wip

* wip

* wip

* fix unit tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 16:41:44 +02:00
Eunjae LeeandDevin AI 18049bc1d6 refactor: update i18n keys to match effectiveReason values (#27381)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 14:16:12 +00:00
MorganandDevin AI 447a0289d6 fix: parse raw body Buffer in Vercel webhook controller (#27384)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 11:54:32 +00:00
2802310268 feat: Add infrastructure for no-show audit integration (#27187)
* feat: Add infrastructure for no-show audit integration

- Add Prisma migrations for SYSTEM source and NO_SHOW_UPDATED audit action
- Add NoShowUpdatedAuditActionService with array-based attendeesNoShow schema
- Update BookingAuditActionServiceRegistry to include NO_SHOW_UPDATED
- Update BookingAuditTaskConsumer and BookingAuditViewerService
- Add AttendeeRepository methods for no-show queries
- Update IAuditActionService interface with values array support
- Update locales with no-show audit translation keys

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add NO_SHOW_UPDATED to BookingAuditAction and SYSTEM to ActionSource types

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED from BookingAuditAction type to match Prisma schema

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update BookingAuditActionSchema to use NO_SHOW_UPDATED instead of HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Remove deprecated no-show audit services and unify to NoShowUpdatedAuditActionService

- Delete HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService
- Update BookingAuditProducerService.interface.ts to use queueNoShowUpdatedAudit
- Update BookingAuditTaskerProducerService.ts to use queueNoShowUpdatedAudit
- Update BookingEventHandlerService.ts to use onNoShowUpdated
- Add integration tests for NoShowUpdatedAuditActionService

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add data migration step for deprecated no-show enum values

Addresses Cubic AI review feedback (confidence 9/10): The migration now
includes an UPDATE statement to convert existing records using the
deprecated 'host_no_show_updated' or 'attendee_no_show_updated' enum
values to the new unified 'no_show_updated' value before the type cast.
This prevents migration failures if any existing data uses the old values.

Co-Authored-By: unknown <>

* fix: Use CASE expression in USING clause for enum migration

Fixes PostgreSQL error 'unsafe use of new value of enum type' by avoiding
the ADD VALUE statement and instead using a CASE expression in the ALTER
TABLE USING clause to convert deprecated enum values (host_no_show_updated,
attendee_no_show_updated) to the new unified value (no_show_updated) during
the type conversion.

Co-Authored-By: unknown <>

* fix: Replace hardcoded color with semantic text-success class

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove color class completely from display fields

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 08:47:26 -03:00
2ec9e903ce feat: implement webhook tasker with async/sync fallback (#27378)
* feat: implement webhook tasker with async/sync fallback

This PR implements a webhook tasker with async/sync fallback architecture
to fix failing E2E tests. The solution follows the existing proration
tasker pattern and uses Dependency Injection with @evyweb/ioctopus.

Key changes:
- Create IWebhookTasker interface for webhook delivery
- Implement WebhookSyncTasker for immediate execution (E2E tests)
- Implement WebhookAsyncTasker for queued execution (production)
- Create main WebhookTasker class extending Tasker<IWebhookTasker>
- Add DI modules and tokens for all tasker components
- Update WebhookTaskerProducerService to use new WebhookTasker
- Add unit tests for sync and async taskers

The ENABLE_ASYNC_TASKER flag automatically selects the appropriate mode:
- Production: Uses WebhookAsyncTasker to queue tasks
- E2E Tests: Uses WebhookSyncTasker for immediate execution

This ensures webhooks are delivered immediately in E2E tests without
requiring the cron job that processes queued tasks.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: update WebhookTaskerProducerService tests for new interface

Update tests to use the new deps-based constructor and
mockWebhookTasker.deliverWebhook instead of mockTasker.create

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: use moduleLoader pattern for WebhookProducerService in container

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: replace InternalTasker with Trigger.dev for webhook delivery

This commit refactors the WebhookTasker to use Trigger.dev instead of
InternalTasker, following the pattern established in BookingEmailAndSmsTasker
and PlatformOrganizationBillingTasker (PR #26803).

Changes:
- Replace WebhookAsyncTasker with WebhookTriggerTasker that uses trigger.dev
- Create trigger.dev task files (deliver-webhook.ts, config.ts, schema.ts)
- Update DI modules to use WebhookTriggerTasker
- Remove old InternalTasker-based implementation
- Update unit tests for new implementation

The WebhookSyncTasker continues to execute webhooks immediately for E2E tests
where ENABLE_ASYNC_TASKER is automatically false.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: update comments to reflect Trigger.dev usage instead of InternalTasker

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 15:30:07 +04:00
Volnei Munhoz db7547fd6d Remove noProcessGlobal for atoms (#27382) 2026-01-29 11:25:01 +00:00
sean-brydonandClaude Opus 4.5 3c91703415 feat: add invoice banner + block additions to teams/orgs (#27327)
* feat: add invoice URL to proration and test seed scripts

- Add invoiceUrl field to MonthlyProration schema
- Update billing service to return hosted_invoice_url after finalizing
- Save invoice URL when creating proration invoices
- Add seed script for testing proration with real Stripe data
- Add cleanup script for test data removal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add due invoice banner and invitation blocking for orgs

- Add DueInvoiceBanner component showing overdue prorations
- Add DueInvoiceService for checking blocking status and banner data
- Block invitations when proration invoices are 7+ days overdue
- Allow sub-team invites for existing org members (exception)
- Show banner to users with billing management permissions
- Link directly to Stripe invoice URL when available

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: set subscriptionId in team metadata in seed script

The seed script was not setting subscriptionId on the team metadata,
causing checkIfOrgNeedsUpgrade to treat the org as needing upgrade
and showing the "trialing" banner.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* push trigger test to script

* fix mocks

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 11:23:27 +00:00
ca5d931165 fix: preserve UI config across iframe resets for element-click embeds (#27363)
* fix: preserve UI config across iframe resets for element-click embeds

For element-click embeds, ui() is called before the iframe exists, and
iframeReset() clears the queue when the modal is opened. This causes UI
config like hideEventTypeDetails, cssVarsPerTheme, and styles to be lost.

This fix stores UI config in a persistent property that survives iframe
resets and applies it when the iframe becomes ready.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: add assertion to verify hideEventTypeDetails config is applied in element-click embed

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Add mergeUiConfig function and related tests for UI configuration merging

- Introduced mergeUiConfig function to handle merging of UI configuration, specifically for cssVarsPerTheme at theme level.
- Added comprehensive tests for mergeUiConfig covering various scenarios including merging themes, handling missing properties, and preserving existing configuration values.
- Updated utils.test.ts to include tests for the new function and ensure correct behavior in different merging situations.

* Fixes

* Remove process import as it breaks embed.js

* Simplify

* fix name

* fix name

* fix: use forEach instead of for...of for URLSearchParams iteration

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2026-01-29 08:18:53 -03:00
3b2e3351c4 docs: api v2 and examples app setup (#27290)
* docs: api v2 and examples app setup

* docs: api v2 and examples app setup

* fix: address Cubic AI review feedback

- Fix env file path typo in README.md (apps/api/v2.env -> apps/api/v2/.env)
- Write generated secrets to file instead of logging to console
- Add .generated-secrets to gitignore
- Update README-PLATFORM.md to reflect new secret generation behavior

Co-Authored-By: unknown <>

* chore: update locale

* chore: update docs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
2026-01-29 11:18:23 +00:00
sean-brydonandClaude Opus 4.5 08a2b0bfb5 feat: add organization.passwordReset PBAC permission (#27377)
* feat: add organization.passwordReset PBAC permission

Allow org admins/owners to reset passwords for members of their
organization via a new PBAC permission. Previously this was only
available to system-level admins.

- Add PasswordReset to CustomAction enum and PERMISSION_REGISTRY
- Create migration to grant permission to admin_role (owner has wildcard)
- Add org-scoped tRPC endpoint using createOrgPbacProcedure
- Handler validates org membership, prevents self-targeting, and blocks
  resetting owner passwords
- Wire permission through MemberPermissions, getOrgMembersPageData, and
  the org members table UI dropdown

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use targeted select in org password reset to avoid over-fetching

Replace findById with findForPasswordReset repository method that only
selects email, name, and locale instead of the full userSelect which
includes sensitive fields like twoFactorSecret and backupCodes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add unit tests for sendPasswordReset handler

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 11:18:02 +00:00
sean-brydonandDevin AI 1f8f134854 feat: enable PBAC feature flag globally via migration (#27376)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 11:00:55 +00:00
Rajiv Sahal 5427d28c9e fix: bad import (#27380) 2026-01-29 09:45:06 +00:00
sean-brydonandDevin AI 0d5560e0d1 fix: use WEBAPP_URL for team payment redirect instead of req.nextUrl.origin (#27233)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 09:30:14 +00:00
Eunjae Lee ea15474edf fix: show bookings-v3 only in the settings but not in the banner (#27330)
## What does this PR do?

Adds a `displayLocations` property to the `OptInFeatureConfig` interface to control where opt-in features are displayed (settings page, banner, or both), and applies this filtering at the callers' side.

## How to test locally

```
update "Feature" set enabled = true where slug='bookings-v3';
```

Run it to globally enable the flag, and then go to the settings page to see the "Features" menu.

---

**Changes:**
- Added `OptInFeatureDisplayLocation` type with values `"settings"` | `"banner"`
- Added optional `displayLocations` property to `OptInFeatureConfig` interface
- Added helper functions:
  - `getFeatureDisplayLocations()` - returns display locations with default of `['settings']`
  - `shouldDisplayFeatureAt()` - checks if a feature should display at a specific location
  - `getOptInFeaturesForLocation()` - filters features by location
- Updated `getOptInFeaturesForScope()` to accept an optional `displayLocation` parameter for filtering
- Simplified `HAS_*_OPT_IN_FEATURES` constants to use `getOptInFeaturesForScope(scope, "settings").length > 0`
- Updated `FeatureOptInService.listFeaturesForUser()` to filter by 'settings' location
- Updated `FeatureOptInService.listFeaturesForTeam()` to filter by 'settings' location
- Updated `useFeatureOptInBanner` hook to check for 'banner' location before showing

**Default behavior:** If `displayLocations` is omitted, features default to `['settings']` only.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - internal config change only.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Verify the helper functions work as expected:
   - `getFeatureDisplayLocations({ slug: "test", ... })` should return `["settings"]` (default)
   - `getFeatureDisplayLocations({ slug: "test", displayLocations: ["banner"] })` should return `["banner"]`
   - `shouldDisplayFeatureAt(feature, "settings")` should return `true` for features without `displayLocations`
   - `getOptInFeaturesForScope("user", "banner")` should only return user-scoped features with `"banner"` in their `displayLocations`

2. Verify caller-side filtering:
   - `listFeaturesForUser()` and `listFeaturesForTeam()` should only return features with 'settings' in displayLocations
   - Banner hook should only show features with 'banner' in displayLocations
   - `HAS_*_OPT_IN_FEATURES` constants should only be true if there are features with 'settings' location

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] My changes generate no new warnings

---

### Human Review Checklist
- [ ] Verify the default behavior (defaulting to `['settings']`) matches requirements
- [ ] Confirm the filtering logic is applied correctly in all callers (service methods, banner hook, constants)
- [ ] Verify the banner hook correctly prevents showing features without 'banner' in displayLocations
- [ ] Note: The test mock returns all features regardless of `displayLocation` parameter - the filtering logic in `getOptInFeaturesForScope` isn't directly tested. Consider if this is acceptable or if tests should be added.

**Link to Devin run:** https://app.devin.ai/sessions/a064ee43a56d458caf2892b55959f1ea
**Requested by:** @eunjae-lee
2026-01-29 10:17:50 +01:00
6acc84661d refactor: fix 413 Request Entity too large error when big image files are uploaded (#27285)
* feat: add image resizing endpoint for organization onboarding

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* chore: add translation keys for image upload errors

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: rename endpoint to resizeBase64Image with imageType enum and Zod validation

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: use ImageUploader and BannerUploader components for organization brand onboarding

Replace server-side image resizing endpoint with client-side cropping using existing ImageUploader and BannerUploader components. This approach:
- Avoids sending large base64 payloads to the server (preventing 413 errors)
- Provides better UX with cropping functionality
- Aligns with team onboarding which already uses ImageUploader
- Removes unnecessary server-side code

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Revert formatting change

* fix: correct max file size from 10mb to 5mb in translations

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Add Remove bvutton too

* fix: correct banner dimension, indentation, and import order

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 08:55:13 +00:00
5b048dd868 fix: exclude third-party video apps from areCalendarEventsEnabled setting (#27230)
* fix: exclude third-party video apps from areCalendarEventsEnabled setting

When areCalendarEventsEnabled is false, video meeting creation for third-party
video apps (like Daily.co) was being skipped, causing the meetingUrl field in
webhook payloads to contain the location identifier (integrations:daily) instead
of the actual video meeting URL.

This fix adds a skipCalendarEvent option to EventManager.create() that:
- Skips calendar event creation when true
- Skips CRM event creation when true (CRM events are tied to calendar events)
- Still creates video meetings for third-party video apps

The calling code in handleConfirmation.ts and RegularBookingService.ts now uses
this option when areCalendarEventsEnabled is false, ensuring video meetings are
still created while respecting the platform customer's preference to manage
their own calendar events.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: update E2E tests to verify skipCalendarEvent option is passed when areCalendarEventsEnabled is false

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: address PR review feedback - remove comments and update E2E tests to spy on createAllCalendarEvents

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: add spy for createAllCRMEvents in e2e tests when areCalendarEventsEnabled is false

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* test: add missing spy for createAllCRMEvents in beforeEach hook

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use videoCallUrl from metadata for webhook payload location

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* fix: simplify webhook location to use metadata?.videoCallUrl || evt.location

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* docs: add description about video call link limitations when calendar events disabled

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* i18n: add translation key for calendar events disabled video limitation

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* fix: update translation text to accurately reflect video app behavior

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* Update common.json

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
2026-01-29 10:23:52 +02:00
b02470e780 feat: add webhook endpoint for Vercel deployment promoted event to promote trigger.dev (#27340)
* feat: add webhook endpoint for Vercel deployment promoted event to promote trigger.dev

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: rename TRIGGER_API_KEY to TRIGGER_SECRET_KEY

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 16:24:42 +09:00
Hariom Balhara c536445eec docs: clarify bookerReopened and bookerReloaded are for prerendered modals (#27348)
## What does this PR do?

Updates the embed lifecycle documentation to clarify that `bookerReopened` and `bookerReloaded` events are only applicable for prerendered modals that are now visible.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - this PR is itself a documentation update.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. N/A - documentation only change.

## How should this be tested?

This is a documentation-only change. Review the accuracy of the added "Applicability" notes for both events.

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

---

### Reviewer Checklist
- [ ] Verify that the documentation accurately reflects when `bookerReopened` and `bookerReloaded` events fire (only for prerendered modals)

---

> [!NOTE]
> **Link to Devin run**: https://app.devin.ai/sessions/35a0c5d4d5fc4feb9a5af2d8d340b9c5
> **Requested by**: @hariombalhara
2026-01-29 10:13:58 +05:30
09f33a840f chore: trigger.version.ts to set trigger tasks versions in prod (#27333)
* chore: trigger.version.ts instead of .env.production

* chore: trigger.version.ts instead of .env.production

* chore: restore dotenv/config import for local development

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fixup! chore: trigger.version.ts instead of .env.production

* fixup! fixup! chore: trigger.version.ts instead of .env.production

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-28 19:36:36 -03:00
16cb9a3126 refactor: join teams with feature enabled directly in findNextSubscriptionBatch query (#27364)
* refactor: join teams with feature enabled directly in findNextSubscriptionBatch query

- Changed findNextSubscriptionBatch to accept featureId instead of teamIds
- Join TeamFeatures table directly in the query instead of separate queries
- Updated CalendarSubscriptionService.checkForNewSubscriptions to pass featureId
- Removed separate getTeamsWithFeatureEnabled call
- Updated tests to reflect the new query structure

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: change featureId to featureIds array for flexibility

- Changed findNextSubscriptionBatch to accept featureIds array instead of single featureId
- Updated Prisma query to use 'in' operator for multiple feature IDs
- Updated CalendarSubscriptionService to pass array with single feature
- Updated all tests to use featureIds array

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-28 17:52:00 -03:00
Alex van AndelandDevin AI 844380e265 fix: reduce forcedSlowMode rate limit from 30s to 1s (#27359)
* fix: reduce forcedSlowMode rate limit from 30s to 1s

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* revert: keep rateLimit.ts unchanged, only update API v2 controllers

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-28 17:39:28 -03:00
034fbd63f1 feat: Add CrmRoutingTraceService and SalesforceRoutingTraceService (#27318)
* Add DB schema

* Init zod schema

* Init RoutingTrace and PendingRoutingTrace repository interfaces

* Create PrismaPendingRoutingTraceRepository

* Init RoutingTraceService

* Create RoutingTraceService container

* User routing trace service in routing

* Create RoutingTraceRepository and PrismaRoutingTraceRepoistory

* Add findByFormResponseId and findByQueuedFormResponseId to PendingRoutingTraceRepository

* Update DI containers

* RoutingTraceService create process booking method

* Use pending routing trace rather than URL params

* Fix schema

* Fix writing assignment reason for routed booking

* Remove  from  service

* Refactor RoutingTraceService to not rely on async local storage

* Pass RoutingTraceService through routing call

* Add attribute-logic-evaluated to routing trace step

* Add routing trace to trpc endpoint

* Add CRM routing trace step

* Fix extracting routing trace to assignment reason

* Add back CRM params to prevent refetching

* test: Add unit tests for RoutingTraceService and repositories

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: Add missing mock for RoutingTraceService in getRoutedUrl tests

Also fix pre-existing lint issues in the test file:
- Add explicit types to mockForm and mockSerializableForm variables
- Add explicit type to url parameter in mockContext
- Replace 'as any' with 'as unknown as InstanceType<typeof UserRepository>'

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Link pending form submission to routing trace

* Clean up

* Add lookup field assignment reasons

* Rename to PendingRoutingTrace

* Add migration file

* fix: Update RoutingTraceService tests to use assignmentReasonRepository mock

- Add getStepsCount() method back to RoutingTraceService
- Add queuedFormResponseId support to processForBooking method
- Update tests to use mockAssignmentReasonRepository instead of prisma mock
- Remove test for missing routingTraceRepository (all deps now required)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Remove PII (organizer email) from log payload in RoutingTraceService

Addresses Cubic AI review feedback with confidence 9/10.
Logging PII violates sensitive information logging rules.

Co-Authored-By: unknown <>

* Write field values at the time of routing

* Write attributes used to route

* feat: add CRM routing trace service

Add CrmRoutingTraceService as a reusable wrapper around RoutingTraceService
for CRM-specific tracing. Also adds CrmRoutingTraceServiceInterface type
to support passing trace services through the CRM call chain.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add Salesforce routing trace infrastructure

Add SalesforceRoutingTrace static class with 19 trace methods covering:
- Account resolution (SOQL path): searching by website, contact domain
- Lookup field queries
- Owner lookups (contact, lead, account)
- Validation and skip scenarios
- GraphQL three-tier resolution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: wire CRM trace service through call chain

Pass crmTrace parameter through the CRM call chain:
- routerGetCrmContactOwnerEmail creates CrmRoutingTraceService
- Passes to app booking form handlers and CRM round robin skip
- CrmManager.getContacts accepts and forwards crmTrace
- All handlers accept optional crmTrace parameter

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add trace instrumentation to Salesforce CRM service

Instrument Salesforce CRM methods with routing trace steps:
- getContacts: trace owner lookups for contact/lead/account
- getAccountIdBasedOnEmailDomainOfContacts: trace website and domain searches
- findUserEmailFromLookupField: trace lookup field queries
- GetAccountRecordsForRRSkip (GraphQL): trace three-tier resolution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: rename SalesforceRoutingTrace to SalesforceRoutingTraceService

Consistent naming with CrmRoutingTraceService.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add unit tests for CrmRoutingTraceService and SalesforceRoutingTraceService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: use AsyncLocalStorage for CRM routing trace

Replace explicit crmTrace parameter passing with AsyncLocalStorage:

- Add AsyncLocalStorage to RoutingTraceService with getCurrent() and runAsync()
- Update SalesforceRoutingTraceService to auto-resolve trace from AsyncLocalStorage
- Remove CrmRoutingTraceService wrapper (no longer needed)
- Remove crmTrace parameter from all CRM method signatures
- Wrap CRM operations in routingTraceService.runAsync() context

This is cleaner than threading crmTrace through 5+ function layers.
The trace context is available within the withReporting wrapper.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Use async local storage for `CrmRoutingTraceService`

* fix: correct template literal syntax in RoutingTraceService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use narrowed eventTypeId variable in nested async function

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: update SalesforceRoutingTraceService tests to use AsyncLocalStorage API

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: rename crmTrace to crmRoutingTraceService for consistency

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-28 17:28:35 -03:00
f536100224 feat: Add RoutingFormTrace (#27316)
* Add DB schema

* Init zod schema

* Init RoutingTrace and PendingRoutingTrace repository interfaces

* Create PrismaPendingRoutingTraceRepository

* Init RoutingTraceService

* Create RoutingTraceService container

* User routing trace service in routing

* Create RoutingTraceRepository and PrismaRoutingTraceRepoistory

* Add findByFormResponseId and findByQueuedFormResponseId to PendingRoutingTraceRepository

* Update DI containers

* RoutingTraceService create process booking method

* Use pending routing trace rather than URL params

* Fix schema

* Fix writing assignment reason for routed booking

* Remove  from  service

* Refactor RoutingTraceService to not rely on async local storage

* Pass RoutingTraceService through routing call

* Add attribute-logic-evaluated to routing trace step

* Add routing trace to trpc endpoint

* Add CRM routing trace step

* Fix extracting routing trace to assignment reason

* Add back CRM params to prevent refetching

* test: Add unit tests for RoutingTraceService and repositories

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: Add missing mock for RoutingTraceService in getRoutedUrl tests

Also fix pre-existing lint issues in the test file:
- Add explicit types to mockForm and mockSerializableForm variables
- Add explicit type to url parameter in mockContext
- Replace 'as any' with 'as unknown as InstanceType<typeof UserRepository>'

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Link pending form submission to routing trace

* Clean up

* Add lookup field assignment reasons

* Rename to PendingRoutingTrace

* Add migration file

* fix: Update RoutingTraceService tests to use assignmentReasonRepository mock

- Add getStepsCount() method back to RoutingTraceService
- Add queuedFormResponseId support to processForBooking method
- Update tests to use mockAssignmentReasonRepository instead of prisma mock
- Remove test for missing routingTraceRepository (all deps now required)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Remove PII (organizer email) from log payload in RoutingTraceService

Addresses Cubic AI review feedback with confidence 9/10.
Logging PII violates sensitive information logging rules.

Co-Authored-By: unknown <>

* Write field values at the time of routing

* Write attributes used to route

* fix: Add CHECK constraint to ensure at least one response ID is set in routing trace tables

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Address PR review comments for routing trace feature

- Add checkedFallback to routing trace step data (Comment 11)
- Extract hardcoded domain/step strings to constants (Comment 13)
- Use @default(now()) for createdAt in PendingRoutingTrace and RoutingTrace (Comment 15)
- Add DEFAULT CURRENT_TIMESTAMP to migration for createdAt fields

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Use UTC-safe timezone expression for createdAt defaults in routing trace tables

Addresses Cubic AI review feedback (confidence 9/10) to prevent timezone
issues by using dbgenerated("timezone('UTC', now())") instead of bare now()
for the createdAt fields in PendingRoutingTrace and RoutingTrace models.

Co-Authored-By: unknown <>

* fix: Align migration SQL with Prisma's expected timezone syntax

Use 'UTC'::text cast in timezone() function to match Prisma's generated SQL.

Co-Authored-By: unknown <>

* fix: Revert migration SQL to match Prisma schema timezone syntax

Remove ::text cast from timezone() function to match what Prisma generates
from the schema definition.

Co-Authored-By: unknown <>

* fix: Use explicit ::text cast in timezone() for PostgreSQL compatibility

PostgreSQL normalizes timezone('UTC', now()) to timezone('UTC'::text, now())
internally. Update both schema and migration to use the explicit cast to
ensure they match and pass the migration check.

Co-Authored-By: unknown <>

* feat: Add RoutingFormTraceService domain class for type-safe routing traces

- Create RoutingFormTraceService class with routeMatched, fallbackRouteUsed,
  attributeLogicEvaluated, and attributeFallbackUsed methods
- Add ROUTING_FORM_STEPS constants
- Add unit tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Integrate RoutingFormTraceService for routing form tracing

- Add routingFormTraceService parameter to findMatchingRoute
- Record route_matched or fallback_route_used step when route is selected
- Use "Default Route" as name for form-level fallback routes
- Refactor findTeamMembersMatchingAttributeLogic to use RoutingFormTraceService
- Update handleResponse to accept and pass routingFormTraceService
- Create RoutingFormTraceService in getRoutedUrl and pass through the flow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Add test coverage for RoutingFormTraceService integration

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: Integrate RoutingFormTraceService for routing form tracing

- Add routingFormTraceService parameter to findMatchingRoute
- Record route_matched or fallback_route_used step when route is selected
- Use "Default Route" as name for form-level fallback routes
- Refactor findTeamMembersMatchingAttributeLogic to use RoutingFormTraceService
- Update handleResponse to accept and pass routingFormTraceService
- Create RoutingFormTraceService in getRoutedUrl and pass through the flow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Restore schema and migration from main branch

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Use correct parameter name routingFormTraceService in tests

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Use 'default_route' instead of 'Default Route' for fallback route name

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 17:15:22 -03:00
Alex van AndelandDevin AI 906ba99d3c fix: add composite index on SecondaryEmail for email verification queries (#27357)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-28 14:53:31 -03:00
620445d85f feat: Use RoutingTraceService to write assignment reasons (#27225)
* Add DB schema

* Init zod schema

* Init RoutingTrace and PendingRoutingTrace repository interfaces

* Create PrismaPendingRoutingTraceRepository

* Init RoutingTraceService

* Create RoutingTraceService container

* User routing trace service in routing

* Create RoutingTraceRepository and PrismaRoutingTraceRepoistory

* Add findByFormResponseId and findByQueuedFormResponseId to PendingRoutingTraceRepository

* Update DI containers

* RoutingTraceService create process booking method

* Use pending routing trace rather than URL params

* Fix schema

* Fix writing assignment reason for routed booking

* Remove  from  service

* Refactor RoutingTraceService to not rely on async local storage

* Pass RoutingTraceService through routing call

* Add attribute-logic-evaluated to routing trace step

* Add routing trace to trpc endpoint

* Add CRM routing trace step

* Fix extracting routing trace to assignment reason

* Add back CRM params to prevent refetching

* test: Add unit tests for RoutingTraceService and repositories

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: Add missing mock for RoutingTraceService in getRoutedUrl tests

Also fix pre-existing lint issues in the test file:
- Add explicit types to mockForm and mockSerializableForm variables
- Add explicit type to url parameter in mockContext
- Replace 'as any' with 'as unknown as InstanceType<typeof UserRepository>'

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Link pending form submission to routing trace

* Clean up

* Add lookup field assignment reasons

* Rename to PendingRoutingTrace

* Add migration file

* fix: Update RoutingTraceService tests to use assignmentReasonRepository mock

- Add getStepsCount() method back to RoutingTraceService
- Add queuedFormResponseId support to processForBooking method
- Update tests to use mockAssignmentReasonRepository instead of prisma mock
- Remove test for missing routingTraceRepository (all deps now required)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Remove PII (organizer email) from log payload in RoutingTraceService

Addresses Cubic AI review feedback with confidence 9/10.
Logging PII violates sensitive information logging rules.

Co-Authored-By: unknown <>

* Write field values at the time of routing

* Write attributes used to route

* fix: Add CHECK constraint to ensure at least one response ID is set in routing trace tables

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Address PR review comments for routing trace feature

- Add checkedFallback to routing trace step data (Comment 11)
- Extract hardcoded domain/step strings to constants (Comment 13)
- Use @default(now()) for createdAt in PendingRoutingTrace and RoutingTrace (Comment 15)
- Add DEFAULT CURRENT_TIMESTAMP to migration for createdAt fields

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Use UTC-safe timezone expression for createdAt defaults in routing trace tables

Addresses Cubic AI review feedback (confidence 9/10) to prevent timezone
issues by using dbgenerated("timezone('UTC', now())") instead of bare now()
for the createdAt fields in PendingRoutingTrace and RoutingTrace models.

Co-Authored-By: unknown <>

* fix: Align migration SQL with Prisma's expected timezone syntax

Use 'UTC'::text cast in timezone() function to match Prisma's generated SQL.

Co-Authored-By: unknown <>

* fix: Revert migration SQL to match Prisma schema timezone syntax

Remove ::text cast from timezone() function to match what Prisma generates
from the schema definition.

Co-Authored-By: unknown <>

* fix: Use explicit ::text cast in timezone() for PostgreSQL compatibility

PostgreSQL normalizes timezone('UTC', now()) to timezone('UTC'::text, now())
internally. Update both schema and migration to use the explicit cast to
ensure they match and pass the migration check.

Co-Authored-By: unknown <>

* fix: Use CURRENT_TIMESTAMP for createdAt defaults (standard Cal.com pattern)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Use @default(now()) for createdAt in routing trace tables to match migration

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Pedro Castro <pedro@cal.com>
2026-01-28 12:45:15 -05:00
c9bd18e866 chore: Disables syncing of calendarList on overlay calendar fetch (#27020)
* chore: Disables syncing of calendarList on overlay calendar fetch

* Unwrap ToggledConnectedCalendars

* Pick the right type for connectedCalendars

* further type amends

* Type fixes, tons of em

* Some further fixups consistent with what was before

* fix: resolve type incompatibility in getConnectedDestinationCalendars return type

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: update DestinationCalendarProps to accept tRPC handler return type

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: use generic type for DestinationCalendarProps to accept tRPC enriched types

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: simplify DestinationCalendarProps type for better compatibility

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: export ConnectedCalendar type for consistent type inference

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: use permissive type for connectedCalendars to accept tRPC enriched types

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: export ConnectedCalendar and ConnectedDestinationCalendars types from platform-libraries

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: update ConnectedCalendar type to use boolean | null for primary field

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* Update ConnectedCalendarItem

* Undo some of Devins fixes, more fixes

* Fixup the destination calendar return type, historically not null

* Change init to undefined to deal with null

* Approach to connect selected calendars with the right credential

* This return type is used way too much everywhere, not refactoring

* Add the selectedCalendars to the type

* Actually fix overlay calendar

* set calendarsToLoad param as required

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Add new translation for 'Calendar Settings'

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-28 14:20:19 -03:00
emrysal c62f333337 chore: release v6.1.7
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-28 16:20:47 +00:00
Eunjae Lee 91a62a14ee fix: disable prefetch in /bookings (#27351) 2026-01-28 13:05:20 -03:00
Alex van AndelandDevin AI 718aef579c fix: optimize bookings/get query to use subqueries instead of materializing 400+ parameters (#27319)
PERFORMANCE: The bookings/get endpoint was taking 24s due to materializing 400+ email
addresses as individual parameters in WHERE IN clauses. This caused massive UNION
queries that overwhelmed the database.

Changes:
- Replace IN clauses with Kysely subqueries for queries 4, 5, 6, and 7
- Query 4 & 5: Use subquery to get emails from users via Membership table
- Query 6: Use subquery to get event type IDs from EventType table
- Query 7: Use subquery to get user IDs from Membership table
- Only fetch user IDs when needed for userIds filter validation
- Add new getUserIdsFromTeamIds function (lighter version without emails)

Before: WHERE email IN ($1, $2, ..., $400+) - passes 400+ parameters
After: WHERE email IN (SELECT email FROM users JOIN Membership...) - passes only team IDs

This reduces parameter count from 400+ to typically 1-10 team IDs, letting the
database optimize the query execution plan.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-28 12:21:49 -03:00
Carina WollendorferandCarinaWolli cba329d6d2 feat: removes account dropdown from oauth consent screen (#27191)
* remove acount dropdown on consent screen

* change button back to go back

* add missing translations

* fix avatar

* code clean up

* add translation

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-01-28 15:34:59 +01:00
sean-brydon ade823f135 sort team Ids (#27349) 2026-01-28 14:33:58 +00:00
Eunjae LeeandDevin AI ddceabe5d4 fix: use FeatureOptInService for bookings-v3 check (#27183)
* fix: use FeatureOptInService for bookings-v3 check

* refactor: simplify FeatureOptInService API and fix bookings page

- Add resolveFeatureStates method that takes only userId and featureIds
- Update listFeaturesForUser to take only userId parameter
- Remove getUserOrgAndTeamIds from _router.ts (now internal to service)
- Fix bookings page to use new resolveFeatureStates method
- Parallelize getUserFeaturesStatus and resolveFeatureStates calls

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* check session?.user?.id first

* remove comment

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-28 14:28:36 +00:00
Lauris Skraucis 987e727464 docs: document business rules in AGENTS.md (#27347) 2026-01-28 14:13:09 +00:00
Volnei Munhoz 61dd7eb64c chore: Upgrade Next & React (#27332)
* upgrade next and react versions

* upgrade next and react versions

* upgrade next and react versions
2026-01-28 10:47:04 -03:00
Benny Joo 1a31f9136b refactor: Move integration attribute async components to /web (#27341)
* calendar switch

* wip

* wip

* wip

* fix
2026-01-28 10:44:18 -03:00
Carina WollendorferandCarinaWolli 8e5a5629a4 fix: fixes oauth flow with user sign up (#27307)
* fix oauth flow with sign up

* extract key as const variable

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-01-28 13:35:27 +00:00
Amit Sharma 5bea18fd5e feat: hubspot rr skip (#27310)
* feat: hubspot show owner availability for round robin

* fix: translations

* fix: use app name variable for text
2026-01-28 16:57:02 +05:30
Carina WollendorferandCarinaWolli ff6fa64b63 fix: UI improvements for team-wide limits (#27133)
* add badge

* allow undefined

* fix ci type errors

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-01-28 11:13:07 +01:00
sean-brydonandClaude Opus 4.5 ea76df47d2 feat: add invoice URL to proration and test seed scripts (#27297)
* feat: add invoice URL to proration and test seed scripts

- Add invoiceUrl field to MonthlyProration schema
- Update billing service to return hosted_invoice_url after finalizing
- Save invoice URL when creating proration invoices
- Add seed script for testing proration with real Stripe data
- Add cleanup script for test data removal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* add invoice url

* add invoice URL to tests

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 09:42:57 +00:00
Rajiv Sahal 8319666d76 fix: replace new Date with dayjs (#27306) 2026-01-28 10:46:17 +05:30
emrysal 843314c397 chore: release v6.1.6
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-28 02:40:17 +00:00
Keith WilliamsandDevin AI 3d0663f4af feat: add composite indexes for booking queries at scale (#27315)
* feat: add composite indexes for booking queries at scale

Add new composite indexes to optimize common query patterns for the Booking
and Attendee tables. These indexes are designed to support the system at scale
(14M+ bookings, 50K daily inserts) while minimizing write overhead.

New indexes on Booking table:
- (userId, endTime): Optimizes /bookings/upcoming queries
- (userId, status, startTime): Optimizes busy times and filtered queries
- (eventTypeId, status): Optimizes round-robin and team booking queries
- (userId, createdAt): Optimizes API queries with createdAt sorting

New index on Attendee table:
- (bookingId, email): Optimizes JOIN queries filtering by attendee email

These indexes target the most common query patterns identified in:
- get.handler.ts (bookings list endpoints)
- BookingRepository.ts (busy times, round-robin)
- API v1 bookings endpoint

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add migration file for booking composite indexes

Add SQL migration to create the new composite indexes:
- Attendee(bookingId, email)
- Booking(userId, endTime)
- Booking(userId, status, startTime)
- Booking(eventTypeId, status)
- Booking(userId, createdAt)

Also clean up comments in schema.prisma to be more generic.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: swap Attendee index column order to (email, bookingId)

Per Cubic AI review feedback - place email first to match the filter
column order in queries that filter by email.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-28 02:01:29 +00:00
Alex van AndelandDevin AI c45be81af5 refactor: lazy load KBar data fetching hooks only when opened (#27314)
* refactor: lazy load KBar data fetching hooks only when opened

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* refactor: move KBar data fetching into RenderResults for proper lazy loading

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 21:45:44 -03:00
Alex van Andel 4228f576b1 Revert "fix: cancel download fetch when progress toast is closed (#27151)"
This reverts commit fd476bf7f7.
2026-01-27 17:37:31 -03:00
MorganandDevin AI 23067cd8af fix: await unawaited calendar.events.patch call in updateEvent (#27313)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 20:29:35 +00:00
Keith WilliamsandDevin AI 21500c7047 fix: remove _count children query from EventType and Workflow repositories (#27309)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 15:23:26 -03:00
fd476bf7f7 fix: cancel download fetch when progress toast is closed (#27152)
* fix: cancel download fetch when progress toast is closed

- Create new progress-toast utility using @coss/ui toastManager
- Add ToastProvider to app providers
- Update download components to use AbortController for cancellation
- When cancel button is clicked, abort signal stops the fetch loop

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: track active toasts with Set instead of accessing toastManager.toasts

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add AnchoredToastProvider to app providers

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: extract common CSV download logic into useCsvDownload hook

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: improve progress toast with i18n support and Progress component

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: replace useCsvDownload hook with DownloadButton component

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename DownloadButton to CsvDownloadButton

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up i18n

* fix: properly throw AbortError when download is cancelled

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "fix: properly throw AbortError when download is cancelled"

This reverts commit 3c64b848140271e4dcd2e45dba5302eef9ca562c.

* fix abort controller

* fix layout shift

* better handle error

* fix: address Cubic AI review feedback

- Fix typo 'copmlete' -> 'complete' in download_progress i18n string
- Treat null batch as failure during CSV download to prevent partial exports

Co-Authored-By: unknown <>

* remove redundant try - catch

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 16:46:37 +00:00
7ce1ee5cea feat: add forcedSlowMode rate limit to Team and Organization DELETE endpoints (#27258)
* feat: add forcedSlowMode rate limit to Team and Organization DELETE endpoints

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* test: add NoOpThrottlerGuard to disable rate limiting in tests

- Create NoOpThrottlerGuard class that always allows requests through
- Create withNoThrottler helper function to override CustomThrottlerGuard
- Update teams.controller.e2e-spec.ts to use withNoThrottler
- Update organizations-teams.controller.e2e-spec.ts to use withNoThrottler
- Update organizations-organizations.controller.e2e-spec.ts to use withNoThrottler

This prevents race conditions when tests fire rapidly against rate-limited endpoints.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: use jest.spyOn to mock throttler guard in tests

Changed approach from overrideGuard to jest.spyOn for mocking
CustomThrottlerGuard.handleRequest to always return true. This
properly disables rate limiting in tests for the DELETE endpoints.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-27 17:24:30 +02:00
cal.com 0bcb110d20 chore: add .env.production to git ignore 2026-01-27 17:02:30 +02:00
85f3cd6228 feat: apply Frame component to webhooks settings page (#27291)
* feat: apply Frame component to webhooks settings page

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: include header and description in Frame component

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: wrap each webhook in individual FramePanel

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: implement two-row badge limit with overflow tooltip for webhooks

Co-Authored-By: peer@cal.com <peer@cal.com>

* style: improve spacing between webhook items and header

Co-Authored-By: peer@cal.com <peer@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 14:48:33 +00:00
Alex van Andel cb7960f571 Revert "chore: release v6.1.6"
This reverts commit 2337e56bea.
2026-01-27 10:43:47 -03:00
emrysal 2337e56bea chore: release v6.1.6 2026-01-27 13:28:58 +00:00
Alex van Andel 53a3b0c111 chore: release v6.1.5
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-27 10:08:56 -03:00
01ae6f1b9e fix: Salesforce tokens add token_lifetime (#27264)
* Create `getSalesforceTokenLifetime`

* When connecting salesforce, add token_lifetime

* Migrate token_lifetime and refetch if token expiry doesn't match

* Add tests for Salesforce token lifetime feature

- Add unit tests for getSalesforceTokenLifetime function
- Add integration tests for token lifecycle management in CrmService
- Fix type error in CrmService.ts by extracting refreshToken variable

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: re-trigger CI

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 10:00:48 -03:00
Morgan 13840764fb Revert "chore: use gh auth login with token for commit step in draft-release …" (#27293)
This reverts commit 8848efef4f.
2026-01-27 14:56:59 +02:00
9b1f86a671 fix: lowercase identifier values in routing form editor (#26616)
* fix: lowercase identifier values in routing form editor

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: remove unused @ts-expect-error directives

Co-Authored-By: peer@cal.com <peer@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 17:39:11 +05:30
Peer RichelsenandDevin AI e3c0e11eb1 revert: remove link cloaking restrictions (reverts #26292 and #26528) (#27289)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 12:01:39 +00:00
sean-brydon 1122c116b6 fix sub-teams (#27284) 2026-01-27 10:26:09 +00:00
sean-brydonandClaude Opus 4.5 cb76e8bde0 feat: add proration invoice and reminder email templates (#27246)
* feat: add proration invoice and reminder email templates

Add email templates for monthly proration billing notifications:

- ProrationInvoiceEmail: Sent when invoice is created for additional seats
- ProrationReminderEmail: Sent 7 days later if invoice remains unpaid

Includes:
- React email templates using V2BaseEmailHtml
- BaseEmail classes for rendering
- Billing email service functions
- Translation keys for email content

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use allSettled

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 09:28:27 +00:00
bf39489899 feat: add token refresh lifecycle callbacks to CalProvider (#25203)
Add three new optional callbacks to CalProvider that enable users to react during the access token refresh lifecycle:
- onTokenRefreshStart: Called when token refresh begins
- onTokenRefreshSuccess: Called when token refresh succeeds
- onTokenRefreshError: Called when token refresh fails with error message

These callbacks are invoked in both token refresh locations:
1. Response interceptor (when API returns 498 status)
2. Initial access token validation

The callbacks are properly passed through the component hierarchy:
CalProvider -> BaseCalProvider -> useOAuthFlow hook

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-01-27 14:47:56 +05:30
Benny JooandDevin AI e625308881 fix: Improve the error handling in Stripe collectCard method (#27249)
* fix: improve error handling in Stripe collectCard method

- Add CollectCardFailure error code for better error categorization
- Replace generic error with ErrorWithCode for consistent error handling
- Add error mappings for common Stripe errors (customer not found, invalid API key, rate limit, etc.)
- Include Stripe error message when available for better debugging
- Follow the same pattern used in chargeCard method

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add CollectCardFailure to getHttpStatusCode mapping

This ensures the error returns 400 instead of 500 when collectCard fails.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* docs: add comments explaining ChargeCardFailure vs CollectCardFailure

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: simplify collectCard error handling

Remove complex error mapping logic per code review feedback.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* test: add CollectCardFailure to HTTP status code tests

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-27 06:47:11 +00:00
Dhairyashil Shinde 15dc8f07d8 chore/companion-version-upgrade-102 (#27266) 2026-01-27 07:40:06 +01:00
devin-ai-integration[bot]andali@cal.com c96e40b3d6 fix: replace by_team_admins with by_team_admin in dynamic i18n keys (#27270)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
2026-01-27 05:59:02 +00:00
Beto 46d54b36ce refactor(companion): simplify context menu implementation and improve layout for badge spacing (#27265) 2026-01-26 22:52:38 +00:00
Dhairyashil Shinde 17cc9358d7 feat/add-tooltip-to-assigned-badge (#27262) 2026-01-26 22:43:13 +00:00
Alex van AndelandDevin AI 43d05f4426 fix: disable prefetch on team page event type links to prevent Google rate limits (#27260)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 21:34:50 +00:00
Barath RajandDhairyashil 4f2f0242eb style(ui): improve padding for VerticalTabItem (#27251)
* style(ui): improve padding for VerticalTabItem

* correct fix

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-01-26 21:21:14 +00:00
Eesh MidhaandDhairyashil 72d6fcb371 fix: remove sticky positioning from page headers in pages on scroll (#27242)
* fix: remove sticky positioning from page headers in pages using ShellMain

* correct fix (mostly)

* fix: disable sticky headers on routing forms and members pages

Applied disableSticky={true} to remaining affected pages:
- Routing Forms page
- Organization Members view
- Platform Members view

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-01-26 18:13:34 -03:00
Udit Takkar 3e30a5c3ea chore: hide download booking button (#27255) 2026-01-26 15:18:25 -03:00
7dcc2fe78a feat: add multi-step download app dropdown with platform-specific options (#27211)
Co-authored-by: peer@cal.com <peer@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: pasqualevitiello <pasqualevitiello@gmail.com>
2026-01-26 16:17:32 +00:00
sean-brydon a359f0ba01 feat: organization upgrade flow v3 (#25972)
* wip flow

* add tests

* WIP migrateing view

* push back step

* fix tests and logic for adding new members to existing teams

* few UI fixes

* type fixes

* fix nits

* few UI + re-route fixes

* fix teamId when migrating
2026-01-26 17:03:12 +01:00
Morgan 8848efef4f chore: use gh auth login with token for commit step in draft-release job (#27248) 2026-01-26 11:38:33 -03:00
1e31ac089a fix: use createPortal for FeatureOptInBanner to avoid Intercom widget conflict (#27121)
* fix: use createPortal for FeatureOptInBanner to avoid Intercom widget conflict

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: guard portal rendering against non-browser environments

Add typeof document check before accessing document.body in createPortal
to prevent SSR/test crashes when document is undefined.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 14:07:29 +00:00
Alex van Andel 667e500918 chore: release v6.1.4
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-26 10:57:41 -03:00
Morgan f4ef922e00 chore: use token for commit step in draft-release job (#27244) 2026-01-26 10:36:28 -03:00
ba6a87b699 refactor(companion): split calcom.ts into modular service files (#27206)
* refactor(companion): split calcom.ts into modular service files

Split the monolithic 1692-line calcom.ts file into focused modules:
- auth.ts: Authentication configuration and token management
- bookings.ts: Booking CRUD operations and actions
- conferencing.ts: Conferencing options
- event-types.ts: Event type CRUD operations
- private-links.ts: Private link management for event types
- request.ts: Core HTTP request functionality
- schedules.ts: Schedule CRUD operations
- user.ts: User profile management
- utils.ts: JSON parsing and payload sanitization utilities
- webhooks.ts: Webhook management (global and event type specific)
- index.ts: Re-exports all functions and maintains backward compatibility

This improves code organization, maintainability, and makes it easier
to understand and modify specific functionality.

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix(companion): avoid logging sensitive booking response data

Replace logging of full responseText (which may contain PII like attendee
emails and names) with responseLength for safer debugging.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 19:03:41 +05:30
Benny JooandDevin AI 0774a41119 refactor: move hooks and stores from packages/features to apps/web/modules (#27221)
* refactor: move booking-audit client components from packages/features to apps/web/modules

This is part of the larger effort to move tRPC-dependent UI components from packages/features to apps/web/modules to eliminate circular dependencies.

Changes:
- Move BookingHistory.tsx and BookingHistoryPage.tsx to apps/web/modules/booking-audit/components/
- Update imports in apps/web to use the new location

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: move formbricks client from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: move hooks and stores from packages/features to apps/web/modules

- Move useAppsData hook from packages/features/apps/hooks to apps/web/modules/apps/hooks
- Move onboardingStore from packages/features/ee/organizations/lib to apps/web/modules/ee/organizations/lib
- Move useWelcomeModal hook from packages/features/ee/organizations/hooks to apps/web/modules/ee/organizations/hooks
- Move useAgentsData hook from packages/features/ee/workflows/hooks to apps/web/modules/ee/workflows/hooks
- Update all import paths in consuming files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: move onboardingStore test file to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 13:11:14 +00:00
Peer RichelsenandDevin AI d93306e32c feat: rename Automation category to AI & Automation (#27237)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 13:04:42 +00:00
Benny JooandDevin AI 7b8272ea20 refactor: move auth components and hooks from packages/features to apps/web/modules (#27223)
* refactor: move auth components and hooks from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add vitest import to Turnstile mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 09:58:57 -03:00
Rajiv Sahal 9a927206bd feat: atoms enhancements (#27224) 2026-01-26 13:28:35 +01:00
sean-brydon 0171b5a08c fix: use batchTriggerAndWait (#27234) 2026-01-26 12:20:37 +00:00
Benny JooandDevin AI 15268bcfb4 refactor: move timezone-select, settings, and insights components from packages/features to apps/web/modules (#27227)
* refactor: move timezone-select, settings, and insights components from packages/features to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix

* wip

* wip

* wip

* wip

* wip

* wip

* wip

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 12:05:18 +00:00
Carina WollendorferandCarinaWolli 216e871b22 fix: improve empty screen for call history (#27231)
* Improve empty screen

* fix type error

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-01-26 10:09:22 +00:00
Lauris SkraucisandDevin AI f5d79a1470 refactor: remove New OAuth client button from admin page (#27181)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 09:34:58 +01:00
Benny JooandDevin AI 6a532c2271 fix: return 400 instead of 500 for invalid email in iCal generation (#27217)
* fix: return 400 instead of 500 for invalid email in iCal generation

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* test: add unit tests for error handling in generateIcsString

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-25 15:02:30 +00:00
Volnei Munhoz 6e1070be31 perf: make nested packages independent for better type-check performance (#27219) 2026-01-25 19:07:46 +05:30
8725733f2c feat(companion): add app store rating prompts for iOS and Android (#27210)
* feat(companion): add app store rating prompts for iOS and Android

- Add useAppStoreRating hook with generalized requestRating(trigger) function
- Add RatingTrigger const for extensible trigger types (EVENT_TYPE_SAVED, BOOKING_CONFIRMED, BOOKING_REJECTED)
- Integrate rating prompt into useCreateEventType and useUpdateEventType hooks
- Integrate rating prompt into useConfirmBooking and useDeclineBooking hooks
- Add expo-store-review package dependency
- Rating prompts only show once per trigger type (tracked via AsyncStorage)

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix(companion): correct expo-store-review version to 9.0.10

Co-Authored-By: peer@cal.com <peer@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-25 09:09:35 -03:00
Joe Au-Yeung b02af9ae53 Update config with new id (#27197) 2026-01-23 21:06:12 -03:00
Joe Au-Yeung 3355fab4fb feat: display assignment reason in organizer emails and booking single view (#27192) 2026-01-23 20:50:07 -03:00
d9658a5a27 fix: skip Select Account step if only one account is available (#23432)
* fix: skip Select Account step if only one account is available

* chore

* chore

* chore

* test fixes

* chore

* refactor: address biome linting issues and decompose getServerSideProps

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2026-01-23 22:51:04 +00:00
a40c3eebd6 feat: group same booking reports together (#26529)
Co-authored-by: unknown <>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 16:31:56 +00:00
sean-brydon 09194c58e1 fix: onboarding - team invites (#27113) 2026-01-23 16:31:35 +00:00
Peer RichelsenandDevin AI 02824b17c3 fix: update API key modal text and reorder developer settings sidebar (#27194)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 16:24:09 +00:00
Udit Takkar 53545bdfb7 fix: type err (#27196) 2026-01-23 14:51:09 +00:00
0ad4367005 feat: Custom host location (#25916)
* chore: save progress

* chore:

* feat: add input dialog

* fix: type error

* feat: mass apply dialog

* test: per host location

* test: fix test

* fix: address Cubic AI review feedback (confidence >= 9/10)

- Remove PII (address, phone number) from tracing logs in RegularBookingService.ts
- Constrain HostLocation.type to EventLocationType["type"] for compile-time validation

Co-Authored-By: unknown <>

* fix: translation

* refactor: improvements

* fix: correct grammar in custom host locations tooltip

Change 'custom host locations is enabled' to 'custom host locations are enabled' (plural subject requires plural verb).

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* refactor: improvements

* fix: auth

* fix: check

* refactor: improvements

* fix: address Cubic AI review feedback (confidence >= 9/10)

- Add scheduleId to newly created hosts in update.handler.ts to persist
  host-specific schedules during create operations
- Change host location deletion filter from !host.location to
  host.location === null to only delete when explicitly set to null
- Fix static-link per-host locations to use actual link instead of type
  in locationBodyString for bookingLocationService.ts

Co-Authored-By: unknown <>

* fix: preserve existing host scheduleId when not explicitly provided

Change scheduleId handling for existing hosts from 'host.scheduleId ?? null'
to 'host.scheduleId === undefined ? undefined : host.scheduleId' so that
when the client doesn't provide a scheduleId, the existing value is preserved
instead of being cleared to null.

Co-Authored-By: unknown <>

* fix; type erro

* fix; type erro

* fix; type erro

* refactor: move repository

* refactor: move repository

* fix: add singular/plural translations for location_applied_to_hosts

Addresses Cubic AI review feedback (confidence 9/10) to fix '1 hosts' rendering as '1 host' by using i18next plural format with _one and _other suffixes.

Co-Authored-By: unknown <>

* refactor: feedback

* fix: type err

* fix: use uuid in schema and remove attendee locaiton

* fix: type err

* fix: type err

* fix: validate eventTypeId as integer in massApplyHostLocation schema

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 11:18:43 -03:00
Morgan b9b7e50f5a refactor: platform billing jobs tasks constants (#27190) 2026-01-23 12:54:05 +00:00
Syed Ali Shahbaz 4115eaacbd chore: Add initial webhook wiring (TRPC handlers) to the new architecture (#27170)
* --init

* clean up

* unnecessary comment

* remove comment

* fix factory resolver

* Add active filter to webhook query
2026-01-23 16:50:34 +04:00
Anik Dhabal Babu 646d18e286 fix: use Cal.com video URL (#27184) 2026-01-23 11:42:08 +00:00
25fa46fd34 fix(coss-ui): convert /settings/my-account/general to coss-ui (#26053)
* fix(coss-ui): convert /settings/my-account/general to coss-ui

* update guide

* fix: add menuPosition fixed to TimezoneSelect in TravelScheduleModal

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use menuPortalTarget to render TimezoneSelect dropdown above dialog footer

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use Object.assign for type-safe styles in TimezoneSelect

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* revert comment

* fix: guard document access for SSR in TravelScheduleModal

Addresses Cubic AI review feedback: menuPortalTarget={document.body} will
throw during server rendering where document is undefined. Added typeof
check to guard against SSR.

Co-Authored-By: unknown <>

* change dialog backdrop from blur to dim

* fix: add menuPlacement auto to open dropdown upward on mobile

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use menuPlacement top on mobile for TimezoneSelect dropdown

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: make timezone button stack vertically on mobile to prevent overflow

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: make timezone select and button 50/50 width on larger viewports

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix date range picker issue on mobile

* prevent travel schedule dialog dismissal with date picker

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 11:19:00 +00:00
Eunjae LeeandDevin AI 052e99f7ba feat: allow normal users to see userId filter with only themselves as option (#26835)
* feat: allow normal users to see userId filter with only themselves as option

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: return empty map when canReadOthersBookings is false and currentUser doesn't exist

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use generic type parameter for Table to fix type compatibility

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* perf: disable listSimpleMembers query when canReadOthersBookings is false

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 16:05:55 +05:30
6216b58460 fix: add type property to @ApiQuery decorators in slots controller (#27175)
* fix: add type property to @ApiQuery decorators in slots controller

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: update openapi.json

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 11:28:09 +02:00
c150828988 feat: add scheduled trigger.dev task for monthly proration (#26991)
* feat: add seat tracking infrastructure for monthly proration

Add seat change logging infrastructure with operationId for idempotency.
This PR adds the foundation for monthly proration billing by tracking
seat additions and removals, gated behind the monthly-proration feature flag.

- Add operationId field to SeatChangeLog for idempotency
- Update SeatChangeLogRepository to support upsert with operationId
- Add feature flag guard in SeatChangeTrackingService
- Integrate seat tracking in team member invites
- Integrate seat tracking in bulk user deletions
- Integrate seat tracking in team service operations
- Integrate seat tracking in DSYNC user creation

When monthly-proration feature flag is disabled, seat logging is skipped
and behavior remains unchanged.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add monthly proration processing

Add monthly proration billing processing that works on top of the seat
tracking infrastructure. This PR implements the core proration logic,
webhook handlers, and integration with Stripe billing.

- Enhance MonthlyProrationService to process seat change logs
- Add payment webhook handlers (invoice.payment_succeeded, invoice.payment_failed)
- Update subscription webhook to sync billing period on renewals
- Update TeamBillingService to skip real-time updates when proration enabled
- Enhance StripeBillingService with proration capabilities
- Add Tasker enhancements for processing queues
- Update team creation/upgrade routes

Depends on: feat/monthly-proration-seat-tracking

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: remove unused logger from SeatChangeTrackingService

* fix: description for calculation

* fix null check on trial

* feat: add scheduled trigger.dev task for monthly proration

* feat: add custom month key support and use batchTrigger

* feat: add isValidMonthKey and return result from batch task

* fix merge artifact

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 09:17:21 +00:00
Anik Dhabal Babu 01a8f53ce7 test: few flaky e2e tests (#27171) 2026-01-23 06:08:34 -03:00
Rajiv Sahal b6b43c3318 fix: BookerEmbed breaking (#27143) 2026-01-23 06:02:50 -03:00
Hariom BalharaandDevin AI 7ff54b4a27 feat: add graceful error handling for audit log enrichment (#27142)
* feat: add graceful error handling for audit log enrichment

- Add hasError field to EnrichedAuditLog type
- Create buildFallbackAuditLog() method for failed enrichments
- Wrap enrichAuditLog() in try-catch to handle errors gracefully
- Add booking_audit_action.error_processing translation key
- Update BookingHistory.tsx to show warning icon for error logs
- Hide 'Show details' button for logs with hasError
- Add comprehensive test cases for error handling scenarios

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: include actionType in error_processing translation and allow expanded content for error logs

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 13:33:50 +05:30
Hariom Balhara 95f7f03f0e chore: Integrate round-robin reassignment booking audit (#26586)
## What does this PR do?

Implements booking audit logging for round-robin reassignment events (both manual and automatic). This is part of the booking audit integration plan (PR 7).

Changes:
- Added audit logging to `roundRobinManualReassignment.ts` for manual host reassignments
- Added audit logging to `roundRobinReassignment.ts` for automatic round-robin reassignments
- Updated tRPC handlers to pass `actionSource: "WEBAPP"` and `reassignedByUuid`
- Updated API v2 bookings service to pass `actionSource: "API_V2"` and `reassignedByUuid`
- Updated `ReassignmentAuditActionService.ts` with proper field schemas and translation keys

The audit logging uses `BookingEventHandlerService.onReassignment()` with proper actor identification and action source tracking.

## Updates since last revision

Addressed review feedback:
- Renamed `title` field to `hostName` for semantic clarity (tracks host name changes, not booking titles)
- Fixed `assignedById` schema: changed from `NumberChangeSchema` to `z.number()` (no old/new pattern needed - it's always the user who performed the reassignment)
- Fixed `reassignmentReason` schema: changed from `StringChangeSchema` to `z.string().nullable()` (no old/new pattern needed)
- Added `ValidActionSource` type that excludes `UNKNOWN` - clients must pass explicit action sources
- Made `actionSource` required in both reassignment functions (no longer optional)
- Added integration tests for `ReassignmentAuditActionService` (15 tests covering all methods)
- Updated `roundRobinManualReassign.handler.ts` to pass required `actionSource` and `reassignedByUuid` params

**Latest fixes:**
- Fixed `hasAttendeeUpdated` check in `ReassignmentAuditActionService.ts`: changed from `!== null` to `!= null` to properly handle undefined values
- Updated test expectations in `ReassignmentAuditActionService.test.ts` to match the new display JSON field names (`hostAttendeeUserUuidNew`/`hostAttendeeUserUuidOld` instead of `newAssignedRRHostUuid`/`previousAssignedRRHostUuid`)
- Fixed async `getDisplayFields` tests to properly await the Promise and include the `previous_assignee` field
- Fixed `hasAttendeeUpdated` to check for `hostAttendeeUpdated` object presence instead of optional `id` field - host changes with only `withUserUuid` populated were being ignored (identified by Cubic AI, confidence 9/10)
- Fixed test expectation in `getDisplayJson` test: removed incorrect null expectations for `hostAttendeeIdUpdated`, `hostAttendeeUserUuidNew`, `hostAttendeeUserUuidOld` - the implementation uses conditional spreading to omit these fields when `hostAttendeeUpdated` is not present, rather than setting them to null

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Trigger a manual round-robin reassignment via the webapp and verify audit logs are created with `actionSource: "WEBAPP"`
2. Trigger an automatic round-robin reassignment and verify audit logs are created
3. Use API v2 to reassign a booking and verify audit logs are created with `actionSource: "API_V2"`
4. Verify the audit data contains correct values for `organizerUuid`, `hostAttendeeUpdated`, `reassignmentReason`, and `reassignmentType`

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

## Human Review Checklist


- [x] Verify the `hasAttendeeUpdated` fix is correct: now checks `fields.hostAttendeeUpdated != null` to detect any host attendee update regardless of whether `id` is populated
- [x] Verify `getDisplayJson` test fix: fields are correctly omitted (not set to null) when `hostAttendeeUpdated` is not present, matching the conditional spreading implementation
- [ ] Verify all callers of reassignment functions pass required `actionSource` and `reassignedByUuid`
- [ ] Confirm `getDisplayFields` is properly awaited in all call sites (it's now async)
- [ ] Check that `ValidActionSource` type properly excludes `UNKNOWN` for client-side validation

## Important Notes for Reviewer

1. **Dependency on base PR**: The translation key changes use the format from base PR (#26046). This PR should be merged after the base PR.

2. **Schema changes**: The `organizerUuid` and `hostAttendeeUpdated` fields track both organizer changes and round-robin host attendee changes separately for complete audit trail.

---


Link to Devin run: https://app.devin.ai/sessions/e4353e2ec6ea4a51ab33313bdc630aba
Requested by: @hariombalhara
2026-01-23 08:13:22 +05:30
Bodhi Russell Silberling 45c9f19b70 fix: correct typos in comments and variable names (#27164)
- Fix 'recieve' -> 'receive' in booking scenario test comment
- Fix 'occured' -> 'occurred' in routing playground HTML
- Fix 'childrenSeperated' -> 'childrenSeparated' in Breadcrumb component
2026-01-23 00:18:26 +00:00
973d83aa57 refactor: move organization members page from /settings/organizations/members to /members (#27053)
* refactor: move organization members page from /settings/organizations/members to /members

- Create new /members route under main-nav with same functionality
- Add permanent redirect from /settings/organizations/members to /members
- Include loading skeleton and server actions for the new route

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: Deduplicate organization members page logic (#27168)

* refactor(web): extract shared org members data fetching logic

- Extract data fetching, coaching, and permission logic into [getOrgMembersPageData.ts](cci:7://file:///Users/dhairyashilshinde/work/cal.com/apps/web/modules/members/getOrgMembersPageData.ts:0:0-0:0)
- Deduplicate logic between [/members](cci:7://file:///Users/dhairyashilshinde/work/cal.com/apps/web/app/%28use-page-wrapper%29/%28main-nav%29/members:0:0-0:0) and  pages
- Reduce page component size and improve maintainability

* safe guard for org id null

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2026-01-22 22:43:34 +00:00
8d038f6bd6 feat: add all event-types and upcoming bookings to KBar (#26507)
Co-authored-by: peer@cal.com <peer@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 21:25:31 +00:00
Dhairyashil Shinde ef26423d56 chore/upgrade-companion-version-1 (#27167) 2026-01-22 20:45:04 +00:00
James P 86875bcc59 docs: add Unkey rate limiting setup documentation (#27163)
- Update .env.example with clarified Unkey configuration comments
- Update README.md with explainer of Unkey and how it's optional.
2026-01-22 16:31:40 -03:00
Ram ShuklaandPallav 0e900a7372 fix: Upgradetip text overlapping fixed (#27118)
* fixed text issue

* matched style of api keys page

* made changes to the upgradetip

* made changes to the upgradetip

* made changes to the upgradetip

* Refactor TextField component properties

---------

Co-authored-by: Pallav <90088723+pallava-joshi@users.noreply.github.com>
2026-01-22 19:14:39 +00:00
Syed Ali Shahbaz 857b3da875 chore: Webhook Scaffolding cleanup (#27159)
* quick cleanup

* more fixes
2026-01-22 16:11:10 -03:00
Pedro Castro 2542e1e5c4 chore: pin tar to 7.5.4 (#27161) 2026-01-22 16:01:03 -03:00
1c09413ef4 docs: add guidance for creating smaller, self-contained PRs (#27155)
* docs: add guidance for creating smaller, self-contained PRs

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: remove PR size check from cubic-devin-review.yml per review feedback

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* docs: clarify PR size limits apply to code files only

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 15:06:11 -03:00
Pedro Castro a0ff6b15f8 chore: update lodash to 4.17.23 (#27157)
Fixes prototype pollution in _.unset and _.omit
2026-01-22 17:58:26 +00:00
Keith Williams 1736c9df3c perf: Add teamId index on Credential (#27153) 2026-01-22 14:29:01 -03:00
6f7c8bdd73 feat: add wrong assignment report dialog and webhook for routing form bookings (#25839)
Co-authored-by: peer@cal.com <peer@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 16:44:29 +00:00
89ae748681 feat: Add download CSV button on bookings page (#27107)
* Add download CSV button on bookings page

* fix: localize CSV headers and filename using i18n

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: prevent infinite loop when batch returns empty bookings during CSV download

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: alex@cal.com <me@alexvanandel.com>
2026-01-22 16:31:17 +00:00
Keith WilliamsandDevin AI aaabcf4430 perf: optimize getEventTypeIdsFromTeamIdsFilter with raw SQL query (#27145)
* perf: optimize getEventTypeIdsFromTeamIdsFilter with raw SQL query

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: use prisma singleton for raw queries to fix runtime error

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: use context prisma for raw queries and update test mocks

- Changed getEventTypeIdsFromTeamIdsFilter to use the context-passed prisma parameter instead of importing the singleton
- Added $queryRaw mock to test file to support raw SQL queries
- Updated test assertion to check for $queryRaw call instead of eventType.findMany

The context prisma IS the same singleton at runtime (passed via tRPC context in createContext.ts). The test was failing because the mock didn't include $queryRaw.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Removed extra subquery where not needed

* fix: restore subquery optimization for better query performance

Restores the subquery structure that allows PostgreSQL to use the composite
index on EventType(parentId, teamId) efficiently via Nested Loop joins,
resulting in ~66x faster execution (2.46ms vs 164ms in production benchmarks).

Identified by Cubic AI (confidence 9/10).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Fighting with AI

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 13:26:49 -03:00
Alex van Andel 7efd9a43c9 chore: drop deprecated user.startTime and user.endTime columns (#27146)
## What does this PR do?

Follow-up to #27085 and #27092 - creates the database migration to drop the deprecated `startTime` and `endTime` columns from the `users` table.

These columns were marked as `// DEPRECATED - TO BE REMOVED` in the Prisma schema. The prerequisite PRs removed all code references to these columns, making it safe to now drop them from the database.

**Changes:**
- Remove `startTime` and `endTime` fields from the `User` model in `schema.prisma`
- Add migration to drop both columns from the `users` table
- Remove `startTime` and `endTime` from test builder (`packages/lib/test/builder.ts`)

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - internal schema cleanup
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. N/A - schema migration only, existing tests should continue to pass

## How should this be tested?

1. Verify PRs #27085 and #27092 have been merged (prerequisite)
2. Run `yarn prisma generate` - should complete without errors
3. Run `yarn type-check:ci --force` - should pass (no code references these columns anymore)
4. Apply migration to a test database and verify columns are dropped

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

## Human Review Checklist

- [ ] Confirm PRs #27085 and #27092 are merged before merging this PR
- [ ] Verify no remaining code references to `user.startTime` or `user.endTime` in the codebase
- [ ] ⚠️ **Breaking change**: This permanently drops data from the `users` table. Ensure no external systems depend on these columns.

---

Link to Devin run: https://app.devin.ai/sessions/c5a10684d905496fbce66a0b464a73a5
Requested by: @emrysal
2026-01-22 12:52:36 -03:00
51976b1eab feat: add rrHostSubsetIds to reschedule booking endpoint (#27135)
* feat: add rrHostSubsetIds to reschedule booking endpoint

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: add e2e test for reschedule with rrHostSubsetIds

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: update openapi.json

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 17:44:26 +02:00
Volnei Munhoz e056274983 chore: improve biome checking (#27140) 2026-01-22 15:34:27 +00:00
aa8804e498 feat(flags): add @Memoize and @Unmemoize decorators for declarative caching (#27063)
* feat(flags): add @Memoize and @Unmemoize decorators for declarative caching

- Add @Memoize decorator for caching method results with Zod validation
- Add @Unmemoize decorator for cache invalidation on mutations
- Create UserFeatureRepository using decorators as example implementation
- Add comprehensive tests with 80%+ coverage (19 tests)
- Add DI module and tokens for UserFeatureRepository
- Enable experimentalDecorators in packages/features/tsconfig.json

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(cache): use lazy Redis lookup in decorators

- Decorators now access Redis via getRedisService() instead of this.redis
- UserFeatureRepository no longer has redis property or direct redis calls
- findByUserIdAndFeatureIds now uses decorated findByUserIdAndFeatureId
- DI module simplified to only pass prisma dependency
- Tests updated to call setRedisService() in beforeEach

This ensures the repository only knows about Prisma, with all caching
handled transparently by the decorators.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(flags): add FeatureRepository and TeamFeatureRepository with decorator-based caching

- Add FeatureRepository with @Memoize decorators for findAll, findBySlug, getFeatureFlagMap
- Add TeamFeatureRepository with @Memoize/@Unmemoize decorators for all CRUD operations
- Add comprehensive Zod schemas for Feature, TeamFeatures, and AppFlags validation
- Add DI modules and tokens for both repositories
- Add comprehensive test coverage (33 tests) for both repositories
- Maintain backward compatibility with existing FEATURES_REPOSITORY tokens

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(cache): use DI container pattern for Redis service

- Create packages/features/di/containers/Redis.ts with getRedisService()
- Update Memoize and Unmemoize decorators to import from DI container
- Remove setRedisService() and IRedisService from types.ts exports
- Update all tests to mock the container's getRedisService
- Fix import ordering issues from biome

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(cache): remove barrel import and add root-level cache export

- Remove packages/features/cache/decorators/index.ts barrel file
- Add packages/features/cache/index.ts as root-level export for cache feature
- Update repository imports to use direct imports from source files
- Follows the pattern: avoid barrel imports at nested levels, keep at feature root

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(flags): minimize repository methods and address PR feedback

- Remove unnecessary methods from FeatureRepository, TeamFeatureRepository, and UserFeatureRepository
- Keep only methods needed by FeatureOptInService
- Update imports to use @calcom/features/cache public API instead of relative paths
- Handle redis.del() errors gracefully in Unmemoize decorator
- Update tests to match simplified repositories

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(cache): use Promise.allSettled for cache invalidation

Cleaner approach than Promise.all with individual .catch() handlers

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(flags): add setAutoOptIn methods and replace featuresRepository usage in _router.ts

- Add setAutoOptIn method to TeamFeatureRepository with @Unmemoize decorator
- Add setAutoOptIn method to UserFeatureRepository with @Unmemoize decorator
- Replace featuresRepository usage in featureOptIn/_router.ts with new repositories
- TeamFeatureRepository.setAutoOptIn unmemoizes KEY.autoOptInByTeamId(teamId)
- UserFeatureRepository.setAutoOptIn unmemoizes KEY.autoOptInByUserId(userId)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(flags): use DI containers for TeamFeatureRepository and UserFeatureRepository

- Create TeamFeatureRepository.ts container with getTeamFeatureRepository()
- Create UserFeatureRepository.ts container with getUserFeatureRepository()
- Update _router.ts to use DI containers instead of direct instantiation

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(feature-opt-in): use DI containers for FeatureOptInService dependencies

- Update FeatureOptInService to use IFeatureOptInServiceDeps with 3 repositories
- Add helper functions teamFeatureToState() and userFeatureToState()
- Update DI module to use depsMap pattern with featureRepo, teamFeatureRepo, userFeatureRepo
- Create FeatureRepository container file
- Replace all FeaturesRepository method calls with new repository methods

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* test(feature-opt-in): update FeatureOptInService tests for new IFeatureOptInServiceDeps interface

- Update mock structure to use featureRepo, teamFeatureRepo, userFeatureRepo
- Add helper functions createMockTeamFeature and createMockUserFeature
- Update all test cases to use new repository method names
- Add explicit types to satisfy biome lint rules

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(flags): use DTOs at repository boundaries to prevent Prisma type leakage

- Create FeatureDto, TeamFeaturesDto, UserFeaturesDto in packages/lib/dto/
- Update repository interfaces to return DTOs instead of Prisma types
- Add toDto() transformation methods in repository implementations
- Update FeatureOptInService to use DTOs instead of Prisma types
- Follow data-dto-boundaries.md guidelines for architectural boundaries

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix(flags): update TeamFeatureRepository tests to match DTO structure

Remove assignedAt from test mock data since TeamFeaturesDto only includes:
teamId, featureId, enabled, assignedBy, and updatedAt

Co-Authored-By: unknown <>

* fix(cache): make Redis failures non-blocking in @Memoize decorator

Wrap Redis get and set operations in try-catch blocks to ensure
Redis failures don't break the application flow. If cache read fails,
proceed to fetch from source. If cache write fails, silently ignore
and return the result.

Co-Authored-By: unknown <>

* fix(cache): add logging for Redis failures and remove barrel import

- Add warning logs for Redis failures in @Memoize and @Unmemoize decorators
- Remove packages/lib/dto/index.ts barrel import file
- Update all imports to use direct file paths instead of barrel imports

Co-Authored-By: unknown <>

* fix(cache): sanitize log messages to avoid exposing sensitive data

- Remove cacheKey from log messages (may contain PII like user/team IDs)
- Log only error.message instead of raw error objects
- Addresses Cubic AI feedback (confidence 9/10)

Co-Authored-By: unknown <>

* sanitize log

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-22 16:26:27 +01:00
Keith WilliamsandDevin AI a2a4ca41ec test: add e2e tests for team filter in bookings list (#27144)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 12:12:02 -03:00
Anik Dhabal Babu dc4404f88c fix: ensure verification token has team before processing (#27139)
* ensure verification token has team before processing

* fix
2026-01-22 14:59:53 +00:00
Alex van AndelandDevin AI a823bd84a1 refactor: remove remaining user.startTime and user.endTime usages (#27092)
Follow-up to #27085 - removes the remaining code references to the
deprecated user.startTime and user.endTime columns that were missed
in the initial PR.

Changes:
- Remove startTime/endTime from availabilityUserSelect in prisma selects
- Remove startTime/endTime from GetUserAvailabilityInitialData type
- Remove startTime/endTime from defaultEvents user mock object

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 11:29:41 -03:00
Alex van Andel c5fbafd9fb Revert "feat: redesign team creation flow to match onboarding-v2 design (#26733)"
This reverts commit 37847c0061.
2026-01-22 11:15:43 -03:00
5e8fd13d1f fix: update Learn more button URL on routing forms page to cal.com/routing (#27068)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: susan@cal.com <susan@cal.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-01-22 13:26:32 +00:00
5dc5faf01f fix: update Learn More button link on teams page to cal.com/teams (#27065)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: susan@cal.com <susan@cal.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-01-22 13:16:58 +00:00
Syed Ali Shahbaz c4c62369e5 chore: Infrastructure scaffolding for Webhook's Producer/Consumer approach before wiring (#25954)
* --INIT

* fixes

* better comments and some clean up

* test and type fix

* clean up

* address feedback

* fix erroneous booking_confirmed to booking_rescheduled
2026-01-22 18:33:34 +05:30
Dhairyashil Shinde a63bf11c3f refactor: companion event type query parameters (#27125)
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-22 09:00:23 -03:00
Alex van Andel 509ceeaa86 chore: release v6.1.3 2026-01-22 08:56:41 -03:00
3af533e2c8 feat: add monthly proration processing (#27002)
* feat: add seat tracking infrastructure for monthly proration

Add seat change logging infrastructure with operationId for idempotency.
This PR adds the foundation for monthly proration billing by tracking
seat additions and removals, gated behind the monthly-proration feature flag.

- Add operationId field to SeatChangeLog for idempotency
- Update SeatChangeLogRepository to support upsert with operationId
- Add feature flag guard in SeatChangeTrackingService
- Integrate seat tracking in team member invites
- Integrate seat tracking in bulk user deletions
- Integrate seat tracking in team service operations
- Integrate seat tracking in DSYNC user creation

When monthly-proration feature flag is disabled, seat logging is skipped
and behavior remains unchanged.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add monthly proration processing

Add monthly proration billing processing that works on top of the seat
tracking infrastructure. This PR implements the core proration logic,
webhook handlers, and integration with Stripe billing.

- Enhance MonthlyProrationService to process seat change logs
- Add payment webhook handlers (invoice.payment_succeeded, invoice.payment_failed)
- Update subscription webhook to sync billing period on renewals
- Update TeamBillingService to skip real-time updates when proration enabled
- Enhance StripeBillingService with proration capabilities
- Add Tasker enhancements for processing queues
- Update team creation/upgrade routes

Depends on: feat/monthly-proration-seat-tracking

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: remove unused logger from SeatChangeTrackingService

* fix: description for calculation

* fix null check on trial

* chore: no more prisma calls

* add feature flag check

* fix stub

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 11:23:38 +00:00
f9d40e083f feat: store utm tags in stripe on signup (#26838)
* feat: store utm params in stripe on signup

* fix: fallback to cookie when query params don't contain valid UTM data

Changed from else-if to separate if statement so that when query
params exist but don't contain valid UTM data, the cookie fallback
is still tried. Previously, any request with non-UTM query params
would skip the stored cookie data entirely.

Co-Authored-By: unknown <>

* fix: e2e

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 08:13:47 -03:00
Eunjae Lee 087fa03513 test: add e2e test for Feature Opt-In banner (#27100)
## What does this PR do?

Adds an end-to-end test for the Feature Opt-In banner flow. This test verifies the complete user journey from seeing the banner to enabling a feature.

Currently `OPT_IN_FEATURES` in `packages/features/feature-opt-in/config.ts` is empty, so this e2e test skips. Once we uncomment the `bookings-v3` item from the config, this e2e test will run and pass. This is a preparation for when we enable the feature.

**Changes:**
- Creates a new e2e test file (`feature-opt-in-banner.e2e.ts`) that tests the complete opt-in flow
- Adds `data-testid` attributes to banner and dialog components for reliable test selectors

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - test only.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Add the `ready-for-e2e` label to run e2e tests in CI
2. The test should pass when run with `PLAYWRIGHT_HEADLESS=1 yarn e2e feature-opt-in-banner.e2e.ts`

**Test requirements:**
- The `bookings-v3` feature flag must exist in the Features table (the test uses `prisma.feature.upsert` to ensure this)
- The test will skip if `bookings-v3` is not in `OPT_IN_FEATURES`

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings

## Updates since last revision

- Replaced text-based locators (`getByText`, `getByRole`) with `data-testid` selectors for more reliable element targeting
- Added `data-testid` attributes to `FeatureOptInBanner`, `FeatureOptInConfirmDialog`, and `FeatureOptInSuccessDialog` components

## Human Review Checklist

- [ ] Verify the `data-testid` attributes don't conflict with existing test IDs in the codebase
- [ ] Confirm the test correctly skips when `bookings-v3` is not in `OPT_IN_FEATURES`
- [ ] Check that the added `data-testid` attributes follow the project's naming conventions

---
Link to Devin run: https://app.devin.ai/sessions/97158ab1b7414e3988ba803b30d95b3e
Requested by: @eunjae-lee
2026-01-22 12:09:13 +01:00
Lachlan HarrisandAnik Dhabal Babu f00568e798 fix(umami): add default SCRIPT_URL in zod.ts (#27114)
* fix(umami): add default SCRIPT_URL in zod.ts

* fix(umami): update default URLs to cloud.umami.is

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-22 10:53:25 +00:00
45ea59ceb8 fix: prevent CalDAV duplicate invitations with RFC-compliant SCHEDULE-AGENT (#22434)
* fix: prevent CalDAV duplicate invitations with RFC-compliant SCHEDULE-AGENT

Fixes #9485

Adds SCHEDULE-AGENT=CLIENT to ATTENDEE lines in CalDAV createEvent and
updateEvent operations per RFC 6638 Section 7.1. This tells CalDAV servers
(Fastmail, NextCloud, etc.) that the client handles scheduling, preventing
duplicate invitation emails.

Implementation includes:
- RFC 5545 compliant line folding (max 75 octets per line)
- UTF-8 aware byte counting for international names
- Proper handling of :mailto: format in ATTENDEE lines
- Skips lines that already have SCHEDULE-AGENT parameter

* fix: address Cubic review - unfold lines and case-insensitive matching

- Add unfoldLines() to handle RFC 5545 folded lines before processing
- Use case-insensitive regex (gim flag) per RFC 5545 spec
- Simplify regex to properly capture params and value separately

* fix: only unfold/refold ATTENDEE lines, preserve other lines

- Match ATTENDEE lines including folded continuations
- Unfold only the matched ATTENDEE line
- Re-fold after adding SCHEDULE-AGENT=CLIENT
- Other iCal lines remain untouched (no RFC 5545 violation)

* fix: check SCHEDULE-AGENT only in params, not value

Only check for existing SCHEDULE-AGENT in the params portion,
not the value (which contains email/CN). This prevents false
positives when email contains "schedule-agent" substring.

* fix: handle quoted colons and exact SCHEDULE-AGENT matching

1. Colon parsing: Match :mailto:/:http:/:urn: patterns, or fallback
   to finding colon not inside quotes
2. SCHEDULE-AGENT check: Use regex to match exact parameter name
   (preceded by ; or at start), not substring match

* add tests

* Update .env.example

---------

Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-22 16:23:06 +05:30
Ram Shukla be13bdf18e fix: Matched styling of Webhooks just like api keys page. (#27116)
* fixed text issue

* fixed text issue

* matched style of api keys page
2026-01-22 10:27:20 +00:00
Keith WilliamsandDevin AI ee076d7102 perf: add composite index on EventType(parentId, teamId) (#27099)
* perf: add composite index on EventType(parentId, teamId)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 06:43:05 -03:00
devin-ai-integration[bot]andali@cal.com 2a98693dcd feat: add assigned badge to team event types (#27036)
* feat: add assigned badge to team event types

Add an 'Assigned' badge to Round Robin and Collective event types
when the current user is a host/participant of the event type.
This provides visibility to users without edit permissions that
they are included in the rotation.

Changes:
- Add isCurrentUserHost flag in getEventTypesFromGroup handler
- Display blue 'Assigned' badge in event types listing view
- Add i18n translation for 'assigned' text

Co-Authored-By: ali@cal.com <ali@cal.com>

* refactor: remove redundant isTeamEvent check for assigned badge

Co-Authored-By: ali@cal.com <ali@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
2026-01-22 10:16:22 +01:00
Lauris Skraucis 3b8b2299af docs: OAuth self serve (#27090) 2026-01-22 12:36:57 +04:00
Anshumancanrock 856deaaead fix: workflows action delete icon hover color (#27106) 2026-01-22 08:21:33 +00:00
Anik Dhabal Babu a934bc5dc2 fix: clic app icon is not showing (#27101) 2026-01-22 13:22:55 +05:30
Eesh Midha 38cdf3b23f fix: disable booking actions for cancelled/rejected/past bookings (#26926)
* fix: disable booking actions for cancelled/rejected/past bookings

* test: add tests for bookign actions disabled states
2026-01-21 20:22:47 +00:00
Volnei Munhoz f7f4df6922 Fix nav tab-stick position (#27097) 2026-01-21 16:37:25 -03:00
8c39210a12 fix: scroll issues in Embed (#26583)
* chore: add new view for two step slot selection for embed

* fix: make sure two step slot selection is false by default

* chore: update embed playground to showcase two step slot selection

* chore: add tests

* chore: update embed snippet generator code to include two step slot selection

* chore: update docs

* fix: back button styling

* chore: implement feedback from cubic

* fix: add missing isEnableTwoStepSlotSelectionVisible properties to test mock store

Co-Authored-By: unknown <>

* chore: implement PR feedback

* chore: update slot selection modal

* chore: add prop to hide available times header

* fix: scope two-step slot selection visibility to mobile only

Restores the isMobile check in the timeslot visibility guard to ensure
desktop embeds continue to show the booking UI when two-step slot
selection is enabled. The feature should only hide the timeslot list
on mobile devices.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* fixup: use translations for loading instead of actual word

* fix: type check

* fix: add window.matchMedia mock for jsdom test environment

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: add window.matchMedia mock to packages/testing/src/setupVitest.ts

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: unit tests failing

* add a width style to the two-step slot selection embed container.

* refactor: rename enableTwoStepSlotSelection to useSlotsViewOnSmallScreen

- Rename external-facing embed config option from enableTwoStepSlotSelection to useSlotsViewOnSmallScreen
- Update URL parameter parsing in embed-iframe.ts
- Update type definitions in types.ts and index.d.ts
- Update internal variable names to slotsViewOnSmallScreen for consistency
- Update documentation, playground examples, and tests

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Add config to prefill all booking fields so that slot has confirm button along with it

* chore: implement PR feedback

* fix: move twoStepSlotSelection embed outside misc-embeds div to fix e2e test

The e2e test was failing because the misc-embeds div content was
intercepting pointer events on mobile viewport. This follows the same
pattern used for skeletonDemo - the embed is now outside misc-embeds
and the div is hidden when testing this namespace.

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: prevent pointer event interception in twoStepSlotSelection embed

Hide heading and note elements and set pointer-events: none on container
elements while keeping pointer-events: auto on the iframe container.
This prevents the container from intercepting clicks on the iframe
during mobile viewport e2e tests.

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: hide all non-essential content for twoStepSlotSelection e2e test

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: disable pointer-events on body for twoStepSlotSelection e2e test

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: remove pointer-events: auto on container to let clicks pass through to iframe

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: explicitly set pointer-events: none on container and inline-embed-container

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: also set pointer-events: none on html element to prevent interception

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: make .place div fill viewport for twoStepSlotSelection e2e test

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: failing embed tests

* fixup

* fixup fixup

* fix: failing tests

* fix: update checks for verifying prefilled date

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2026-01-21 15:44:33 -03:00
Obaidullah IshfaqandAnik Dhabal Babu 6c620e37a6 refactor: remove redundant filtering in service (#25874)
* refactor: remove redundant filtering and return filtered users from service

* Simplify user retrieval by returning users directly

* Fix formatting issue in users.service.ts

* Filter out null users in getDynamicEventType

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-21 15:12:54 -03:00
Ram Shukla 5bfbec6915 made changes to the nav dropdown style to maintain the centre lining and the differentiator in the option avaialable with dropdown (#27038) 2026-01-21 18:04:12 +00:00
ddcac4b3b1 fix: make linting required for CI (#27091)
* fix: make linting required for CI

- Remove continue-on-error from lint workflow so CI fails on lint errors
- Fix 2 lint errors: avoid importing from @trpc/server in lib package
- Add trpcErrorUtils.ts to handle TRPC errors without circular dependencies
- Update lint-staged to show warnings but not block commits

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add message field validation to isTRPCErrorLike type guard

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 15:01:37 -03:00
AnshumancanrockandAnik Dhabal Babu f17933bc43 fix: prevent HTML encoding in names (#26959)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-21 17:37:08 +00:00
Peer RichelsenandDevin AI 769035b1ee feat: add Help Desk search link when KBar has no results (#27062)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 17:32:58 +00:00
Anik Dhabal Babu 186a3e648f fix: handle incomplete href attributes in workflow email links (#27094)
* handle incomplete href

* addrss cubic comment
2026-01-21 17:20:16 +00:00
Hariom Balhara 9fa245a03b getSchedule request similar to booking page needs org username instead of user.username (#27086) 2026-01-21 22:19:13 +05:30
cfb1db45b2 feat: add Cloudflare URL Scanner for malicious URL detection (#26387)
* feat: add Cloudflare URL Scanner integration for malicious URL detection

- Add MALICIOUS_URL_IN_WORKFLOW to LockReason enum
- Add URL_SCANNING_ENABLED constant for feature flag
- Create urlScanner.ts utility for Cloudflare Radar URL Scanner API
- Create scanWorkflowUrls task for async URL scanning with polling
- Integrate URL scanning into scanWorkflowBody task
- Add URL scanning for event type redirect URLs
- Lock user accounts when malicious URLs are detected
- Fix pre-existing lint issues (parseInt radix, optional chaining)

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: address biome lint warnings and TypeScript iterator errors

- Wrap iterators with Array.from() to fix TS2802 errors
- Add biome-ignore comments for process.env usage
- Extract helper functions to reduce function length
- Move exports to end of file per useExportsLast rule
- Remove problematic imports that cause TypeScript errors

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: address cubic-dev-ai review comments for URL scanning

- Fix P0: Re-fetch workflow steps before scheduling notifications to use actual verifiedAt values from database instead of overriding with new Date()
- Fix P1: Mark workflow step as verified in submitWorkflowStepForUrlScanning when URL scanning is disabled or no URLs found
- Fix P1: Add whitelistWorkflows parameter to submitUrlForUrlScanning for consistency
- Fix P2: Preserve URL context in error results in urlScanner.ts scanUrls function

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: add select clause to Prisma query for workflow steps

Address cubic-dev-ai P2 comment: Use select to fetch only the required
fields (id, action, sendTo, emailSubject, reminderBody, template, sender,
verifiedAt) instead of fetching all columns from workflowStep table.

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: add select clause to Prisma query in scanWorkflowBody.ts

Address cubic-dev-ai P2 review comment: Use select to fetch only the
required fields (id, action, sendTo, emailSubject, reminderBody,
template, sender, verifiedAt) instead of fetching all columns.

Co-Authored-By: peer@cal.com <peer@cal.com>

* test: add unit tests for URL scanning functionality

- Add tests for urlScanner.ts (extractUrlsFromHtml, isUrlScanningEnabled)
- Add tests for scanWorkflowUrls.ts (happy/unhappy paths for URL scanning task)
- Add tests for scanWorkflowBody.ts (happy/unhappy paths for workflow body scanning)

Tests cover:
- URL extraction from HTML content
- URL normalization and deduplication
- Handling of malicious URLs and user locking
- Fail-open behavior for API errors
- Whitelisted user handling
- Iffy spam detection integration

Co-Authored-By: peer@cal.com <peer@cal.com>

* test: remove incomplete test that provides no value

Removed the 'should mark all steps as verified when neither Iffy nor URL scanning is enabled' test as it used vi.doMock() which doesn't work after module import, had no assertions, and gave false confidence in test coverage.

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: use Cloudflare bulk scanning endpoint to reduce API quota usage

- Added submitUrlsForBulkScanning function that uses /urlscanner/v2/bulk endpoint
- Updated scanUrls to use bulk submission instead of individual URL submissions
- Bulk endpoint accepts up to 100 URLs per request, batching is handled automatically
- Reduces API quota usage as suggested by keithwillcode

Co-Authored-By: peer@cal.com <peer@cal.com>

* Update packages/features/tasker/tasks/scanWorkflowUrls.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: address cubic-dev-ai review comments

- P1: Sanitize URLs before logging to prevent exposing sensitive query parameters
- P2: Extract handleUrlScanningForStep helper function to reduce code duplication
- P2: Use vi.stubGlobal for fetch mock in tests for proper cleanup

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: address volnei review comments on PR #26387

- Move vi.unstubAllGlobals() to afterEach hook in iffyScanBody tests
- Restore updateMany optimization when URL scanning is disabled

Co-Authored-By: peer@cal.com <peer@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-21 12:28:57 -03:00
a03722fd7f feat: add OAuth client developer settings page with approval workflow (#25556)
* feat: add OAuth client developer settings page with approval workflow

- Add new developer OAuth page at /settings/developer/oAuth for users to submit OAuth client requests
- Transform admin OAuth page into management dashboard for reviewing/approving submissions
- Add OAuthClientApprovalStatus enum (PENDING, APPROVED, REJECTED) to track submission status
- Add userId and createdAt fields to OAuthClient model for tracking submissions
- Create email notifications for admin (new submission) and user (approval)
- Add sidebar navigation link in developer section below API keys
- Add comprehensive translations for new UI strings
- Create OAuthClientRepository for data access following repository pattern

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: re-export generateSecret for backward compatibility

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat: make logo mandatory and list items clickable for OAuth clients

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: add missing translation keys and remove client secret from details dialog

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: address cubic AI reviewer comments

- Remove duplicate 'there' JSON key in common.json
- Add select clause to findByUserId to avoid exposing clientSecret
- Add @@index([userId]) to OAuthClient model for query performance
- Update migration to include the index

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: address PR review comments - fix indentation and use useCopy hook

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: change react-dom/server import to fix Turbopack compatibility

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "fix: change react-dom/server import to fix Turbopack compatibility"

This reverts commit c3e0b709c2d88fd221143cb4ce9cd25bb8c94277.

* fix: use email service pattern for OAuth client notifications

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add try-catch around email sending to handle Turbopack react-dom/server issue

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "fix: add try-catch around email sending to handle Turbopack react-dom/server issue"

This reverts commit fc9d47cd773505ebc5ee2696718aad4a8a98be77.

* fix: improve OAuth client UI with skeleton loaders and smaller dialog styling

- Replace 'Loading...' text with proper skeleton loaders in both developer and admin OAuth client views
- Make client_id and copy button smaller in dialogs using size='sm' and text-sm styling
- Add 'client_id' translation key to common.json for proper i18n

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: improve skeleton loader to match actual OAuth client list structure

- Remove divide-y from container and use conditional border-b on rows
- Match the exact structure from oauth-clients-view.tsx L126-160
- Use proper spacing for text elements (mt-1 instead of space-y-2)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix skeleton

* rename the selected oauth client dialog

* fix: address PR feedback - admin auth, dropdown styling, sidebar label

- Add defense-in-depth admin authorization check in updateClientStatus handler
- Fix broken dropdown menu by using DropdownItem with StartIcon prop
- Fix sidebar menu label from 'oAuth' to 'oauth_clients' to match developer view

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update common.json

* feat: show client secret in approval email for confidential OAuth clients

- Add regenerateSecret method to OAuthClientRepository
- Regenerate secret when admin approves a PENDING confidential client
- Include client secret in approval notification email
- Add one-time warning message about storing the secret securely
- Only regenerate on first approval (not re-approvals)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add Website URL field, fix logo styling, show client secret after approval

- Add Website URL field to OAuth client forms (admin and developer views)
- Fix Upload Logo section styling by wrapping in Label div with proper gap
- Display client secret in dialog after admin approves a confidential OAuth client
- Add websiteUrl field to Prisma schema with migration
- Update tRPC handlers and repository to support websiteUrl
- Add translation keys for new UI elements

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: move clientSecret variable declaration outside if block for proper scoping

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: dont expose client secret in emails

* refactor: dont regenerate secret upon status change

* refactor: reuse existing hash function

* refactor: rename admin/oAuth to admin/oauth page

* refactor: deduplicate oauth repositories

* refactor: remove withGlobalPrisma from oauth repository

* refactor: developer oauth page

* refactor: oauth status by default accepted

* refactor: request oauth status when creating

* refactor ux

* fix: address Cubic AI code review feedback

- Add purpose field to plain text email body for accessibility
- Convert NewOAuthClientButton to inline JSX to avoid React anti-pattern
- Trigger re-approval when redirectUri changes for security
- Add e.preventDefault() for Space key to prevent page scroll
- Change default approvalStatus to PENDING for defense-in-depth
- Use oauth_clients translation key for consistency
- Add meaningful alt text to Avatar for accessibility
- Remove onClick from DialogClose to prevent double-run close effects
- Return NOT_FOUND for non-owner delete to prevent resource enumeration

Co-Authored-By: unknown <>

* common.json file

* refactor: delete all prisma migrations

* refactor: have just 1 prisma migration

* revert: some devin changes

* fix: typecheck

* test: owner OAuth crud

* test: admin OAuth approval / rejection

* fix: address Cubic AI review feedback (confidence 9/10 issues)

- schema.prisma: Remove @default("") from purpose field to make it required
- schema.prisma: Use UTC-aware timezone expression for createdAt default
- OAuthClientFormFields.tsx: Localize redirect URI placeholder using t()
- common.json: Add redirect_uri_placeholder translation key

Co-Authored-By: unknown <>

* cubic changes

* refactor: dont log sensitive info and rethrow error

* cubic feedback

* refactor: make oauth client purpose optional

* refactor: admin/oauth not allowed if not logged in

* refactor: admin view skeleton

* refactor: rename state

* refactor: get rid of redundant mapping

* refactor: remove redundant handler

* refactor: remove redundant handler

* refactor: re-usable new oauth client button

* refactor: dialogs

* refactor: modals

* refactor: handler names, dialog, skeleton

* fix: purpose being null

* refactor: rename handler and delete old oauth admin page

* fix: purpose in submission

* refactor: handler names

* refactor: rename

* refactor: update handler

* refactor: rename approvalStatus -> status

* refactor: simplify modal

* refactor: name

* dont require repproval if redirectUri changes

* fix: remove integration sync index creation

* refactor: require re-approval if redirectUri updated

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: remove duplicate common.json keys

* refactor: replace team@cal.com with SUPPORT_MAIL_ADDRESS

* refactor: generate client secret on handler level

* fix: authorization code only available to approved clients

* refactor: cubic review dont display exclamation

* refactor: cubic review website_url in common json

* fix: dont default in ui to approved status

* refactor: optiona logo in schema create handler

* fix: tests

* fix: tests

* fix: /authorize redirect if client not approved or show error

* test: authorize page with invalid client id

* refactor: dont allow refreshing tokens unless approved client

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* chore: warn that pending client is not usable

* fix: approve and reject buttons

* fix: /authorize show error if client not approved

* refactor: info message about editing oauth client and status

* change info alert to warning

* try to fix ci test

* debug: failing e2e test

* fix: improve session propagation in oauth-client-admin E2E test

- Add navigateToAdminOAuthPage helper that waits for listClients API call
- If the API call doesn't arrive (session issue), reload page to force session refresh
- This fixes the CI flakiness where admin page wasn't loading due to session not having ADMIN role

Co-Authored-By: lauris@cal.com <lauris@cal.com>

* fix: register waitForResponse before navigating in E2E test

- Register the listClients waitForResponse promise BEFORE page.goto()
- This ensures the response isn't missed during page load
- Also register the promise before reload in the catch block

Co-Authored-By: lauris@cal.com <lauris@cal.com>

* fix: rename oAuth folder to oauth for case-sensitive filesystems

The admin OAuth page route was at /settings/admin/oAuth (capital A) but the
code references /settings/admin/oauth (lowercase). This caused 404 errors
on case-sensitive filesystems (Linux).

Also improved the E2E test navigation helper to retry with delays if the
admin page doesn't load immediately, handling session propagation timing.

Co-Authored-By: lauris@cal.com <lauris@cal.com>

* test style

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: eunjae@cal.com <hey@eunjae.dev>
Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: lauris@cal.com <lauris@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-21 12:23:51 -03:00
Eunjae LeeandDevin AI 5449b8d913 refactor: store timestamp instead of boolean for feature opt-in (#27080)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 15:17:32 +00:00
Alex van AndelandDevin AI 1e1379546b refactor: remove usage of deprecated user.startTime and user.endTime columns (#27085)
These columns are marked as deprecated in the Prisma schema and will be
removed in a follow-up migration. This PR removes all code references to
prepare for the column removal.

Changes:
- Remove startTime/endTime from ProfileRepository userSelect and methods
- Remove startTime/endTime from UserRepository userSelect and methods
- Remove startTime/endTime from me/get.handler.ts API response
- Remove endTime from API v1 user validation schema

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 11:45:37 -03:00
Alex van AndelandDevin AI ccf99fbb6b refactor: remove Object.freeze hack in getConnectedCalendars (#27070)
* refactor: remove Object.freeze hack in getConnectedCalendars

The previous implementation used Object.freeze to prevent the destinationCalendar
object from being mutated when looping through multiple calendar credentials.
This was a workaround for a bug where the wrong calendar's primaryEmail and
integrationTitle would be set when multiple credentials existed.

This refactor properly fixes the issue by:
1. Only setting destinationCalendar once (when first found)
2. Using a flag to track when the destination calendar is found in the current credential
3. Only setting primaryEmail and integrationTitle for the credential that contains
   the destination calendar

Fixes the hack mentioned in: https://github.com/calcom/cal.com/pull/7644

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* refactor: move destinationCalendar enrichment outside the loop

Per feedback, moved the destinationCalendar finding and enrichment
completely outside the Promise.all loop. After all connected calendars
are fetched, we search through the results to find and enrich the
destination calendar with primaryEmail and integrationTitle.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 11:30:20 -03:00
f00f80ed26 chore: ensure default calendars with trigger.dev apiv2 (#27058)
* chore: ensure default calendars with trigger.dev apiv2

* test: add unit and e2e tests for CalendarsTasker integration

- Add unit tests for CalendarsTasker.dispatch when enableAsyncTasker is true
- Add e2e test to verify ensureDefaultCalendarsForUser is called when creating membership
- Mock CalendarsTasker and ConfigService in unit tests
- Test both async (Trigger.dev) and sync (Bull queue) paths
- Fix missing return types on helper functions in e2e tests
- Add *.spec.ts to biome test file exceptions for noExcessiveLinesPerFunction rule

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 16:03:30 +02:00
f44ee33c6c fix: filter out Google system calendars from calendar list (#27074)
* fix: filter out Google system calendars from calendar list

Google system calendars (holidays, birthdays) don't return proper
free/busy information, making them useless for availability checking.
This change filters them out from the listCalendars() method so users
won't see these calendars as selectable options.

Filtered calendar types:
- Holiday calendars (#holiday@group.v.calendar.google.com)
- Birthdays/contacts calendar (#contacts@group.v.calendar.google.com)

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* test: add tests for Google system calendar filtering

Tests verify that listCalendars() correctly filters out:
- Holiday calendars (#holiday@group.v.calendar.google.com)
- Birthdays/contacts calendar (#contacts@group.v.calendar.google.com)

Test cases cover:
- Filtering holiday calendars
- Filtering birthdays calendar
- Mixed calendars (keeping regular, filtering system)
- All system calendars (returns empty array)
- Null/undefined calendar IDs
- Various international holiday calendar formats

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 10:00:08 -03:00
Dhairyashil Shinde 1c3c6292df refactor: handle unavailable features on iOS and consolidate settings UI (#27081)
- Refactor duplicate UI components (SettingsGroup, SettingRow, NavigationRow) into [SettingsUI.tsx]
- Centralize showNotAvailableAlert in utils/alerts.ts
- Replace in-app browser links with Feature not available alerts for iOS on:
  - More tab items (Apps, Routing, Workflows, Insights, Support)
  - Event Type Other tab (Apps, Workflows, Webhooks)
  - Event Type Advanced tab (Private Links)
- Remove View public page from Profile Sheet on iOS
- Remove Preview actions from Event Type (List menu and Detail quick actions) on iOS
- Add Learn More links to Advanced Tab settings
2026-01-21 09:42:06 -03:00
cb567a91c5 feat: add option to hide duration selector in booking page for multiple durations (#27033)
* feat: add option to hide duration selector in booking page for multiple durations

- Add 'hideDurationSelectorInBookingPage' field to event type metadata schema
- Add checkbox under Default Duration select in event type settings
- Modify Duration component to hide selector when setting is enabled
- URL params can still set duration when selector is hidden
- Add i18n translation for the new checkbox label
- Add e2e tests for the new functionality

Co-Authored-By: ali@cal.com <ali@cal.com>

* fix: rename checkbox label to 'Hide duration selector'

Co-Authored-By: ali@cal.com <ali@cal.com>

* fix: replace text locator with data-testid in E2E test

Replace `text=Multiple duration` locator with `page.getByTestId("event-types").locator('a[title="Multiple duration"]')` to follow E2E test best practices.

Co-Authored-By: unknown <>

* fix: add data-testid to hide duration selector checkbox for E2E tests

Co-Authored-By: ali@cal.com <ali@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2026-01-21 10:39:36 +02:00
4162b5be55 feat: remove Revert.dev dependency from Pipedrive integration (#22492)
* feat: remove Revert.dev dependency from Pipedrive integration

- Replace Revert API calls with direct Pipedrive OAuth2 and REST API
- Update OAuth flow to use Pipedrive's authorization endpoint
- Implement token exchange in callback handler
- Map Revert's unified API format to Pipedrive's native API structure
- Remove REVERT_* environment variables from configuration
- Update app config to reflect direct Pipedrive integration
- Follow patterns from other CRM integrations like HubSpot

Breaking change: Requires PIPEDRIVE_CLIENT_ID and PIPEDRIVE_CLIENT_SECRET
environment variables instead of REVERT_* variables

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: implement proper token refresh logic for Pipedrive OAuth

- Add token refresh implementation following Pipedrive OAuth2 specification
- Use proper Basic Auth for token refresh requests
- Handle token refresh errors with appropriate logging
- Update access token and expiry date after successful refresh
- Add note about database credential update requirement

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: add database credential updates for Pipedrive token refresh

- Import updateTokenObjectInDb utility for proper credential management
- Store credentialId in constructor for database updates
- Update token refresh logic to persist refreshed tokens to database
- Follow Cal.com patterns for OAuth credential management
- Ensure tokens are properly updated after successful refresh

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: use OAuthManager for Pipedrive token management

- Refactor CrmService.ts to use OAuthManager instead of manual token refresh
- Create getPipedriveAppKeys helper function for client credentials
- Update callback.ts to use the new helper function
- Add requestPipedrive helper method for all API calls
- Implement proper token refresh callbacks (isTokenObjectUnusable, isAccessTokenUnusable)

This addresses the review comments from hariom and cubic on PR #22492.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: validate token endpoint response before storing Pipedrive credentials

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 13:42:15 +05:30
Benny JooandDevin AI c28a0d7db0 fix: handle invalid timezones gracefully in calendar events (#27042)
* fix: handle invalid timezones gracefully in getLuckyUser

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: move timezone validation to getCalendarsEvents with offset conversion

- Move invalid timezone handling from getLuckyUser.ts to getCalendarsEvents.ts
- Add convertOffsetToEtcGmt() to convert offset formats (GMT-05:00, UTC+08:00) to valid IANA Etc/GMT timezones
- Preserves timezone precision for fairness calculations instead of falling back to UTC
- Add unit tests for timezone conversion scenarios

* refactor: extract timezone conversion to dedicated file

- Create timezone-conversion.ts with concise convertOffsetToIanaTimezone and normalizeTimezone functions
- Update getCalendarsEvents.ts to import from the new file
- Follow kebab-case naming convention for utility files

* test: add unit tests for timezone conversion proving Intl.DateTimeFormat behavior

- Add tests proving Intl.DateTimeFormat throws RangeError for offset formats (GMT-05:00, UTC+08:00)
- Add tests for convertOffsetToIanaTimezone function
- Add tests for normalizeTimezone function

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 02:51:52 -03:00
ec951cacad perf: getUserAvailability if dateRange is empty, early return (#26000)
* Early return if date range is empty

* test: add tests for empty workingHours early return optimization

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-21 02:51:01 -03:00
Alex van Andel 546a1510b2 chore: release v6.1.2
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-21 02:19:24 -03:00
Alex van AndelandDevin AI 455a91935d fix: enable alby app in E2E tests to fix payment-apps test failures (#27071)
PR #27012 introduced logic to disable apps without valid keys during seeding.
This caused the alby payment app tests to fail because the alby app was
disabled in the App table when its environment keys weren't configured.

This fix adds an ensureAppEnabled helper function that enables the app
in the App table before running the tests, treating it as a mock/test
setup step.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 08:40:31 +05:30
Volnei Munhoz 5ddb4dce3f Add calendar subscription error better management (#27019) 2026-01-20 18:47:03 +02:00
Udit Takkar 6c3b10672c fix: managed event type bug (#27047) 2026-01-20 17:29:12 +01:00
Jagadish MadavalkarandAnik Dhabal Babu cb6b52b334 right fix (#26963)
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
2026-01-20 15:31:43 +00:00
Shoaib Akhtar AnsariandAnik Dhabal Babu e8e50b70df fix: resolve search bar overlap with title on tablet viewports (#27050) (#27055)
* fix: resolve search bar overlap with title on tablet viewports (#27050)

* Update ShellMainAppDir.tsx

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-20 14:36:58 +00:00
Udit Takkar fd130a3fbd chore: don't use object in dependency (#26972) 2026-01-20 18:45:41 +05:30
Hariom Balhara 7ec8601bd6 chore: Integrate edit location booking audit (#26569)
## What does this PR do?

Integrates booking audit logging for the edit location functionality, following the pattern established in PR #26046 (booking creation/rescheduling audit).

This PR adds audit logging when a booking's location is changed through:
1. **Web app** (tRPC handler): `packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts`
2. **API v2**: `apps/api/v2/src/ee/bookings/2024-08-13/services/booking-location.service.ts`

### Changes:
- Added `actionSource` as a **required** parameter to `editLocationHandler` (no fallback)
- Added optional `userUuid` parameter (defaults to logged-in user's uuid)
- Added `ValidActionSource` type that excludes "UNKNOWN" for client-facing APIs
- Captures old location before update for audit data
- Calls `BookingEventHandlerService.onLocationChanged()` after successful location update
- Web app uses `actionSource: "WEBAPP"`, API v2 uses `actionSource: "API_V2"`
- Updated router to explicitly pass `actionSource: "WEBAPP"`
- Updated test to pass `actionSource: "WEBAPP"`
- **API v2**: Uses NestJS dependency injection pattern with `BookingEventHandlerService` injected via constructor

### Updates since last revision:
- **Created `BookingEventHandlerModule`** (`apps/api/v2/src/lib/modules/booking-event-handler.module.ts`) to encapsulate `BookingEventHandlerService` and its dependencies (Logger, TaskerService, HashedLinkService, BookingAuditProducerService)
- Updated both bookings modules (2024-04-15 and 2024-08-13) to import `BookingEventHandlerModule` instead of listing individual providers
- This reduces code duplication and makes dependency management cleaner

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. N/A - using existing audit infrastructure that is already tested.

## How should this be tested?

1. Update a booking's location through the web app
2. Update a booking's location through API v2
3. Verify audit logs are created with:
   - Correct `bookingUid`
   - Correct `actor` (user who made the change)
   - Correct `source` ("WEBAPP" or "API_V2")
   - Correct `auditData.location.old` and `auditData.location.new` values

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings

## Human Review Checklist

- [ ] Verify all callers of `editLocationHandler` pass `actionSource` (router updated, test updated)
- [ ] Verify `organizationId` derivation is correct in both handlers (tRPC uses `booking.user?.profiles?.[0]?.organizationId`, API v2 uses `existingBookingHost.organizationId`)
- [ ] Confirm audit call placement after location update is intentional (audit failures would fail the operation even though location was already updated)
- [ ] Note: API v2 has its own implementation and does NOT reuse `editLocationHandler` - this is correct
- [ ] Verify `BookingEventHandlerModule` properly exports `BookingEventHandlerService` and is imported in both bookings modules
- [ ] Verify the `updateBookingLocationInDb` return value (`{ updatedLocation }`) is destructured and used correctly for audit data
- [ ] Verify API v2 uses `bookingLocation` for audit `new` value, while tRPC uses `updatedLocation` from DB update

---


Link to Devin run: https://app.devin.ai/sessions/fd1d439779674050a26ea3fa7d799943
Requested by: @hariombalhara
2026-01-20 18:40:48 +05:30
Hariom Balhara 39ae54d682 feat: add auto-accept logic for team memberships based on org email domain (#26860)
## What does this PR do?

Adds auto-accept logic to the `/v2/teams/{teamId}/memberships` endpoint, similar to what exists in the `/v2/organizations/{orgId}/teams/{teamId}/memberships` endpoint.

When a user is added to a sub-team of an organization, the system now checks if the user's email domain matches the organization's `orgAutoAcceptEmail` setting. If it matches and the organization is verified, the membership is automatically accepted (overriding any `accepted: false` in the request).

### Changes:
- Modified `TeamsMembershipsService.createTeamMembership()` to check if the team has a parent organization and apply auto-accept logic using the existing `OrganizationMembershipService.shouldAutoAccept()` method
- Exported `OrganizationMembershipService` from `OrganizationsModule` for dependency injection
- Added `TeamsModule` and `UsersModule` imports to `TeamsMembershipsModule`
- Added required dependencies (`OrganizationMembershipService`, `OAuthClientRepository`, etc.) to `TeamsModule` and `TeamsSchedulesModule` since they provide `TeamsMembershipsService` directly
- Added comprehensive E2E tests for auto-accept scenarios
- Added `createOrgSettings` and `deleteOrgSettings` helper methods to test fixtures

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

The E2E tests cover the following scenarios:
1. **Auto-accept when email matches** - User with `@acme.com` email is auto-accepted when org has `orgAutoAcceptEmail: "acme.com"`
2. **Case-insensitive matching** - User with `@ACME.COM` email matches `orgAutoAcceptEmail: "acme.com"`
3. **Override accepted:false** - Even if `accepted: false` is passed, it's overridden to `true` when email matches
4. **No auto-accept for non-matching emails** - User with `@external.com` email is NOT auto-accepted
5. **EventTypes assignment** - Verifies user is added to event types with `assignAllTeamMembers: true`

To run the tests:
```bash
TZ=UTC yarn test:e2e --testPathPattern="teams-memberships.controller.e2e-spec"
```

## Human Review Checklist

- [ ] Verify the auto-accept logic matches the existing implementation in `organizations-teams-memberships.controller.ts`
- [ ] Confirm all modules that provide `TeamsMembershipsService` directly (`TeamsModule`, `TeamsSchedulesModule`, `OrganizationsModule`) have the required dependencies
- [ ] Verify `updateNewTeamMemberEventTypes` is called when auto-accept triggers (controller checks `membership.accepted` after service returns)
- [ ] Consider if organization membership creation is needed when a user is auto-accepted into a sub-team but doesn't have org membership yet (not implemented in this PR)

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings

---

Link to Devin run: https://app.devin.ai/sessions/578b8904a5a94385b59031f9616379cc
Requested by: @hariombalhara
2026-01-20 18:40:44 +05:30
Dhairyashil Shinde bea542b310 fix: correct bookingUrl for EU instance in API responses (#27046)
* fix: use WEBAPP_URL for booking URLs when domains differ

For EU deployments where WEBAPP_URL (app.cal.eu) differs from
WEBSITE_URL (cal.com), use WEBAPP_URL for non-org booking URLs.
This fixes incorrect bookingUrl in API responses for EU instance.

* Created new shared utility getTldPlus1 and updated code to use shared function instead of inline copy

* use same comment
2026-01-20 12:48:30 +00:00
Dhairyashil Shinde e7a69d68df fixed the issue with the copy link button not working in the extension (#27048) 2026-01-20 09:47:00 -03:00
BetoandDhairyashil d67bf45527 feat: integrate DateTimePickerAndroid for date/time selection (#26979)
* feat: integrate DateTimePickerAndroid for date/time selection

- Added @react-native-community/datetimepicker dependency for native date/time picker functionality.
- Replaced modal-based date/time picker implementation with DateTimePickerAndroid for improved user experience.
- Updated RescheduleScreen to utilize the new date/time picker methods, enhancing the selection process and ensuring better styling consistency.

* feat: add LimitsTabDatePicker component for date selection

- Introduced a new LimitsTabDatePicker component utilizing DateTimePickerAndroid for improved date selection on Android.
- Implemented date parsing and formatting for user-friendly display.
- Enhanced user interaction with a pressable element to open the date picker.

* feat: add EditAvailabilityOverrideScreen for managing schedule overrides

- Introduced EditAvailabilityOverrideScreen component to allow users to create and edit availability overrides.
- Implemented date and time selection using DateTimePickerAndroid for improved user experience.
- Added functionality to handle existing overrides, including editing and deleting options.
- Enhanced user interaction with clear alerts for success and error states during save operations.

* fixed lint warnings, info

* address cubics comments

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-01-20 09:46:42 -03:00
Rajiv Sahal 72dc999108 chore: disable dashboard for creating new platform accounts (#27052)
* chore: disable dashboard for creating new platform accounts

* chore: remove page altogether
2026-01-20 12:45:47 +00:00
14e2fa6893 feat: api v2 getSchedules that are applied to team event type (#25912)
* chore: update teams schedules module

* chore: update schedules and team events repository

* chore: input for teams schedules

* feat: add logic to filter schedules based on event type id

* fix: bad import

* chore: add input for get user schedules

* feat: add logic in user schedule to filter schedules based on event type id

* chore: update e2e tests

* fix: add EventTypesModule_2024_06_14 import to SchedulesModule_2024_06_11

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: import path

* chore: implement cubic feedback

* fix: replace .finally() with try/finally in E2E tests

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* chore: implement PR feedback

* fix: correct schedule precedence order for team hosts

Fix the effective schedule resolution to follow the intended precedence:
host schedule > user default schedule > event type schedule

This addresses Cubic AI review feedback with confidence 9/10:
- schedules.service.ts: Fix precedence in getUserSchedulesForEventType
- teams-schedules.service.ts: Fix precedence in getTeamSchedulesForEventType

Co-Authored-By: unknown <>

* fixup

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-20 17:55:38 +05:30
Hariom Balhara 2c105aceb8 chore: convert console.log to debug log in raqbUtils (#27008)
## What does this PR do?

Converts a `console.log` statement to use the proper `@calcom/lib/logger` with debug level in the raqbUtils.server.ts file. This ensures the log message only appears when debug logging is enabled, reducing noise in production logs.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. N/A - logging change only.

## How should this be tested?

This is a simple logging change. No specific testing required beyond CI passing.

The log message "A group option found. Using all its sub-options instead" will now only appear when the logger level is set to debug (level 2 or lower via `NEXT_PUBLIC_LOGGER_LEVEL`).

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

<!-- Link to Devin run: https://app.devin.ai/sessions/45d95cd7127541ffac96764f251ae1c9 -->
<!-- Requested by: @hariombalhara -->
2026-01-20 13:54:25 +05:30
devin-ai-integration[bot]andali@cal.com 1e0b0d949f feat: add 40-minute duration option for multiple duration event types (#27032)
- Add 40 minutes to the multipleDurationOptions array in EventSetupTab
- Add comprehensive tests for 40-minute slot generation including:
  - Full day slot generation
  - Correct time intervals
  - Default duration handling
  - Same day booking with time constraints
  - Multiple date ranges

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
2026-01-20 10:43:55 +04:00
c60addc528 feat: add PlatformOrganizationBillingTasker with sync and trigger.dev versions (#26803)
* feat: add PlatformOrganizationBillingTasker with sync and trigger.dev versions

- Create PlatformOrganizationBillingTasker extending Tasker base class
- Add sync tasker (PlatformOrganizationBillingSyncTasker) for synchronous execution
- Add trigger.dev tasker (PlatformOrganizationBillingTriggerTasker) for async execution
- Create trigger.dev task for incrementing subscription usage
- Add PlatformOrganizationBillingTaskService with business logic
- Add PlatformOrganizationBillingRepository for data access
- Add createSubscriptionUsageRecord method to StripeBillingService
- Follow BookingEmailAndSmsTasker pattern for consistency

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: move repository methods per PR feedback

- Move findPlatformOrgByUserId to OrganizationRepository
- Create new PlatformBillingRepository for billing queries
- Remove PlatformOrganizationBillingRepository (consolidated)
- Update task service and trigger.dev task to use new repositories

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat: add DI using @evyweb/ioctopus for platform billing tasker

- Create di/tasker/ directory following BookingEmailAndSmsTasker pattern
- Add tokens.ts with DI tokens for all billing tasker classes
- Add module files for PlatformBillingRepository, TaskService, SyncTasker, TriggerTasker, Tasker
- Add container files with getter functions
- Update trigger.dev task to use DI container instead of manual instantiation

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: add select statement to PlatformBillingRepository.findByTeamId

Only select subscriptionId field since that's the only field used by the task service

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat: add NestJS DI modules for platform billing tasker in API v2

- Add platform billing tasker exports to platform-libraries/organizations.ts
- Export IBillingProviderService type from platform-libraries
- Create StripeBillingProviderService wrapper implementing IBillingProviderService
- Create PrismaPlatformBillingRepository extending PlatformBillingRepository
- Create NestJS service wrappers for all platform billing tasker classes
- Create PlatformBillingTaskerModule with all providers and exports
- Update PlatformOrganizationBillingTaskService to use Pick<IBillingProviderService>

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat: handle cancel and reschedule usage

* fix: restore IsUserInBillingOrg to billing module providers

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: add idempotency key

* fix: just log error]

* fix: logger and typo

* fix: address Cubic AI review feedback (high confidence issues)

- Fix grammar error: 'Delayed task are' -> 'Delayed tasks are' in PlatformOrganizationBillingSyncTasker.ts (3 occurrences)
- Re-throw error after logging in increment-usage.ts to enable trigger.dev retry mechanism

Co-Authored-By: unknown <>

* fix: remove duplicate code and use DI instead

* fix: remove orThrow on find first in findPlatformOrgByUserId

* refactor: prevent usage increment task from re-throwing errors

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-20 15:26:50 +09:00
Hariom Balhara 38a7fcfedd fix: filter segment members to only show those with host entries (#26816)
## What does this PR do?

Fixes a bug where the UI shows team members who match segment criteria even when they don't have host entries in the database. When `assignAllTeamMembers` is `true` and segment filtering is enabled, members would appear in the Assignment tab but wouldn't actually be assigned during booking because they lack host entries.

**The Problem:**
- The filtering logic in `EditWeightsForAllTeamMembers` short-circuited when `assignAllTeamMembers` was true, showing all segment-matching members regardless of whether they had host entries
- The `handleSave` function only updates hosts that already exist in the `value` array, filtering out members without host entries
- This created a misleading UI where members appeared but wouldn't be assigned

**The Fix:**
- Removed the `assignAllTeamMembers` prop from `EditWeightsForAllTeamMembers` component entirely since the filtering should always check for existing host entries
- Updated the filter in `EditWeightsForAllTeamMembers.tsx` to always check for existing host entries in the `value` array
- Added `filterMemberIds` prop to `Segment` component to filter matching team members to only show those who are hosts of the event-type
- `AddMembersWithSwitch` now passes the list of non-fixed host user IDs to the Segment component via `filterMemberIds`

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Create a team event type with round-robin scheduling
2. Enable "Assign all team members" toggle
3. Enable segment filtering with criteria that matches some team members
4. Verify that only members who have host entries (are actually assigned to the event type) appear in the "Edit team member weights" sheet
5. Members matching segment criteria but without host entries should NOT be displayed

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

---

### Human Review Checklist
- [ ] Verify the filtering logic correctly shows only members with host entries in both `EditWeightsForAllTeamMembers` and `Segment` components
- [ ] Confirm this aligns with the actual booking behavior (members without host entries won't be assigned)
- [ ] Check that `filterMemberIds` prop is correctly passed through `AddMembersWithSwitch` → `MembersSegmentWithToggle` → `Segment` → `MatchingTeamMembers`
- [ ] Verify the filter `value.filter((host) => !host.isFixed).map((host) => host.userId)` correctly extracts non-fixed host IDs

---

Link to Devin run: https://app.devin.ai/sessions/3333b41226d0452e98ef7ac358511f5b
Requested by: @hariombalhara
2026-01-20 07:01:49 +05:30
Volnei MunhozandDevin AI e620264848 fix: resolve noNonNullAssertion and noImplicitAnyLet lint issues (#27021)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 20:07:18 -03:00
Dhairyashil Shinde 12e42427e2 fix(auth): show splash screen during auth check to prevent login flash (#27022) 2026-01-19 21:13:33 +01:00
ad137fbf9c chore: disable apps with missing required keys (#27012)
* ci(companion): add separate typecheck workflow to catch type errors

This adds a new companion-typecheck.yml workflow that runs TypeScript type
checking for the companion app. This would have caught the missing useEffect
import issue in PR #26931.

Changes:
- Add new companion-typecheck.yml workflow file
- Update pr.yml to call the new workflow when companion files change
- Add typecheck-companion to the required jobs list

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* add lint checks

* test

* remove

* update typecheck

* address review

* chore:- hide apps with missing required keys from app store

* update

* Delete packages/app-store/_utils/hasRequiredAppKeys.test.ts

* Update validateAppKeys.ts

* Update validateAppKeys.ts

* Update validateAppKeys.test.ts

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 19:32:30 +00:00
da91152365 feat: standalone page config to use in companion (#27018)
* feat: hide navigation when ?standalone=true URL parameter is present

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat: standalone page config to use in companion

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: peer@cal.com <peer@cal.com>
2026-01-19 19:27:14 +00:00
adc198b37b feat: add feature opt-in banner system (#26625)
* docs: add feature opt-in banner system plan

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: iterate on feature opt-in banner plan based on feedback

- Use config.ts for feature metadata instead of TRPC response
- Consolidate localStorage dismissal into single key to avoid bloat
- Replace separate success dialog with in-dialog success state for smoother UX

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: implement feature opt-in banner system

- Add checkFeatureOptInEligibility TRPC procedure to check if user can opt-in
- Create useFeatureOptInBanner hook with localStorage dismissal state
- Create FeatureOptInBanner floating component for bottom-right display
- Create FeatureOptInConfirmDialog with role-based options and success state
- Integrate banner into bookings-view.tsx as example usage

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add i18n translation keys for feature opt-in banner

* refactor: create FeatureOptInBannerWrapper for simpler consumer integration

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use @calcom/lib/webstorage and add Zod schema for localStorage

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: address PR review comments - use PBAC, move logic to service, improve typing

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

# Conflicts:
#	packages/features/feature-opt-in/services/FeatureOptInService.ts

* test: add comprehensive tests for checkFeatureOptInEligibility method

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: correct import and Checkbox type errors

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update message

* invalidate after dialog dismiss

* feat: simulate user opt-in to determine banner eligibility

When a feature has a strict policy and org/team hasn't explicitly
enabled it, user opt-in alone won't enable the feature. This change
simulates what would happen if the user opts in and only shows the
banner if opting in would actually enable the feature.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add early return for missing featureConfig and clarify simulation comment

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix repository usage

* refactor: simplify FeatureOptInConfirmDialog UI and remove unused translation

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: replace radio buttons with multi-select dropdown in FeatureOptInConfirmDialog

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* resize banner

* refactor: use AnimatedPopover pattern for team selection and rename titleI18nKey to nameI18nKey

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: change 'Just for me' to 'For me', fix width clipping, remove divider

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update style

* feat: make 'Just for me' mutually exclusive with teams/org and store opt-ins in localStorage

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove barrel imports and update to direct imports

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add modal prop to AnimatedPopover to fix scroll lock conflict in dialogs

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: wrap Popover.Content with Portal to prevent layout interference in dialogs

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use flexbox gap instead of space-y to prevent popover wrapper from affecting layout

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "fix: use flexbox gap instead of space-y to prevent popover wrapper from affecting layout"

This reverts commit 8385adafa890c2f2674aa3ae3b10ca6e0c55ba5c.

* Revert "fix: wrap Popover.Content with Portal to prevent layout interference in dialogs"

This reverts commit e84301a35a99b3559d47c2d37316af290834ca2d.

* Revert "fix: add modal prop to AnimatedPopover to fix scroll lock conflict in dialogs"

This reverts commit b015af2f1cf31ef7087c02cb8535d96cc4a34125.

* feat: replace Radix Dialog and AnimatedPopover with coss-ui components

This migration uses @coss/ui Dialog and Popover components which are built on
Base UI instead of Radix. Base UI handles scroll locking and positioning
differently, which should fix the gap issue when opening the popover inside
the dialog.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: replace remaining @calcom/ui components with coss-ui

- Replace Divider with Separator from @coss/ui
- Replace Label with Label from @coss/ui
- Replace CheckboxField with Checkbox + Label from @coss/ui
- Replace Icon with direct lucide-react icons (UserIcon, BuildingIcon, UsersIcon, CheckIcon)
- Replace showToast with toastManager.add() from @coss/ui

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: replace Popover with Menu component from coss-ui

- Replace Popover + FilterCheckboxField with Menu + MenuCheckboxItem
- MenuCheckboxItem provides built-in checkbox indicator and styling
- MenuSeparator provides proper menu separators
- Cleaner API with onCheckedChange callback
- Better keyboard navigation support

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: align icon and text on same line in MenuCheckboxItem, widen dialog

- Wrap icon and text in flex container with items-center gap-2
- Change dialog width from sm:max-w-md to sm:max-w-lg to prevent text wrapping

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* use dimmed bg for coss dialog title

* refactor: change nameI18nKey/descriptionI18nKey to nested i18n object

- Change OptInFeatureConfig interface to use i18n: { name, description }
- Update all component usages to use featureConfig.i18n.name and featureConfig.i18n.description
- Update test mocks to use new structure

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add i18n.title to OptInFeatureConfig type definition

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update texts

* use title instead of name

* update banner style

* refactor: split FeatureOptInConfirmDialog into separate success and confirmation dialogs

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: don't record dismissed info in local storage after successful opt-in

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add checkFeatureOptInEligibility to IFeatureOptInService interface

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update common.json

* refactor: move tRPC usage from features package to apps/web/modules

Addresses Cubic AI review feedback (confidence 9/10):
- Remove @calcom/trpc import from FeatureOptInConfirmDialog.tsx
- Add FeatureOptInMutations type for passing mutation functions via props
- Move tRPC hooks to useFeatureOptInBanner hook in apps/web/modules
- Pass mutations through FeatureOptInBannerWrapper to dialog component

This maintains the architectural constraint that packages/features
should not import from @calcom/trpc to prevent circular dependencies.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 18:48:26 +00:00
Joe Au-YeungandDevin AI 2608e136cb fix: use appropriate error codes in chargeCard handler (#27013)
- Change 'Booking not found' to throw NOT_FOUND (404) instead of plain Error
- Preserve ErrorWithCode for ChargeCardFailure to properly map to BAD_REQUEST (400)
- Add specific error handling for 'User is not a member of the team' -> FORBIDDEN (403)
- Add specific error handling for 'User ID is required' and 'No payment credential found' -> BAD_REQUEST (400)
- Keep INTERNAL_SERVER_ERROR (500) only for actual server errors like 'Payment app not implemented'
- Update test to expect ErrorWithCode to be re-thrown instead of wrapped in translated Error

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 18:14:13 +00:00
7f46ce1851 feat: add HubSpot contact owner toggle (#26552)
* feat: add HubSpot contact owner toggle

* chore

* Update packages/app-store/hubspot/lib/CrmService.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: updated test to verify new behavior

* fix: implement cubic suggestions

* refactor: update contact owner strings and enhance meeting creation logic

* refactor: fix failing unit tests

* refactor: streamline contact owner retrieval and error handling

* update tests

* update text

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
2026-01-19 17:43:25 +00:00
a4f8571f59 fix: update transaction timeout for large managed event-types (#25944)
* fix: update transaction timeout for large managed event-types

* test: add findMany mock for batch update optimization in handleChildrenEventTypes tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: reduce batch size to 50 and use skipDuplicates for workflow linkage

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: add comprehensive tests for batch execution and retry behavior

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use logger instead of console.log and fix type error

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: update test file to mock logger instead of console.log

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: type issues

* fixup! fix: type issues

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: keith@cal.com <keithwillcode@gmail.com>
2026-01-19 20:37:21 +04:00
Anik Dhabal Babu f319b662c5 fix: skip reminders when scheduled date is in the past (#26942)
* flaky-e2e

* workflow reminder

* remove
2026-01-19 14:54:31 +00:00
37847c0061 feat: redesign team creation flow to match onboarding-v3 design (#26733)
* feat: redesign team creation flow to match onboarding-v3 design

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* feat: skip invite options and go directly to email invite step

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* feat: invalidate teams query on submit to refresh teams list

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: use server action to invalidate server-side teams cache

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: conditionally render avatar in browser view to remove extra padding

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix browser view

* test: update team creation E2E tests to use new onboarding-v3 flow

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* test: update auth-index.e2e.ts to use new team creation flow

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* test: update team-management.e2e.ts to use new team creation flow

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: add error handling for createTeam and improve CSV parsing for quoted fields

Co-Authored-By: sean@cal.com <Sean@brydon.io>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 14:53:51 +00:00
a8abe2cdf1 ci: add separate typecheck and lint workflows for companion (#26961)
* ci(companion): add separate typecheck workflow to catch type errors

This adds a new companion-typecheck.yml workflow that runs TypeScript type
checking for the companion app. This would have caught the missing useEffect
import issue in PR #26931.

Changes:
- Add new companion-typecheck.yml workflow file
- Update pr.yml to call the new workflow when companion files change
- Add typecheck-companion to the required jobs list

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* add lint checks

* test

* remove

* update typecheck

* address review

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 14:40:43 +00:00
ea66a9093c fix(teams): add organization scope to membership operations (#26964)
* refactor(teams): improve membership validation for org admins

- Add organization scope validation to removeMember handler
- Ensure team operations are scoped to users organization context
- Update related tests

* test(teams): align removeMember tests with updated interface

- Add organizationId to test contexts
- Add team.findMany mock for org validation
- Add test cases for org scope validation

* refactor(teams): use TeamRepository for org validation in LegacyRemoveMemberService

- Add findByIdsAndOrgId method to TeamRepository
- Inject TeamRepository into LegacyRemoveMemberService via constructor
- Update RemoveMemberServiceFactory to instantiate and inject TeamRepository
- Update tests to mock TeamRepository instead of direct prisma calls

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: keith@cal.com <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 11:26:05 -03:00
62216f2db6 feat: add CalendarsTasker with sync and trigger.dev versions (#26854)
* feat: add CalendarsTasker with sync and trigger.dev versions

This PR implements a CalendarsTasker following the same pattern as
PlatformOrganizationBillingTasker to replace the logic in
apps/api/v2/src/ee/calendars/processors/calendars.processor.ts

New files created:
- CalendarsTasker main orchestrator extending Tasker base class
- CalendarsSyncTasker for sync execution
- CalendarsTriggerTasker for async execution via trigger.dev
- CalendarsTaskService with business logic for ensuring default calendars
- trigger.dev task with queue config and retry settings
- DI modules using @evyweb/ioctopus
- NestJS DI modules for API v2

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: import and deasync

* style: format trigger.config.ts dirs array

Co-Authored-By: unknown <>

* refactor: move prisma query to UserRepository and set onboarding to true

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: remove credential.key from UserRepository method

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 16:20:05 +02:00
sean-brydon e0c637b8ec feat: add seat tracking infrastructure for monthly proration (#27001)
Part 1 of monthly proration feature.

Adds seat change tracking infrastructure with operationId for idempotency.

**Dependency chain:**
- This PR (seat tracking)
- PR #27002  depends on this
2026-01-19 13:56:30 +00:00
Alex van Andel 9690a0111d fix: Outdated lockfile
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-19 13:53:58 +00:00
Alex van Andel 60e5aa6afb chore: release v6.1.1 2026-01-19 13:51:00 +00:00
b8166293e9 feat: add organizeImports and useSortedClasses to biome config (#26999)
* feat: add organizeImports and useSortedClasses to biome config

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* feat: add custom import groups matching trivago plugin order

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 13:41:25 +00:00
Dhairyashil Shinde 28bf058b16 fix(companion): Android bottom navbar styling and iOS event type spacing issues (#26981)
* refactor: android bottom navbar color

* fix bottom navbar color for android and new account can log in now

* fix ios event type item spacing issue
2026-01-19 13:59:11 +01:00
950f9555ee fix(ui): update coss ui components (#26989)
* fix(ui): update coss ui components

* fix(sidebar): remove redundant overflow-auto from SidebarContent

ScrollArea already provides the scroll container, so keeping overflow-auto
on the child creates a nested scroll area and prevents scrollFade from
reflecting actual overflow.

Addresses Cubic AI review feedback with confidence 9/10.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 09:45:20 +00:00
d137787330 feat: API endpoint to fetch bookings for standalone teams (#26818)
* inputs valid

* modules

* similar route to get bookings

* removed plan

* test case spec

* fix: e2e tests for teams booking controller

* chore: update openapi spec

* added filter

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* filter cases

* test(teams-bookings): fix eventTypeIds filter test to use correct query parameter

* fix: e2e tests

* fix: e2e tests

* fixup

---------

Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-19 09:32:27 +00:00
2227d990b6 refactor: replace loggedInUsersTz with timeZone property in busy-times API (#25440)
* refactor: replace loggedInUsersTz with timeZone in busy-times API

- Add new timeZone parameter to CalendarBusyTimesInput
- Mark loggedInUsersTz as deprecated
- Update getBusyTimes endpoint to prioritize timeZone parameter
- Maintain backward compatibility with loggedInUsersTz
- Add validation to ensure at least one timezone parameter is provided
- Update API documentation with new parameter example

Fixes #25423

* fix: improve timezone validation in CalendarBusyTimesInput

- Use custom ValidatorConstraint instead of problematic ValidateIf
- Properly validate that at least one timezone parameter is provided
- Improve code quality and clarity

* fix: update DTOs for getBusyTimes

* cleanup

* fix: abstract normalize timezone logic into platform types util function

* chore: update e2e tests

* fixup

* fixup

---------

Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-01-19 09:22:19 +00:00
Syed Ali Shahbaz c1d0a6bb1b fix: Stores the DateRange in UTC instead of user machine that caused the bug (#26900)
* fix init

* remove comment

* fix to v2

* type fix

* edge case

* test fix to suit the date storage method

* fix for atoms

* backward compatibility

* fix test mock

* test fix?

* testing a theory

* address cubic
2026-01-19 10:41:53 +02:00
9f0d035a3b fix: pass seatUid when rescheduling seated booking from booking limit error (#26389)
* fix: pass seatUid when rescheduling seated booking from booking limit error

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* test: add test case for seatUid in booking limit reschedule error for seated events

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 17:30:29 +09:00
0aad5520cc chore: ensure default selected calendars in calendars processor job (#26944)
* chore: ensure default selected calendars handleEnsureDefaultCalendars

* fix: bypass cache when ensureDefaultSelectedCalendars is true

When ensureDefaultSelectedCalendars is true, the cache should be bypassed
to ensure the defaults logic actually runs. Previously, cached data would
be returned before the ensure-defaults logic could execute.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 17:28:53 +09:00
Rajiv Sahal adc4272545 fix: atoms issues (#26983)
* fix: missiing imports

* chore: add popover components for atoms

* chore: keep openapi spec up to date
2026-01-19 08:09:57 +00:00
02530b86f3 perf: timezone select component (#26980)
* perf: timezone select component

* fix: type error

* fix: type error

* fix: use object assign

* fix: use data. length

* fix: use props.data reference instead of length for memoization

The useMemo dependency on props.data?.length could return stale timezone
options when the array contents change but the length stays the same.
Using the full props.data reference ensures updates propagate correctly.

Fix identified by Cubic AI (confidence 9/10)

Co-Authored-By: unknown <>

* fix: use data. length

* fix: use props.data reference instead of length for memoization

The useMemo dependency on props.data?.length could return stale timezone
options when the array contents change but the length stays the same.
Using the full props.data reference ensures updates propagate correctly.

Fix identified by Cubic AI (confidence 9/10)

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-19 11:59:08 +05:30
cal-com-ci[bot]andLingo.dev ad2255aaa6 feat: update translations via @LingoDotDev (#26776)
Co-authored-by: Lingo.dev <support@lingo.dev>
2026-01-19 00:23:46 +00:00
Dhairyashil Shinde f915088d78 feat: add new issue template for companion (#26939) 2026-01-18 21:12:48 -03:00
da143ae546 fix: availability unlockedFields initialisation for team-managed event types (#25666)
* Fix: availability unlockedFields initialisation for team-managed event types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: init managed event type for local atoms testing

* chore: add changeset file

* chore: add tests

* fix: restore eslint-disable comments in managed-user.ts

Addresses review feedback from @anikdhabal to fix the eslint comment
issues where comments were accidentally replaced with whitespace.

Co-authored-by: gusdudey2k <45557946+gusdudey2k@users.noreply.github.com>
Co-Authored-By: unknown <>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-18 09:31:27 -03:00
Rajiv Sahal 19f4677d95 chore: update docs (#26971) 2026-01-18 08:47:23 -03:00
MorganandDevin AI bca6615da9 test: add unit tests for Tasker class (#26975)
- Test that params are properly passed to async tasker methods
- Test that params are passed in correct order
- Test fallback to sync tasker when async tasker fails
- Test params are passed correctly to sync tasker fallback
- Test error handling when both taskers fail
- Test logging of dispatch information with args
- Test behavior when async tasker is disabled (missing env vars)
- Test error details logging

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-18 11:06:43 +00:00
Dhairyashil Shinde dccc69e6a4 fix(companion): add missing useEffect import and fix type errors (#26960)
* fix(companion): add missing useEffect import to AvailabilityDetailScreen

* fix(companion): fix type errors in edit-availability-hours routes
2026-01-17 21:35:27 +05:30
9eb5692c3c feat: api v2 team invite link endpoint (#26644)
* init: team invite link endpoint

* chore: add e2e tests

* fix: use SUCCESS_STATUS and ERROR_STATUS constants in invite output DTO

Address Cubic AI review feedback by using proper enum typing with
SUCCESS_STATUS and ERROR_STATUS constants from @calcom/platform-constants
for consistency with other API v2 output DTOs.

Co-Authored-By: unknown <>

* fixup: add missing memberships module

* fixup: revert previous change, not needed

* chore: use createInvite from teams service

* chore: remove unused value

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-17 07:16:07 -03:00
9fcddbf27b refactor: calEventParser CalendarEvent ISP (#25890)
* refactor: calEventParser CalendarEvent ISP

* update

* fix: complete CalEventParser ISP refactoring - update call sites and fix type errors

- Update getUid call sites to pass only uid instead of whole CalendarEvent
- Update getLocation call sites to pass narrow shape with videoCallData, additionalInformation, location, uid
- Update narrow input shapes to accept null for location (matching CalendarEvent type)
- Update recurringEvent type to accept RecurringEvent | null instead of boolean
- Update videoCallData type to be more flexible ({ type?: string; url?: string })
- Fix ManageLink.tsx to pass recurringEvent directly instead of converting to boolean

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* test: update CalEventParser tests to use narrow input shapes

- Update getPublicVideoCallUrl test to pass uid instead of calEvent
- Update getVideoCallPassword tests to pass videoCallData instead of calEvent

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* few fix

* fix type error

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-17 10:40:01 +05:30
DeepanshuandDeepanshu Verma c42d60256d Fix app card action button alignment (#26954)
Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
2026-01-17 10:24:44 +05:30
Eesh Midha 07fee3a0aa fix: prevent HTML encoding of forward slash in booking confirmation (#26949)
- Add interpolation: { escapeValue: false } to AttendeeRequestEmail.tsx
- Add interpolation: { escapeValue: false } to attendee-request-email.ts
- Add interpolation: { escapeValue: false } to bookings-single-view.tsx

This prevents special characters like '/' from being HTML-encoded to '&#x2F;'
in booking confirmation emails and success page dialogs.

Fixes #26938
2026-01-17 04:53:38 +00:00
9c6e331a37 fix: validate hosts belong to team in managed event type create/update (#26952)
* fix: validate hosts belong to team in managed event type create/update

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: add e2e tests for managed event type host validation

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: move update test after get team event-types test to fix ordering

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 22:35:56 +00:00
Rajiv SahalandDevin AI 1f28504db1 fix(api): add @ApiExtraModels for location types in OpenAPI spec (#26951)
The UpdateInputAddressLocation_2024_08_13 and related location types were
referenced via getSchemaPath() but not registered with @ApiExtraModels,
causing them to be missing from the generated OpenAPI spec.

This fix adds @ApiExtraModels decorator to the BookingLocationController
to register all location types used in the UpdateBookingLocationInput.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-17 00:22:19 +02:00
Dhairyashil Shinde 9d2fa89a5e feat(companion): add optimistic updates to EventTypeDetail screen 2 (#26945)
* feat(companion): add optimistic updates to EditAvailabilityNameScreen

- Refactor useUpdateSchedule hook with optimistic updates
- Update EditAvailabilityNameScreen to use mutation hook instead of direct API call
- Update EditAvailabilityNameScreen.ios.tsx with same pattern
- Cache is updated immediately on save, then synced with server
- On error, cache is rolled back to previous state

* fix(companion): fix cache update for schedule list when detail cache is empty

- Update list cache in onMutate even when detail cache doesn't exist
- Remove onSettled invalidation that was causing issues with staleTime: Infinity
- Add fallback invalidation in onSuccess when list cache doesn't exist

* fix(companion): fix AvailabilityDetailScreen not reflecting cache updates

The previous optimistic updates implementation in EditAvailabilityNameScreen
correctly updated the React Query cache, but AvailabilityDetailScreen was
still using direct CalComAPIService.getScheduleById() calls with local
useState, completely bypassing the cache.

The disconnect:
- EditAvailabilityNameScreen → useUpdateSchedule → Updates React Query Cache ✓
- AvailabilityDetailScreen → CalComAPIService.getScheduleById → Local state ✗

This meant when a user saved changes to a schedule's name/timezone, the
cache was updated but the detail screen (and subsequently the list screen)
never saw those updates because they weren't reading from the cache.

Changes:
- Refactor AvailabilityDetailScreen.tsx to use useScheduleById hook
- Refactor AvailabilityDetailScreen.ios.tsx to use useScheduleById hook
- Replace direct API calls with React Query for cache synchronization
- Add RefreshControl for pull-to-refresh support
- Use mutation hooks (useSetScheduleAsDefault, useDeleteSchedule) for actions
- Derive availability/overrides data using useMemo from query result

Now when EditAvailabilityNameScreen updates the cache, AvailabilityDetailScreen
automatically reflects those changes because both read from the same cache.

* feat(companion): refactor EditAvailabilityOverrideScreen to use mutation hook

- Replace direct CalComAPIService.updateSchedule calls with useUpdateSchedule hook
- Remove local isSaving state, use isPending from mutation hook instead
- Cache is now updated automatically via the mutation hook's optimistic updates
- Consistent pattern with EditAvailabilityNameScreen refactoring

* feat(companion): refactor EditAvailabilityDayScreen to use mutation hook

- Replace direct CalComAPIService.updateSchedule calls with useUpdateSchedule hook
- Remove local isSaving state, use isPending from mutation hook instead
- Cache is now updated automatically via the mutation hook's optimistic updates
- Consistent pattern with EditAvailabilityNameScreen and EditAvailabilityOverrideScreen

* fix(companion): refactor edit-availability-hours routes to use useScheduleById hook

The working hours page (page 2 in the flow) was showing stale data because
it used direct CalComAPIService.getScheduleById() calls with local useState,
bypassing the React Query cache.

The disconnect:
- EditAvailabilityDayScreen → useUpdateSchedule → Updates React Query Cache ✓
- edit-availability-hours route → CalComAPIService.getScheduleById → Local state ✗

This meant when a user saved changes to a day's availability, the cache was
updated but the working hours page never saw those updates because it wasn't
reading from the cache.

Changes:
- Refactor edit-availability-hours.tsx to use useScheduleById hook
- Refactor edit-availability-hours.ios.tsx to use useScheduleById hook
- Replace direct API calls with React Query for cache synchronization
- Now all 3 pages in the flow read from the same cache

* fix(companion): make Date Overrides section clickable when empty

Previously, when there were no date overrides, the Date Overrides section
was just a plain View without any press handler, making it impossible for
users to navigate to the edit override page to add new overrides.

This follows the same pattern as other sections (Weekly Schedule, Timezone)
which are always clickable regardless of their content state.

Changes:
- Wrap the 'No Overrides' section in AppPressable with navigation handler
- Add chevron-forward icon to indicate it's tappable
- Apply fix to both AvailabilityDetailScreen.tsx and .ios.tsx

* fix(companion): use useEffect instead of useMemo for side effects

- Change useMemo to useEffect for onActionsReady callback (side effect)
- Move error handling (showErrorAlert, router.back) to useEffect
- Keep early return for error state after useEffect hooks

Fixes Cubic AI review feedback (confidence 9/10)

* feat(companion): add optimistic updates to EventTypeDetail screen

- Enhance useUpdateEventType hook with full optimistic update support
  - Add onMutate callback to update cache immediately
  - Add onSuccess callback to sync with server response
  - Add onError callback to rollback on failure
  - Update both eventTypes.detail(id) and eventTypes.lists() caches

- Refactor handleSave in event-type-detail.tsx
  - Replace direct CalComAPIService.updateEventType() with useUpdateEventType hook
  - Replace direct CalComAPIService.createEventType() with useCreateEventType hook
  - Remove manual fetchEventTypeData() call after save (cache updates automatically)
  - Replace local saving state with mutation hooks' isPending states

- Refactor handleDelete in event-type-detail.tsx
  - Replace direct CalComAPIService.deleteEventType() with useDeleteEventType hook

This ensures the event types list updates immediately after save/delete
without requiring manual refresh.
2026-01-16 19:04:52 -03:00
442779d08d feat: monthly-proration-tasker (#26870)
* feat: monthly-proration-taskerh

* remove cronjob from tasker implementation

* feat: add DI for MonthlyProrationService and TriggerDevLoggerServiceModule

- Create TriggerDevLoggerServiceModule for DI injection of TriggerDevLogger
- Add tokens for TriggerDevLogger in shared.tokens.ts
- Create MonthlyProrationService DI module and container
- Update processMonthlyProrationBatch.ts to use DI container
- Use redactError in Tasker.ts to avoid logging sensitive information

Co-Authored-By: sean@cal.com <Sean@brydon.io>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 20:58:51 +00:00
Rajiv SahalandDevin AI b7c497f79e fix(ci): add build step for platform packages in API v2 breaking changes check (#26948)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-17 01:43:01 +05:30
Dhairyashil Shinde ef0af95bb1 feat(companion): add optimistic updates to availability edit screens (#26931)
* feat(companion): add optimistic updates to EditAvailabilityNameScreen

- Refactor useUpdateSchedule hook with optimistic updates
- Update EditAvailabilityNameScreen to use mutation hook instead of direct API call
- Update EditAvailabilityNameScreen.ios.tsx with same pattern
- Cache is updated immediately on save, then synced with server
- On error, cache is rolled back to previous state

* fix(companion): fix cache update for schedule list when detail cache is empty

- Update list cache in onMutate even when detail cache doesn't exist
- Remove onSettled invalidation that was causing issues with staleTime: Infinity
- Add fallback invalidation in onSuccess when list cache doesn't exist

* fix(companion): fix AvailabilityDetailScreen not reflecting cache updates

The previous optimistic updates implementation in EditAvailabilityNameScreen
correctly updated the React Query cache, but AvailabilityDetailScreen was
still using direct CalComAPIService.getScheduleById() calls with local
useState, completely bypassing the cache.

The disconnect:
- EditAvailabilityNameScreen → useUpdateSchedule → Updates React Query Cache ✓
- AvailabilityDetailScreen → CalComAPIService.getScheduleById → Local state ✗

This meant when a user saved changes to a schedule's name/timezone, the
cache was updated but the detail screen (and subsequently the list screen)
never saw those updates because they weren't reading from the cache.

Changes:
- Refactor AvailabilityDetailScreen.tsx to use useScheduleById hook
- Refactor AvailabilityDetailScreen.ios.tsx to use useScheduleById hook
- Replace direct API calls with React Query for cache synchronization
- Add RefreshControl for pull-to-refresh support
- Use mutation hooks (useSetScheduleAsDefault, useDeleteSchedule) for actions
- Derive availability/overrides data using useMemo from query result

Now when EditAvailabilityNameScreen updates the cache, AvailabilityDetailScreen
automatically reflects those changes because both read from the same cache.

* feat(companion): refactor EditAvailabilityOverrideScreen to use mutation hook

- Replace direct CalComAPIService.updateSchedule calls with useUpdateSchedule hook
- Remove local isSaving state, use isPending from mutation hook instead
- Cache is now updated automatically via the mutation hook's optimistic updates
- Consistent pattern with EditAvailabilityNameScreen refactoring

* feat(companion): refactor EditAvailabilityDayScreen to use mutation hook

- Replace direct CalComAPIService.updateSchedule calls with useUpdateSchedule hook
- Remove local isSaving state, use isPending from mutation hook instead
- Cache is now updated automatically via the mutation hook's optimistic updates
- Consistent pattern with EditAvailabilityNameScreen and EditAvailabilityOverrideScreen

* fix(companion): refactor edit-availability-hours routes to use useScheduleById hook

The working hours page (page 2 in the flow) was showing stale data because
it used direct CalComAPIService.getScheduleById() calls with local useState,
bypassing the React Query cache.

The disconnect:
- EditAvailabilityDayScreen → useUpdateSchedule → Updates React Query Cache ✓
- edit-availability-hours route → CalComAPIService.getScheduleById → Local state ✗

This meant when a user saved changes to a day's availability, the cache was
updated but the working hours page never saw those updates because it wasn't
reading from the cache.

Changes:
- Refactor edit-availability-hours.tsx to use useScheduleById hook
- Refactor edit-availability-hours.ios.tsx to use useScheduleById hook
- Replace direct API calls with React Query for cache synchronization
- Now all 3 pages in the flow read from the same cache

* fix(companion): make Date Overrides section clickable when empty

Previously, when there were no date overrides, the Date Overrides section
was just a plain View without any press handler, making it impossible for
users to navigate to the edit override page to add new overrides.

This follows the same pattern as other sections (Weekly Schedule, Timezone)
which are always clickable regardless of their content state.

Changes:
- Wrap the 'No Overrides' section in AppPressable with navigation handler
- Add chevron-forward icon to indicate it's tappable
- Apply fix to both AvailabilityDetailScreen.tsx and .ios.tsx

* fix(companion): use useEffect instead of useMemo for side effects

- Change useMemo to useEffect for onActionsReady callback (side effect)
- Move error handling (showErrorAlert, router.back) to useEffect
- Keep early return for error state after useEffect hooks

Fixes Cubic AI review feedback (confidence 9/10)
2026-01-16 19:08:52 +01:00
25f7381393 fix: add ensureProtocol helper to handle URLs without protocol (#26667)
* fix(event-types): keep slug in sync with title until manually edited

Changed from checking `touchedFields` to `dirtyFields` when deciding
whether to sync the slug with the title. This fixes the issue where
merely focusing on the slug field would stop the sync, even if the
user didn't actually edit it.

Now the slug stays in sync with the title until the user actually
modifies the slug value.

Note: The hardcoded "Slug" label for platform users was preserved from
the original code. Localizing it would be a separate enhancement.

Fixes #26265

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add ensureProtocol helper to handle URLs without protocol

Some container orchestration tools (like Coolify) strip the protocol
from URL environment variables. This causes `new URL()` to throw
`ERR_INVALID_URL` because strings like "sub.domain.com" are invalid
without a protocol prefix.

This fix adds an `ensureProtocol` helper function that:
- Returns empty string for null/undefined URLs
- Preserves URLs that already have http:// or https://
- Prepends https:// to URLs missing the protocol

Applied to WEBAPP_URL, WEBSITE_URL, and CAL_URL env var parsing.

Fixes #25774

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Clarify URL protocol handling in comments

Updated comment to clarify handling of URLs.

* Refactor slug handling in CreateEventTypeForm

---------

Co-authored-by: simiondolha <simiondolha@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-16 16:03:32 +00:00
463987c02d feat: add GitHub Action to check Prisma migrations match schema (#26897)
* feat: add GitHub Action to check Prisma migrations match schema

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: use CI_DATABASE_URL secret instead of hardcoded URL

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: add test field to verify prisma migration check workflow

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use git-based check for prisma changes to bypass paths-filter issue

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add migration for test field to verify prisma migration check workflow

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: revert test field and migration after verifying workflow

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: split paths-filter into two actions to fix predicate-quantifier issue

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: rename has_companion to has-companion for consistent naming

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: update steps.filter references to steps.filter-exclusions

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 15:50:20 +00:00
c0302bfc51 fix: get bookings handler for pbac and fallback roles (#25434)
* fix: getTeamIdsWithPermission

* fix get bookings handler for pbac and fallback roles

* add tests

* fix fallback roll query

* push integration test fixes

* Check for pbac features

* fix

* restore role behaviour

* fix fallabck roles no pbac enabled

* debug: add logging to investigate PBAC query failures

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* re-write integration tests

* fix: use >= comparison with bigint cast for PBAC permission count

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* Restore permission repo

* re-write from scratch

* fix tests + file

* imrpove perf by makign CTE and moving to left join

* fix org scoped taems

* clean up

* fix: update PermissionCheckService mock to use function instead of arrow function

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* refactor: rename scopedOrgId to orgId

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* refactor: use MembershipRole enum instead of hardcoded strings

Co-Authored-By: sean@cal.com <Sean@brydon.io>

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
2026-01-16 15:03:15 +00:00
Peer RichelsenandDevin AI d6c9967c1b feat(companion): add register=false param to OAuth URL for iOS (#26905)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 20:30:12 +05:30
Dhairyashil Shinde 80c973def5 chore/remove-platform-issue-template (#26941) 2026-01-16 14:46:53 +00:00
Eesh MidhaandDevin AI 54af3a2939 fix: sync filter segment checkmark with button selection state (#26930)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 14:05:55 +00:00
Morgan 9391b523e3 fix: rrHostsubsetIds not provided to mapBookingToMutationInput, atoms 2.3.1 (#26122) 2026-01-16 13:55:09 +00:00
Rajiv SahalandDevin AI 689ce1ec7f fix: rescheduled booking with multiple durations does not preserve the duration (API v2) (#26746)
* fix: make sure we dont implement directly from @calcom/features

* fix: preserve the original booking duration instead of using the default event type length

* chore: update tests

* fix: merge conflicts

* chore: revert linting changes

* chore: implement PR feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 13:53:50 +00:00
Eunjae LeeandDevin AI f691258a5c refactor(agents): move prescriptive content from knowledge-base to rules (#26925)
* refactor(agents): move prescriptive content from knowledge-base to rules

- Create architecture-page-level-auth.md for Next.js auth checks
- Create data-prefer-select-over-include.md for Prisma query optimization
- Create performance-dayjs-usage.md for Day.js performance guidelines
- Create quality-avoid-barrel-imports.md for import best practices
- Update knowledge-base.md to reference rules directory
- Remove duplicated prescriptive content from knowledge-base.md

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* chore(agents): remove redundant rules reference from knowledge-base

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: add agents/rules reference to AGENTS.md extended documentation

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 10:43:36 -03:00
9affeef99e fix: seated event bug (#26929)
* fix: seated event bug

* fix

* add tests

* fix type error

* small tweak

---------

Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-16 13:29:25 +00:00
Anik Dhabal Babu c297c7704e fix: flaky E2E tests (#26934)
* flaky-e2e

* fix one more
2026-01-16 18:50:23 +05:30
Hariom BalharaandDevin AI bd10eb9983 feat: seed admin API key for local development (#26876)
* feat: seed admin API key for local development

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: query API key by hash instead of separate ID

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: remove redundant comments from seedApiKey

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: make seedApiKey reusable and use owner1-acme user

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: extract ensureAcmeOwnerHasApiKeySeeded wrapper function

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 18:45:48 +05:30
Udit Takkar 7a9fdd5a0c feat: add react best practises and web design skills (#26918)
## What does this PR do?

This PR adds https://vercel.com/blog/introducing-react-best-practices for your coding agent using `npx add-skill vercel-labs/agent-skills` command

The skills are added to `.claude/`, `.cursor/`, and `.opencode/` directories to provide React and Next.js performance optimization guidance for AI-assisted workflows.

## Updates since last revision

Addressed Cubic AI review feedback for issues with confidence >= 9/10:

- **rerender-dependencies.md** - Replaced `console.log(user.id)` with `fetchUserDetails(user.id)` to avoid logging sensitive information
- **server-after-nonblocking.md** - Removed `sessionCookie` from `logUserAction` call to avoid logging sensitive authentication data, added `await` to async call
- **bundle-conditional.md** - Added `loadError` state and `setLoadError` setter to fix undefined `setEnabled` reference
- **advanced-event-handler-refs.md** - Updated `useWindowEvent` handler signature to accept `Event` parameter and forward it to the stored handler
- **rerender-derived-state.md** - Closed `<nav>` elements in both examples for valid JSX

Fixes applied to both `.claude` and `.cursor` skill directories for consistency.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] N/A I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox.
- [x] N/A, I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

These are documentation files for AI coding agents. No runtime testing required - review the markdown files to verify the example code snippets are correct.

## Checklist for human review

- [ ] Verify example code snippets in the skill files are syntactically correct
- [ ] Confirm the fixes don't introduce new issues in the documentation examples
- [ ] Check that `.claude` and `.cursor` directories have consistent content

---

Link to Devin run: https://app.devin.ai/sessions/f7f7e67fdeea4b22a4817d63ed9e1759
Requested by: unknown ()
2026-01-16 17:19:34 +05:30
c9f9712f41 fix: meeting URL is missing in the email after rescheduling a seated event (#26914)
* fix: missing meeting url

* test: verify reschedule emails for seated events include meeting URL

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 10:49:38 +00:00
Volnei Munhoz b584f0a9de chore: reduce log spam on Calendars (#26927)
* Remove Vercel warnings on deploy

* reduce log noise
2026-01-16 10:41:00 +00:00
Dhairyashil Shinde 411ca11d25 feat: pass register param directly to login page from OAuth authorize (#26922) 2026-01-16 10:25:39 +00:00
Eunjae Lee b13e0f46ad feat: clear all filters when deselecting a segment (#26920)
## What does this PR do?

When a filter segment is selected and the user clicks it again to deselect, this PR now clears all active filters in addition to deselecting the segment.

Previously, deselecting a segment only called `setSegmentId(null)`, which removed the segment selection but left the filters in place. Now it calls `clearAll()` which clears both the segment selection and all active filters.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Go to a page with DataTable and filter segments (e.g., Bookings page or Organization Members page)
2. Select a filter segment (e.g., "My Bookings" system segment or a user-created segment)
3. Verify filters are applied (URL contains `activeFilters`)
4. Click the same segment again to deselect it
5. Verify the segment is deselected AND all filters are cleared (URL should no longer contain `activeFilters`)

An e2e test has been added to `filter-segment.e2e.ts`:
- `Deselecting a segment clears all active filters`

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

## Human Review Checklist

- [ ] Verify that calling `clearAll()` instead of `setSegmentId(null)` is the intended behavior (clears both segment selection and all active filters)
- [ ] Consider if there are use cases where users might want to keep filters when deselecting a segment

---

> **Link to Devin run**: https://app.devin.ai/sessions/44f22b80d9c442bdb334d04dac2b476d
> **Requested by**: @eunjae-lee
2026-01-16 11:19:25 +01:00
Keith Williams 20dfa93527 revert: "fix: api v2 get event-types non org users (#26896)" (#26924)
This reverts commit 77c8e34073.
2026-01-16 10:10:20 +00:00
Keith WilliamsandDevin AI d4ea931bf8 feat(agents): add modular engineering rules from 2026 standards (#26847)
* feat(agents): add modular engineering rules from 2026 standards

Add a rules directory with individual rule files derived from the
Cal.com Engineering in 2026 and Beyond blog post. Rules are organized
by section (architecture, quality, data, api, performance, testing,
patterns, culture) following the Vercel agent-skills structure.

Includes:
- _sections.md defining rule categories and impact levels
- _template.md for creating new rules
- 14 individual rule files covering key engineering standards
- README documenting the rules structure and usage

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat(agents): consolidate DI and Repository+DTO docs into rules

- Move di-pattern.md content to rules/patterns-di-pattern.md
- Extract Repository + DTO section from knowledge-base.md into:
  - rules/data-repository-methods.md (method naming conventions)
  - rules/data-dto-boundaries.md (DTO location and naming)
- Update knowledge-base.md to reference the new rule files
- Delete old di-pattern.md file

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore(agents): remove stub reference sections from knowledge-base.md

The rules directory is self-contained with its own README, so these
redirect sections are unnecessary clutter.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor(agents): combine DI pattern rules into single file

Merged patterns-di-pattern.md into patterns-dependency-injection.md
to eliminate overlap and create one comprehensive DI guide.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 10:57:28 +01:00
Carina WollendorferandDevin AI 9f231d98a4 fix: sort workflow dropdown to show org before teams (#26796)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 08:57:47 +00:00
Peer RichelsenandDevin AI fc518bfdc1 feat: allow link cloaking for Organization accounts in workflow emails (#26528)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 08:33:38 +00:00
Anik Dhabal Babu 04c9453d5c fix: cancel workflow (#26915) 2026-01-16 08:27:24 +00:00
Alex van Andel 8d1ad74650 chore: release v6.1.0
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-16 00:57:52 +00:00
Manas KengeandAnik Dhabal Babu b843c19f01 fix: Availability reset to default hours on day toggle (#26410)
* persist toggle time

* Refactor time slot management in Schedule component

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-16 00:52:44 +00:00
4d9e726fef fix: make SSR-safe and fix ESLint warning for Beacon in UserDropdown (#24275)
* fix(user-dropdown): make SSR-safe and fix ESLint warning for Beacon

* fix: added ssr guard in second useEffect and added type for beacon instead of ts-ignoring

* fix: add dependency array to Beacon useEffect

Address review feedback by adding [user?.username] dependency array
to the Beacon session-data useEffect, improving performance by
preventing unnecessary re-runs on every render.

Co-authored-by: albin-baby-2002 <albinbaby2002@gmail.com>
Co-Authored-By: unknown <>

* test: add automated tests for UserDropdown Beacon functionality

Add comprehensive tests for:
- Beacon session-data calls with correct payload
- Handling of undefined Beacon (no errors)
- Username change triggering useEffect re-run
- SSR safety (window undefined check)
- Component rendering states (loading, user available, no user)

Co-authored-by: albin-baby-2002 <albinbaby2002@gmail.com>
Co-Authored-By: unknown <>

* refactor: remove useless comments and misleading SSR test

- Remove redundant comments above vi.mock calls (per keithwillcode feedback)
- Remove SSR safety test that provided false coverage since jsdom always has window defined (per Cubic feedback)
- The 'should not throw error when Beacon is undefined' test already covers graceful handling

Co-Authored-By: unknown <>

* fix: remove unused @ts-expect-error directives

The Window interface is augmented with optional Beacon and Support properties,
so TypeScript allows deleting them without errors.

Co-Authored-By: unknown <>

* fix: handle lazy-loaded Beacon with polling

When Beacon loads lazily after component mount, the useEffect now polls
every second until Beacon becomes available, then sends session data
and clears the interval. This ensures session info is always sent even
when HelpScout loads asynchronously.

Added test to verify lazy loading behavior works correctly.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: albin-baby-2002 <albinbaby2002@gmail.com>
2026-01-16 00:43:01 +00:00
0a0b32046f fix: spacing between editable heading and pencil fixed (#25500)
* fix: spacing in editable heading fixed

* fix: set pointer events auto in input

* fix: updated availability test

* fix: updated pointer events

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Pedro Castro <pedro@cal.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-16 00:01:40 +00:00
Keith WilliamsandDevin AI 4932588309 fix: remove Stale label when Devin starts completing a stale PR (#26909)
* fix: remove Stale label when Devin starts completing a stale PR

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: update Devin prompt to remove Stale label after pushing changes

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: use lowercase 'stale' label to match repository label

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update stale-pr-devin-completion.yml

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 20:09:17 -03:00
Peer RichelsenandDevin AI eb2fedf7de feat: hide 'Don't have an account?' button when register=false query param is set (#26904)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 20:09:34 +00:00
77c8e34073 fix: api v2 get event-types non org users (#26896)
* fix: get event-types non org users

* fix: add excludeOrgUsers parameter to findByUsername for targeted filtering

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: create dedicated findByUsernameExcludingOrgUsers function

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: add e2e test for same username org vs non-org user event types

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: move e2e test for same username org vs non-org to 2024_06_14

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add organizationId to orgUser in e2e test

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: reorder afterAll cleanup to delete users before team

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add organizationId null check to findByUsernameExcludingOrgUsers

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* Revert "fix: add organizationId null check to findByUsernameExcludingOrgUsers"

This reverts commit 0d31e3d5d7c0eaa408939d697ea790521e520a3c.

* fixup! fix: add organizationId null check to findByUsernameExcludingOrgUsers

* fix: restore /public suffix in e2e test URL

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use findByUsernameExcludingOrgUsers in getEventTypeByUsernameAndSlug when no org context

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fixup! fix: use findByUsernameExcludingOrgUsers in getEventTypeByUsernameAndSlug when no org context

* refactor: remove unused getEventTypesPublicByUsername from 2024_06_14 service

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: test user creation

* chore: add test for org event-types

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 19:26:51 +00:00
f5085af396 docs: improve beforeEventBuffer and afterEventBuffer descriptions in API v2 (#26899)
* docs: improve beforeEventBuffer and afterEventBuffer descriptions in API v2

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fixup! docs: improve beforeEventBuffer and afterEventBuffer descriptions in API v2

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 15:27:13 -03:00
Dhairyashil Shinde d68ae41eed fix: wrong-event-type-link-for-org-user with same username (#26884) 2026-01-15 22:55:34 +05:30
5364655f14 fix(ui): prevent page scroll when link button clicked in toolbar (#26662)
Adds e.preventDefault() to link button click handler to prevent
unexpected page scrolling behavior.

Fixes #26435

Co-authored-by: simiondolha <simiondolha@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 16:57:06 +00:00
22201cbc75 fix: app card description truncation (#26722)
* Fix app card description truncation

* Refactor AppCard description paragraph for line clamping

---------

Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-15 16:55:33 +00:00
Joe Au-Yeung 40a7f53d1f Add IF NOT EXISTS (#26893) 2026-01-15 16:46:09 +00:00
a328ff6bab test: CodeRabbit Generated Unit Tests: Add unit tests for permissions hooks, registry, and traversal (#23441)
* introduce a dependsOn permission string

* fix permissions toggle

* add DFS to allow permission chains

* Update packages/features/pbac/utils/permissionTraversal.ts

Co-authored-by: Eunjae Lee <hey@eunjae.dev>

* fix splitPerms to work with attributes or dotted resources

* CodeRabbit Generated Unit Tests: Add unit tests for permissions hooks, registry, and traversal

* Fix UTG issues (iteration 1)

---------

Co-authored-by: Sean Brydon <sean@cal.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-15 16:42:45 +00:00
Rajiv Sahal 568d9de160 chore: better error messages (#26890) 2026-01-15 18:28:54 +02:00
mintlify[bot] 0578c89766 docs: Minor clean up (#26892)
* Documentation edits made through Mintlify web editor

* Documentation edits made through Mintlify web editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2026-01-15 16:28:10 +00:00
Keith WilliamsandDevin AI 23ee05743e feat: add completion status to Cubic AI review comments (#26891)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 16:11:56 +00:00
Joe Au-Yeung adb7509d96 Rename migration file (#26889) 2026-01-16 01:06:19 +09:00
Keith Williamsandmintlify[bot] a2c769251a docs: Fix Cal.com brand casing inconsistencies (#26887)
* Update docs/api-reference/v2/oauth.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/self-hosting/deployments/gcp.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/self-hosting/deployments/gcp.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/self-hosting/deployments/gcp.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/self-hosting/deployments/gcp.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/self-hosting/deployments/gcp.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/api-reference/v2/oauth.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/self-hosting/deployments/gcp.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/self-hosting/deployments/gcp.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/api-reference/v2/oauth.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/self-hosting/deployments/gcp.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2026-01-15 15:27:20 +00:00
Anik Dhabal Babu 3feae24b20 fix: riverside video url regexp fix (#26886)
* revierside video

* Delete packages/prisma/migrations/20260115132417_test/migration.sql
2026-01-15 15:26:21 +00:00
mintlify[bot]andSyed Ali Shahbaz c5213be60d docs: Clean up (#26879)
* clean-up nav

* Documentation edits made through Mintlify web editor

* Documentation edits made through Mintlify web editor

* further clean up

* add oauth in sidebar

* --

* land in v2

* land in v2

* Documentation edits made through Mintlify web editor

* Documentation edits made through Mintlify web editor

* cleanup

* Documentation edits made through Mintlify web editor

* deprecated v1

---------

Co-authored-by: Syed Ali Shahbaz <alishahbaz7@gmail.com>
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2026-01-15 15:18:23 +00:00
9ea71d2ba5 refactor: migrate MembershipRole usages to PBAC permission checks (#26871)
* refactor: migrate MembershipRole usages to PBAC permission checks

- Refactor get.handler.ts to use PermissionCheckService for canUpdateTeams
- Refactor checkForInvalidAppCredentials.ts to use getTeamIdsWithPermission
- Refactor outOfOffice.utils.ts to use checkPermission for ooo.update
- Refactor checkIfOrgNeedsUpgrade.handler.ts to use organization.manageBilling
- Refactor getActiveOnOptions.handler.ts to use eventType.update permission
- Refactor WorkflowRepository.ts to use workflow.update permission
- Refactor organization.tsx to use team.update permission
- Refactor getEventTypesByViewer.ts to use eventType.update permission
- Refactor getPublicEvent.ts to use team.read permission for private teams
- Update CreateNewOutOfOfficeEntryButton.tsx to use canUpdateOOO prop

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: use organization.update permission instead of team.update for org management

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: rename teamsWithEventTypeManagePermission to teamsWithEventTypeUpdatePermission

Renamed variable to match the permission string being used (eventType.update)

Co-Authored-By: sean@cal.com <Sean@brydon.io>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 15:59:00 +01:00
Keith WilliamsandDevin AI 3a8fe8c7af perf: convert services to factory functions and add TypeScript project references (#26117)
* perf(app-store): convert services to factory functions to narrow SDK type exports

This change converts CRM, Calendar, Payment, and Analytics services from
exporting classes to exporting factory functions that return interface types.
This prevents SDK types (HubSpot, Stripe, etc.) from leaking into the type
system when TypeScript emits .d.ts files.

Services modified:
- CRM: hubspot, salesforce, closecom, pipedrive-crm, zoho-bigin, zohocrm
- Calendar: all 13 calendar services
- Payment: stripe, paypal, alby, btcpayserver, hitpay, mock-payment-app
- Analytics: dub

Video adapters were audited and already use factory pattern.

WIP: Salesforce CRM service has a type error that needs fixing.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(salesforce): add type assertion for appOptions in factory function

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update remaining consumers to use factory functions

- getAnalytics.ts: call factory function instead of new
- getConnectedApps.ts: call factory function instead of new
- salesforce/CrmService.ts: fix type assertion with default value
- salesforce/routingForm/incompleteBookingAction.ts: use factory function
- salesforce/routingFormBookingFormHandler.ts: use factory function

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(salesforce): add SalesforceCRM interface for Salesforce-specific methods

- Create SalesforceCRM interface extending CRM with findUserEmailFromLookupField and incompleteBookingWriteToRecord methods
- Add createSalesforceCrmServiceWithSalesforceType factory function for internal Salesforce modules
- Update routing form files to use the new factory function with proper typing

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(salesforce): correct return type in SalesforceCRM interface

The findUserEmailFromLookupField method returns { email: string; recordType: RoutingReasons } | undefined,
not string | undefined. Updated the interface to match the actual implementation.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update all call sites to use factory functions

- Update calendar API add files to use factory functions (7 files)
- Update Google Calendar test files to use factory functions (3 files)
- Update Salesforce test files to use SalesforceCRM interface
- Add testMode parameter to createSalesforceCrmServiceWithSalesforceType
- Remove unused @ts-expect-error directive in bookingScenario.ts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add GoogleCalendar interface and update factory functions for service-specific methods

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add type annotation to attendee parameter in google-calendar.e2e.ts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update selected-calendars/route.ts to use GoogleCalendar factory function

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update remaining GoogleCalendarService call sites to use factory function

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove explicit type annotation in google-calendar.e2e.ts to fix type error

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update test mocks to use factory function pattern for calendar and payment services

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: convert MockPaymentService to factory function in setupVitest.ts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(api-v2): call calendar service factory functions instead of using new

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* perf(trpc): add TypeScript project references to reduce build file count

- Add tsconfig.build.json to app-store with composite settings for declaration emit
- Add tsconfig.server.build.json to trpc with project references
- Add types and typesVersions to app-store package.json to redirect type resolution to dist-types
- Add build:types script to app-store for generating declarations
- Add dist-types to .gitignore

This reduces the tRPC build file count from 7,733 to 5,618 files (27% reduction)
by having TypeScript resolve to prebuilt .d.ts files instead of source files.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(app-store): add fallback to typesVersions for CI compatibility

The typesVersions now prefers dist-types but falls back to source files
when dist-types don't exist. This fixes CI type-check failures while
still allowing the optimization when dist-types are built.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Added build dependency for tRPC on app-store

* fix(app-store): exclude test directories from tsconfig.build.json

Exclude __tests__, __mocks__, and tests directories from the build
config to prevent test utility files (which import from outside rootDir)
from being included in the declaration emit.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(turbo): add build:types task definition for app-store

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(turbo): remove circular build dependency between trpc and app-store

The build:types task for app-store transitively imports from @calcom/features,
which imports from @calcom/trpc. This creates a circular build dependency when
@calcom/trpc#build depends on @calcom/app-store#build:types.

Solution: Remove the turbo dependency. The typesVersions fallback pattern
['./dist-types/*', './*'] will use source files when dist-types/ doesn't exist,
and use prebuilt declarations when they do exist (for faster builds).

Also exclude dist-types from regular tsconfig.json to prevent 'Cannot write file'
errors when dist-types/ exists.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor(app-store): rename dist-types to types for consistency

Rename the prebuilt TypeScript declarations folder from dist-types to types
to match the convention used by @calcom/trpc and other packages in the monorepo.

Updated files:
- tsconfig.build.json: declarationDir and exclude
- tsconfig.json: exclude
- package.json: typesVersions paths
- turbo.json: build:types outputs
- .gitignore: ignore path

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(api-v2): update ICS calendar test to mock factory function instead of class prototype

The IcsFeedCalendarService is now a factory function, not a class, so
jest.spyOn(IcsFeedCalendarService.prototype, 'listCalendars') no longer works.

Updated to use jest.spyOn(appStore, 'IcsFeedCalendarService').mockImplementation()
to mock the factory function return value instead.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor(app-store): rename factory functions to Build* naming convention

- Rename Calendar factory functions from create*CalendarService to BuildCalendarService
- Rename CRM factory functions from create*CrmService to BuildCrmService
- Rename Payment factory functions from PaymentService to BuildPaymentService
- Rename Analytics factory function from createDubAnalyticsService to BuildAnalyticsService
- Update all index.ts re-exports to use new names
- Update all call sites throughout the codebase
- Update test mocks to use new factory function names

This makes it clear that these are factory functions, not class constructors.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(app-store): update remaining CalendarService and PaymentService imports to Build* names

- Update api/add.ts files for applecalendar, caldavcalendar, exchange2013calendar, exchange2016calendar, exchangecalendar, ics-feedcalendar
- Update mock-payment-app index.ts to export BuildPaymentService
- Fix googlecalendar test import alias for createInMemoryDelegationCredentialForBuildCalendarService

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(tests): update payment service mocks to use BuildPaymentService

- Update setupVitest.ts to use BuildPaymentService instead of PaymentService
- Update handlePayment.test.ts mock to use BuildPaymentService

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: address PR review comments - rename to Build* and remove unused code

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: remove explanatory comments and fix indentation

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: update .gitignore to use *.tsbuildinfo pattern

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(api-v2): update IcsFeedCalendarService to BuildIcsFeedCalendarService in e2e test

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* style: format CalendarService.test.ts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Delete apps/ui-playground/next-env.d.ts

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 11:28:05 -03:00
Hariom BalharaandDevin AI 511cc87d34 fix: properly await async operations in addMembersToTeams (#26866)
* fix: properly await async operations in addMembersToTeams

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* test: add unit tests for addMembersToTeams function

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 19:54:47 +05:30
6501743e5e feat: Add attribute sync logic from Salesforce (#26517)
* Add db schema

* Add `CredentialRepository.findByTeamIdAndSlugs`

* Add enabled app slugs for attribute syncing

* Create repository for `IntegrationAttributeSync`

* Create zod schemas

* Create `AttributeSyncUserRuleOutputMapper`

* Create `IntegrationAttributeSyncService`

* Create DI contianer

* Create trpc endpoints

* Create page

* Include team name in `CredentialRepository.findByTeamIdAndSlugs`

* Update schema and relations

* Update types and schemas

* Add more methods to IntegrationAttributeSyncRepository

* Add more services to `IntegrationAttributeSyncService`
- getById
- Init updateIncludeRulesAndMappings

* Refactor `getTeams.handler` to use repository

* Create `createAttributeSync` trpc endpoint

* Create `updateAttributeSync` trpc endpoint

* Add router to trpc

* Create attribute sync child components

* Pass custom actions to `FormCard`

* Create `IntegrationAttributeSyncCard`

* Pass inital props via server side

* Fix prop

* Only refetch on mutation

* Fixes

* Add form error when duplicate field and attribute combo

* Add `updateTransactionWithRUleAndMappings` logic

* Adjust zod schemas

* Service add `updateIncludeRulesAndMappings`

* Pass orgId from server to component

* Rename types

* Add deleteById method to repository

* Add name to integrationAttributeSync

* Add deleteById method to service

* Rename method

* Add deleteAttributeSync trpc endpoint

* Make the IntegrationAttributeSyncCard a dummy component

* test: add tests for IntegrationAttributeSync feature

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Move creating a attribute sync record to the service

* Add i18n strings

* Safe select credential in find by id and team

* Fix default credentialId value in form

* Update repository return types

* Add i18n string

* Make credentialId optional for form schema

* Fix label

* Add cascade deletes

* Add verification that syncs belong to org

* Create mapper for repository output

* Type fixes

* Remove old test file

* Pass `attributeOptions` from parent to children

* Infer types from zod schema

* Type fixes

* Type fix

* Clean up

* Add i18n strings

* Remove unused file

* Address feedback

* Add migration file

* Address feedback

* Add validation for new integration values

* Remove unused router

* Move away from z.infer to z.ZodType

* Clean up comments

* Type fix

* Type fixes

* Type fix

* fix: add passthrough to syncFormDataSchema to preserve extra fields

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Add endpoint for SF to call

* Create scratch org config

* Create sf cli scripts

* Create package logic

* Update README

* Remove unused file

* Add indexes

* Add aria label

* Address feedback - consistent validation

* Fix import paths for attribute types

* Add `CredentialRepository.findByAppIdAndKeyValue`

* Get credential by instance URL

* Verify incoming sfdc orgId matches credential sfdc orgId

* Rename method

* Get user name integration syncs

* refactor: change attributeSyncRules array to singular attributeSyncRule

The database schema enforces a one-to-one relationship between
IntegrationAttributeSync and AttributeSyncRule (via @unique constraint),
and the UI only supports a single rule. This change makes the TypeScript
type match the database schema and UI behavior.

Changes:
- Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null
- Update mapper to return singular rule instead of wrapping in array
- Update UI component to access sync.attributeSyncRule directly
- Update IIntegrationAttributeSyncUpdateParams Omit type
- Update tests to use attributeSyncRule: null instead of attributeSyncRules: []

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Convert `membershipRepository.findAllByUserId` to a normal method

* Add temp files to git ignore

* Init  and process team conditions

* Biome formatting

* Add `AttributeService` to get user attributes

* Add DI container for AttributeService

* AttributeSyncService evaluate attribute conditions

* Create DI container for attributeSyncService

* Return result for full condition

* Evaluate if attribute sync should apply to user

* Add  method

* Change PrismaAttributeOptionRepository to instance methods

* Init AttributeSyncFieldMappingsService and process attribute syncs

* Add AttributeSyncFieldMappingService DI container

* Refactor orgId to organizationId

* Add membership validation to sync field service

* AttributeSYncFieldMappingService use repository methods

* AttributeSyncFieldMappingService.processMappings add mapping logic

* Add DI tokens

* user-sync endpoint to implement attribute syncing

* Validate team belongs to org for rule

* test: add tests for AttributeSyncRuleService, AttributeSyncFieldMappingService, and AttributeService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Remove duplicate migration file

* Fix merge conflict

* fix: resolve type errors in attribute sync feature (#26814)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Rename  variable

* Fix log typo

* Fix file name

* Add error logging

* Use credential teamId

* fix: add missing mockTeamRepository and team validation to tests

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Fix naming

* Fix file import

* Type fix

* Pass MembershipRepository as a dep in AttributeSyncFieldMappingService

* Type fix

* fix: add mockMembershipRepository to AttributeSyncFieldMappingService tests

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Update packages/app-store/salesforce/api/user-sync.ts

Add error handling when getting orgId from stored salesforce id

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: address Cubic code review comments

- PrismaAttributeRepository: use nested select instead of include: true for options
- CredentialRepository: use this.primaClient instead of global prisma, use select instead of include for relations
- AttributeSyncFieldMappingService: optimize O(n*m) complexity with Map lookup for O(1) access

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Fix typo in CredentialRepository

* Update README

* Update sfdx-project

* Add SFDC package tests

* fix: improve Salesforce Apex test assertions to verify actual behavior

- Enhanced CalComHttpMock to track HTTP callout invocations and capture requests
- Updated UserUpdateHandlerTest to verify HTTP callouts are made with correct data
- Updated CalComCalloutQueueableTest to verify HTTP callouts are made correctly
- Replaced System.assert(true, ...) with meaningful assertions that verify:
  - Correct number of HTTP callouts
  - Request body contains expected fields
  - Request method is POST

Addresses Cubic AI review feedback (confidence 9/10 issues only)

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-15 09:19:57 -05:00
Alex van Andel 8c8a5b4ae9 chore: release v6.0.13
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-15 13:45:42 +00:00
Morgan eee31d6e9e chore: tag deprecated platform oauth endpoints in api v2 (#26873)
* chore: tag deprecated platform oauth endpoints in api v2

* fixup! chore: tag deprecated platform oauth endpoints in api v2

* fixup! fixup! chore: tag deprecated platform oauth endpoints in api v2

* chore: fix docs.json mintlify

* chore: fix docs.json mintlify
2026-01-15 12:39:55 +00:00
Peer Richelsen 42531db484 Documentation edits made through Mintlify web editor 2026-01-15 13:05:11 +01:00
Peer Richelsen 9a449608b5 Documentation edits made through Mintlify web editor 2026-01-15 13:01:23 +01:00
Peer Richelsen 58a947b32e Documentation edits made through Mintlify web editor 2026-01-15 12:59:06 +01:00
Peer Richelsen c9502b5518 Documentation edits made through Mintlify web editor 2026-01-15 12:57:51 +01:00
Peer Richelsen 40c9d629f1 Documentation edits made through Mintlify web editor 2026-01-15 12:57:30 +01:00
Peer Richelsen 52784482d3 Documentation edits made through Mintlify web editor 2026-01-15 12:56:46 +01:00
Peer Richelsen 0ff8b02247 Documentation edits made through Mintlify web editor 2026-01-15 12:56:24 +01:00
Peer Richelsen 52f79fedb7 Documentation edits made through Mintlify web editor 2026-01-15 12:54:33 +01:00
Peer Richelsen 89ef150c1a Documentation edits made through Mintlify web editor 2026-01-15 12:53:23 +01:00
Peer Richelsen 6ea1b8964d Documentation edits made through Mintlify web editor 2026-01-15 12:52:15 +01:00
Joe Au-Yeung d04bc970e0 Add missing migration (#26799) 2026-01-15 13:49:40 +02:00
Peer Richelsen db76f7c4d1 Documentation edits made through Mintlify web editor 2026-01-15 12:49:05 +01:00
Anik Dhabal Babu 8dc2bdf604 fix: send cancellation email to previous round robin host (#26868) 2026-01-15 11:14:46 +00:00
sean-brydonandDevin AI 710d36a96c fix: remove trpc build dependency from turbo dev command (#26862)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 10:45:06 +00:00
Anik Dhabal Babu a8d559d331 fix: hide team members details when hideOrganizerEmail is enabled (#26833)
* fix: hide organizer email

* update
2026-01-15 09:39:51 +00:00
Alex van Andel 1dd2652080 fix: Duplicate calls syncing Calendar integrations (#26858)
* fix: Duplicate calls syncing Calendar integrations

* fix: TS error in handler

* Minor fixup

* Set cacheUpdatedAt at correct depth of array

* Import RouterOutputs
2026-01-15 00:21:40 -03:00
Volnei Munhoz a708e088c9 Remove Vercel warnings on deploy (#26855) 2026-01-14 19:47:37 -03:00
Volnei MunhozandDevin AI 53395695b4 fix: resolve useLiteralKeys biome lint issues (#26851)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 19:13:13 -03:00
Volnei MunhozandDevin AI 92d2b59946 fix: replace @ts-ignore with @ts-expect-error to fix biome lint errors (#26849)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 19:05:57 -03:00
9bfd11a36a fix: increase type-check memory limit to 12GB (#26853)
* fix: detect OOM errors in type-check CI workflow

Turborepo has a known bug where tasks killed by signals (like OOM)
are incorrectly marked as successful because the exit code is -1,
and Turborepo takes max(-1, 0) = 0.

This fix captures the type-check output and explicitly checks for
OOM error patterns, failing the job if detected.

See: https://github.com/vercel/turbo/issues/4227
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: increase type-check memory limit to 6144MB and add OOM detection

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: increase type-check memory limit to 12GB

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 21:42:09 +00:00
dd7b647715 feat(api-v2): ensure default calendars for delegation credentials when user added to org (#26800)
* feat(api-v2): ensure default calendars for delegation credentials when user added to org

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: make calendars queue optional in OrganizationsMembershipService

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: make delegation credential repository and users repository optional

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: move calendar setup logic to delegation credential service

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: make usersRepository optional for E2E tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: module deps

* Update apps/api/v2/src/modules/organizations/delegation-credentials/services/organizations-delegation-credential.service.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* test: add unit tests for ensureDefaultCalendarsForUser method

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: address Cubic AI feedback (confidence 9/10)

- Repository query now uses select: { id: true } for existence check
- Add job removal before adding new job (consistent with ensureDefaultCalendars)
- Fix test spy reuse issue

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-14 16:13:25 -03:00
Volnei MunhozandDevin AI f5cd2342c7 chore: add biome-ignore comments for dangerouslySetInnerHTML (#26848)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 19:05:53 +00:00
Dhairyashil Shinde ff65dee89f fix(companion): iOS event type detail fixes (#26845)
* fix(companion): iOS event type detail fixes

- Fix #1: Weekly schedule now shows multiple time slots per day in AvailabilityTab
- Fix #2: Allow numeric input fields to be empty with proper validation
- Fix #3: Add native iOS date picker for date range in Limits tab
- Fix #4: Change 'Email verification' to 'Booker email verification' in Advanced tab
- Fix #5: Fix Requires confirmation comparison logic in buildPartialUpdatePayload
- Fix #6: Forward parameters toggle already working, verified wiring
- Fix #7: Add toggles for redirect booking URL and interface language in Advanced tab
- Fix #8: Increase scroll padding at bottom from 200 to 350 for better keyboard access

* fix(companion): conditional scroll padding for limits and advanced tabs only

* fix(companion): remove static date text from iOS date picker, keep only picker

* fix(companion): simplify iOS date picker to match RescheduleScreen pattern

* update code
2026-01-14 19:58:44 +01:00
Volnei Munhoz 5778409055 chore: Biome increase line numbers per function (#26846) 2026-01-14 15:46:50 -03:00
ec383f6eef fix: make flaky E2E tests more stable (#26844)
* fix: make flaky E2E tests more stable

- Add waitForFunction for localStorage check in change-theme test to wait for app-theme to be set before asserting
- Use waitUntil: 'domcontentloaded' for waitForURL calls in routing-forms tests to handle client-side navigation more reliably

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
2026-01-14 15:14:05 -03:00
Keith WilliamsandDevin AI ea3bab57b0 refactor: consolidate Devin session logic into reusable action (#26843)
* fix: reuse existing Devin sessions in stale PR completion workflow

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: consolidate Devin session logic into reusable action

- Create .github/actions/devin-session composite action for session checking
- Update stale-pr-devin-completion.yml to use the new action
- Update cubic-devin-review.yml to use the new action
- Update devin-conflict-resolver.yml to use the new action
- Rename workflows to 'PR Labeled' with descriptive job names

The new action checks for existing Devin sessions by:
1. Looking for session URLs in PR body (for PRs created by Devin)
2. Searching PR comments for known Devin session patterns
3. Verifying session is active (working, blocked, or resumed status)

This eliminates duplicated session checking logic across all three workflows.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* revert: restore original workflow names

Reverted workflow names back to descriptive names:
- 'Stale Community PR Devin Completion' (was 'PR Labeled')
- 'Devin PR Conflict Resolver' (was 'PR Labeled')

Descriptive names are the recommended convention as they appear in
GitHub Actions tab, status checks, and notifications.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add active status check for PR body sessions

Addresses Cubic AI feedback (confidence 9/10): PR body sessions
now verify the session is active (working, blocked, or resumed)
before reusing, matching the behavior of comment-based session checks.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 18:02:25 +00:00
1487901f8e docs: correct AGPLv3 license statement in README (#26660)
Co-authored-by: simiondolha <simiondolha@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 16:47:15 +00:00
Keith WilliamsandDevin AI 90f71b9802 feat: enable Stale Community PR workflow for fork PRs via pull_request_target (#26842)
* feat: remove fork restriction from Stale Community PR Devin Completion workflow

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add back request maintainer access step for fork PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 16:28:20 +00:00
Anik Dhabal Babu 5386d6d839 skip PR checks for vscode settings changes (#26840) 2026-01-14 15:32:30 +00:00
Hariom BalharaandDevin AI eedca01447 feat(vscode): add Biome auto-fix on save configuration (#26839)
Replace ESLint fixAll with Biome codeActionsOnSave settings:
- source.fixAll.biome: applies safe lint fixes (e.g., removing unused imports)
- source.organizeImports.biome: sorts and organizes imports/exports

Both are needed separately because they serve different purposes:
- fixAll handles lint rule auto-fixes
- organizeImports handles import sorting/ordering

This aligns with Biome being the default formatter in this repo.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 15:10:54 +00:00
Morgan e23316eca1 chore: add TRIGGER_DEV_PROJECT_REF to draft release (#26837) 2026-01-14 14:50:35 +00:00
Eunjae LeeandDevin AI 079749518b fix: add integration-test.ts pattern to biome test file overrides (#26836)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 14:43:11 +00:00
Morgan 1d5382bed4 chore: trigger.dev cli version for ci (#26834) 2026-01-14 14:32:14 +00:00
Morgan ab6b7c0ced fix: draft release trigger (#26832) 2026-01-14 15:50:03 +02:00
Morgan fe23980161 fix: draft release trigger (#26831) 2026-01-14 15:48:15 +02:00
Morgan ecaf24d9a2 chore: sync vercel env var with trigger.dev and deploy (#25610)
* chore: sync vercel env var with trigger.dev

* chore: get trigger version from .env.production

* chore: deploy trigger dev tasks in draft release

* fixup! chore: deploy trigger dev tasks in draft release

* fixup! Merge branch 'main' into sync-trigger-dev-env-vercel

* remove trigger version from commit message it's already in .env.production

* chore: use generated token instead of GITHUB_TOKEN in draft release

* fix: code review
2026-01-14 13:34:58 +00:00
Eunjae LeeandDevin AI 97bfb8158d fix: load .env file in vitest config and update integration test docs (#26828)
* docs: update integration test commands for Vitest 4.0

Vitest 4.0 no longer supports custom CLI flags like --integrationTestsOnly.
Updated documentation to use the new VITEST_MODE=integration environment
variable syntax instead.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: load .env file in vitest config for integration tests

Vitest 4.0 doesn't automatically load .env files into process.env.
This caused integration tests to fail with ECONNREFUSED errors because
DATABASE_URL was not available.

Added loadEnv from Vite to load .env file at the start of vitest config.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* chore: remove unnecessary comment

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: only load .env vars if not already set

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 14:12:34 +01:00
Dhairyashil Shinde b94e522dd1 fix(api): use public username and correct base URL for platform orgs (#26830)
- Use public  instead of internal profile username for platform orgs
- Use  base URL instead of
2026-01-14 12:32:10 +00:00
cfbcd0f95b chore: upgrade sentry and start using metrics for Calendar Cache (#26827)
* upgrade sentry and start using metrics

* format changes

* format changes

* format changes

* type error

* type error

* format changes

* format changes

* fix: add updateSyncStatus call on API error and mock Sentry metrics in tests

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 12:29:09 +00:00
38ed00d71a fix: add server-side redirect for users with pending invites on onboarding page (#26829)
* fix: add server-side redirect for users with pending invites on onboarding page

When users sign up with an invite token, they were being redirected to
/onboarding/getting-started (plan selection page) instead of going
directly to /onboarding/personal/settings. This caused users to see
the payment prompt for team/org plans before being redirected.

This fix adds a server-side check in the /onboarding/getting-started
page to redirect users with pending invites directly to the personal
onboarding flow, preventing them from seeing the plan selection page.

Also refactored onboardingUtils.ts to use MembershipRepository instead
of direct prisma access.

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* test: add integration tests for hasPendingInviteByUserId method

Co-Authored-By: sean@cal.com <Sean@brydon.io>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 09:22:05 -03:00
2881961859 feat: add custom calendar reminder for Google Calendar events (#26078)
* feat: add custom calendar reminder for Google Calendar events

Allows users to set default reminder notifications (10, 30, or 60 minutes)
for events created via Cal.com bookings in Google Calendar. This addresses
the issue where Google Calendar's default reminders don't apply to
API-created events.

- Add customCalendarReminder field to DestinationCalendar model
- Create reminder selector UI in destination calendar settings
- Update GoogleCalendarService to apply custom reminders (popup + email)
- Add TRPC endpoint for updating reminder settings

* fix: address code review feedback

- Use z.union with literal values (10, 30, 60) for stricter schema validation
- Add localization for toast messages using t()
- Fix test data to use null for customCalendarReminder to match test intent

* fix: add customCalendarReminder to DestinationCalendar types

Update manually-defined DestinationCalendar types to include the new
customCalendarReminder field added in the previous commit. This fixes
type mismatches when passing Prisma-persisted destination calendars to
functions using these local type definitions.

* fix: update customCalendarReminder type in test to match Prisma schema

The customCalendarReminder field is defined as a non-nullable Int with
default value of 10 in the Prisma schema. Changed test value from null
to 10 to fix TS2345 type error.

* feat: add 'just in time' reminder option for Google Calendar events

- Add 0 (just in time) as a valid reminder option alongside 10, 30, 60 minutes
- Update TRPC schema to accept 0 as valid reminder value
- Add 'Just in time' option to reminder dropdown selector UI
- Add translation for 'just_in_time' key in English locale
- Include comprehensive test case for 0-minute (just in time) reminders
- Remove unused import from test file

This addresses reviewer feedback to provide flexible 'just in time' option that allows reminders to fire at exact event start time.

🤖 Generated with Claude Code

* fix: add customCalendarReminder to calendars service mock

- Add missing customCalendarReminder field to destination calendar mock
- Matches the Prisma schema requirement
- Fixes type error in calendars controller e2e test

* fix: add customCalendarReminder to destination calendars controller test

- Add missing customCalendarReminder field to mock destination calendar
- Matches Prisma schema requirement
- Fixes type error in destination-calendars controller e2e test

* fix: cast customCalendarReminder to ReminderMinutes type

- Add type cast for reminderValue to ensure type safety
- Use nullish coalescing (??) to preserve 0 as valid reminder value
- Ensures database number type is properly cast to ReminderMinutes union

* refactor: simplify translation logic in DestinationReminderSelector

- Remove conditional check for 'just_in_time' label
- Pass count parameter to all translations uniformly
- Translation function handles unused parameters gracefully

Addresses review feedback from @Khaan25

* refactor: make custom calendar reminder opt-in and use repository pattern

- Change default from 10 to null (opt-in feature)
- Add DestinationCalendarRepository to avoid direct Prisma usage
- Add 'Use default reminders' option to UI

* refactor: remove redundant migration file

The original migration already creates customCalendarReminder as nullable,
so this second migration to make it nullable is not needed.

* fix: type error for customCalendarReminder in destination calendar settings

* refactor: validate customCalendarReminder with Zod schema instead of type casting

* refactor: use instance methods in DestinationCalendarRepository

Changed from static to instance methods with getInstance() pattern as requested in review.

* refactor: replace singleton with DI for DestinationCalendarRepository

- Remove getInstance() singleton pattern
- Add DI tokens, module, and container
- Update GoogleCalendarService and tRPC handler to use DI

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2026-01-14 12:32:00 +01:00
0b37520f0d fix: translate location dropdown group labels and options in event-type settings (#26784)
* fix: translate location dropdown group labels in event-type settings

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use requesting user's locale for team event type translations

For team event types, the current user might not be in eventType.users,
causing translations to default to English. This fix queries the user's
locale directly from the database when not found in the event type users.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: pass userLocale as parameter instead of database call

Per PR feedback, pass the authenticated user's locale as an optional
parameter to getEventTypeById instead of making an extra database call.
The locale is passed from ctx.user.locale in the tRPC handler.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: provide userLocale in apiv2 getEventTypeById

* fix: remove unused ts comments

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 08:28:31 -03:00
+46 a7a8c78494 chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow (#24159)
* chore: Inject repositories instead of Prisma in canellation flow

* simplify

* simplify

* fix formatting issue

* chore: resolve merge conflicts for PR #24159 (#26820)

* matched colour of icons across website (#26394)

* fix(auth): resolve session user by token subject ID (#26399)

* fix(auth): align session user resolution with token subject

* test(auth): add unit tests for getServerSession user resolution

* chore: release v6.0.7

* fix: Custom time input for availability (#26373)

* add custom time input

* add unit test

* add validation logic

* feat(companion): Add DropdownMenu and Alert Dialog for Android (#26385)

* feat(companion): add DropdownMenu for Android event types list

Replace Alert.alert with react-native-reusables DropdownMenu component
for Android event type list items, providing a native-feeling menu
experience that matches iOS functionality.

Changes:
- Install react-native-reusables dropdown-menu component and dependencies
  (lucide-react-native, tailwindcss-animate, class-variance-authority,
  clsx, tailwind-merge)
- Create EventTypeListItem.android.tsx with DropdownMenu implementation
  - Single ellipsis button triggers dropdown menu
  - Menu includes: Preview, Copy link, Edit, Duplicate, Delete
  - Delete action marked as destructive variant
  - Proper safe area insets handling
- Add PortalHost to app/_layout.tsx for portal rendering support
- Create lib/utils.ts with cn() helper for className merging
- Update global.css with theme CSS variables (popover, border, accent,
  destructive, etc.) for dropdown menu styling
- Update tailwind.config.js with theme colors and tailwindcss-animate plugin
- Update metro.config.js with inlineRem: 16 for proper rem unit handling
- Remove Android Alert.alert fallback from event types index.tsx
- Fix lint issues in generated dropdown-menu.tsx (remove unnecessary fragments)

The Android experience now matches iOS with a single menu button that
opens a dropdown containing all event type actions, replacing the
previous Alert.alert dialog and separate action buttons.

Refs: https://reactnativereusables.com/docs/components/dropdown-menu

* adjust with of menu

* feat(companion): add DropdownMenu for Android booking and availability list items

- Add BookingListItem.android.tsx with DropdownMenu for booking actions
- Add BookingDetailScreen.android.tsx with DropdownMenu in header
- Add AvailabilityListItem.android.tsx with DropdownMenu for schedule actions

Actions include: Reschedule, Edit Location, Add Guests, View Recordings,
Meeting Session Details, Mark as No-Show, Report Booking, Cancel Event
for bookings; Set as Default, Duplicate, Delete for availability schedules.

* fix lint issues

* feat(android): replace native alerts with AlertDialog and Toast in event types

- Install AlertDialog and Alert components from react-native-reusables
- Create Android-specific event types screen (index.android.tsx)
- Replace native Alert.alert() with AlertDialog for delete confirmation
- Add inline validation errors (red border + error text) in create modal
- Implement Toast snackbar for success/error notifications (no layout shift)
- Auto-dismiss toast after 2.5 seconds
- Fix React Compiler compatibility by removing animated refs

This provides a more consistent and polished UI experience on Android,
matching the design system used in other parts of the app.

* feat(android): add AlertDialog for availability delete and booking cancel

- Add index.android.tsx for availability with AlertDialog for delete confirmation
- Add index.android.tsx for bookings with AlertDialog for cancel (with reason input)
- Both screens include Toast snackbar for success/error notifications
- Follows the same pattern as event types Android implementation

* feat(companion): add DropdownMenu and AlertDialog for Android

- Replace native Alert.alert context menus with DropdownMenu component
  for event types, bookings, and availability lists
- Replace FullScreenModal with AlertDialog for create/delete/cancel flows
- Add toast notifications for success/error feedback on Android
- Set consistent 380px max-width for all AlertDialogs
- Fix layout headers showing "index" text on event-types and availability
- Create Android-specific More screen with AlertDialog logout confirmation

Uses react-native-reusables components for polished Android UI

* better code

* fix cubics comments

* refactor(android): revert delete confirmations to native Alert.alert()

- Logout: reverted to native Alert.alert() (simple yes/no)
- Event Types Delete: reverted to native Alert.alert() (simple yes/no)
- Availability Delete: reverted to native Alert.alert() (simple yes/no)

Keep AlertDialog only where user input is needed:
- Event Types Create (has TextInput for title)
- Availability Create (has TextInput for name)
- Bookings Cancel (has TextInput for cancellation reason)

* refactor(android): remove redundant index.android.tsx files

The main index.tsx files already handle Android via Platform.OS checks.
Android-specific behavior for actions is in the list item components:
- EventTypeListItem.android.tsx
- BookingListItem.android.tsx
- AvailabilityListItem.android.tsx

This consolidates the code and reduces duplication.

* corrected the implementation both native and alert dialog

* address cubics comments

* fix lint issue and address cubic comments

* chore: add logging in next-auth (#26404)

* Add logging in next-auth
* Add logging at other return

* fix: Make incomplete booking form mobile-responsive (#26413)

* fix: update bundle identifier (#26402)

* fix: patch React 19 vulnerabilities by upgrading to 19.2.3 (#26411)

* security: patch React 19 vulnerabilities by upgrading to 19.2.3

* chore: revert lingo.dev upgrade

* refactor(companion): event type details screen improvements (#26415)

* refactor(companion): move EventTypeDetail component to a new file and update routing

* refactor(companion): format code for better readability in TabLayout and EventTypeDetail components

* refactor(companion): improve code formatting and readability in EventTypeDetail component

* refactor(companion): enhance code readability and formatting in EventTypeDetail component

* refactor(companion): improve code formatting and readability in EventTypeDetail component

* refactor(companion): enhance code formatting and readability in EventTypeDetail component

* refactor(companion): improve code formatting and readability in TabLayout component

* fix: add vertical spacing when hovered (#26419)

* fix(seed): add missing Host entries for seeded round‑robin team events (#26426)

* feat(companion): new availability detail and actions pages for ios (#26424)

* version 1

* version 1.1

* better code

* covered all edge cases

* address cubics comments

* address cubics comments

* fix(auth): enhance SAML login handling by introducing userId field and updating JWT token structure (#26428)

* fix(ci): delete old prod build caches on cache miss (#26437)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(ci): add yarn prisma generate before cache key generation (#26439)

This ensures consistent cache keys between the Build Web App job and E2E
shards by running yarn prisma generate before generating the cache key.

The issue was that packages/prisma/enums/index.ts is:
1. Generated by yarn prisma generate
2. In .gitignore (not committed to git)
3. Included in the SOURCE_HASH (matches packages/**/**.[jt]s)
4. NOT excluded from the hash

E2E jobs already run yarn prisma generate before cache-build, but the
Build Web App job did not, causing different cache keys in the same
workflow run.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: show empty screen from event type availability tab (#26396)

* fix

* update

* fix

* Remove copying of App Store static files step

Removed step to copy App Store static files from the workflow.

* feat: queue or cancel payment reminder flow (#24889)

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* feat: integrate BookingHistory with Bookings V3 design (#26301)

* Integrate BookingHistory with Bookings V3 design

* Enhance booking features by integrating booking audit functionality

- Updated the booking page to retrieve user feature statuses for "bookings-v3" and "booking-audit".
- Modified BookingDetailsSheet and BookingListContainer components to accept and utilize the new bookingAuditEnabled prop.
- Adjusted the BookingHistory display logic to conditionally render based on the bookingAuditEnabled state.
- Refactored SegmentedControl to support generic types for better type safety.

This change improves the user experience by allowing conditional access to booking audit features based on user permissions.

* Refactor BookingDetailsSheet to manage active segment state with Zustand store

- Removed local state management for active segment in BookingDetailsSheet and integrated Zustand store for better state synchronization.
- Introduced useActiveSegmentFromUrl hook to sync active segment with URL query parameters.
- Updated BookingDetailsSheet to handle derived active segment logic based on bookingAuditEnabled state.
- Adjusted SegmentedControl to ensure it defaults to "info" when activeSegment is null.

This refactor enhances the maintainability and responsiveness of the booking details component.

* refactor: rename useBiDirectionalSyncBetweenZustandAndNuqs to useBiDirectionalSyncBetweenStoreAndUrl

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: create BookingHistoryViewerService to combine audit logs with routing form submissions (#26045)

* feat: create BookingHistoryViewerService to combine audit logs with routing form submissions

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor(booking): rename audit log query and enhance type safety

- Updated the booking logs view to use the new getBookingHistory query instead of getAuditLogs.
- Introduced DisplayBookingAuditLog type for improved clarity in BookingAuditViewerService.
- Refactored BookingHistoryViewerService to utilize the new DisplayBookingAuditLog type and added sorting functionality for history logs.
- Adjusted related types and methods to ensure consistency across services.

* refactor(routing-forms): streamline imports and enhance type definitions

- Consolidated type exports and imports from the features library for better organization.
- Removed redundant type definitions and functions in zod.ts, findFieldValueByIdentifier.ts, getFieldIdentifier.ts, and parseRoutingFormResponse.ts.
- Introduced new utility functions for handling field responses and parsing routing form responses.
- Improved type safety and clarity across routing form response handling.

* fix: remove double prefix from uniqueId in form submission entry

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* 1c97f9cc5d50416788c01876fe539bcc9750e9b2 (#26453)

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: Ensure that uuid is available in server session[Booking Audit Prerequisite] (#25963)

## What does this PR do?

Similar to #25721, adds uuid in session so that BookingAudit has it readily available

Adds the user's UUID to the booking metadata by:
1. Extending the NextAuth `User` interface to include an optional `uuid` property from PrismaUser
2. Making `uuid` required on `Session.user` via intersection type (`User & { uuid: PrismaUser["uuid"] }`)
3. Adding `uuid` to the session user object in `getServerSession.ts`
4. Adding `uuid` to the `AdapterUser` transformation in `next-auth-custom-adapter.ts`
5. Passing `userUuid` from the session to the booking creation flow
6. Updating the API key verification flow to include `uuid` in the user data (repository, service, and type definitions)
7. Adding `req.userUuid` as a required field on the request object (like `req.userId`)
8. Adding `uuid` to mock session objects in web app routes and test context
9. Adding `uuid` to the `findByEmailAndIncludeProfilesAndPassword` query in UserRepository

Also removes commented-out code that was placeholder for future work and fixes lint warnings for unused variables.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Verify that the NextAuth session callback is already populating the `uuid` field on the user object
2. Create a booking and confirm `userUuid` is included in the booking metadata
3. Test API v1 endpoints (`/api/invites` POST and `/api/teams/[teamId]/publish`) to verify they receive the uuid from the authenticated user
4. Check that the booking flow works correctly with the new parameter
5. Test SAML login flow to verify session still works correctly (uuid is resolved from database after authentication)

## Human Review Checklist

- [ ] Verify the NextAuth session callback populates `uuid` - if not, this change will pass `undefined` at runtime
- [ ] Confirm `userUuid` is consumed downstream in the booking service
- [ ] Verify that `PrismaApiKeyRepository.findByHashedKey()` correctly fetches the user's uuid from the database
- [ ] Verify the discriminated union type in `ApiKeyService.ts` ensures `result.user` is always defined when `result.valid` is true
- [ ] Confirm all API v1 endpoints using `req.userUuid` go through the `verifyApiKey` middleware
- [ ] Verify `UserRepository.findByEmailAndIncludeProfilesAndPassword()` includes `uuid` in the select clause
- [ ] Verify SAML login still works correctly - uuid is now optional on User interface so SAML providers don't need to supply it at profile stage

## Updates since last revision

- **Made uuid optional on User, required on Session**: Changed the type strategy so `uuid` is optional on the NextAuth `User` interface but required on `Session.user` via intersection type. This allows SAML providers to not supply uuid at the profile stage while ensuring uuid is always present on the session after the user is resolved from the database.
- **Removed uuid from SAML functions**: Since uuid is now optional on User, the SAML profile and authorize functions no longer need to include it.

---

Link to Devin run: https://app.devin.ai/sessions/97e5603b719a420b9b35041252c9db26
Requested by: hariom@cal.com (@hariombalhara)

* fix: add @calcom/trpc#build dependency to @calcom/web#dev task (#26460)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(auth): make identityProviderId lookup case-insensitive (#26405)

SAML IdPs may send NameIDs with different casing than stored, causing login failures.
Aligns with the existing case-insensitive email lookup pattern

* fix: cancel running CI workflow before re-triggering and allow trusted GitHub Apps (#26461)

* fix: cancel running CI workflow before re-triggering and allow trusted bots

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove hardcoded bot allowlist, keep only cancel-and-rerun improvement

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add app_id verification for trusted GitHub Apps (Graphite)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: simplify trusted bot check to use sender type, login, and installation context

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove unnecessary comments

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: update translations via @LingoDotDev (#26445)

Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* fix: remove installation requirement from trusted bot check (#26466)

* fix: remove installation requirement from trusted bot check

The installation object is not present in the webhook payload when
GitHub Apps add labels via pull_request_target events. This caused
graphite-app[bot] to fail the authorization check and fall through
to the human permission check, which doesn't work for bots.

The fix removes the installation requirement and relies on:
- sender.type === 'Bot'
- sender.login matching the trusted bot list

This is secure because the sender fields come from GitHub's webhook
payload and cannot be forged by contributors.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: add extra logging about sender type

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove senderId from logging

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Update run-ci.yml

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: Move trpc-dependent components from features to web [2] (#26420)

* fix

* move event types components to web

* update import paths

* mv apps components

* migrate form builder

* fix

* mv sso

* fix

* mv

* update import paths

* update import paths

* mv

* mv

* mv

* fix

* update Booker

* fix

* fix

* fix

* fix

* mv video

* mv embed components to web

* update import paths

* mv calendar weekly view components

* update import paths

* fix

* fixp

* fix

* fix

* fix

* fix: update FormBuilder imports to use @calcom/features/form-builder

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update broken import paths after file migrations

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: correct import paths for platform atoms and moved components

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: apply CSS type fixes and add missing atoms exports

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: resolve type errors in test files after component migrations

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: resolve remaining type errors in test files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* migrate

* fix: resolve type errors in test and mock files

- Add missing bookingForm, bookerFormErrorRef, instantConnectCooldownMs to Booker.test.tsx bookings prop
- Add all required BookerEvent properties to event.mock.ts
- Add vi import from vitest to all mock files
- Fix date parameter types in packages/dayjs/__mocks__/index.ts
- Add verificationCode and setVerificationCode to test-utils.tsx mock store
- Remove children.type access in Section.tsx mock to fix type error
- Fix lint issues: remove unused React imports, use import type where needed, add return types
- Add biome-ignore comments for pre-existing lint warnings in test files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* migrate

* migrate

* migrate

* update import paths

* update import paths

* update import paths

* fix

* migrate data table

* migrate data table

* fix

* fix

* fix

* migrate insights components

* migrate insights components

* fix

* mv

* update import paths

* fix

* fix

* fix

* fix

* fix

* fix: resolve type errors in test mocks

- Booker.test.tsx: Add all required UseFormReturn methods to bookingForm mock
- event.mock.ts: Fix entity, subsetOfHosts, instantMeetingParameters, fieldTranslations, image types
- dayjs/__mocks__/index.ts: Use Object.assign for proper typing of mock properties
- Section.tsx: Change 'class' to 'className' in JSX with biome-ignore comment

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing hasDataErrors and dataErrors to bookings.errors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing loadingStates properties to bookings mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing slots properties (setTentativeSelectedTimeslots, tentativeSelectedTimeslots, slotReservationId)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update quickAvailabilityChecks to include utcEndIso and use valid status type

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing bookerForm properties (formName, beforeVerifyEmail, formErrors)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing UseFormReturn properties to bookerForm.bookingForm mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add hasFormErrors and formErrors to bookerForm.formErrors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add hasFormErrors and formErrors to bookerForm.errors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing isError property to mockEvent

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use complete BookerEvent mock in Booker.test.tsx

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use branded bookingFields type in event mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing schedule mock properties (isError, isSuccess, isLoading, dataUpdatedAt)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* revert

* fix

* fix

* fix

* fix build

* fix

* fix

* fix

* fix: correct AddMembersWithSwitch test wrapper to use initial assignAllTeamMembers value

- Fixed test wrapper to initialize useState with componentProps.assignAllTeamMembers
  instead of hardcoded false, allowing tests to properly test different states
- Updated test expectations for ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_NOT_APPLICABLE
  state to match actual component behavior (toggle should be present and checked)
- Fixed 'should show Segment when toggled on' test to start with assignAllTeamMembers: false
  to properly test the flow of enabling it
- Added explicit types to satisfy biome lint requirements

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use JSX.Element instead of React.JSX.Element for type compatibility

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore(deps): update dependencies and add version constraints (#26390)

- Update sanitize-html to 2.17.0
- Remove unused Storybook dependencies from @calcom/ui
- Add resolutions for consistent dependency versions
- Clean up packageExtensions

* feat: add lightweight E2E session warmup page (#26451)

* feat: add lightweight E2E session warmup endpoint

- Add /api/__e2e__/session-warmup endpoint that triggers NextAuth session loading
- Update apiLogin fixture to use the new endpoint instead of navigating to /settings/my-account/profile
- The endpoint is gated by NEXT_PUBLIC_IS_E2E=1 (already set in playwright.config.ts)
- This reduces overhead in E2E tests by avoiding loading a full UI page just to warm up the session

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move session warmup endpoint to App Router

- Move /api/__e2e__/session-warmup from pages/api to app/api
- Use App Router patterns (NextResponse, buildLegacyRequest)
- Maintains same functionality for E2E session warming

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* rename path

* refactor: switch from API route to minimal SSR page (Option 2)

- Replace /api/e2e/session-warmup API route with /e2e/session-warmup page
- Use App Router page pattern with getServerSession for session warmup
- Update apiLogin fixture to navigate to the page instead of API request

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* revert users fixture but with a new url

* render nothing on success

* clean up

* trying something

* Revert "trying something"

This reverts commit 2ae2f7dcb42612e54eb072a9f09857272020889a.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* Disable noReactSpecificProps as we use react (#26479)

* fix(auth): fix SAML tenant extraction and validation (#26482)

- Extract tenant from userInfo in saml-idp (IdP-initiated)
- Add profile.requested?.tenant fallback for OAuth (SP-initiated)
- Block invalid tenant format in hosted (security)

* fix: atoms build by updating import paths (#26489)

* fix build

* fix build

* fix: "New" button sizing inconsistent between Workflows and Event Types pages (#26066)

* fix: consistent button sizing between fab and button variants on desktop

* fix: consistent button sizing between fab and button variants on desktop

* fix(ui): align New button sizing across pages

* fix: New button sizing inconsistent between Workflows and Event Types pages

* Update Button.tsx

* test: fix unit test flake (#25557)

* fix: revalidate teams cache after accepting invite via token

When a user accepts a team invite via token on the /teams page, the
teams cache was not being invalidated. This caused the page to show
stale data (empty list) while the sidebar correctly showed the teams.

This fix adds a call to revalidateTeamsList() after processing an
invite token, ensuring the cache is invalidated and fresh data is
fetched immediately.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: revalidate teams cache after creating team in onboarding flow

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Remove comments on teams cache revalidation

Removed comments about revalidating teams cache after invite processing.

* fix unit test flake

* Remove unused import in useCreateTeam hook

Removed unused import for revalidateTeamsList.

* Remove unused import for revalidateTeamsList

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: Add impersonation context support to booking audit (#26014)

## What does this PR do?

Adds infrastructure to track impersonation context in booking audit records and displays it in the UI. When an admin impersonates another user and performs booking actions, the audit system now:
- Records the **admin** as the actor (who actually performed the action)
- Stores the **impersonated user's UUID** in a separate `context` field
- Displays **"Impersonated By"** in the booking logs UI when viewing audit details

This separation ensures audit trail integrity (the admin is accountable) while preserving full context about whose account was being used.

### Changes
- Added `uuid` to `impersonatedBy` session object for actor identification
- Added `uuid` to top-level `User` type in next-auth types for session enrichment
- Added `context Json?` field to `BookingAudit` Prisma model
- Added `BookingAuditContextSchema` for type-safe context handling with `actingAsUserUuid` field
- Updated producer service interface and implementation to pass context through all queue methods
- Updated consumer service to persist context to database
- Updated repository to store and fetch context in BookingAudit records
- Added `impersonatedBy` field to `EnrichedAuditLog` type in `BookingAuditViewerService`
- Added `enrichImpersonationContext` method to resolve impersonated user details
- Updated booking logs UI to display "Impersonated By" in expanded details
- Added `impersonated_by` translation key

Link to Devin run: https://app.devin.ai/sessions/3f1252527aef4ead9401bdf055c0817b
Requested by: hariom@cal.com (@hariombalhara)

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - internal infrastructure change
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Verify type checks pass: `yarn type-check:ci --force`
2. Verify existing audit tests still pass: `TZ=UTC yarn test`
3. To fully test impersonation context display:
   - Have an admin impersonate a user
   - Perform a booking action (create, cancel, reschedule)
   - Navigate to the booking's audit logs
   - Expand the details for the action
   - Verify "Impersonated By" row appears showing the impersonated user's name
   - Verify the BookingAudit record has:
     - `actorId` pointing to the admin's AuditActor
     - `context` containing `{ actingAsUserUuid: "<impersonated-user-uuid>" }`

## Human Review Checklist

- [ ] Verify the `context` field schema design is appropriate for future extensibility
- [ ] Confirm the `uuid` addition to User type in next-auth doesn't break existing auth flows
- [ ] Check that the optional `context` parameter doesn't break existing queue method callers
- [ ] Verify no migration file is needed (or if squashing is handled separately)
- [ ] Verify the UI displays "Impersonated By" correctly when impersonation context is present
- [ ] Confirm `enrichImpersonationContext` handles edge cases (null context, invalid context, deleted user)

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings

* perf: improve cal video webhook (#26495)

* perf: improve cal video webhook

* save format

* refactor: use errorMs

* chore: change API codeowner to Foundation (#26504)

* chore(auth): add error logging for saml-idp silent failures (#26484)

* chore(auth): add error logging for saml-idp silent failures

* chore(auth): add warn-level logging for saml-idp silent failures

* chore(auth): change 'No user found' log to warn level

* chore(auth): add warn-level logging for silent auth failures

- saml-idp authorize: credentials, code, token, userInfo, user lookup
- callbacks:signIn: account type, email, name, catch-all
- callbacks:jwt: unknown account type (info → warn)
- saml:profile: missing email from IdP
- getServerSession: user not found for valid token

* feat(api): add team event-types webhooks controller (#26449)

* feat(api): add team event-types webhooks controller

- Add TeamsEventTypesWebhooksController for managing webhooks on team event types
- Add IsTeamEventTypeWebhookGuard for authorization
- Add TeamEventTypeWebhooksService for business logic
- Register new controller in TeamsEventTypesModule
- Enable unsafeParameterDecoratorsEnabled in biome.json for NestJS support

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test(api): add e2e tests for team event-types webhooks controller

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api): restrict team event-type webhooks to admins/owners only

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api): use regular imports instead of type imports for DI and DTOs

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api): use regular imports for DI in guard file

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: circular depndency in modules

* delete teams in test

* fix roles guard

* fix biome

* fix guard

* resolve type import

* resolve review feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: remove Mintlify AI chat from CMD+K widget (#26485)

* chore: remove Mintlify AI chat from CMD+K widget

- Remove MintlifyChat component and related state from Kbar.tsx
- Delete packages/features/mintlify-chat directory (MintlifyChat.tsx, util.ts)
- Delete apps/web/app/api/mintlify-chat API routes and tests
- Delete packages/lib/server/mintlifyChatValidation.ts
- Remove Mintlify-related env vars from .env.example and turbo.json
- Refactor Kbar.tsx to fix lint issues (explicit types, exports at end)

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: use ReactNode import instead of JSX from react

The JSX type is not exported from 'react' module. Use the global
JSX.Element type (available in React projects) and import ReactNode
for the children prop type.

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat: add all event-types and upcoming bookings to KBar

- Increase event types limit from 10 to 100 to show more event types
- Add useUpcomingBookingsAction hook to fetch and display upcoming bookings
- Bookings show title, date, and time in KBar search results
- Navigate to booking details page when selecting a booking

Co-Authored-By: peer@cal.com <peer@cal.com>

* Revert "feat: add all event-types and upcoming bookings to KBar"

This reverts commit 69d03397e3820e45e7207eb55b38117d269eae5e.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: update translations via @LingoDotDev (#26497)

Co-authored-by: Lingo.dev <support@lingo.dev>

* feat: implement FeatureOptInService (#25805)

* feat: implement FeatureOptInService WIP

* clean up

* feat: consolidate feature repositories and add updateFeatureForUser

- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename updateFeatureForUser to setUserFeatureState

Rename to match the convention used for setTeamFeatureState

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState

* fix integration tests

* clean up logics

* update services and router

* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array

- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add getFeatureStateForTeams for batch querying multiple teams

- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: combine org and team state queries into single call

- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use team.isOrganization and clarify computeEffectiveState comment

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use MembershipRepository.findAllByUserId with isOrganization

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add featureId validation using isOptInFeature type guard

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* less queries

* add fallback value

* fix type error

* move files

* add autoOptInFeatures column

* use autoOptInFeatures flag within FeatureOptInService

* add setUserAutoOptIn and setTeamAutoOptIn

* fix computeEffectiveState logic

* rewrite computeEffectiveState

* clean up integration tests

* clean up in afterEach

* fix type error

* refactor: use FeaturesRepository methods instead of direct Prisma calls

Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.

Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts

This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* fix the logic

* extract some logic into applyAutoOptIn()

* remove wrong code

* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union

- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests

* fix type error

* use Promise.all

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add organization banner to user profile page (#26514)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: Hubspot write to meeting object (#26039)

* feat: Hubspot write to meeting object

* fix: translate hardcoded strings and remove debug console.log

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor

* fix: improve static value detection for placeholder replacement

- Changed condition from startsWith/endsWith to includes('{') to properly detect embedded placeholders
- Strings like 'Hello {name}!' are now correctly processed for placeholder replacement
- Pure placeholder tokens that can't be resolved return null
- Partially resolved values are returned as-is

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor: split WriteToObjectSettings into types and utils files

- Extract interfaces, enums, and type definitions to WriteToObjectSettings.types.ts
- Extract constants and utility functions to WriteToObjectSettings.utils.ts
- Update main component to use the new utility functions
- Improves code organization and maintainability

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* revert: restore original static value detection logic

Per user request - the startsWith/endsWith check was intentional

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* test: add unit tests for HubSpot CRM service

Tests cover:
- ensureFieldsExistOnMeeting: field validation against HubSpot properties
- getTextValueFromBookingTracking: UTM parameter extraction
- getTextValueFromBookingResponse: placeholder replacement
- getDateFieldValue: date field resolution for different date types
- getFieldValue: main field value resolution for all field types
- generateWriteToMeetingBody: write-to-meeting body generation
- getContacts: contact search functionality

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: correct type errors in HubSpot CRM service tests

- Import WhenToWrite enum from crm-enums
- Replace string literals with WhenToWrite.EVERY_BOOKING enum values
- Add missing whenToWrite property to field config objects

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: use type casting for intentional type errors in tests

- Cast numeric fieldValue to string for testing non-string handling
- Cast invalid field type string to CrmFieldType for testing unsupported types

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: prevent unhandled promise rejections in HubSpot CRM tests

- Re-apply mockGetAppKeysFromSlug implementation in beforeEach to ensure
  mock is always set correctly after clearAllMocks
- Change vi.resetAllMocks() to vi.clearAllMocks() to preserve mock
  implementations between tests
- Add explicit types to satisfy biome lint rules
- This fixes the 'Cannot read properties of undefined (reading client_id)'
  errors that were causing CI to fail with exit code 1

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor: convert HubSpot tests to black-box testing through public methods

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: properly type mock CalendarEvent in HubSpot tests

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: properly type TFunction in mock CalendarEvent

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: graceful owner fail test

* refactor

* fix: type check

* fix: remove null fields

* Update packages/app-store/hubspot/lib/CrmService.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* docs: add DTO location and naming conventions to knowledge base (#26478)

* docs: add DTO location and naming conventions to knowledge base

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: clarify DTO location rules for new features vs refactored code

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: simplify DTO location - all DTOs go in packages/lib/dto/

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: convert PrismaAttributeToUserRepository to accept Prisma as dependency (#26515)

* refactor: convert PrismaAttributeToUserRepository to accept Prisma as dependency

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use Prisma types from generated client instead of custom types

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: handle existing users on invite token flow (#26217)

* fix(auth): validate user before signup with invite token

Validate if user already exists before creating account when
signing up with team or organization invite tokens. Existing users
are redirected to login to accept the invitation.

- Add user existence check in signup handlers
- Return 409 for existing users with redirect to login
- Extract signup fetch logic to dedicated module
- Add e2e test coverage

* fix(auth): address code review feedback

- Fix fetchSignup tests to use vi.spyOn for proper mock restoration
- Add content-type validation before parsing JSON response
- Guard against undefined error in Stripe callback
- Use t() for localized error message
- Fix race condition in handlers by catching P2002 on create

* fix(auth): address additional code review feedback

- Add INVALID_SERVER_RESPONSE constant to follow established pattern
- Check error.meta.target includes email before returning USER_ALREADY_EXISTS
to avoid false positives from other unique constraint violations
- Add select: { id: true } to user.create calls since downstream functions only
need the user id

* test: add unit tests for P2002 handling in signup handlers

- Add shared test suite covering all P2002 edge cases
- Ensure 409 only for email constraint violations
- Fix non-token paths to use atomic create + catch pattern

* fix: update error message copy per review feedback

* fix(auth): address code review feedback and prevent orphan Stripe customers

- Add user existence check before Stripe customer creation (token flow)
- Add select clause to user.create for consistency
- Fix showToast argument order (pre-existing bug)
- Use toHaveURL instead of waitForURL in E2E tests

* fix(auth): resolve 500 errors by fixing Prisma error detection across module boundaries

The instanceof check for PrismaClientKnownRequestError fails when different
Prisma client instances are loaded. Added fallback check by constructor name

* fix(auth): validate invitedTo before upsert on team invite signup

* test(auth): update P2002 tests for new invite flow

P2002 tests now use non-token flow since token flow uses upsert
Added tests for invitedTo validation on invite signup

* fix(auth): add guards and P2002 handling per review feedback

- Guard existingUser check with if (foundToken?.teamId)
- Guard username check with if (username) for premium flow
- Add `select` clause to findFirst/findUnique queries
- Add try-catch on upsert for race condition P2002 errors

* fix(auth): narrow P2002 handling to email/username targets

* chore: release v6.0.8

* fix: Support 10-digit phone numbers for Ivory Coast (+225) (#26465)

* fix: update ivory coast mask to 10 digits

* update formating for Benin numbers

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>

* fix(ci): use env vars for input interpolation in workflow run steps (#26520)

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* refactor: use structured logger in video adapters (#26285)

- Remove debug console.log/console.error statements
- Add logger.debug for observability (meeting lifecycle events)
- Add logger.error with safe error pattern (message + name only)
- Fix error messages to avoid exposing response details
- Remove redundant try/catch blocks (errors propagate naturally)

* fix: validate owner email on platform org creation (#26286)

Remove isPlatform bypass from owner verification to ensure users can only create organizations where they are the designated owner. Add test coverage for create and intentToCreateOrg handlers:

- Regression tests for isPlatform bypass fix
- Happy path for admin creating org for another user

* perf: batch booking queries in output service (#25900)

Replace N sequential queries with single batch queries in:
- getOutputRecurringBookings
- getOutputRecurringSeatedBookings

Uses existing batch repository methods. Reduces database roundtrips
from O(n) to O(1) for recurring booking lookups

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>

* Make booking-audit integration test utils reusable (#26526)

* fix: generate compliant passwords using meeting_password_requirement (#26148)

* fix(zoomvideo): generate compliant passwords using meeting_password_requirement

- Add meetingPasswordRequirementSchema to parse Zoom's password policy settings
- Implement validatePasswordAgainstRequirements() to check if a password meets the policy
- Implement generateCompliantPassword() to create passwords that comply with the policy
- Update translateEvent() to use getCompliantPassword() which validates the default password
  or generates a new compliant one based on meeting_password_requirement
- Add meeting_password_requirement to the settings API filter
- Improve error handling for non-JSON responses in OAuthManager (XML validation errors)

This fixes the frequent 'Error in JSON parsing Zoom API response' errors caused by
Zoom returning XML validation errors when the password doesn't comply with the
account's password policy (e.g., numeric-only requirement).

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: use cleaner single-pass consecutive character check

- Replace nested-loop O(n*k) implementation with single-pass O(n) helper
- Add proper guard for consecutiveLength < 4 (Zoom allows 0, 4-8)
- Move consecutive check before only_allow_numeric to apply it for all cases
- Fix edge-case bug where consecutiveLength 1-3 could incorrectly reject passwords

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Optimize OAuth response handling

Refactor OAuth response validation to read body only once.

* Improve error handling in Zoom API response parsing

Refactor error handling for Zoom API response parsing to improve logging and clarity.

* Improve compliant password generation logic

Enhance password generation to avoid consecutive characters when numeric only is required.

* Remove password requirement handling from VideoApiAdapter

Removed meeting password requirement schema and related functions for password validation and generation.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: Clean up the /tests in the root (#26525)

* refactor: Delete mockTRPCContext and mockData, and relocate mockStripeSubscription to stripe mock.

* chore: Delete unused Stripe, video client, and reminder scheduler mock files.

* feat(companion): UI Enhancements for Android and Extension (#26434)

* feat: companion-android-ui-upgrade version 1

* recurrings and unconfirmed booking filter and page implementation

* add badge and links to event type list page

* address cubics comments

* feat(companion): unify dropdown menu for Android and extension (#26486)

* feat(companion): unify dropdown menu for Android and extension

- Merge Android-specific dropdown implementations into base component files
- EventTypeListItem: Add DropdownMenu with Preview, Copy link, Edit, Duplicate, Delete actions
- BookingListItem: Add DropdownMenu with booking actions (reschedule, edit location, add guests, etc.)
- RecurringBookingListItem: Add DropdownMenu with recurring booking actions
- AvailabilityListItem: Add DropdownMenu with Set as Default, Duplicate, Delete actions
- BookingDetailScreen: Add DropdownMenu in header for Android with AlertDialog for cancel confirmation
- Delete all .android.tsx files as implementations are now unified

* fix(companion): fix typecheck errors after dropdown unification

- Remove unused props from EventTypeListItem.ios.tsx (copiedEventTypeId, handleEventTypeLongPress)
- Remove unused onActionsPress prop from BookingListItem.ios.tsx
- Remove copiedEventTypeId and handleEventTypeLongPress props from index.ios.tsx and index.tsx
- Remove onLongPress and onActionsPress props from BookingListScreen.tsx
- Remove handleScheduleLongPress, setSelectedSchedule, setShowActionsModal props from AvailabilityListScreen.tsx
- Fix BookingDetailScreen.tsx to use correct action property names (reschedule.visible instead of canReschedule, etc.)

* fix(companion): remove unused code after dropdown unification

- Remove unused handleEventTypeLongPress function and ActionSheetIOS import from index.ios.tsx
- Remove unused copiedEventTypeId state, handleEventTypeLongPress function, and ActionSheetIOS import from index.tsx
- Prefix unused setSelectedBooking with underscore in BookingListScreen.tsx
- Remove unused handleScheduleLongPress function and ActionSheetIOS import from AvailabilityListScreen.tsx

* feat(companion): unify booking filter UI for Android and extension

- Remove SegmentedControl from web/extension booking list page
- Use Header dropdown for booking status filter on both Android and web
- Use unified event type filter dropdown for both platforms
- Remove unused showFilterModal state and related code
- Pass filterOptions, activeFilter, and onFilterChange to Header for all platforms

* fix(companion): add header padding for web/extension to prevent button clipping

- Add headerLeftContainerStyle and headerRightContainerStyle with 12px padding for web platform
- Applied to root Stack and all nested tab Stack layouts
- Fixes issue where header buttons were touching edges and getting chopped off on extension/web
- Android remains unaffected as the fix is web-only

* fix(companion): add HeaderButtonWrapper for web-only header padding

- Create HeaderButtonWrapper component that adds 12px margin on web only
- Wrap all header buttons with HeaderButtonWrapper to prevent clipping
- Revert invalid screenOptions changes that caused typecheck errors
- Apply fix to all screens with native header buttons:
  - reschedule.tsx, edit-location.tsx, add-guests.tsx
  - mark-no-show.tsx, view-recordings.tsx, meeting-session-details.tsx
  - event-type-detail.tsx, BookingDetailScreen.tsx, profile-sheet.tsx
  - edit-availability-day.tsx, edit-availability-name.tsx, edit-availability-override.tsx

* update more ui-ux

* address cubics comments

* address cubics comments & open event type list page first for inttial render of app

* chore: Integrate booking cancellation audit (#26458)

## What does this PR do?
> **⚠️ Note: This PR does not enable booking audit in production.** The `BookingAuditTaskerProducerService` has an [`IS_PRODUCTION` guard](https://github.com/calcom/cal.com/blob/integrate-booking-creation-reschedule-audit/packages/features/booking-audit/lib/service/BookingAuditTaskerProducerService.ts#L106-L108) that skips audit task queueing in production environments. This allows the integration to be tested in development before enabling it in production.

Integrates audit logging for booking cancellations, following the pattern established in PR #26046 for booking creation/rescheduling audit.

- Related to #25125 (Booking Audit Infrastructure)

### Changes:
- Add audit logging for single booking cancellation via `onBookingCancelled`
- Add audit logging for bulk recurring booking cancellation via `onBulkBookingsCancelled`
- Pass `userUuid` and `actionSource` from webapp cancel route (WEBAPP)
- Pass `userUuid` and `actionSource` from API-v2 bookings service (API_V2)
- Create `getAuditActor` helper to derive actor from userUuid or create synthetic guest actor
- Add `getUniqueIdentifier` helper for generating unique actor identifiers
- Add warning log when `actionSource` is "UNKNOWN" for observability
- Add integration tests for booking cancellation audit

### Audit Data Captured:
- `cancellationReason` (simple string value)
- `cancelledBy` (simple string value)  
- `status` (old → new, e.g., "ACCEPTED" → "CANCELLED")

### Updates since last revision:
- Simplified `CancelledAuditActionService` schema: `cancellationReason` and `cancelledBy` are now stored as simple nullable strings instead of change objects (old/new), since cancellation is a one-time event where tracking previous values doesn't apply
- Added integration tests for cancelled booking audit in `booking-audit-cancelled.integration-test.ts`
- Added `getUniqueIdentifier` helper function in actor.ts for generating unique identifiers with prefixes

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Cancel a single booking via the webapp - verify audit record is created with actor and actionSource="WEBAPP"
2. Cancel a single booking via API v2 - verify audit record is created with actionSource="API_V2"
3. Cancel all remaining bookings in a recurring series - verify bulk audit records are created with shared operationId
4. Cancel via unauthenticated cancel link - verify guest actor is created with synthetic email (prefixed with "param-" or "fallback-")
5. Run integration tests: `yarn test packages/features/booking-audit/lib/service/__tests__/booking-audit-cancelled.integration-test.ts`

## Human Review Checklist

- [ ] Verify `onBookingCancelled` and `onBulkBookingsCancelled` methods exist in `BookingEventHandlerService`
- [ ] Review the `getAuditActor` fallback logic - creates synthetic email with "fallback-" or "param-" prefix when no userUuid available
- [ ] Confirm the simplified schema for `cancellationReason`/`cancelledBy` (no longer tracking old→new) is intentional
- [ ] Note: Audit logging calls are awaited directly - if audit service fails, the cancellation will fail. Confirm this is the desired behavior.
- [ ] Verify `CancelledAuditDisplayData` type no longer includes `previousReason` and `previousCancelledBy` fields

---

Link to Devin run: https://app.devin.ai/sessions/42404e76a66946fe9e46fa07fb12e779
Requested by: @hariombalhara (hariom@cal.com)

* feat: OAuth2 controller api v2 + refactor oAuth Trpc handlers  (#25989)

* feat(api-v2): add OAuth2 controller skeleton for auth module

- Add new OAuth2 module under /auth with controller, service, repository, and DTOs
- Implement skeleton endpoints:
  - GET /v2/auth/oauth2/clients/:clientId - Get OAuth client info
  - POST /v2/auth/oauth2/clients/:clientId/authorize - Generate authorization code
  - POST /v2/auth/oauth2/clients/:clientId/exchange - Exchange code for tokens
  - POST /v2/auth/oauth2/clients/:clientId/refresh - Refresh access token
- Create input DTOs for authorize, exchange, and refresh operations
- Create output DTOs for client info, authorization code, and tokens
- Register OAuth2Module in endpoints.module.ts

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: add missing functions to platform libraries

* feat(api-v2): integrate OAuthService from platform-libraries into OAuth2 controller

- Add OAuthService export to platform-libraries
- Refactor OAuth2Service to use OAuthService.validateClient() and OAuthService.verifyPKCE()
- Remove duplicate local implementations of validateClient and verifyPKCE methods

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat(api-v2): use local validateClient and verifyPKCE implementations

- Remove OAuthService export from platform-libraries (will be deprecated)
- Reimplement validateClient and verifyPKCE methods locally in OAuth2Service
- Use verifyCodeChallenge and generateSecret from platform-libraries directly

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor(api-v2): separate repositories for OAuth2, access codes, and teams

- Create AccessCodeRepository for access code Prisma operations
- Add findTeamBySlugWithAdminRole method to TeamsRepository
- Move generateAuthorizationCode, createTokens, verifyRefreshToken to OAuth2Service
- Update OAuth2Repository to only contain OAuth client operations
- Update OAuth2Module to import TeamsModule and provide AccessCodeRepository

Addresses PR review comments to properly separate concerns

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat(api-v2): implement JWT token creation and verification for OAuth2

- Implement createTokens method using jsonwebtoken to sign access and refresh tokens
- Implement verifyRefreshToken method to verify JWT refresh tokens
- Add ConfigService injection for CALENDSO_ENCRYPTION_KEY access
- Import ConfigModule in OAuth2Module for dependency injection

Based on logic from apps/web/app/api/auth/oauth/token/route.ts and
apps/web/app/api/auth/oauth/refreshToken/route.ts

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: refactor and dayjs import fix

* feat(api-v2): add ApiAuthGuard to getClient endpoint and e2e tests for OAuth2

- Add @UseGuards(ApiAuthGuard) to getClient endpoint for authentication
- Add comprehensive e2e tests for all OAuth2 endpoints:
  - GET /v2/auth/oauth2/clients/:clientId
  - POST /v2/auth/oauth2/clients/:clientId/authorize
  - POST /v2/auth/oauth2/clients/:clientId/exchange
  - POST /v2/auth/oauth2/clients/:clientId/refresh
- Tests cover happy paths and error cases (invalid client, invalid code, etc.)

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore(api-v2): hide OAuth2 endpoints from Swagger documentation

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* hide endpoints from doc

* fix(api-v2): address PR feedback for OAuth2 controller

- Fix P0 critical bug: token_type field name mismatch in DecodedRefreshToken interface
- Add @Equals('authorization_code') validation to exchange.input.ts grantType
- Add @Equals('refresh_token') validation to refresh.input.ts grantType
- Add @IsNotEmpty() validation to get-client.input.ts clientId
- Add @Expose() decorators to all output DTOs for proper serialization
- Add security test assertion to verify clientSecret is not returned in response

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat(api-v2): implement redirect behavior for OAuth2 authorize endpoint

- Update authorize endpoint to return HTTP 303 redirect with authorization code
- Add exact match validation for redirect URI (security requirement)
- Implement error handling with redirect to redirect URI and error query params
- Add state parameter support for CSRF protection
- Update e2e tests to verify redirect behavior (303 status, Location header, error redirects)

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor(api-v2): address PR feedback for OAuth2 authorize endpoint

- Make redirectUri a required input parameter (remove optional fallback)
- Move buildRedirectUrl and mapErrorToOAuthError to oauth2Service
- Add return statements to res.redirect() calls
- Simplify controller by delegating redirect URL building to service

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* wip move code outside of api v2

* feat(oauth): wire up dependency injection for OAuthService and repositories

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: oAuthService used in routes

* fix imports

* fix(api-v2): return 404 for invalid client ID instead of redirect in authorize endpoint

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api-v2): fix E2E test URL paths and remove bootstrap() in authenticated section

- Remove bootstrap() call in authenticated section to match working test pattern
- Change URL paths from /api/v2/... to /v2/... in authenticated section
- Keep bootstrap() and /api/v2/... paths in unauthenticated section

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api-v2): mock getToken from next-auth/jwt for E2E tests

- Add jest.mock for next-auth/jwt getToken function
- Mock returns null for unauthenticated tests
- Mock returns { email: userEmail } for authenticated tests
- Remove withNextAuth helper since ApiAuthGuard uses ApiAuthStrategy
  which calls getToken directly, not NextAuthStrategy

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix tests and code review

* cleanup generate secrets

* cleanup controller

* chore: remove console.log from OAuthService.validateClient

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* Update apps/web/app/api/auth/oauth/refreshToken/route.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix(api-v2): add bootstrap() to authenticated E2E tests and update URL paths to /api/v2/

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* Merge remote-tracking branch 'origin/devin/oauth2-controller-skeleton-1765988792' and remove console.log from token route

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: remove dead code

* refactor

* refactor: generateAuthCode trpc handler and getClient trpc handler

* remove pkce check for refreshToken endpoint

* Update packages/trpc/server/routers/viewer/oAuth/getClient.handler.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor: error handling

* refactor: error handling

* refactor: error handling

* remove console log

* provide redirectUri in generateAuthCodeHandler

* provide redirectUri in authorize view

* refactor: replace HttpError with ErrorWithCode in OAuth files

- Update OAuthService to use ErrorWithCode instead of HttpError
- Update mapErrorToOAuthError to check ErrorCode instead of status codes
- Update token/route.ts and refreshToken/route.ts to use ErrorWithCode
- Add ErrorWithCode export to platform-libraries
- Use getHttpStatusCode to map ErrorCode to HTTP status codes

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update generateAuthCode handler to use ErrorWithCode instead of HttpError

The handler was still checking for HttpError in its catch block, but OAuthService
now throws ErrorWithCode. This caused the error messages to be lost and replaced
with 'server_error' instead of the specific error messages.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update OAuth2 controller to use ErrorWithCode instead of HttpError

The controller was still checking for HttpError in its catch blocks, but OAuthService
now throws ErrorWithCode. This caused all errors to return 500 Internal Server Error
instead of the correct HTTP status codes (400, 401, 404).

Also added getHttpStatusCode export to platform-libraries.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add explicit unknown type annotation to catch blocks in OAuth2 controller

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: change NotFoundException to HttpException in authorize endpoint

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: handle err with ErrorWithCode in authorize endpoint catch block

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: move errorWithCode

* fix: error code rfc

* fix: no need to handle errors there is a middleware

* refactor errors

* refactor errors

* refactor redirecturi and state from api

* refactor: address PR comments for OAuth2 controller

- Remove unused GetOAuth2ClientInput class
- Change API tag from 'Auth / OAuth2' to 'OAuth2'
- Move OAuthClientFixture to separate fixture file (oauth2-client.repository.fixture.ts)
- Add 'type' property to OAuth2ClientDto for confidential/public client type
- Rename 'clientId' to 'id' in OAuth2ClientDto (using @Expose mapping)
- Clean up duplicate provider declaratio…

* fix: remove duplicate onBookingCancelled call

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Signed-off-by: Bandhan Majumder <bandhanmajumder16@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Ram Shukla <codewithrex@gmail.com>
Co-authored-by: Pedro Castro <pedro@cal.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Manas Kenge <man.kng02@gmail.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Eesh Midha <72607015+eeshm@users.noreply.github.com>
Co-authored-by: Beto <43630417+betomoedano@users.noreply.github.com>
Co-authored-by: shashank-100 <shashank.telkhade@gmail.com>
Co-authored-by: Kartik Labhshetwar <kartik.labhshetwar@gmail.com>
Co-authored-by: Abhay Mishra <grabhaymishra@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: cal-com-ci[bot] <247290566+cal-com-ci[bot]@users.noreply.github.com>
Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: Anshumancanrock <109489361+Anshumancanrock@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Kartik <103111467+kartik-212004@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Adarsh Tiwari <adarshtiwari797023@gmail.com>
Co-authored-by: Dylan Tarre <timecreepsby@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Amin Jaoui <101276751+aminjaoui@users.noreply.github.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: Mehmet Sungur <mehmetsungurmutlu@gmail.com>
Co-authored-by: xDipzz <155362028+xDipzz@users.noreply.github.com>
Co-authored-by: Pasquale Vitiello <pasqualevitiello@gmail.com>
Co-authored-by: pasquale@cal.com <pasquale@cal.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Anas Najam <129951478+anzz14@users.noreply.github.com>
Co-authored-by: Bandhan Majumder <133476557+bandhan-majumder@users.noreply.github.com>
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Abhishek <abhiifour@gmail.com>
Co-authored-by: susan@cal.com <susan@cal.com>
Co-authored-by: Bailey Pumfleet <bailey@pumfleet.co.uk>
Co-authored-by: simiondolha <34995943+simiondolha@users.noreply.github.com>
Co-authored-by: simiondolha <simiondolha@users.noreply.github.com>
Co-authored-by: Kirankumar Ambati <kiran.chinna12520@gmail.com>
2026-01-14 08:20:37 -03:00
Alex van Andel 02d61da9b0 chore: release v6.0.12
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-14 11:15:04 +00:00
Dhairyashil ShindeandMorgan c0017114ef fix(api): return empty bookingUrl for managed users in API v2 (#26826)
Managed users (isPlatformManaged: true) don't have public booking pages -
their scheduling is handled through the platform's app.

- Fetch isPlatformManaged in event-types repository
- Return empty string for managed users in buildBookingUrl
- Added unit test for managed users case

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-14 15:28:25 +05:30
Eunjae LeeandDevin AI 4b99072bcc feat: add scope configuration for feature opt-in (#26801)
* feat: add scope configuration for feature opt-in

Add scope field to OptInFeatureConfig that allows features to be scoped
to specific levels (org, team, user). This enables features to be shown
only at certain settings pages rather than all three.

Changes:
- Add OptInFeatureScope type with values 'org', 'team', 'user'
- Add optional scope field to OptInFeatureConfig interface
- Add getOptInFeaturesForScope helper function to filter features by scope
- Update FeatureOptInService to filter features based on scope
- Update tRPC router to pass scope parameter for org/team endpoints

Features without a scope field default to all scopes for backward compatibility.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add scope validation to setUserFeatureState and setTeamFeatureState

- Add isFeatureAllowedForScope helper function to check if a feature is allowed for a scope
- Update setUserFeatureState to reject if feature is not scoped to 'user'
- Update setTeamFeatureState to accept scope parameter and reject if feature is not allowed
- Update tRPC router to pass scope parameter for team and org endpoints
- Fix unit test mock to include new config exports

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: use ErrorWithCode for scope validation and add tests

- Replace raw Error with ErrorWithCode using ErrorCode.BadRequest
- Add comprehensive tests for setUserFeatureState scope validation
- Add comprehensive tests for setTeamFeatureState scope validation
- Test both enabled/disabled and inherit state scenarios
- Test error messages include feature ID and scope name

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: improve Features menu visibility to use scope configuration

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove unused hasOptInFeaturesForScope function

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: allow features not in config at all scopes (permissive default)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: revert permissive default and mock scope validation in integration tests

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-14 09:21:56 +00:00
Dhairyashil ShindeandMorgan 821dce6a04 fix(api): skip platform org subdomain in bookingUrl for API v2 (#26812)
Platform organizations don't have public-facing subdomains, so non-managed
users in platform orgs should get cal.com URLs instead of the platform
org subdomain.

- Updated EventTypeUser type to include isPlatform field
- Modified buildBookingUrl to check isPlatform before using org slug
- Added unit test for platform org users

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-14 09:04:45 +00:00
3860717ae3 fix: workflow locale (#26509)
* fix: workflow locale

* fix: workflow locale

* fix: check if tmeplate is changed

* fix: regression

* fix: also check subject when determining if template is customized

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: extract template matching logic into testable function

- Create detectMatchedTemplate function in separate file
- Add comprehensive unit tests (20 test cases)
- Refactor EmailWorkflowService to use the new function

Addresses review comment from hariombalhara requesting
abstraction and tests for the template matching logic.

Co-Authored-By: udit@cal.com <udit222001@gmail.com>

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
2026-01-14 13:01:40 +05:30
Syed Ali Shahbaz f4303d8d60 icalsequence fix (#26815) 2026-01-14 10:08:19 +05:30
Rajiv Sahal 851aa30829 fix: respect hideCalendarNotes setting during booking reschedule (#25945)
Add hideCalendarNotes support to reschedule flow

The hideCalendarNotes flag was only handled in CalendarManager.createEvent(), not in updateEvent(). This caused notes to become visible again in ICS files after rescheduling.

Changes:
- Add hideCalendarNotes handling to CalendarManager.updateEvent()
- Add hideCalendarNotes checks to reschedule email functions
- Move description reset before reschedule call (required for cloned event)
2026-01-13 20:31:38 -03:00
2664eb459b feat: Init Cal.com Salesforce package (#26330)
* Add db schema

* Add `CredentialRepository.findByTeamIdAndSlugs`

* Add enabled app slugs for attribute syncing

* Create repository for `IntegrationAttributeSync`

* Create zod schemas

* Create `AttributeSyncUserRuleOutputMapper`

* Create `IntegrationAttributeSyncService`

* Create DI contianer

* Create trpc endpoints

* Create page

* Include team name in `CredentialRepository.findByTeamIdAndSlugs`

* Update schema and relations

* Update types and schemas

* Add more methods to IntegrationAttributeSyncRepository

* Add more services to `IntegrationAttributeSyncService`
- getById
- Init updateIncludeRulesAndMappings

* Refactor `getTeams.handler` to use repository

* Create `createAttributeSync` trpc endpoint

* Create `updateAttributeSync` trpc endpoint

* Add router to trpc

* Create attribute sync child components

* Pass custom actions to `FormCard`

* Create `IntegrationAttributeSyncCard`

* Pass inital props via server side

* Fix prop

* Only refetch on mutation

* Fixes

* Add form error when duplicate field and attribute combo

* Add `updateTransactionWithRUleAndMappings` logic

* Adjust zod schemas

* Service add `updateIncludeRulesAndMappings`

* Pass orgId from server to component

* Rename types

* Add deleteById method to repository

* Add name to integrationAttributeSync

* Add deleteById method to service

* Rename method

* Add deleteAttributeSync trpc endpoint

* Make the IntegrationAttributeSyncCard a dummy component

* test: add tests for IntegrationAttributeSync feature

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Move creating a attribute sync record to the service

* Add i18n strings

* Safe select credential in find by id and team

* Fix default credentialId value in form

* Update repository return types

* Add i18n string

* Make credentialId optional for form schema

* Fix label

* Add cascade deletes

* Add verification that syncs belong to org

* Create mapper for repository output

* Type fixes

* Remove old test file

* Pass `attributeOptions` from parent to children

* Infer types from zod schema

* Type fixes

* Type fix

* Clean up

* Add i18n strings

* Remove unused file

* Address feedback

* Add migration file

* Address feedback

* Add validation for new integration values

* Remove unused router

* Move away from z.infer to z.ZodType

* Clean up comments

* Type fix

* Type fixes

* Type fix

* fix: add passthrough to syncFormDataSchema to preserve extra fields

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Add endpoint for SF to call

* Create scratch org config

* Create sf cli scripts

* Create package logic

* Update README

* Remove unused file

* Add indexes

* Add aria label

* Address feedback - consistent validation

* Fix import paths for attribute types

* refactor: change attributeSyncRules array to singular attributeSyncRule

The database schema enforces a one-to-one relationship between
IntegrationAttributeSync and AttributeSyncRule (via @unique constraint),
and the UI only supports a single rule. This change makes the TypeScript
type match the database schema and UI behavior.

Changes:
- Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null
- Update mapper to return singular rule instead of wrapping in array
- Update UI component to access sync.attributeSyncRule directly
- Update IIntegrationAttributeSyncUpdateParams Omit type
- Update tests to use attributeSyncRule: null instead of attributeSyncRules: []

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: implement FeatureOptInService (#25805)

* feat: implement FeatureOptInService WIP

* clean up

* feat: consolidate feature repositories and add updateFeatureForUser

- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename updateFeatureForUser to setUserFeatureState

Rename to match the convention used for setTeamFeatureState

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState

* fix integration tests

* clean up logics

* update services and router

* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array

- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add getFeatureStateForTeams for batch querying multiple teams

- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: combine org and team state queries into single call

- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use team.isOrganization and clarify computeEffectiveState comment

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use MembershipRepository.findAllByUserId with isOrganization

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add featureId validation using isOptInFeature type guard

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* less queries

* add fallback value

* fix type error

* move files

* add autoOptInFeatures column

* use autoOptInFeatures flag within FeatureOptInService

* add setUserAutoOptIn and setTeamAutoOptIn

* fix computeEffectiveState logic

* rewrite computeEffectiveState

* clean up integration tests

* clean up in afterEach

* fix type error

* refactor: use FeaturesRepository methods instead of direct Prisma calls

Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.

Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts

This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* fix the logic

* extract some logic into applyAutoOptIn()

* remove wrong code

* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union

- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests

* fix type error

* use Promise.all

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Prevent duplicate field and attribute mappings

* Add validation that attribute belongs to the org

* fix: address Cubic AI review feedback

- Add @@index([credentialId]) to IntegrationAttributeSync model for efficient cascade deletes and credential-based queries (confidence: 9/10)
- Fix translation key from 'credential_required' to 'attribute_sync_credential_required' to match existing locale definition (confidence: 10/10)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: address remaining cubic review feedback

- RuleBuilder.tsx: Use unique IDs for React keys instead of array index to prevent reconciliation bugs when removing conditions
- updateAttributeSync.handler.ts: Add early organization check before service calls for consistency
- createAttributeSync.handler.ts: Add CredentialNotFoundError class for type-safe error handling instead of string matching
- IntegrationAttributeSyncService.test.ts: Replace expect.fail() with proper Vitest rejects.toSatisfy() pattern

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Pull test file from main

* fix: address Cubic AI review feedback (confidence >= 9/10)

- Remove sensitive fields (email, changedFields) from logging in user-sync.ts
- Rename scratch-org:open to scratch-org:start in package.json to match README

Co-Authored-By: unknown <>

* Update README

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2026-01-13 20:01:21 -03:00
ce997447a4 fix: fix email exclusion validation for full emails and and @-prefixed domains (#26727)
* fix(bookings): fix email exclusion validation for full emails and @-prefixed domains

* NIT

* make case insensitive

* fix: make domain matching case-insensitive in doesEmailMatchEntry

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 16:56:28 -03:00
Abhay MishraandAnik Dhabal Babu 5fa76f943b fix(phone-input): add Austria mask and prevent double plus prefix (#26626)
* fix(phone-input): add Austria mask and prevent double plus prefix (#24193)

* updated code

* Update Austria phone mask format

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-13 19:22:15 +00:00
Pedro Castro 4226231b8a perf: batch user queries in schedules output service (#25901)
Replace N sequential queries with single batch query for fetching
user default schedule IDs

Changes:
- Add getUsersScheduleDefaultIds batch method to UsersRepository
- Add getResponseSchedules batch method to OutputSchedulesService
- Extract transformScheduleToOutput for reuse
- Simplify OrganizationsSchedulesService and TeamsSchedulesService
- Remove dead code (formatInput no-op method)

Reduces database round-trips from O(n) to O(1) for schedule lookups
2026-01-13 19:21:17 +00:00
Dhairyashil Shinde 69695d3022 feat(companion): manifest id for safari extension & add delete account link (#26802)
* feat: manifest id for safari

* add delete account button
2026-01-13 16:12:43 -03:00
c13fce4483 fix: changes to error on schedule name empty save (#24044)
* fix #21709: change to error on schedule name empty save

* fix comments

* minor enahncemnts

---------

Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-13 18:29:58 +00:00
f32ea8b4c5 fix: Booker reschedule behaviour for org admin (#26530)
* fix: reschedule behaviour for org admin

* fix: use pbac for permissions check

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-13 18:12:32 +00:00
Anshumancanrock 36cf6e3703 fix: Yarn installation fails in windows due to mixed path separators … (#26771)
* fix: Yarn installation fails in windows due to mixed path separators in app-store-cli

* fix: normalize paths for cross-platform Biome compatibility in app-store-cli
2026-01-13 18:07:51 +00:00
455973b394 fix(ui): improve Variables Dropdown styling consistency (#26675)
* fix(ui): improve Variables Dropdown styling consistency

- Change focus ring from brand-800 to subtle for consistent design
- Add rounded-md to dropdown container for visual consistency
- Add rounded-md to DropdownMenuItem for rounded corners
- Remove redundant hover:bg-muted and conditional bg-muted styling

Fixes #25848

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: restore keyboard navigation active state indicator

Keep the conditional bg-muted styling for the selected item during
keyboard navigation, while still removing the redundant hover:bg-muted
since DropdownMenuItem already handles hover styling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: simiondolha <simiondolha@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-13 14:53:11 -03:00
0b73491367 refactor: split large org creation transaction into smaller batches (#25688)
* refactor: split large org creation transaction into smaller batches

The prisma.team.create call at L418 was creating the organization along with
all orgProfiles and memberships in a single large transaction, which could
timeout when there are many members.

This change splits the operation into smaller, separate transactions:
1. Create the organization (team) with just metadata and organizationSettings
2. Create org profiles in batches of 50 using Promise.all
3. Create memberships in batches of 100 using createMany
4. Fetch created profiles to rebuild the member-profile mapping

This approach avoids transaction timeouts while maintaining the same
functionality and data integrity.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-13 14:56:46 +00:00
573756eaa2 docs: fix CALENDSO_ENCRYPTION_KEY generation command (#26658)
The AES256 encryption used for 2FA requires exactly 32 bytes.
The previous command `openssl rand -base64 32` generates a 44-character
base64 string (32 bytes encoded in base64), which is too long.

Changed to `openssl rand -base64 24` which generates exactly 32
characters (24 bytes encoded in base64 = 32 characters).

This was causing 2FA setup failures with "Something went wrong" errors
and RangeError: Invalid key length in self-hosted Docker installations.

Fixes #22365

Co-authored-by: simiondolha <simiondolha@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-13 11:46:39 -03:00
5c686d90f9 feat: add tri-state UI settings pages and auto opt-in preference (#25892)
* feat: add tri-state UI settings pages and auto opt-in preference

TASK 5: Tri-state UI with ToggleGroup
- Create shared TeamOrgFeaturesSettings component
- Create user features settings page (features-view.tsx)
- Create team features settings page
- Create org features settings page

TASK 6: Add auto opt-in preference
- Add autoOptInExperimentalFeatures field to User and Team models
- Add migration for new fields
- Add TRPC endpoints for auto opt-in preference (using repository pattern)
- Add auto opt-in checkboxes to settings pages

Also adds i18n keys for feature opt-in UI.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

refactor: rename autoOptInExperimentalFeatures to autoOptInFeatures

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

refactor: apply PBAC procedure pattern to featureOptIn router

- Create createTeamPbacProcedure for team-scoped endpoints
- Create createOrgPbacProcedure for organization-scoped endpoints
- Refactor all team/org endpoints to use the new PBAC procedures
- Significantly reduces boilerplate code for permission checks

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

add features pages

implement hooks

update style

update style

rename slug to featureId

show Features page on the side bar only if OPT_IN_FEATURES.length > 0

revert unncessary renaming

revert some changes

remove some changes

* fix repository usage

* test: add unit tests for PBAC utility procedures

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add 'disabled by organization' badge for Team Level Features page

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* a little clean up

* feat: add effectiveReason to computeEffectiveStateAcrossTeams for better UI feedback

- Update computeEffectiveStateAcrossTeams to return both enabled state and reason
- Add EffectiveStateReason type with 6 possible values
- Update FeatureOptInService to include effectiveReason in resolved state
- Simplify useUserFeatureOptIn.getBlockedWarning to use effectiveReason directly
- Add feature_no_explicit_enablement_warning translation
- Invalidate feature list when auto-opt-in setting changes in all hooks

* test: add tests for FeatureOptInService.listFeaturesForTeam and refactor router to use TeamRepository

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* make it clearer about auto opt in

* move hooks to apps/web/module

* fix

* fix: move types to packages/features/feature-opt-in, fix imports and test mocks

- Move types.ts from apps/web/modules/feature-opt-in/hooks to packages/features/feature-opt-in
- Update FeaturesSettings.tsx to import types from new location
- Update hooks to import types from @calcom/features/feature-opt-in/types
- Fix organization features-view import path (~/settings/organizations -> ~/ee/organizations)
- Fix PermissionCheckService mock in util.test.ts to use class syntax

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add validation for team ID and remove isPublic from featureOptIn handler

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: resolve biome lint errors in feature-opt-in files

- Add explicit return types to functions and methods
- Replace ternary operators with if-else statements
- Replace forEach with for...of loops to avoid useIterableCallbackReturn
- Extract helper functions to reduce function complexity
- Add explicit type annotations to variables
- Move exports to end of file to satisfy useExportsLast rule

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: resolve type errors in featureOptIn router

- Replace ctx.organizationId with ctx.user.organization.id
- Add null checks for organizationId in org procedures
- Remove incorrect type annotation from featureOptInRouter

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: address PR feedback on feature opt-in implementation

- Refactor createMutationCallbacks to useMutationCallbacks hook with useLocale internally
- Restore comment on featureOptIn prop in FeaturesSettings.tsx
- Revert getAllTeamIds helper, use ternary operator instead
- Use ctx.user.organizationId with proper guard clauses

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix type error

* feat: disable toggle when feature is blocked by higher level

- Add isBlockedByHigherLevel function to UseFeatureOptInResult interface
- Implement blocking detection for user level (org/team disabled)
- Implement blocking detection for team level (org disabled)
- Organization level never blocked (top level)
- Update FeaturesSettings to disable ToggleGroup when blocked

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* change order of toggle buttons

* feat: add policy field (permissive/strict) to feature opt-in config

- Add OptInFeaturePolicy type with 'permissive' and 'strict' modes
- Update computeEffectiveStateAcrossTeams to handle both policies:
  - Permissive: user opt-in can activate; disables only win if ALL teams disable
  - Strict: user opt-in alone not enough; ANY explicit disable blocks
- Add new EffectiveStateReason values for strict policy
- Update FeatureOptInService to read policy from config
- Add unit tests for all 9 policy scenarios from spec

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rewrite test file with scenario tables and make policy required

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix type

* fix types

* make policy required

* disable toggle group if blocked by higher level

* refactor: move PBAC procedures to packages/trpc/server/procedures

- Move util.ts to pbacProcedures.ts in procedures folder for better reusability
- Move util.test.ts to pbacProcedures.test.ts alongside the main file
- Update imports in _router.ts to use new location

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: remove redundant null checks in featureOptIn router

The createOrgPbacProcedure middleware already validates organizationId
and throws if null. Use non-null assertion (!) instead of redundant
runtime checks since the middleware guarantees the value exists.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: improve middleware typing to avoid non-null assertions

Remove explicit return type from createOrgPbacProcedure to let TypeScript
infer the extended context type. This allows handlers to use ctx.organizationId
directly (typed as number) instead of ctx.user.organizationId! assertions.

The middleware validates organizationId and adds it to the context, so
downstream handlers can safely access ctx.organizationId as a number.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): use featureOptIn permissions instead of generic team/org permissions

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): add PBAC to team features page and pass canEdit to views

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add effectiveReason to IFeatureOptInService and update listFeaturesForTeam interface

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add feature_any_team_disabled to isUserBlockedByHigherLevel check

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add strict-policy reasons to warning helper function

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2026-01-13 15:37:53 +01:00
9ad8aa981a chore: deploy api v2 on vercel (#26735)
* chore: deploy api v2 on vercel

* fix: replace console.log with logger.log in Vercel handler

Address Cubic AI review feedback to use the logging framework
consistently instead of console.log in the serverless handler.

Co-Authored-By: unknown <>

* chore: enable esModuleInterop

* chore: deploy api v2 on vercel

* chore: deploy api v2 on vercel

* Update apps/api/v2/src/bootstrap.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fixup! Merge branch 'main' into deploy-api-v2-vercel

* Revert "chore: deploy api v2 on vercel"

This reverts commit 45c704a48e8396c46118069e1a25d8d7a5ee84be.

* chore: deploy api v2 on vercel

* fix: address Cubic AI review feedback in main.ts

- Replace console.log with logger.log for consistent logging
- Replace console.error with logger.error for consistent error logging
- Restore comma: true option in qs.parse to support comma-separated arrays

Co-Authored-By: unknown <>

* fix: remove comma: true from qs.parse to maintain backward compatibility

The main branch does not have comma: true in the query parser, so adding
it would be a breaking change for existing API consumers. Removing it to
maintain consistency with the current production behavior.

Co-Authored-By: unknown <>

* chore: deploy api v2 on vercel

* small fixes

* chore: add try catch around bootstrap.ts

* fix: use NestJS Logger and throw error instead of process.exit in bootstrap

- Replace console.error with logger.error for consistent logging
- Replace process.exit(1) with throw error to avoid breaking Vercel serverless instance reuse

Addresses Cubic AI review feedback (confidence 10/10 for both issues)

Co-Authored-By: unknown <>

* chore: try log redis url

* fix: sanitize REDIS_URL logging to avoid exposing credentials

Replace full REDIS_URL logging with a boolean check that only indicates
whether Redis is configured, without exposing the connection string.

Addresses Cubic AI review feedback (confidence 9/10)

Co-Authored-By: unknown <>

* chore: remove unnecessary logs

* fix: prisma adapter

* chore: handle USE_POOL platform libraries

* fix: use JSON.stringify for Vite define value

Wrap usePool with JSON.stringify() to properly serialize the string value.
Without this, Vite injects the raw value as an identifier instead of a
string literal, breaking runtime behavior.

Addresses Cubic AI review feedback (confidence 9/10)

Co-Authored-By: unknown <>

* fix: docker file builds

* fix: correct Dockerfile build order for platform packages

Reorder builds to match the dependency graph from dev:build script:
constants → enums → utils → types → libraries → trpc → api-v2

platform-libraries depends on the other platform packages, so they
must be built first.

Addresses Cubic AI review feedback (confidence 9/10)

Co-Authored-By: unknown <>

* fix: docker file builds

* chore: add docker build

* chore: upgrade nest/bull

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-13 11:31:21 -03:00
Carina WollendorferandCarinaWolli bb9581d0d9 fix: oauth flow for safari extension (companion) (#26795)
* oauth flow for safair extension

* code clean up

* fix type and lint errors

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-01-13 19:44:26 +05:30
Hariom BalharaandDevin AI 75d611c2e8 chore: Integrate creation/rescheduling booking audit for Recurring/regular booking/seated bookings (#26046)
* Integrate creation/rescheduling booking audit

* fix: add missing hostUserUuid to booking audit test data

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix-ci

* feat: enhance booking audit with seat reference

- Added support for seat reference in booking audit actions.
- Updated localization for booking creation to include seat information.
- Modified relevant services to pass attendee seat ID during booking creation.

* fix: update test data to match schema requirements

- Add seatReferenceUid: null to default mock audit log data
- Add seatReferenceUid: null to multiple audit logs test case
- Convert SEAT_RESCHEDULED test data to use numeric timestamps instead of ISO strings

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Allow nullish seatReferenceUid

* feat: enhance booking audit to support rescheduledBy information

- Updated booking audit actions to include rescheduledBy details, allowing tracking of who rescheduled a booking.
- Refactored related services to accommodate the new rescheduledBy parameter in booking events.
- Adjusted type definitions and function signatures to reflect the changes in the booking audit context.

* Avoid possible run time issue

* Fix imoport path

* fix failing test due to merge from main\

* Pass useruuid

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 13:16:16 +00:00
Alex van Andel 0408ce0741 chore: release v6.0.11
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-13 13:03:49 +00:00
Udit TakkarandVolnei Munhoz 5818da414b feat: update recording, transcript endpoint and add tests (#25771)
* feat: add tests and update endpoint

* chore: undo

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-13 09:54:23 -03:00
Syed Ali Shahbaz d381c2c2cb init (#26782) 2026-01-13 12:51:24 +00:00
3aa6499cd4 fix: remove header bug (#26438)
* remove header and add standard pagination

* Remove unused props from OutOfOfficeEntriesList

Removed unnecessary props from the data table component.

* removed standard pagination

* fix

* Update OutOfOfficeEntriesList.tsx

* remove unnecessary padding

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-13 12:14:19 +00:00
Pedro Castro 1e67f98970 fix: add Icelandic, Lithuanian, and Norwegian locale support for Booker (#25519)
- Create unified date/time formatter with Intl-first approach and dayjs fallback
- Add support for is/lt/nb locales in Booker components
- Unify date formatting across Booker (Header, dates, weekdays)
- Update translation pipeline to include is, lt, nb
- Add tests for new locales and formatter
- Add timezone support in dayjs fallback
- Add formatter caching with circuit breaker
- Use unified formatDateTime in Header.tsx
2026-01-13 08:47:39 -03:00
sean-brydon aaf5958b7d feat: adds admin billing section (#26747)
* feat: adds admin billing section

* use loading prop

* add log on resend error

* add error log in billing portal
2026-01-13 10:34:52 +00:00
Dhairyashil Shinde 80941c17a0 feat: companion unique id firefox (#26791) 2026-01-13 10:29:10 +00:00
Eunjae LeeandDevin AI 829d6c4714 feat(pbac): add FeatureOptIn resource to permission registry (#26761)
* feat(pbac): add Feature resource to permission registry

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): add migration for Feature resource permissions

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): add English translations for Feature resource

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): update Feature resource for opt-in/opt-out control (read and update only)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): rename Feature to FeatureOptIn resource

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): simplify update description text

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 10:17:41 +00:00
Eunjae LeeandDevin AI fd6e2a9ca5 fix: enable DI for FeatureOptInService (#26061)
* fix integration test

* fix: enable DI for FeatureOptInService

* create containers/FeaturesRepository.ts

* refactor: convert FeatureOptInService and FeaturesRepository to moduleLoader pattern

- Create feature-specific tokens in feature-opt-in/di/tokens.ts and flags/di/tokens.ts
- Update modules to use bindModuleToClassOnToken for type-safe dependency injection
- Simplify containers to use moduleLoader.loadModule() for automatic dependency loading
- Import feature-specific tokens in central tokens.ts using spread operator

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename FeatureOptInServiceInterface to IFeatureOptInService

Follow the codebase convention of using 'I' prefix for interface files and names.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: export featuresRepositoryModule for backward compatibility

The FeaturesRepository module was refactored to use moduleLoader pattern but
AvailableSlots.ts still imports featuresRepositoryModule. This adds the export
to maintain backward compatibility.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 11:02:00 +01:00
383314d3e2 feat: add skip trial feature for teams/orgs billing page (#26584)
* feat: add skip trial feature for teams/orgs billing page

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* feat: add translation strings for skip trial feature and fix lint-staged config

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: use IS_TEAM_BILLING_ENABLED instead of IS_SELF_HOSTED

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: use correct DialogHeader props in billing-view.tsx

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* restore lint staged config file

* invalidate trpc cache

* fix: update role filter and error message in skipTrialForTeam handler

- Changed role filter to include both OWNER and ADMIN roles to match authorization logic
- Updated error message to reflect that both owners and admins can skip the trial

Addresses Cubic AI review feedback on PR #26584

Co-Authored-By: unknown <>

* fix: optimize skipTrialForTeam to query only specific team by ID

Address Cubic AI review feedback: Replace findAllAcceptedTeamMemberships
(which fetches all teams) with TeamRepository.findById (which fetches
only the specific team needed). Authorization is already validated
earlier in the handler, so this redundant query was inefficient.

Co-Authored-By: unknown <>

* fix static methods

* feat: use pbac

* fix: remove redundant team query in getSubscriptionStatus handler

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* add pbac to skip team handler

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 09:17:42 +00:00
Hariom BalharaandDevin AI cee3195708 fix: optimize routing form mutation to avoid costly name update triggers (#26781)
* fix: optimize routing form mutation to avoid costly name update triggers

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Add load test script for form responses

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 08:53:10 +00:00
7c66f33de2 chore: UX Fixes (#26643)
* Copy changes

* Move search bar inline with new button

* Get rid of no more results message

* Change hidden badge to (hidden)

* Remove Cal.ai badge from sidebar

* Add dropdown to create button when there is multiple options

* Fix delete dialog

* Saved filters updates

* More string fixes

* Switch members table to use names

* Fix member spacing

* Fix routing form identifier field

* Fix routing forms stuff

* Only show SMS hint on SMS options

* Make workflow delete button minimal

* Fix padding on workflow steps

* Remove min width on workflow title

* Fix delete workflow PR

* Fix org profile buttons

* Fix org profile screen partially scrolled down

* Improve logos & banner uploads

* Personal profile fixes

* Fix settings general view stuff

* Sentence case consistency

* Fix stuff I broke

* Fix fab

* Fix hidden translation string

* Fix text fields

* Make button small for solo users too

* fix: update E2E tests to match sentence case labels in routing forms

* fix: update tests to match sentence case label changes

- insights.e2e.ts: chart titles (14 strings)
- event-types.e2e.ts: Organizer phone number location
- EditLocationDialog.test.tsx: phone number labels

* fix: address Cubic AI review feedback (confidence 9+)

- Replace hardcoded text-gray-500 with text-muted in TextField.tsx hint section
- Replace text locator with data-testid in E2E test for location select

Co-Authored-By: unknown <>

* fix: update E2E tests for sentence case label changes

- Use data-testid selectors for location options (more reliable than text)
- Update field identifiers in routing-forms tests to match new labels
- Fix Long text selector in manage-booking-questions test

* fix: replace text locator with data-testid in manage-booking-questions E2E test

Replace fragile text="Long text" locator with resilient
page.getByTestId("select-option-textarea") selector per E2E best practices.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* fix: use .last() for multiple location select items

---------

Co-authored-by: Pedro Castro <pedro@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 00:56:08 -05:00
Syed Ali Shahbaz 32d97fbea4 Add parentId condition to findOrganizationIdBySlug (#26729) 2026-01-13 03:53:06 +00:00
Volnei MunhozandDevin AI a20ad44209 feat: filter generic calendars from subscription batch (#26774)
Add filtering to SelectedCalendarRepository.findNextSubscriptionBatch to
exclude generic calendars (holidays, contacts, shared, imported, resources)
based on their externalId suffixes.

Changes:
- Add GENERIC_CALENDAR_SUFFIXES constant mapping providers to their
  generic calendar suffixes in AdaptersFactory
- Add getGenericCalendarSuffixes method to AdapterFactory interface
- Update findNextSubscriptionBatch to accept and use genericCalendarSuffixes
  parameter to filter out calendars with matching externalId suffixes
- Update CalendarSubscriptionService.checkForNewSubscriptions to pass
  generic calendar suffixes from the adapter factory
- Update tests to cover the new filtering logic

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 22:39:49 -03:00
Volnei Munhoz a6d7e4f107 Add claude.md (#26778) 2026-01-12 22:03:21 -03:00
5f21f54bae feat: Add compliance page to settings (#26777)
* Add compliance page to settings

* fix: sanitize error logging in B2 download route

Avoid logging raw error objects which may expose sensitive B2 credentials
or internal information. Use sanitized error message instead.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 21:50:09 -03:00
Pedro Castro 3a6ca9ef15 chore: update dependencies (#26710)
* chore: update dependencies

   - @modelcontextprotocol/sdk: 1.24.0 → 1.25.2
   via resolution
   - jose: 4.13.1 → 4.15.9
   - serialize-javascript: 6.0.1 → 6.0.2 via
   resolution

* fix: update jose and webpack versions

* chore: bump transitive dependencies

- webpack 5.94.0
- express 5.2.1
- @adobe/css-tools 4.3.2
- jsondiffpatch 0.7.2

* chore: add min-document resolution

* fix: remove jose from resolutions

Incompatible with openid-client@6.x which requires jose 5.x/6.x exports.
jose is updated directly in apps/web and packages/features/auth

* fix: replace express with body-parser, remove webpack

- body-parser: 2.2.1 (CVE-2025-13466)
- Removed webpack 5.94.0 (causes TS2729)
- Removed express 5.2.1 (causes path-to-regexp errors)

* fix: remove body-parser resolution for Express 4.x compatibility

body-parser 2.x is designed for Express 5.x but NestJS uses Express 4.x,
causing API v2 E2E tests to fail
2026-01-12 21:48:55 -03:00
95688b38fa fix(companion): event type links for org user (#26775)
* checkpoint 1

* checkpoint 2

* update extension header

* fix some minor ios ui bugs

* fix(companion): restore username fetching for URL fallback display

Addresses Cubic AI review feedback (confidence 9/10): The username was
hardcoded to 'username' but still used by BasicsTab as a fallback for
URL display when bookingUrl is unavailable. This restores the useEffect
that fetches the actual username from CalComAPIService.getUsername().

Co-Authored-By: unknown <>

* complete devins code change

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 05:37:56 +05:30
8dbe3848e7 feat: Create Integration Attribute Sync records (#26007)
* Add db schema

* Add `CredentialRepository.findByTeamIdAndSlugs`

* Add enabled app slugs for attribute syncing

* Create repository for `IntegrationAttributeSync`

* Create zod schemas

* Create `AttributeSyncUserRuleOutputMapper`

* Create `IntegrationAttributeSyncService`

* Create DI contianer

* Create trpc endpoints

* Create page

* Include team name in `CredentialRepository.findByTeamIdAndSlugs`

* Update schema and relations

* Update types and schemas

* Add more methods to IntegrationAttributeSyncRepository

* Add more services to `IntegrationAttributeSyncService`
- getById
- Init updateIncludeRulesAndMappings

* Refactor `getTeams.handler` to use repository

* Create `createAttributeSync` trpc endpoint

* Create `updateAttributeSync` trpc endpoint

* Add router to trpc

* Create attribute sync child components

* Pass custom actions to `FormCard`

* Create `IntegrationAttributeSyncCard`

* Pass inital props via server side

* Fix prop

* Only refetch on mutation

* Fixes

* Add form error when duplicate field and attribute combo

* Add `updateTransactionWithRUleAndMappings` logic

* Adjust zod schemas

* Service add `updateIncludeRulesAndMappings`

* Pass orgId from server to component

* Rename types

* Add deleteById method to repository

* Add name to integrationAttributeSync

* Add deleteById method to service

* Rename method

* Add deleteAttributeSync trpc endpoint

* Make the IntegrationAttributeSyncCard a dummy component

* test: add tests for IntegrationAttributeSync feature

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Move creating a attribute sync record to the service

* Add i18n strings

* Safe select credential in find by id and team

* Fix default credentialId value in form

* Update repository return types

* Add i18n string

* Make credentialId optional for form schema

* Fix label

* Add cascade deletes

* Add verification that syncs belong to org

* Create mapper for repository output

* Type fixes

* Remove old test file

* Pass `attributeOptions` from parent to children

* Infer types from zod schema

* Type fixes

* Type fix

* Clean up

* Add i18n strings

* Remove unused file

* Address feedback

* Add migration file

* Address feedback

* Add validation for new integration values

* Remove unused router

* Move away from z.infer to z.ZodType

* Clean up comments

* Type fix

* Type fixes

* Type fix

* fix: add passthrough to syncFormDataSchema to preserve extra fields

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Add indexes

* Add aria label

* Address feedback - consistent validation

* Fix import paths for attribute types

* refactor: change attributeSyncRules array to singular attributeSyncRule

The database schema enforces a one-to-one relationship between
IntegrationAttributeSync and AttributeSyncRule (via @unique constraint),
and the UI only supports a single rule. This change makes the TypeScript
type match the database schema and UI behavior.

Changes:
- Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null
- Update mapper to return singular rule instead of wrapping in array
- Update UI component to access sync.attributeSyncRule directly
- Update IIntegrationAttributeSyncUpdateParams Omit type
- Update tests to use attributeSyncRule: null instead of attributeSyncRules: []

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: implement FeatureOptInService (#25805)

* feat: implement FeatureOptInService WIP

* clean up

* feat: consolidate feature repositories and add updateFeatureForUser

- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename updateFeatureForUser to setUserFeatureState

Rename to match the convention used for setTeamFeatureState

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState

* fix integration tests

* clean up logics

* update services and router

* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array

- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add getFeatureStateForTeams for batch querying multiple teams

- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: combine org and team state queries into single call

- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use team.isOrganization and clarify computeEffectiveState comment

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use MembershipRepository.findAllByUserId with isOrganization

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add featureId validation using isOptInFeature type guard

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* less queries

* add fallback value

* fix type error

* move files

* add autoOptInFeatures column

* use autoOptInFeatures flag within FeatureOptInService

* add setUserAutoOptIn and setTeamAutoOptIn

* fix computeEffectiveState logic

* rewrite computeEffectiveState

* clean up integration tests

* clean up in afterEach

* fix type error

* refactor: use FeaturesRepository methods instead of direct Prisma calls

Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.

Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts

This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* fix the logic

* extract some logic into applyAutoOptIn()

* remove wrong code

* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union

- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests

* fix type error

* use Promise.all

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Prevent duplicate field and attribute mappings

* Add validation that attribute belongs to the org

* fix: address Cubic AI review feedback

- Add @@index([credentialId]) to IntegrationAttributeSync model for efficient cascade deletes and credential-based queries (confidence: 9/10)
- Fix translation key from 'credential_required' to 'attribute_sync_credential_required' to match existing locale definition (confidence: 10/10)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: address remaining cubic review feedback

- RuleBuilder.tsx: Use unique IDs for React keys instead of array index to prevent reconciliation bugs when removing conditions
- updateAttributeSync.handler.ts: Add early organization check before service calls for consistency
- createAttributeSync.handler.ts: Add CredentialNotFoundError class for type-safe error handling instead of string matching
- IntegrationAttributeSyncService.test.ts: Replace expect.fail() with proper Vitest rejects.toSatisfy() pattern

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Pull test file from main

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2026-01-12 22:57:28 +00:00
9202028ab6 fix: resolve API v2 test flakes with cleanup and simplified slug (#26766)
* fix: resolve API v2 test flakes by using UUID-only slug

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: add beforeAll cleanup to prevent test flakes from leftover data

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 18:54:29 -03:00
cal-com-ci[bot]andLingo.dev 2f90138757 feat: update translations via @LingoDotDev (#26773)
Co-authored-by: Lingo.dev <support@lingo.dev>
2026-01-12 21:52:37 +00:00
devin-ai-integration[bot]andsusan@cal.com 41dcfe0307 chore: update company email banner copy (#26767)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: susan@cal.com <susan@cal.com>
2026-01-12 20:52:35 +00:00
913eb47ff1 fix: weekly view scheduler breaking on view switch (#25891)
* fix: weekly view scheduler columns offset

* fix

* fix

---------

Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-12 18:58:11 +00:00
Dhairyashil Shinde e879c923ea feat(api): add bookingUrl field to event types API v2 response (#26195)
* feat(api): add bookingUrl field to event types API v2 response

Add a new bookingUrl field to EventTypeOutput_2024_06_14 that contains
the full, correct booking URL for each event type. This fixes the issue
where companion app and Chrome extension were hardcoding cal.com URLs
instead of using organization subdomains.

Changes:
- Add bookingUrl field to EventTypeOutput_2024_06_14 type definition
- Update repository to include organization data when fetching users
- Add buildBookingUrl method to compute URL using getOrgFullOrigin
- Include bookingUrl in getResponseEventType return object

The booking URL is computed using the first user's organization slug
(if any) to generate the correct subdomain URL (e.g., i.cal.com/keith/30min
for organization users instead of cal.com/keith/30min).

* fix: include organization data in getEventTypeByIdWithHosts

Update getEventTypeByIdWithHosts to use usersInclude to fetch
organization slug data, ensuring bookingUrl is computed correctly
for the GET /v2/event-types/{eventTypeId} endpoint.

* test: add unit tests and E2E assertions for bookingUrl field

* fix(api-v2): correct bookingUrl format for org users and fix double slashes

Fix issues with bookingUrl field in event types API v2 response:
- Remove trailing slashes from base URLs to prevent double slashes
- Use profile.username instead of user.username for organization users
  (profile contains clean username without org suffix)
- Include user profiles in repository queries to access profile data
- Create local org-domains utility to replace @calcom/features dependency
  which isn't available in API v2 runtime

Changes:
- Add apps/api/v2/src/lib/org-domains.ts with getOrgFullOrigin function
  adapted from @calcom/features/ee/organizations/lib/orgDomains
- Update event-types.repository.ts to include profiles in usersInclude
- Update buildBookingUrl() to prioritize profile data when available
- Update unit tests to cover organization user profile scenarios

Fixes:
- Double slashes in URLs (e.g., http://localhost:3000//user/slug)
- Incorrect username format for org users (e.g., owner1-acme instead
  of owner1)
- Missing organization subdomain in booking URLs (e.g., should be
  http://acme.localhost:3000/owner1/30min not
  http://localhost:3000/owner1-acme/30min)

* deslop ai code

* handle empty username in both code and write test for it, use select instead of include

* feat(api-v2): reuse core org domain logic for event type bookingUrl

Export getOrgFullOrigin and subdomainSuffix from @calcom/platform-libraries/organizations
to reuse existing core logic instead of duplicating it in API v2. This ensures consistency
across the codebase and reduces maintenance burden.

- Export getOrgFullOrigin and subdomainSuffix from platform-libraries/organizations
- Update output-event-types.service to import from @calcom/platform-libraries/organizations
- Remove duplicate org-domains.ts file from API v2
- Update test mocks to use platform-libraries import path
- buildBookingUrl method now uses core getOrgFullOrigin function

This addresses feedback to reuse core code rather than introducing duplicate logic.

* test(api-v2): exclude bookingUrl from output comparison in e2e test

* refactor(api-v2): reuse core logic for event type bookingUrl

Replace duplicated username/org extraction logic in buildBookingUrl with
core functions. Use getBookerBaseUrlSync from @calcom/platform-libraries/organizations
for base URL generation, and add enrichUserWithProfile method that follows
the same pattern as core's UserRepository.enrichUsersWithTheirProfiles.

The enrichment logic is applied synchronously since profiles are already
fetched by the repository, avoiding the need to make the service async.
This ensures consistency with core patterns while maintaining the existing
synchronous API contract.

- Replace getOrgFullOrigin with getBookerBaseUrlSync
- Add enrichUserWithProfile method following core enrichment pattern
- Simplify buildBookingUrl to use enriched user data
- Update tests to mock getBookerBaseUrlSync and verify enrichment flow

* trailing slash cubic comment

* address review comments

* address review comments 2

* better code

* Updated the test to give the user an organization

* address review comments again

* Revert "address review comments again"

This reverts commit 622ea3fc8dcd7f5c3113614afcfc86beadecca0e.

* allow both the full UserWithProfile and the partial EventTypeUser (from select queries) to use the same getUserMainProfile() method, eliminating code duplication without changing the performance-optimized repository queries.

* reveiw points
2026-01-12 14:57:17 -03:00
Keith WilliamsandDevin AI ae2ea190d8 feat: add DEVIN_ACTIONS_PAT instructions for pushing to forked PRs (#26693)
* feat: add DEVIN_ACTIONS_PAT instructions for pushing to forked PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: simplify PAT instructions to be high-level

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: allow workflow_dispatch to run on draft PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: only process targeted PR when pr_number is provided

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add critical fork PR error handling instruction to stale PR workflow

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 14:42:37 -03:00
Anshumancanrock 5c9a5c5729 fix: use cross-platform rimraf for build scripts (#25814)
* use cross-platform rimraf for build scripts

* fix: use cross-platform rimraf for build scripts

* fix: replace cp with npx shx cp for cross-platform compatibility

* Update schema.prisma
2026-01-12 22:56:18 +05:30
Keith WilliamsandDevin AI 77184226e5 ci: use pull_request_target for conflict resolver label trigger (#26762)
* fix: use pull_request_target for conflict resolver label trigger

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: update if condition to check for pull_request_target event name

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 14:24:43 -03:00
Keith WilliamsandPeer Richelsen a4d4626319 revert: "feat: rename --font-cal to --font-heading + use Cal Sans UI (#26064)" (#26759)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2026-01-12 16:57:27 +00:00
Pedro Castro 3e063d6744 fix: use HEAD^2 and relative threshold in conflict (#26758)
resolver validation

- Change git diff from HEAD^1 to HEAD^2 to show PRs contribution
(matches GitHubs Files changed view) instead of what main brought in
- Replace fixed 50-file threshold with relative threshold (original PR files + 10)
- A 20-file PR with 100 files in merge = bad
- A 100-file PR with 108 files in merge = fine
2026-01-12 16:47:08 +00:00
Eunjae LeeandDevin AI 0413783ffb docs: extract DI pattern guide to separate file with moduleLoader pattern (#26756)
* docs: add moduleLoader pattern documentation to knowledge-base

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: rewrite DI section to use moduleLoader pattern as primary approach

- Replace manual module loading examples with moduleLoader pattern
- Add Mistake 4 about manual module loading being not type-safe
- Update Core Concepts to explain moduleLoader components
- Show both depsMap (multiple deps) and dep (single dep) usage
- Emphasize build-time type safety throughout

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: extract DI pattern to separate file

- Move DI documentation from knowledge-base.md to di-pattern.md
- Add brief reference in knowledge-base.md pointing to the new file
- Keeps knowledge-base.md focused on quick notes while DI gets its own detailed guide

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 15:26:47 +00:00
Keith WilliamsandDevin AI 92f13cdb56 fix: strengthen validation in conflict resolver to prevent bad merge commits (#26754)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 15:10:18 +00:00
Keith WilliamsandDevin AI 1e295827c7 refactor: change conflict resolver from cron to label-based trigger (#26757)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 15:01:51 +00:00
Morgan c7cd25b7d5 chore: api v2 esModuleInterop more imports (#26755) 2026-01-12 11:39:01 -03:00
Keith WilliamsandDevin AI d24807e0e1 fix: make OOO team member select close after selection (#26736)
* fix: make OOO team member select close after selection

Replace the custom always-visible scrollable list with a proper Select
component that closes after selection like a normal dropdown. The Select
component uses onMenuScrollToBottom for infinite scroll and onInputChange
for search functionality.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: also convert Team OOO member select to use Select component

Both 'Select team member' sections now use the proper Select component
that closes after selection. Removed unused useInViewObserver import.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add menuPlacement='bottom' to Team OOO member select

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 14:35:19 +00:00
Morgan 6840642cb7 chore: esModuleInterop: true api v2 tsconfig (#26752)
* chore: api v2 esModuleInterop

* chore: api v2 esModuleInterop
2026-01-12 11:24:08 -03:00
d5c2212c41 chore: Add logging eventId from Stripe webhook (#26623)
* Add loggin

* fix: use established logger instead of console.log for Stripe webhook eventId

Co-Authored-By: unknown <>

* fix: remove sensitive stripe-signature header from error logs

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 14:02:35 +00:00
Keith WilliamsandDevin AI c5cb2edd65 feat: add Biome rule to restrict @calcom imports in API v2 (#26749)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 13:39:29 +00:00
Keith WilliamsandDevin AI 023dfc2a5e feat: request maintainer access for fork PRs without edit permissions (#26750)
- Update devin-conflict-resolver.yml to check maintainerCanModify for fork PRs
- Instead of skipping fork PRs entirely, now checks if maintainer access is enabled
- Posts friendly comment asking contributors to enable 'Allow edits from maintainers'
- Adds 'maintainer-access-requested' label to track which PRs have been notified
- Update stale-pr-devin-completion.yml to post similar comment when triggered
- Both workflows avoid duplicate comments by checking for existing requests

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 13:39:15 +00:00
Dhairyashil Shinde dd4e1ba11b fix: api v2 dev server error (#26748) 2026-01-12 13:33:48 +00:00
Eunjae LeeandDevin AI 70d5a78d69 docs: add DI pattern guide to knowledge-base.md (#26751)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 14:33:40 +01:00
AnshumancanrockandPallav ea2036672b fix: normalize backslashes in glob paths for Windows compatibility (#25613)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2026-01-12 13:33:28 +00:00
Kartik LabhshetwarandAnik Dhabal Babu 77a0d69c1a fix(ui): fixing the hover bug in the dropdown component (#26257)
* fix(ui): fixing the hover bug in the dropdown component

* revert

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-12 13:26:19 +00:00
Keith WilliamsandDevin AI cf6581eaea ci: only auto-fix Cubic suggestions with confidence >= 9/10 (#26745)
* fix: only auto-fix Cubic suggestions with confidence >= 9/10

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 18:16:35 +05:30
Volnei Munhoz c36f4d4a65 Revert "fix: add withSentryConfig to enable Sentry tracing in production (#26…" (#26744)
This reverts commit dd4e8344c9.
2026-01-12 12:16:08 +00:00
Volnei MunhozandDevin AI dd4e8344c9 fix: add withSentryConfig to enable Sentry tracing in production (#26743)
This adds the withSentryConfig wrapper to the Next.js configuration,
which is required for Sentry tracing to work properly. The wrapper is
only applied in production when both NEXT_PUBLIC_SENTRY_DSN and
SENTRY_TRACES_SAMPLE_RATE environment variables are set.

Without this wrapper, Sentry cannot properly instrument the build for
performance monitoring, causing spans (including calendar telemetry)
to not be recorded despite the SDK being initialized.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 12:07:31 +00:00
6fb42b63e0 feat: add comprehensive validation tests for event-types/[id] GET endpoint (#23809)
* feat: add comprehensive validation tests for event-types/[id] GET endpoint

- Add integration tests for complex validation scenarios
- Test locations, booking fields, metadata, and seats validation
- Test edge cases that could cause validation mismatches between validators and DB results
- Ensure API response structure matches schemaEventTypeReadPublic schema
- Successfully catch validation discrepancies like missing displayLocationPublicly and assignAllTeamMembers fields

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: add explicit type annotations for booking fields find callbacks

- Fix TypeScript errors on lines 388 and 395
- Provide proper type annotations for find method callback parameters
- Replace any[] with specific { label: string; value: string }[] type
- Ensure CI type checking passes

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* feat: convert event-types integration test to use real database

- Replace prismaMock with real Prisma client operations
- Create actual database records for comprehensive test scenarios
- Add proper setup/teardown with unique timestamps for test isolation
- Maintain all existing validation test coverage
- Follow Cal.com integration test patterns for database operations

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* feat: restore original mock-based test alongside integration test

- Restored original _get.test.ts with prismaMock for unit testing
- Kept _get.integration.test.ts with real database for integration testing
- Both tests provide complementary coverage: mocks for fast unit tests, real DB for validation testing
- Fixed type annotations in find callbacks to maintain type safety

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: rename integration test to use proper naming convention

- Rename _get.integration.test.ts to _get.integration-test.ts
- Follows Cal.com vitest workspace pattern for integration tests
- Ensures integration test runs in proper CI workflow with database setup

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: update tests to use handler return value instead of res._getData()

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add proper type assertions for locations and bookingFields in tests

Co-Authored-By: unknown <>

* fix: create schedule for test user to fix foreign key constraint in integration tests

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: keith@cal.com <keithwillcode@gmail.com>
2026-01-12 12:01:43 +00:00
Carina WollendorferandCarinaWolli b6df61d287 fixes for safari extension (#26741)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-01-12 16:50:44 +05:30
Hariom BalharaandDevin AI 77f59b1e4d chore: Integrate confirmation booking audit (#26523)
* chore: Integrate booking confirmation booking audit

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Use BookingStatus type instead of string for booking.status

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Make booking-audit integration test utils reusable

* refactor: enhance handlePaymentSuccess to accept appSlug and actor identification

- Updated handlePaymentSuccess function to accept an object with paymentId, bookingId, appSlug, and traceContext.
- Introduced getActor function to determine the actor based on appSlug and credentialId.
- Modified webhook handlers for Alby, BTCPayServer, HitPay, PayPal, and Stripe to pass the new parameters.
- Improved logging for missing credentialId in payment processing.
- Adjusted related schemas to ensure proper type handling for booking status and actor identification.

* fix: Correct import paths and getActor function call

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Use ActorIdentification type instead of AuditActor in getActor

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add guard clause for undefined actor in fireBookingAcceptedEvent

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add actionSource to all confirm calls

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Integrate actor identification and action source updates across booking services

- Added `makeUserActor` to various booking service files to enhance actor identification.
- Updated action source handling in booking confirmation and related functions to include "MAGIC_LINK".
- Refactored schemas to accommodate new actor and action source requirements, ensuring consistent type handling.
- Improved error handling and logging for booking actions to enhance traceability.

* Remvoe formatting changes

* Add test

* refactor: Enhance booking confirmation tests and event handling

- Updated `confirm.handler.test.ts` to improve test coverage for booking acceptance and rejection scenarios, including bulk bookings.
- Refactored the mock implementation of `BookingEventHandlerService` to streamline event handling for accepted and rejected bookings.
- Adjusted the `handleConfirmation` function to utilize `acceptedBookings` for better clarity and maintainability.
- Added tests to ensure correct invocation of event handler methods for both single and bulk booking confirmations and rejections.

* fix tests

* refactor: Use confirmHandler directly in link and verify-booking-token routes

Refactors the link and verify-booking-token API routes to call confirmHandler directly instead of using the tRPC caller pattern. This simplifies the code by removing the need for session getter, legacy request building, and context creation.

Changes:
- apps/web/app/api/link/route.ts: Use confirmHandler directly with ctx and input
- apps/web/app/api/verify-booking-token/route.ts: Use confirmHandler directly with ctx and input
- Updated tests to mock confirmHandler instead of tRPC caller

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix ts errors due to merge frommain

* feat: introduce getAppActor utility for actor creation

This commit adds a new utility function, getAppActor, to streamline the process of creating actor objects for apps based on their slug and credential ID. The function is integrated into handlePaymentSuccess and handleStripePaymentSuccess, replacing the previous inline actor creation logic. This refactor enhances code maintainability and readability by centralizing actor creation logic.

Changes:
- New file: packages/app-store/_utils/getAppActor.ts
- Updated handlePaymentSuccess and handleStripePaymentSuccess to use getAppActor
- Removed redundant actor creation code from these functions

* refactor: Update appSlug in payment success handlers to use appConfig.slug

This commit modifies the appSlug parameter in the handlePaymentSuccess function across multiple payment webhook handlers to utilize the appConfig.slug value instead of hardcoded strings. This change enhances consistency and maintainability of the code.

Changes:
- Updated appSlug in handlePaymentSuccess for btcpayserver, hitpay, and paypal webhooks.
- Adjusted a test case to reflect the new appSlug value for consistency.

* test: Enhance booking token verification and audit action tests

This commit adds additional assertions to the booking token verification tests to ensure that the confirmHandler is not called when an error occurs. It also introduces a mechanism to clean up additional booking UIDs after each test in the accepted action integration tests, improving test reliability. Furthermore, it updates the action source schema comment for clarity.

Changes:
- Updated tests in `verify-booking-token` to check that `mockConfirmHandler` is not called on error.
- Implemented cleanup logic for additional booking UIDs in `accepted-action.integration-test.ts`.
- Clarified comment in `actionSource.ts` regarding the schema for action sources.
- Refactored `handleConfirmation.ts` and `confirm.handler.ts` to include tracing logger for error handling in booking events.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 08:17:26 -03:00
Hariom BalharaandDevin AI c9bb03b602 chore: Integrate add guests booking audit (#26568)
* chore: Integrate add guests booking audit

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* chore: Add actionSource parameter to support API_V2 audit logging

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: update attendee audit action service to use new email schema

- Modified the `AttendeeAddedAuditActionService` to replace the old attendees schema with a new `emailSchema` for better validation.
- Adjusted the `addGuestsHandler` to pass the action source explicitly and updated the audit logging to reflect the new structure.
- Cleaned up the code for better readability and consistency.

* test: add happy path integration test for attendee added action

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 11:11:33 +00:00
Abhay Mishra b517adfb66 fix: auto-scroll active installed-apps category tab into view on mobile (#26414)
* fix: auto-scroll active installed-apps category tab into view on mobile

* updated code3
2026-01-12 11:11:15 +00:00
ac90caa81b feat: add DAL for monthly proration tracking (#26588)
* feat(billing): add database schema for monthly proration tracking

add new database models and migration for tracking seat changes and monthly proration on annual subscriptions

- new models: SeatChangeLog, MonthlyProration
- new enums: SeatChangeType, ProrationStatus
- extend TeamBilling and OrganizationBilling with billingPeriod, pricePerSeat, paidSeats fields
- add feature flag 'monthly-proration' (disabled by default)
- squashed migration: 20260106093811_add_monthly_proration_tracking

the schema supports:
- tracking seat additions/removals per month with metadata
- storing proration calculations and stripe invoice details
- high-water mark billing via paidSeats field
- proper foreign key relationships and indexes for query performance

* feat(billing): add repository layer for monthly proration

add repository pattern for proration data access

- MonthlyProrationRepository: crud operations for proration records
  - create, update, and query proration records
  - status management (pending, invoice_created, charged, failed)
  - retry count tracking

- MonthlyProrationTeamRepository: team-specific queries with billing context
  - fetch teams with billing information
  - query annual teams with unprocessed seat changes
  - update billing info and paidSeats
  - metadata fallback for legacy teams without billing records

- update IBillingRepository interface to include proration fields

these repositories provide clean data access layer without business logic

* feat(billing): add seat change tracking service

add service for logging and querying seat changes per month

- SeatChangeTrackingService: track seat additions and removals
  - log seat additions with user and metadata context
  - log seat removals with optional triggered-by info
  - calculate monthly changes (additions, removals, net change)
  - retrieve unprocessed changes for a given month
  - mark changes as processed after proration calculation
  - auto-detect billing entity (team vs organization)

- stripe-subscription-utils: extract billing data from stripe subscriptions
  - determine billing period (monthly vs annually)
  - extract price per seat and quantity

includes comprehensive unit tests

* feat(billing): add billing period service

add service to determine billing period and proration eligibility

- BillingPeriodService: query and manage billing period information
  - check if team is on annual vs monthly plan
  - check if team is in trial period
  - determine if monthly proration should apply (annual + not in trial + feature flag)
  - lazy load billing data from stripe if missing in database
  - backfill missing billing data automatically

supports both TeamBilling and OrganizationBilling models
includes comprehensive unit tests with stripe mocking

* feat(billing): add monthly proration service

add core service for calculating and processing monthly seat prorations

- MonthlyProrationService: orchestrate monthly proration workflow
  - process monthly prorations for teams with seat changes
  - calculate prorated amounts based on remaining subscription days
  - create stripe invoice items for seat additions
  - handle payment success and failure webhooks
  - track high-water mark (paidSeats) for billing
  - update stripe subscription quantities after payment
  - lazy load and backfill missing billing data from stripe
  - support retry logic for failed payments

calculation logic:
- only charge for net seat increases (additions - removals, capped at 0)
- prorate based on remaining days in annual subscription
- track separately from stripe's built-in proration to aggregate monthly

includes unit tests and integration tests with stripe mocking

* refactor(billing): extract prisma logic from services to repositories

move database access logic from services to repository layer for better separation of concerns

- add SeatChangeLogRepository for seat change log data access
- add BillingPeriodRepository for billing period queries and updates
- refactor SeatChangeTrackingService to use SeatChangeLogRepository
- refactor BillingPeriodService to use BillingPeriodRepository
- add create methods to MonthlyProrationTeamRepository for billing records
- refactor MonthlyProrationService to use repository for billing creation
- remove direct prisma calls from services (except FeaturesRepository dependency)

services now focus on business logic while repositories handle data access

* refactor(billing): inject prisma via constructor in repositories

make repositories more testable by accepting prisma client via constructor

- SeatChangeLogRepository: accept optional prisma in constructor
- BillingPeriodRepository: accept optional prisma in constructor
- MonthlyProrationRepository: accept optional prisma in constructor
- MonthlyProrationTeamRepository: accept optional prisma in constructor

all repositories default to global prisma instance when not provided
enables easier mocking in tests by injecting test prisma instances

* refactor: remove verbose comments and unnecessary try-catch

* refactor: change pricePerSeat and proratedAmount to cents (Int)

store monetary values as integers in cents instead of floats for precision
remove unnecessary schema comments

* fix tests and add back try catch error handlign

* Update packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* add faeture flag to config.ts

* Update packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* restore schema

* add hooks types for flag

* fix: correct pricePerSeat calculations for cents-based storage

MonthlyProrationService now correctly handles pricePerSeat stored as
cents (INTEGER) instead of dollars (DOUBLE PRECISION). Removed duplicate
conversions to cents that were causing 100x price inflation.

* Use cents for money values

* fix type error

* Move integration to test to use cents value

* fix integration import

* mock subscription

* include paid seats tracking in proration service

* add mocks for invoice creation

* feat: use stripebilling service instead of using stripe directly

* fix validation erorr handler in proration service

* fix: fix sub

* use correct seat value

* fix(billing): mark seat changes as processed when netChange is zero

When a team has additions and removals that net to zero, the function
was returning null without calling markAsProcessed(). This left seat
change logs in an unprocessed state indefinitely, causing subsequent
proration runs to re-query the same changes repeatedly.

Changed the early return condition from checking netChange === 0 to
checking if there are no changes at all (additions === 0 && removals === 0).
This ensures that when there are actual seat changes that net to zero,
a proration record is still created and seat changes are marked as processed.

Co-Authored-By: unknown <>

* update test to reflect new return type of proration

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-12 10:58:21 +00:00
Volnei Munhoz 4c0b0115a2 remove explicity json check as it is already in included files (#26739) 2026-01-12 10:43:49 +00:00
Dhairyashil Shinde ec87eee900 added the API v2 Imports section to your AGENTS.md (#26737) 2026-01-12 07:21:22 -03:00
Alex van Andel aed80cdbe1 chore: release v6.0.10
Post release / release (push) Canceled after 0s
Release Docker / Prepare Release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-12 10:18:43 +00:00
Benny JooandDevin AI e3eaa69339 fix: return 400 instead of 500 for invalid eventTypeId in booking flow (#26732)
* fix: return 400 instead of 500 for invalid eventTypeId in booking flow

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: use ErrorWithCode instead of HttpError in BotDetectionService

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: use vi.stubEnv for safer environment variable handling in tests

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 07:07:35 -03:00
Benny JooandDevin AI fc0a2b5a37 refactor: Remove trpc/server dependency from @calcom/atoms (#26717)
* mv useTeamMembersWithSegment

* remove

* fix ts error

* remove

* remove

* remove

* biome rule

* wip

* refactor: remove remaining @calcom/trpc/server imports from atoms

- Create local types for schedule handlers (CreateScheduleHandlerReturn, DuplicateScheduleHandlerReturn, GetAvailabilityListHandlerReturn, CreateScheduleInput)
- Create local GetAvailableSlotsResponse type for slots hook
- Update imports in useAtomCreateSchedule, useAtomDuplicateSchedule, useAtomGetAllSchedules, and useAvailableSlots

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix: add userId to Schedule type and create ScheduleForList type

- Schedule type now includes userId for create/duplicate handlers
- Created ScheduleForList type for list handler (uses select without userId)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix

* fix

* fix: correct fromUser/toUser types in GetAvailableSlotsResponse

- fromUser: { id, displayName } (matches IFromUser)
- toUser: { id, username, displayName } (matches IToUser)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 07:06:22 -03:00
Rajiv Sahal f7dee536d7 fix: dont import directly from @calcom/trpc or @calom/features (#26734) 2026-01-12 10:05:39 +00:00
Anik Dhabal Babu a8e4097c4c test: fix flaky (#26728) 2026-01-12 08:08:01 +00:00
0994050b0f fix(api): return original email without OAuth suffix in bookings (#25593)
* fix(api): remove OAuth client ID suffix from email in booking API responses

Fixes #25494 | Linear: CAL-6843

When managed users create or receive bookings, their emails were being returned with an internal OAuth client ID suffix (e.g., bob+cuid123@example.com). This suffix is used internally for user identification but should not be exposed in API responses.

Changes:
- Add cleanOAuthEmailSuffix() helper using CUID regex pattern
- Clean email suffix in hosts[], attendees[], bookingFieldsResponses.email, bookingFieldsResponses.guests[], and reassignedTo.email
- Pattern consistent with google-calendar.service.ts implementation

Affected output methods:
- getOutputBooking
- getOutputRecurringBooking
- getOutputSeatedBooking
- getOutputRecurringSeatedBooking
- getOutputReassignedBooking
- getHost

* refactor(api): preserve original email, add displayEmail field

Per team discussion, keep original email unchanged to avoid breaking changes for platform customers.
Add displayEmail field with CUID suffix removed for display purposes

* feat(api): add displayEmail to booking output DTOs

Add displayEmail property to BookingAttendee, BookingHost and ReassignedToDto for API documentation and type safety

* test(api): add e2e tests for displayEmail fields in managed user bookings

Add tests to verify that displayEmail fields correctly strip CUID suffix from OAuth managed user emails in booking API responses:

- Test host displayEmail returns email without CUID suffix
- Test attendee displayEmail returns email without CUID suffix
- Test bookingFieldsResponses.displayEmail returns clean email
- Test displayGuests array returns emails without CUID suffix

* false positive breaking change

* false positive breaking change

* test(api): update existing e2e tests to expect displayEmail field

* fix(api): add missing displayEmail to seated booking test assertions

The seated booking tests were missing displayEmail in the attendee
assertions for the second booking test and cancel-as-host test,
causing CI test failures

---------

Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-12 07:48:37 +00:00
Syed Ali ShahbazandVolnei Munhoz 3e7e376100 chore: Some minor fixes and follow up to #26446 (#26587)
* init

* DI and other improvements

* type fix

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-12 04:32:55 +00:00
Anik Dhabal Babu 93cac5a1c9 fix: don't include ics for unconfirmed booking (#26718) 2026-01-12 03:48:27 +00:00
a03e64da1b feat: implemented skeleton loader (#23654)
* implemented skeleton loader

* fix: improve skeleton ui

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 08:42:46 +05:30
mintlify[bot] 2e571eaedf docs: Enhanced Booker Atom Documentation (#24773)
* Update docs/platform/atoms/booker.mdx

* Update docs/platform/atoms/booker.mdx

* Update docs/platform/atoms/booker.mdx

* Update docs/platform/atoms/booker.mdx

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2026-01-12 00:56:07 +00:00
Anshumancanrock 258b1a7bb8 fix: make travel schedule delete icon red (#26725) 2026-01-11 23:28:32 +00:00
Keith WilliamsandDevin AI d675f82557 chore: migrate e2e-atoms and nextjs-bundle-analysis to cache-checkout (#26713)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-11 20:10:22 -03:00
Alex van Andel 312733ce68 refactor: Extract schedule determination to seperate fn (#26600)
* refactor: Extract schedule determination to seperate fn

* refactor: Extract schedule detection to seperate file and add tests

* RouterOutputs should be used in hooks, not direct type imports
2026-01-11 19:44:09 -03:00
58798f27d2 feat: add source: 'onboarding' metadata to subscriptions from onboarding v3 (#26619)
When a user signs up to a team/org from onboarding v3, the subscription
now includes source: 'onboarding' in its metadata. This helps track
which subscriptions originated from the onboarding flow.

Changes:
- Add source: 'onboarding' to subscription_data.metadata in team checkout
  when isOnboarding is true
- Add source: 'onboarding' to subscription metadata for organization
  onboarding flow

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-11 21:49:10 +00:00
Dhairyashil ShindeandDevin AI 478ca05246 feat(companion): update Android booking detail page to match iOS design (#26715)
* feat(companion): update Android booking detail page to match iOS design

* feat(companion): add video icon button to Android header for join meeting

* fix(companion): use eventType.description instead of booking.description

Address Cubic AI review feedback - the booking description may contain
Additional Notes which can cause duplicate display. The event type
description is the proper source for this information.

Co-Authored-By: unknown <>

* Revert "fix(companion): use eventType.description instead of booking.description"

This reverts commit 3e324313f2d72704ab51f723a52b2784b33e7867.

* fix(companion): extract IOSPickerTrigger to platform-specific files for web compatibility

* fix(companion): extract iOS pickers to platform-specific files for web compatibility

Extract iOS-only native picker components from AvailabilityTab, BasicsTab,
LimitsTab, RecurringTab, and LocationsList to platform-specific files to
fix 'requireNativeViewManager is not available on web' error in browser extension.

Each tab now has:
- TabIOSPicker.ios.tsx - iOS implementation with native @expo/ui/swift-ui
- TabIOSPicker.tsx - Web/Android fallback that returns null

* fix(companion): fix Switch toggle thumb color for web/extension

Change thumbColor condition from Platform.OS === 'android' to
Platform.OS !== 'ios' so that web/extension also gets white thumb color
instead of the default green.

* fix(companion): fix Participants section padding for web/extension

Move padding classes from AppPressable to a child View to ensure
padding is properly applied on web. AnimatedPressable doesn't
reliably apply className padding on web platforms.

* fix(companion): fix unexpected text node error on web

Change ternary operator in Hosts section from 'booking.user && (...)' to
'booking.user ? (...) : null' to prevent React Native Web from trying
to render 'false' as a text node when booking.user is falsy.

* fix(companion): wrap Stack.Header in iOS platform check for web compatibility

The Stack.Header components are iOS-specific and cause 'Unexpected text node'
errors on web. Wrap them in Platform.OS === 'ios' check to prevent rendering
on web/Android where they're not supported.

* fix(companion): convert all && conditionals to ternary operators for web compatibility

React Native Web renders boolean 'false' from && operators as text nodes.
Changed all conditional rendering patterns from 'condition && (<Component>)'
to 'condition ? (<Component>) : null' to prevent 'Unexpected text node' errors.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-11 16:02:13 -03:00
Keith Williams f0ffc24d39 chore: Improve Devin prompt for resolving conflicts (#26714) 2026-01-11 14:22:24 -03:00
Beto 5eacd6b807 refactor(companion)(ios): Improve header right button in booking details screen (#26721)
* refactor: improve code formatting and readability in BookingDetailScreen and Bookings components

* refactor: enhance code structure and readability in EventTypesIOS component
2026-01-11 17:11:32 +00:00
Anik Dhabal Babu 98ef45be18 fix: prevent calendar event creation for unconfirmed round robin reschedules (#26719)
* fix rr booking

* fix test

* use actual prisma

* fix

* Refactor
2026-01-11 16:38:46 +00:00
1e98652161 feat: reuse existing Devin sessions when resolving conflicts (#26711)
* feat: reuse existing Devin sessions when resolving conflicts

- Check if PR was created through Devin and use that session
- Check PR comments for existing active Devin sessions
- Send message to existing session instead of creating new one
- Only create new session if no active session exists
- Update comment message to reflect whether session is new or reused

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: also check for Cubic AI review sessions when reusing Devin sessions

- Added 'Devin AI is addressing Cubic AI' to session patterns
- Now checks for both conflict resolution and Cubic AI review sessions

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-11 14:08:32 +00:00
Keith WilliamsandDevin AI 7a6f4b2594 fix: add global CRM services mock to prevent test flakes (#26716)
* fix: mock CRM services to prevent test flakes in handlePaymentSuccess.test.ts

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add global CRM services mock to prevent test flakes

The test flakes were caused by the Salesforce CRM service importing @urql/core,
which triggers fetch calls during module loading. These fetch calls remain
pending when the Vitest worker shuts down, causing the error:
'[vitest-worker]: Closing rpc while fetch was pending'

This fix adds a global mock for CrmServiceMap in setupVitest.ts, similar to
how payment services are already mocked. This prevents the Salesforce module
from being loaded during test execution.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-11 18:18:05 +05:30
Benny Joo c826e9cea8 refactor: Remove trpc/react dependency from @calcom/atoms (#26694)
* mv useTeamMembersWithSegment

* remove

* fix ts error

* remove

* remove

* remove

* biome rule
2026-01-11 08:02:30 -03:00
784db75b38 ci: optimize sparse-checkout and cache to reduce cache size (#26692)
* ci: optimize sparse-checkout to reduce cache size by ~230MB

Exclude additional large files from CI checkout that are not needed for builds/tests:
- docs/images/ (~90MB) - Documentation images
- packages/app-store/*/static/*.png,jpg,jpeg,gif (~140MB) - App store screenshots

These files are only needed for documentation rendering and app store UI display,
not for CI builds, linting, type checking, or tests.

SVG icons in app-store are preserved as they may be needed for the build.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* ci: exclude generated app-store static files from cache

The apps/web/public/app-store directory contains ~151MB of static files
copied from packages/app-store/*/static/ during build. These files are
regenerated during yarn install and don't need to be cached.

Combined with the sparse-checkout exclusions, this should significantly
reduce the git checkout cache size.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* ci: fix sparse-checkout by limiting first checkout to .github only

The first checkout in the prepare job was doing a full checkout (~535 MB),
and then dangerous-git-checkout applied sparse-checkout. But the files from
the first checkout remained on disk because sparse-checkout doesn't remove
files that were already checked out.

By limiting the first checkout to only .github (which is needed to access
the local actions), we avoid downloading the full repo twice. The actual
sparse-checkout with exclusions is then applied by dangerous-git-checkout.

This should reduce the cache from ~504 MB to ~148 MB.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: update cache-checkout to include sparse-checkout exclusions and fix pr.yml compatibility

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-11 19:17:09 +09:00
BetoandDhairyashil Shinde 75962f7719 fix: update iOS app configuration to disable tablet support (#26705)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2026-01-11 14:44:35 +05:30
f24f5b2b35 feat: update translations via @LingoDotDev (#26700)
Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-11 09:01:28 +00:00
08edd4f361 chore: Add logging to msteams (#23684)
* Add logging

* fix: Add response status checking to MS Teams adapter error handling

- Add response.ok checks before parsing JSON in createMeeting and updateMeeting
- Remove console.log statements that could leak credential information
- Ensure error handling matches original handleErrorsRaw behavior for tests

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Fix logs

* Revert "fix: Add response status checking to MS Teams adapter error handling"

This reverts commit 35820d21e1a54d9e04d83fd5f53584d64a5459b6.

* fix: Add response status checking to MS Teams adapter error handling

- Check response.ok before parsing JSON in createMeeting and updateMeeting
- Re-throw HttpError instances instead of wrapping them in catch blocks
- This ensures HTTP errors (like 500) are properly propagated

Co-Authored-By: unknown <>

* fix: Correct log message in updateMeeting to say 'updating' instead of 'creating'

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-11 10:34:02 +05:30
Dhairyashil Shinde 8b9c3dcbb9 feat(companion): add skeleton loading for Event Types, Bookings, and Availability pages (#26687)
* feat(companion): add skeleton loading for Event Types list page

- Install skeleton component from react-native-reusables
- Create EventTypeListItemSkeleton and EventTypeListSkeleton components
- Replace LoadingSpinner with skeleton loading for initial load
- Show skeleton during pull-to-refresh instead of spinner
- Update both index.tsx (Android/Web) and index.ios.tsx (iOS)

* fix(companion): use inline styles for skeleton spacing to ensure distinct elements

* update skeleton

* feat(companion): add skeleton loading for Bookings page

* fix(companion): wrap iOS booking skeleton in ScrollView with contentInsetAdjustmentBehavior

* feat(companion): add skeleton loading for Availability page

* fix(companion): fix iOS availability skeleton layout issue

* fix(companion): remove native spinner from pull-to-refresh on skeleton pages

* fix(companion): remove unused refreshing variable from AvailabilityListScreen

* fix(companion): restore native spinner for empty states during pull-to-refresh

* fix(companion): add try/finally to onRefresh to prevent stuck loading state

* fix - react compiler issue, lint, typecheck
2026-01-11 10:02:07 +05:30
Keith WilliamsandDevin AI 539214b164 fix: improve BookingReferenceRepository integration test isolation (#26707)
The integration tests were flaky because they relied on a shared booking
created in beforeAll, which could cause race conditions when tests run
in parallel or when cleanup from previous runs interfered.

Changes:
- Use seed user (member0-acme@example.com) when available, fallback to
  creating a test user for local development
- Create a fresh booking in beforeEach instead of sharing one across tests
- Track created bookings and clean them up properly in afterEach
- Fix import organization to satisfy linter

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-11 10:01:25 +05:30
9d9a85ddd9 docs: calendso encryption key of length 24 (#23045)
* docs: calendso encryption key of length 24

Signed-off-by: Bandhan Majumder <bandhanmajumder16@gmail.com>

* Update .env.example

---------

Signed-off-by: Bandhan Majumder <bandhanmajumder16@gmail.com>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-10 21:40:23 +00:00
Keith WilliamsandDevin AI 560598db56 fix: Check for existing Devin sessions from conflict resolver in cubic workflow (#26706)
When addressing Cubic AI comments, the workflow now also looks for existing
Devin sessions from the conflict resolver workflow and stale PR completion
workflow, not just previous Cubic review sessions.

This ensures that if a Devin session is already working on a PR (e.g., fixing
merge conflicts), new Cubic feedback will be sent to that existing session
instead of creating a new one.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 21:22:46 +00:00
Keith WilliamsandDevin AI 3dd0b2d46b fix: add fallback for ref parameter in cache-checkout action (#26703)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 19:37:06 +00:00
Keith WilliamsandDevin AI bf4cdf6245 fix: refactor cache-checkout to use actions/cache@v4 with fallback (#26702)
This fixes cache propagation delay issues with Blacksmith's distributed cache.

The previous implementation used separate save/restore actions with
fail-on-cache-miss: true, which failed when the cache wasn't immediately
available after being saved by the Prepare job.

The new implementation uses actions/cache@v4 (combined save/restore)
with a fallback to do the checkout if cache miss, matching the pattern
used by cache-build and cache-db which don't have this issue.

Changes:
- Refactored cache-checkout action to use actions/cache@v4
- Added fallback checkout step when cache miss occurs
- Removed mode input (no longer needed)
- Updated all workflows to use the simplified cache-checkout action

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 19:26:28 +00:00
Anik Dhabal BabuandDevin AI eecf9e1ab9 fix: make BookingReferenceRepository integration tests use unique identifiers (#26701)
The integration tests were flaky because they used fixed identifiers
(email, username, uid) that could conflict across parallel test runs
or with leftover data from previous runs.

Changes:
- Add unique testRunId using timestamp and random suffix
- Use testRunId in email, username, and booking uid
- Change afterAll cleanup to use deleteMany instead of delete to
  prevent failures when records are already deleted

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 16:20:11 -03:00
Keith WilliamsandDevin AI 2b4be9c34e fix: remove proactive cache deletion to prevent race condition (#26698)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 15:46:50 -03:00
Keith WilliamsandDevin AI 9c4ed1a303 fix(ci): improve conflict resolver prompt to prevent bad merge commits (#26699)
- Remove explicit git commands from the prompt to avoid Devin reproducing changes
- Add validation step before pushing to detect if merge commit incorrectly includes changes from target branch
- Add guidance to use git's merge functionality properly instead of manually copying content
- Add rule to never reproduce or recreate changes from the target branch

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 15:33:17 -03:00
Keith WilliamsandDevin AI 6aa1dbad90 chore: delete cached build after bundle analysis completes (#26689)
* chore: delete cached build after bundle analysis completes

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: use useblacksmith/cache-delete action

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 15:01:21 -03:00
Keith WilliamsandDevin AI 7a9462b756 fix: parsing error in stale PR workflow for workflow_dispatch (#26691)
* fix: fix parsing error and add token support for fork PRs in stale PR workflow

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: keep only parsing error fix, remove token support for fork PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 15:00:52 -03:00
Keith WilliamsandDevin AI 46b1bc3365 fix: switch conflict resolver from push to schedule trigger to save runner costs (#26690)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 15:00:33 -03:00
cal-com-ci[bot]andLingo.dev f86a8dc93e feat: update translations via @LingoDotDev (#26599)
Co-authored-by: Lingo.dev <support@lingo.dev>
2026-01-10 17:54:22 +00:00
Keith WilliamsandDevin AI d9b49b2c41 fix: mock salesforce graphql queries to prevent flaky test failures (#26688)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 23:22:44 +05:30
Keith WilliamsandDevin AI 728f55e4bc fix: use PR head SHA for cache-checkout key in pull_request_target events (#26686)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 09:57:42 -03:00
d3e7554835 refactor: move WebWrapper files from packages/platform to apps/web/modules (#26629)
* refactor: move WebWrapper files from packages/platform to apps/web/modules

Move the following WebWrapper files to their appropriate locations in apps/web/modules:
- EventTypeWebWrapper and related tab wrappers to apps/web/modules/event-types/components/wrappers/
- BookerWebWrapper to apps/web/modules/bookings/components/
- ConferencingAppsViewWebWrapper to apps/web/modules/apps/components/
- SelectedCalendarsSettingsWebWrapper to apps/web/modules/calendars/components/
- AddMembersWithSwitchWebWrapper to apps/web/modules/event-types/components/

This reduces the number of files in packages/platform that import from @calcom/web,
improving the separation between platform and web-specific code.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: move web-specific hooks to apps/web and update imports

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* add back comments

* fix

* fix

* fix

* fix

* fix: correct relative import paths in moved WebWrapper files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* final

* fix: use package alias for event-type hooks instead of deeply nested relative paths

- Move sortHosts function to @calcom/lib/bookings/hostGroupUtils.ts for shared access
- Add exports for useEventTypeForm, useHandleRouteChange, useTabsNavigations to @calcom/atoms package.json
- Update EventTypeWebWrapper.tsx to use @calcom/atoms package alias instead of ../../../../../packages/... paths
- Update useEventTypeForm.ts to import sortHosts from @calcom/lib instead of @calcom/web
- Re-export sortHosts from HostEditDialogs.tsx for backward compatibility

This addresses the Cubic AI review feedback about fragile deeply nested relative paths that bypass proper package resolution.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 12:55:39 +00:00
cbb56f6a61 feat: implement git checkout caching to speed up CI workflows (#26636)
* feat: implement git checkout caching to speed up CI workflows

- Create cache-checkout action to save/restore git working directory
- Update prepare job in pr.yml to cache checkout after dangerous-git-checkout
- Update all downstream workflows to restore from cache instead of checkout
- Pass commit-sha to all workflow calls for cache key consistency

This reduces the number of full git checkouts from 20+ per workflow run to just 1,
significantly improving CI performance especially for large repos.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: use actions/cache/restore directly instead of custom action

Remove sparse-checkout and use actions/cache/restore@v4 directly in all
downstream workflows. This eliminates the need for any git fetch operation
before restoring from cache, making the optimization more effective.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: use github.event.pull_request.head.sha for cache key

- Remove commit-sha input from all downstream workflows
- Update cache-checkout action to use github.event.pull_request.head.sha directly
- Remove commit-sha output from prepare job
- Remove commit-sha from all workflow calls in pr.yml
- Keep sparse-checkout of .github to access the cache-checkout action

This eliminates the need to pass commit-sha around while still using
a reusable action for the cache restore logic.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: update cache key to include branch name and add cache cleanup

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: use github.head_ref and github.sha for cache key

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add prefix delete before saving cache to clear previous caches

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* perf: add sparse-checkout to exclude example-apps and mp4 files

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: restore get_sha step and commit-sha output that was accidentally removed

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add trailing dash to cache key prefix to prevent accidental deletion of other branches' caches

The prefix-based cache deletion was using 'git-checkout-{branch}' which would
accidentally match and delete caches for branches with similar prefixes.
For example, branch 'feature' would delete caches for 'feature-2', 'feature-new', etc.

Adding a trailing '-' ensures exact branch matching:
- 'git-checkout-feature-' matches 'git-checkout-feature-abc123' (intended)
- 'git-checkout-feature-' does NOT match 'git-checkout-feature-2-def456' (correct)

Fixes both the cache-checkout action and the PR close cleanup workflow.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 21:46:21 +09:00
+2 2d514a2a3e feat: companion alert system for browser extension (#26613)
* feat: companion alert system for browser extension

* feat: implement cross-platform alert system for browser extension

- Add ToastContext.tsx with global toast provider for managing toast state
- Add GlobalToast.tsx centered toast component for web/browser extension
- Modify alerts.ts to be platform-aware (native Alert on iOS/Android, toast on web)
- Add showInfoAlert function for informational alerts
- Update _layout.tsx to wrap app with ToastProvider and GlobalToast
- Export new toast context and alert functions from index files

* style: update toast to white/black design system

- Use white background with gray border
- Use black icons and text colors
- Match companion app design system

* open the toast at the center

* refactor: migrate event-types/index.tsx to unified alert system

- Remove inline toast state (showToast, toastMessage) and showToastMessage function
- Remove inline toast UI component at the end of the file
- Migrate all platform-specific Alert.alert calls to showSuccessAlert/showErrorAlert
- Simplifies code by using cross-platform alert utilities

* refactor: migrate useBookingActions.ts to unified alert system

- Add showSuccessAlert import alongside showErrorAlert
- Migrate all Alert.alert('Success', ...) calls to showSuccessAlert
- Affected handlers: handleSubmitReschedule, handleRescheduleWithValues,
  handleSubmitCancel, handleCancelBooking, handleConfirmBooking,
  handleRejectBooking, handleSubmitReject, handleInlineConfirm

* refactor: migrate useBookingActionModals.ts to unified alert system

- Add showSuccessAlert import alongside showErrorAlert
- Migrate all Alert.alert('Success', ...) calls to showSuccessAlert
- Affected handlers: handleAddGuests, handleUpdateLocation, handleMarkNoShow

* refactor: migrate medium-priority screens to unified alert system

- AvailabilityDetailScreen.ios.tsx: 4 Alert.alert calls migrated
- RescheduleScreen.tsx/ios/android: 3 Alert.alert calls each migrated
- EditLocationScreen.tsx/ios: 4 Alert.alert calls each migrated
- Removed unused Alert imports

* refactor: migrate remaining medium-priority screens to unified alert system

- BookingDetailScreen.tsx: 2 Alert.alert calls migrated
- AvailabilityListScreen.tsx: 1 Alert.alert call migrated
- AddGuestsScreen.tsx: 6 Alert.alert calls migrated
- MarkNoShowScreen.tsx: 2 Alert.alert calls migrated
- EditAvailabilityOverrideScreen.tsx: 4 Alert.alert calls migrated
- EditAvailabilityOverrideScreen.ios.tsx: 2 Alert.alert calls migrated
- Removed unused Alert imports

* refactor: migrate medium-priority app routes to unified alert system

Migrated 24 app route files from direct Alert.alert() calls to unified
alert utilities (showErrorAlert, showSuccessAlert, showInfoAlert):

- reschedule.tsx, reschedule.ios.tsx
- edit-location.tsx, edit-location.ios.tsx
- add-guests.tsx, add-guests.ios.tsx
- mark-no-show.tsx, mark-no-show.ios.tsx
- view-recordings.tsx, view-recordings.ios.tsx
- meeting-session-details.tsx, meeting-session-details.ios.tsx
- profile-sheet.tsx, profile-sheet.ios.tsx
- edit-availability-hours.tsx, edit-availability-hours.ios.tsx
- edit-availability-day.tsx, edit-availability-day.ios.tsx
- edit-availability-name.tsx, edit-availability-name.ios.tsx
- edit-availability-override.tsx, edit-availability-override.ios.tsx
- booking-detail.tsx, booking-detail.ios.tsx

This enables cross-platform alert support where native Alert.alert()
is used on iOS/Android and toast notifications on web (browser extension).

* refactor: migrate lower-priority components to unified alert system

Migrated Alert.alert calls to showSuccessAlert/showErrorAlert/showInfoAlert in:
- event-types/index.ios.tsx (copy link, delete, duplicate success alerts)
- event-type-detail.tsx (copy link, create/update success, validation errors, info alerts)
- deep-links.ts (error alerts for link failures)
- LogoutButton.tsx (error alert)
- BookingModals.tsx and .ios.tsx (report booking info alerts)
- AdvancedTab.tsx (info alert for unsaved event type)
- BookingListScreen.tsx (success/error/info alerts for bulk actions)

Confirmation dialogs with buttons remain as Alert.alert (out of scope).

* fix: restore Alert import for confirmation dialogs, migrate remaining info alert

- AdvancedTab.tsx: Added back Alert import for timezone selector confirmation dialog (out of scope), migrated private links info alert to showInfoAlert
- deep-links.ts: Added back Alert import for request reschedule confirmation dialog (out of scope)

* some ui dialoes were missing

* fixed multi hours ui issues on Availability detail page for android and web

* fix: add __DEV__ check for web platform in showErrorAlert

The showErrorAlert function was showing error toasts to production users
on web platform, bypassing the __DEV__ check that exists for native platforms.
This fix ensures consistent behavior across all platforms - error alerts
are only shown in development mode, while production errors are logged
to console.

Co-Authored-By: unknown <>

* fix: address dual dialogs on web and onSuccess timing issues

- BookingDetailScreen.tsx: Add Platform.OS === 'android' guard to AlertDialog
  to prevent dual dialogs rendering on web (FullScreenModal + AlertDialog)
- RescheduleScreen.android.tsx: Restore original Alert.alert with callback
  to ensure onSuccess() is called after user dismisses the alert

Co-Authored-By: unknown <>

* fix: restore Alert.alert with callback for native platforms

- AddGuestsScreen.tsx: Use platform-specific handling - Alert.alert with
  callback on iOS/Android, showSuccessAlert on web
- EditAvailabilityOverrideScreen.tsx: Same pattern - wait for user
  acknowledgment on native platforms before calling onSuccess()

Co-Authored-By: unknown <>

* fix: RescheduleScreen timing and GlobalToast useState pattern

- RescheduleScreen.tsx: Use platform-specific handling - Alert.alert with
  callback on iOS/Android, showSuccessAlert on web
- GlobalToast.tsx: Replace useMemo with useState for Animated.Value to
  guarantee instance preservation across renders

Co-Authored-By: unknown <>

* fix: restore Alert.alert with callback for iOS delete success

AvailabilityDetailScreen.ios.tsx: Use Alert.alert with callback to ensure
router.back() is called after user dismisses the success alert

Co-Authored-By: unknown <>

* feat(companion): new event type detail page  (#26678)

* fix: skip stale run-ci label check on workflow re-runs (#26590)

* fix: trust community PRs when maintainer pushes to the branch

When a maintainer merges main into a community PR branch, the new SHA
invalidates the run-ci label timing check because the label was added
before the new push. This fix adds a check to trust the PR if the
person who pushed the latest commit has write access.

This handles the case where a maintainer:
- Merges main into a community PR to resolve conflicts
- Pushes any changes to help the contributor

The security model is maintained because:
- Only users with write access can trigger this trust
- The maintainer has reviewed the code by pushing to it

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: skip stale label check on workflow re-runs

Instead of implicitly trusting maintainer pushes (which could be just
a sync action without code review), use github.run_attempt to detect
re-runs. If run_attempt > 1, it means the workflow was explicitly
re-triggered (via run-ci.yml or manual re-run), so we skip the stale
label check.

This avoids the need to remove and re-add the 'run-ci' label after
syncing a community PR with main, while keeping the explicit approval
flow intact.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Simplify comment about re-runs in PR workflow

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* fix: Text cursor barely visible in calendar event name field (#26563)

* fix: cursor visibility in input fields

* fix: cursor visibility in input fields with suffix addons

* fix: text cursor visibility in input fields

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* fix: PayPal setup page inconsistent spacing and button styling (#26612)

* chore: api v2 generate swagger only in dev (#26617)

* feat: add BUILD_FROM_BRANCH option to release-docker workflow (#26615)

* feat: add BUILD_FROM_BRANCH option to release-docker workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: sanitize branch names with slashes for valid Docker tags

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: extract common logic into prepare job to avoid duplication

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add Cubic AI to Devin review integration workflow (#26618)

* feat: add Cubic AI to Devin review integration workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update permissions to allow posting PR comments

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove sensitive API response logging from CI workflow

Address Cubic AI review feedback: Remove the debug log that outputs the
full Devin API response, which could expose sensitive session tokens or
authentication data in CI logs. The session URL is still logged when
successfully extracted.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: enable/disable slots workers via env (#26621)

* chore: enable/disable slots workers via env

* fix: address Cubic AI review feedback

- Fix incorrect JSDoc comment for getSerializableContext method
- Remove debug console.log statement from slots controller
- Fix port suffix condition to preserve original behavior

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: USE_POOL env var for api v2 prisma pooling

* fix list numbering in Manual setup section of README (#26620)

* Revert "chore: USE_POOL env var for api v2 prisma pooling"

This reverts commit a97092619f.

* feat: limit badges to 2 with hover/click popover in UserListTable (#26556)

* feat: limit badges to 2 with hover tooltip in UserListTable

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: reuse LimitedBadges component with clickable popover for mobile

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move LimitedBadges to components/ui with hover+click support

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: fix Biome lint issues in LimitedBadges and UserListTable

- Refactor LimitedBadges to concrete component with BadgeItem type
- Move exports to end of files to comply with useExportsLast rule
- Add explicit types to callback parameters for useExplicitType rule
- Convert nested ternary to if-else for filterType calculation
- Remove unused imports (Row, Table types)
- Update ResponseValueCell and UserListTable to use new LimitedBadges API

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add proper types for filterType and getFacetedUniqueValues

- Add FilterType import from @calcom/types/data-table
- Add FacetedValue import from @calcom/features/data-table
- Type filterType as FilterType to allow reassignment to different ColumnFilterType values
- Type getFacetedUniqueValues return as Map<FacetedValue, number>

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* add vertical gap

* fix: address code review feedback for LimitedBadges

- Add index to id for unique keys in ResponseValueCell.tsx
- Restore orange variant for group options in UserListTable.tsx
- Fix useMemo dependency array (add t, remove dispatch)
- Fix import ordering with biome
- Convert ternary operators to if-else statements for biome compliance

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove id from BadgeItem type, use label as key

- Remove id field from BadgeItem type in LimitedBadges
- Use label as React key instead of id
- Remove unused rowId parameter from ResponseValueCell
- Update all consumers to not pass id field

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use index for key instead of label in LimitedBadges

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "refactor: use index for key instead of label in LimitedBadges"

This reverts commit 1daaac47e596fd6b5f5583847faa10b131783349.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: add database-backed feature flag for sidebar tips section (#26516)

* chore: remove tips section from sidebar

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: add feature flag for sidebar tips section

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: use database-backed feature flag for sidebar tips section

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add automated stale PR completion workflow with Devin API (#26627)

* feat: add stale PR completion workflow with Devin API

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: only trigger for community PRs (non-calcom org members)

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: use author_association pattern from pr.yml for community check

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: simplify workflow - use community label check and let Devin gather PR details

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add Devin PR conflict resolver workflow (#26624)

* feat: add Devin PR conflict resolver workflow

Adds a GitHub Actions workflow that automatically detects PRs with merge
conflicts and spins up Devin sessions to resolve them.

How it works:
1. Triggers on push to main branch (when main updates could cause conflicts)
2. Also supports manual trigger via workflow_dispatch
3. Lists all open PRs and checks their mergeable status
4. For PRs with conflicts (mergeable=false, mergeable_state=dirty):
   - Checks if a Devin session was already created (avoids duplicates)
   - Creates a new Devin session with instructions to resolve conflicts
   - Posts a comment on the PR with the Devin session link

The workflow follows the same pattern as cubic-devin-review.yml for
consistency.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: skip draft PRs in conflict detection workflow

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: use GitHub Search API to filter draft PRs at API level

Instead of filtering draft PRs in the loop, use the GitHub Search API
with 'draft:false' filter which is more efficient as it filters at the
API level rather than fetching all PRs and filtering locally.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* style: remove explanatory comments from workflow

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* style: remove all unnecessary explanatory comments

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: use GraphQL for batched PR fetching and labels for tracking

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add support for resolving conflicts on fork PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: check response.ok before parsing Devin API response

Address Cubic AI review feedback: Add response.ok check before parsing
the response body to explicitly handle HTTP error status codes from the
Devin API. This distinguishes API failures (authentication errors,
server errors) from successful responses that might be missing expected
fields.

Co-Authored-By: unknown <>

* fix: improve Devin API error logging with PR number

Co-Authored-By: unknown <>

* feat: add pr_number input for manual fork PR conflict resolution

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add maximum 15 PRs safety net limit

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: make stale PR workflow fork-aware with workflow_dispatch support (#26633)

* feat: make stale PR workflow fork-aware with workflow_dispatch support

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add null check for pr.head.repo in stale PR workflow

When a fork is deleted after a PR is created, pr.head.repo can be null
(documented GitHub API behavior). This would cause a TypeError when
accessing properties like fork, full_name, or clone_url.

Added a null check that fails gracefully with a clear error message
when the source repository has been deleted.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: reuse existing Devin session for Cubic AI review feedback (#26632)

* feat: reuse existing Devin session for Cubic AI review feedback

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: parse session ID from PR comments instead of API search

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add error handling for message send API call in Cubic-Devin workflow

Addresses Cubic AI review feedback: The POST request to send a message
to an existing Devin session now checks the HTTP status code and fails
the step if the message wasn't delivered successfully. This prevents
posting a misleading comment claiming feedback was sent when the API
call actually failed.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: Remove stale label when work is completed (#26638)

* chore: Remove stale label when work is completed

* Mark as ready for review too

* feat: add retry mechanism for UNKNOWN mergeable status PRs (#26635)

* feat: add retry mechanism for UNKNOWN mergeable status PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: remove redundant filtering logic for unknown mergeable status PRs

Address Cubic AI review feedback by:
- Having processPR return isTargetPR in the unknown case (like the conflict case)
- Simplifying the main loop to just push PRs to unknownPRs without re-checking
  draft status and devin label (already checked in processPR)

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: Add sentry http integration (#26634)

* chore: ignore fork PRs in devin-conflict-resolver workflow (#26640)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* limits and advanced tabs

* availability tab

* basics tab

* black toggles!!

* new recurring, others tab and update basics

* version 1

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Anshumancanrock <109489361+Anshumancanrock@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Anas Najam <129951478+anzz14@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>

* fix: address Cubic AI review feedback

- Add HTTP error handling for Devin API session creation in cubic-devin-review.yml
- Localize aria-label in LimitedBadges.tsx using t() function
- Improve Docker tag sanitization in release-docker.yaml to handle all invalid characters
- Avoid logging raw error objects and sensitive API response data in devin-conflict-resolver.yml
- Fix selectedSchedule dependency array issue in event-type-detail.tsx using ref pattern

Co-Authored-By: unknown <>

* chore: add translation key for show_x_more_items aria-label

Co-Authored-By: unknown <>

* fix: reset schedule ref on id change and add i18n pluralization

- Reset hasAutoSelectedScheduleRef when event type id changes to handle component reuse
- Add proper i18next pluralization variants (_one/_other) for show_x_more_items

Co-Authored-By: unknown <>

* revert: remove i18n changes from LimitedBadges and common.json

Per user request - i18n not needed in companion for now

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Anshumancanrock <109489361+Anshumancanrock@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Anas Najam <129951478+anzz14@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-10 17:57:42 +05:30
49e392423a feat: reuse PR-creator Devin session when addressing Cubic AI reviews (#26683)
* feat: prioritize PR-creator Devin session when addressing Cubic AI reviews

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: always use PR-creator Devin session regardless of status

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: use checkSessionStatus helper for both PR description and comment cases

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Clarify comment about PR review session check

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 10:47:18 +00:00
Morgan 32ecb924d7 chore: USE_POOL env var for api v2 prisma pooling (#26622) 2026-01-10 09:10:38 +00:00
Keith WilliamsandDevin AI e4ead13b3b fix: improve Devin conflict resolver for fork PRs and label cleanup (#26655)
* fix: improve Devin conflict resolver for fork PRs and label cleanup

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Update devin-conflict-resolver.yml

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-10 02:43:27 +00:00
f6d3b11582 refactor: Membership.findByUserIdAndTeamId to instance method (#26628)
* Make  and instance method

* Refactor files

* fix: update MembershipRepository mocks to use vi.hoisted() for proper hoisting

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 22:37:42 -03:00
Keith WilliamsandDevin AI 2a26a591a8 chore: ignore fork PRs in devin-conflict-resolver workflow (#26640)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 20:35:30 +00:00
Volnei Munhoz 4819be0093 chore: Add sentry http integration (#26634) 2026-01-09 20:14:42 +00:00
a9314471b4 feat: add retry mechanism for UNKNOWN mergeable status PRs (#26635)
* feat: add retry mechanism for UNKNOWN mergeable status PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: remove redundant filtering logic for unknown mergeable status PRs

Address Cubic AI review feedback by:
- Having processPR return isTargetPR in the unknown case (like the conflict case)
- Simplifying the main loop to just push PRs to unknownPRs without re-checking
  draft status and devin label (already checked in processPR)

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 20:06:46 +00:00
Keith Williams 52cff6882c chore: Remove stale label when work is completed (#26638)
* chore: Remove stale label when work is completed

* Mark as ready for review too
2026-01-09 19:52:16 +00:00
d0e942b30b feat: reuse existing Devin session for Cubic AI review feedback (#26632)
* feat: reuse existing Devin session for Cubic AI review feedback

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: parse session ID from PR comments instead of API search

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add error handling for message send API call in Cubic-Devin workflow

Addresses Cubic AI review feedback: The POST request to send a message
to an existing Devin session now checks the HTTP status code and fails
the step if the message wasn't delivered successfully. This prevents
posting a misleading comment claiming feedback was sent when the API
call actually failed.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 19:41:13 +00:00
e995e2439f feat: make stale PR workflow fork-aware with workflow_dispatch support (#26633)
* feat: make stale PR workflow fork-aware with workflow_dispatch support

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add null check for pr.head.repo in stale PR workflow

When a fork is deleted after a PR is created, pr.head.repo can be null
(documented GitHub API behavior). This would cause a TypeError when
accessing properties like fork, full_name, or clone_url.

Added a null check that fails gracefully with a clear error message
when the source repository has been deleted.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 19:22:37 +00:00
b367e153de feat: add Devin PR conflict resolver workflow (#26624)
* feat: add Devin PR conflict resolver workflow

Adds a GitHub Actions workflow that automatically detects PRs with merge
conflicts and spins up Devin sessions to resolve them.

How it works:
1. Triggers on push to main branch (when main updates could cause conflicts)
2. Also supports manual trigger via workflow_dispatch
3. Lists all open PRs and checks their mergeable status
4. For PRs with conflicts (mergeable=false, mergeable_state=dirty):
   - Checks if a Devin session was already created (avoids duplicates)
   - Creates a new Devin session with instructions to resolve conflicts
   - Posts a comment on the PR with the Devin session link

The workflow follows the same pattern as cubic-devin-review.yml for
consistency.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: skip draft PRs in conflict detection workflow

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: use GitHub Search API to filter draft PRs at API level

Instead of filtering draft PRs in the loop, use the GitHub Search API
with 'draft:false' filter which is more efficient as it filters at the
API level rather than fetching all PRs and filtering locally.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* style: remove explanatory comments from workflow

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* style: remove all unnecessary explanatory comments

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: use GraphQL for batched PR fetching and labels for tracking

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add support for resolving conflicts on fork PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: check response.ok before parsing Devin API response

Address Cubic AI review feedback: Add response.ok check before parsing
the response body to explicitly handle HTTP error status codes from the
Devin API. This distinguishes API failures (authentication errors,
server errors) from successful responses that might be missing expected
fields.

Co-Authored-By: unknown <>

* fix: improve Devin API error logging with PR number

Co-Authored-By: unknown <>

* feat: add pr_number input for manual fork PR conflict resolution

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add maximum 15 PRs safety net limit

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 19:10:13 +00:00
bd361844d6 feat: add automated stale PR completion workflow with Devin API (#26627)
* feat: add stale PR completion workflow with Devin API

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: only trigger for community PRs (non-calcom org members)

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: use author_association pattern from pr.yml for community check

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: simplify workflow - use community label check and let Devin gather PR details

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 18:27:57 +00:00
a12ab5bb65 chore: add database-backed feature flag for sidebar tips section (#26516)
* chore: remove tips section from sidebar

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: add feature flag for sidebar tips section

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: use database-backed feature flag for sidebar tips section

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 22:31:45 +05:30
Eunjae LeeandDevin AI 2b7c087ac8 feat: limit badges to 2 with hover/click popover in UserListTable (#26556)
* feat: limit badges to 2 with hover tooltip in UserListTable

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: reuse LimitedBadges component with clickable popover for mobile

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move LimitedBadges to components/ui with hover+click support

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: fix Biome lint issues in LimitedBadges and UserListTable

- Refactor LimitedBadges to concrete component with BadgeItem type
- Move exports to end of files to comply with useExportsLast rule
- Add explicit types to callback parameters for useExplicitType rule
- Convert nested ternary to if-else for filterType calculation
- Remove unused imports (Row, Table types)
- Update ResponseValueCell and UserListTable to use new LimitedBadges API

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add proper types for filterType and getFacetedUniqueValues

- Add FilterType import from @calcom/types/data-table
- Add FacetedValue import from @calcom/features/data-table
- Type filterType as FilterType to allow reassignment to different ColumnFilterType values
- Type getFacetedUniqueValues return as Map<FacetedValue, number>

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* add vertical gap

* fix: address code review feedback for LimitedBadges

- Add index to id for unique keys in ResponseValueCell.tsx
- Restore orange variant for group options in UserListTable.tsx
- Fix useMemo dependency array (add t, remove dispatch)
- Fix import ordering with biome
- Convert ternary operators to if-else statements for biome compliance

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove id from BadgeItem type, use label as key

- Remove id field from BadgeItem type in LimitedBadges
- Use label as React key instead of id
- Remove unused rowId parameter from ResponseValueCell
- Update all consumers to not pass id field

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use index for key instead of label in LimitedBadges

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "refactor: use index for key instead of label in LimitedBadges"

This reverts commit 1daaac47e596fd6b5f5583847faa10b131783349.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 16:57:06 +00:00
cal.com 71729813a9 Revert "chore: USE_POOL env var for api v2 prisma pooling"
This reverts commit a97092619f.
2026-01-09 17:59:10 +02:00
Anas Najam 0500056831 fix list numbering in Manual setup section of README (#26620) 2026-01-09 15:56:16 +00:00
cal.com a97092619f chore: USE_POOL env var for api v2 prisma pooling 2026-01-09 17:55:25 +02:00
8666efa29d chore: enable/disable slots workers via env (#26621)
* chore: enable/disable slots workers via env

* fix: address Cubic AI review feedback

- Fix incorrect JSDoc comment for getSerializableContext method
- Remove debug console.log statement from slots controller
- Fix port suffix condition to preserve original behavior

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 15:03:13 +00:00
87a2f855f8 feat: add Cubic AI to Devin review integration workflow (#26618)
* feat: add Cubic AI to Devin review integration workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update permissions to allow posting PR comments

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove sensitive API response logging from CI workflow

Address Cubic AI review feedback: Remove the debug log that outputs the
full Devin API response, which could expose sensitive session tokens or
authentication data in CI logs. The session URL is still logged when
successfully extracted.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 11:23:41 -03:00
Keith WilliamsandDevin AI 0e3b9f08b8 feat: add BUILD_FROM_BRANCH option to release-docker workflow (#26615)
* feat: add BUILD_FROM_BRANCH option to release-docker workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: sanitize branch names with slashes for valid Docker tags

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: extract common logic into prepare job to avoid duplication

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 14:01:27 +00:00
Morgan 02a334e072 chore: api v2 generate swagger only in dev (#26617) 2026-01-09 15:12:42 +02:00
Anshumancanrock 3a5c97553d fix: PayPal setup page inconsistent spacing and button styling (#26612) 2026-01-09 12:27:33 +00:00
AnshumancanrockandKeith Williams 5b1ee1a7ac fix: Text cursor barely visible in calendar event name field (#26563)
* fix: cursor visibility in input fields

* fix: cursor visibility in input fields with suffix addons

* fix: text cursor visibility in input fields

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-09 12:09:24 +00:00
67faf454d9 fix: skip stale run-ci label check on workflow re-runs (#26590)
* fix: trust community PRs when maintainer pushes to the branch

When a maintainer merges main into a community PR branch, the new SHA
invalidates the run-ci label timing check because the label was added
before the new push. This fix adds a check to trust the PR if the
person who pushed the latest commit has write access.

This handles the case where a maintainer:
- Merges main into a community PR to resolve conflicts
- Pushes any changes to help the contributor

The security model is maintained because:
- Only users with write access can trigger this trust
- The maintainer has reviewed the code by pushing to it

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: skip stale label check on workflow re-runs

Instead of implicitly trusting maintainer pushes (which could be just
a sync action without code review), use github.run_attempt to detect
re-runs. If run_attempt > 1, it means the workflow was explicitly
re-triggered (via run-ci.yml or manual re-run), so we skip the stale
label check.

This avoids the need to remove and re-add the 'run-ci' label after
syncing a community PR with main, while keeping the explicit approval
flow intact.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Simplify comment about re-runs in PR workflow

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-09 17:21:51 +05:30
Udit Takkar 0330d14210 feat: system admin blocklist table (#25039)
* feat: system admin blocklist table

* chore: text

* fix: type error

* fix: type error

* fix: type error

* fix: frontend bug

* chore: improvments

* refactor: use shared components

* refactor: improvements

* fix: delete

* refactor: support multiple watchlist

* chore: update translation

* fix: type err

* fix: bulk bug

* tests: add unit test

* refactor: file

* refactor: file

* fix: type error

* fix: type error

* chore: translation

* refactor: use shared comments

* fix: imports

* fix: type error
2026-01-09 08:19:54 -03:00
Dhairyashil Shinde d865f6cb5f feat: companion add missing advanced event type (#26594)
* feat: companion add missing advanced event type

* feat: companion add missing advanced event type

* remove metadata code and remove non implemented Auto translate title and description toggle from companion

* Save Button Dirty State

* address cubic feedback - default value for sendTranscriptionEmails

* address cubic comments - fix new event type blocked issue

* ios language dropdown
2026-01-09 08:09:46 -03:00
Pedro Castro 51639e38d7 fix(auth): block OAuth linking for unverified accounts (#26598)
* fix(auth): sanitize unverified accounts during OAuth linking

- Add AccountSanitizationService for secure account cleanup
- Clear webhooks, API keys, credentials, and sessions for unverified accounts
- Reset password and 2FA settings during OAuth conversion
- Nullify redirect URLs on event types

Only affects accounts that never completed email verification

* fix(auth): block OAuth linking for unverified accounts

  Replace sanitization with simpler blocking approach:
  - Unverified CAL accounts cannot link to OAuth (Google/SAML)
  - Add user-friendly error message with recovery path
  - Remove AccountSanitizationService (no data loss risk)
2026-01-09 11:04:39 +00:00
c380ea810c feat: rename --font-cal to --font-heading + use Cal Sans UI (#26064)
* feat: rename --font-cal to --font-heading + use Cal Sans UI

* chore: remove font-weight from font-heading elements and CSS variables

Co-Authored-By: pasquale@cal.com <pasquale@cal.com>

* chore: remove unneeded css vars

* fix: cubic issues

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: pasquale@cal.com <pasquale@cal.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-01-09 10:42:23 +00:00
Morgan 56b29b5df6 chore: rename app.ts to bootstrap.ts on api-v2 (#26604) 2026-01-09 09:56:27 +00:00
b6c243f1dd fix: improve cleanup for managed event types and fix flaky api v2 e2e test (#26602)
* fix: improve cleanup for managed event types in e2e tests

- Add deleteAllUserEventTypes method to EventTypesRepositoryFixture
- Update afterAll cleanup to delete user event types before deleting users
- This ensures child event types of managed event types are properly cleaned up
- Fixes flaky tests caused by incomplete cleanup between test runs
- Add explicit return types to fixture methods to satisfy lint rules
- Replace @ts-ignore with @ts-expect-error for better type safety

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 06:16:59 -03:00
Benny JooandDevin AI b78ca7be2a fix: Update Dockerfile since /tests directory no longer exists (#26601)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 06:15:22 -03:00
Hariom Balhara f3a37886e3 chore: Integrate reschedule request booking audit (#26527)
## What does this PR do?

Adds audit logging for the reschedule request flow. When an organizer requests an attendee to reschedule a booking, this action is now logged to the booking audit system.

This is part of the booking audit integration effort, following the pattern established in PR #26046 (booking creation/rescheduling audit) and PR #26458 (cancellation audit).

## Changes

- Added audit logging call to `requestReschedule.handler.ts` using `BookingEventHandlerService.onRescheduleRequested()`
- Captures audit data:
  - `rescheduleReason`: The reason provided for requesting the reschedule (nullable string)
  - `rescheduledRequestedBy`: Email of the user who requested the reschedule
- Uses `makeUserActor(user.uuid)` to identify the actor performing the action
- Added required `source` parameter for action source tracking (passed as `"WEBAPP"` from tRPC router)
- Updated `RescheduleRequestedAuditActionService` schema to use simpler field structure
- Updated test helper `getTrpcHandlerData` to pass `source: "WEBAPP"` parameter

## Updates since last revision

- Changed `source` parameter from optional with default to required - tests now explicitly pass `source: "WEBAPP"` instead of relying on a default value

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. N/A - follows established audit pattern with existing infrastructure tests.

## How should this be tested?

1. Log in as a user with a booking
2. Navigate to the booking and click "Request Reschedule"
3. Provide a reschedule reason and submit
4. Verify the audit log is created with the correct data (requires access to audit log storage/database)

The audit logging follows the same pattern as other booking audit integrations, so if those are working, this should work as well.

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

---

**Link to Devin run**: https://app.devin.ai/sessions/ae84d093c4594a5d89b88c45639a6a06
**Requested by**: @hariombalhara

## Human Review Checklist

- [ ] Verify the audit data schema matches `RescheduleRequestedAuditActionService` expectations (fields: `rescheduleReason`, `rescheduledRequestedBy`)
- [ ] Confirm the schema change from change-based fields (`{ old, new }`) to simple nullable strings is intentional
- [ ] Confirm `user.uuid` is available in the tRPC session context
- [ ] Note: API v2 does not have a reschedule request endpoint, so no API v2 changes are needed
2026-01-09 14:03:01 +05:30
Anik Dhabal Babu 3cb59b7874 test: cleanup & revived old skipped e2e tests (#26597) 2026-01-09 04:32:42 +00:00
Alex van Andel 4c336fba92 chore: release v6.0.9
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-09 00:21:26 +00:00
cal-com-ci[bot]andLingo.dev 4cd664315d feat: update translations via @LingoDotDev (#26511)
Co-authored-by: Lingo.dev <support@lingo.dev>
2026-01-08 22:27:14 +00:00
Pedro Castro d9aef5b6a6 fix: add URL validation for logo fields (#26522)
* fix(auth): add URL validation for organization logo fields

- Add URL validation utility for server-side fetched URLs
- Validate logo URLs in tRPC organization schema
- Validate logo URLs in API v2 team DTOs
- Add graceful fallback in logo route for invalid URLs
- Only allow HTTPS and image data URLs
- Add unit tests for URL validation

* fix: add missing IP range and type validation

- Add RFC 6598 CGNAT range (100.64.0.0/10) to blocked IPs
- Add @IsString() decorator before custom URL validators
- Add boundary tests for new IP range

* fix: address review feedback

   - Export validateUrlForSSRFSync via @calcom/platform-libraries
   - Fix nullable/optional order in Zod schema

* fix: block localhost hostname and explicit null check

- Add localhost to BLOCKED_HOSTNAMES for sync validation
- Use explicit null check (url == null) instead of falsy check

* fix: allow empty string in URL validation

* refactor: extract shared validation logic

- Extract validateUrlCore() to eliminate duplication between sync/async versions
- Add JSDoc to all exported functions for better discoverability
- Remove redundant comments that repeated function names
- Simplify existing comments to be more concise

* fix: reject empty strings in URL validator

Previously if (!url) allowed empty strings to bypass validation.
Now explicitly checks for null/undefined only
2026-01-08 22:03:54 +00:00
Volnei Munhoz a5387bbffe update yarn lock (#26596) 2026-01-08 18:59:03 +00:00
Keith WilliamsandDevin AI 53833f15ea fix: add waitFor calls to prevent flaky time slot selection tests (#26592)
* fix: add waitFor calls to prevent flaky time slot selection tests

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: use locator variables to avoid repeating selectors

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 15:25:03 -03:00
Dhairyashil ShindeandVolnei Munhoz 84d1ce5bff feat(companion): availability detail page for android and extension (#26560)
* Availability Detail Page Header and fix event type payment amount badge, and index ui bug bottom navbar

* feat(companion): implement read-only availability detail page for Android/Extension

- Convert AvailabilityDetailScreen.tsx to read-only display with expandable sections
- Add header dropdown menu with edit options in availability-detail.tsx
- Update edit-availability-name.tsx with modal presentation pattern
- Update edit-availability-hours.tsx with modal presentation pattern
- Update edit-availability-override.tsx with modal presentation pattern
- Match iOS flow: read-only detail page with edit actions via header menu

* fix header on Availability Detail screen for android

* make dialoges center on extension

* update padding

* AvailabilityDetailScreen for android and extension

* added click to modal feat

* fix Date Overrides Card was always shown

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-08 23:31:59 +05:30
Keith Williams a748a75b08 chore: Update CODEOWNERS for GitHub actions/workflows (#26591) 2026-01-08 17:52:44 +00:00
Abhay MishraandVolnei Munhoz dc308a9538 fix: prevent seed-app-store startup crash by removing undefined seedAppData call (#26400)
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-08 17:19:00 +00:00
ccff0045fc fix: Add email verification requirement for API v1 and v2 email updates (#24988)
* fix: Add email verification requirement for API v1 and v2 email updates

- API v2 (/v2/me): Implement email verification check when updating primary email
  - Store new email in metadata as emailChangeWaitingForVerification when verification is required
  - Send verification email using sendChangeOfEmailVerification
  - Allow immediate email change if new email is already a verified secondary email
  - Add hasEmailBeenChanged and sendEmailVerification flags to response
  - Add tests to verify email verification behavior
  - Add findVerifiedSecondaryEmail method to UsersRepository
  - Add PrismaFeaturesRepository to MeModule providers

- API v1 (/v1/users/{userId}): Implement same email verification logic
  - Check if email-verification feature flag is enabled
  - Store new email in metadata when verification is required
  - Send verification email for unverified email changes
  - Allow immediate change for verified secondary emails
  - Preserve existing API v1 response format

- Test fixtures: Add createSecondaryEmail method to UserRepositoryFixture

This fixes the vulnerability where users could update their primary email
without verification via API endpoints.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* update

* update

* refactor: Extract business logic to MeService and add platform-managed bypass

- Create MeService with all business logic extracted from MeController
- Update MeController to delegate to MeService (thin controller pattern)
- Add PrismaWorkerModule to MeModule imports to provide PrismaWriteService
- Add isPlatformManaged bypass: platform-managed users can update email without verification
- Fix test cleanup to use delete by ID instead of email to avoid failures when email changes
- Remove hasEmailBeenChanged and sendEmailVerification response flags per reviewer feedback
- Add comprehensive documentation to @ApiOperation describing email verification behavior
- Update tests to remove flag assertions

Addresses PR comments:
- supalarry: Extract logic to service layer
- supalarry: Allow platform-managed users to update email without verification
- supalarry: Remove response flags and document behavior in @ApiOperation instead
- cubic-dev-ai: Fix module dependency for PrismaFeaturesRepository
- cubic-dev-ai: Fix test cleanup issue

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* docs: Simplify API operation description

Remove internal implementation details about metadata staging and shorten the description to focus on API consumer behavior.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix

* update

* update

* update

* remove comment

* addressed commit

* review addressed

* use repository

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 15:51:11 +00:00
Eunjae LeeandDevin AI 03bb9481a2 fix: update E2E test to match German translation without '+' prefix (#26589)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 15:37:50 +00:00
Alex van Andel 23ecd1c906 refactor: First high level changes to getUsersAvailability (#26566)
* refactor: First high level changes to getUsersAvailability

* Fix usage of getUserAvailability where getUsersAvailability is unused

* Fix user.schema.ts in APIv2

* User handler did not provide initial data

* Small ts fixes

* Set user non-nullable in getTimezoneFromDelegatedCredential

* Small ts fixes, ensure consumers are aware its nonnullable

* Mode is defaulted to none

* Mode is defaulted to none, fix ts when directly using fn (temp)
2026-01-08 14:45:26 +00:00
Pedro CastroandKeith Williams f8dcc6b13d fix: filter Google Workspace credentials by current user (#26216)
* fix: filter Google Workspace credentials by current user

Add userId filter to getUsersFromGWorkspace credential query and add
unit tests for all googleWorkspace handler functions. Also fix OAuth2Client
import to use google-auth-library for proper type compatibility

* refactor(tests): improve googleWorkspace handler test structure

Move dynamic imports to beforeEach block to reduce repetition
and improve test readability

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-08 14:44:50 +00:00
f629b61be7 fix: capitalize German 'Uhr' in 24-hour time format (#25403)
* fix: capitalize German 'Uhr' in 24-hour time format

- Conditionally apply toLowerCase() only for 12-hour format (AM/PM)
- Preserve proper capitalization for 24-hour format in German and other locales
- German 'Uhr' now displays correctly as 'Uhr' instead of 'uhr'

Fixes #24455

* refactor: remove code comments for clarity

* use ternary in return instead of mutable variable

* refactor: remove toLowerCase from time formatting

* addressed cubic suggestion

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
2026-01-08 14:25:50 +00:00
Kartik 2f932f617c fix: remove "+" from Add Guests translations (#26582) 2026-01-08 14:19:26 +00:00
Mehmet SungurandPallav 9c4754dfcc fix(ui): prevent nested <p> hydration errors in confirmation dialogs (#25643)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2026-01-08 10:27:11 -03:00
dbc6b15ffc fix: time and timeUnit partial update workflows api v2 (#26503)
* test: add e2e test for workflow partial update time/timeUnit preservation

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: time and timeUnit partial update workflows api v2

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 09:26:55 -03:00
ac3699dcb4 fix: set attendeeSeatId in evt for seated booking reschedule emails (#26498)
* fix: set attendeeSeatId in evt for seated booking reschedule emails

When an attendee reschedules a seated booking, the reschedule/cancel links
in emails were using bookingUid instead of seatUid after the first reschedule.
This was because evt.attendeeSeatId was not being set before sending the email.

This fix ensures that evt.attendeeSeatId is set to bookingSeat.referenceUid
so that the email links consistently use seatUid for seated bookings.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: add E2E test for seatUid preservation across multiple reschedules

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use valid time slots within availability window for E2E test

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: make E2E test self-contained to avoid shared state issues

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update E2E test to validate seatUid usability across reschedules

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 14:15:40 +02:00
a62eb2bdac refactor: replace shouldServeCache with mode parameter for calendar cache control (#26539)
* refactor: replace shouldServeCache with mode parameter for calendar cache control

Replace the boolean shouldServeCache parameter with a new CalendarFetchMode type
that can have values 'slots', 'overlay', and 'booking'. This provides better
control over when to serve cache vs relay on calendar providers.

- 'slots' mode: Check feature flags and use cache when available (for getting
  actual calendar availability)
- 'overlay' mode: Don't use cache (for overlay calendar availability)
- 'booking' mode: Don't use cache (for booking confirmation)
- undefined: Same as 'slots' for backwards compatibility

The cache decision logic is now centralized in getCalendar.ts based on the mode
parameter.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: update CalendarService.test.ts to use mode parameter

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: use shared GetAvailabilityParams type across all calendar services

- Import GetAvailabilityParams and GetAvailabilityWithTimeZonesParams from @calcom/types/Calendar
- Replace inline type definitions with shared types in all calendar service implementations
- Update BaseCalendarService, CalendarCacheWrapper, and CalendarTelemetryWrapper
- Ensures consistent typing and follows DRY principles

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add missing IntegrationCalendar import and update mock getAvailability signature

- Add IntegrationCalendar back to sendgrid CalendarService imports
- Update bookingScenario mock getAvailability to use typed params object
- Add listCalendars method to mock Calendar object

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: update test files to use typed params object for getAvailability methods

- Update CalendarCacheWrapper.test.ts to call getAvailability/getAvailabilityWithTimeZones with params object
- Update getCalendarsEvents.test.ts toHaveBeenCalledWith assertions to expect params object
- All 32 tests now pass

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: consolidate to single GetAvailabilityParams type for both getAvailability methods

- Remove GetAvailabilityWithTimeZonesParams, use GetAvailabilityParams for both methods
- Add mode parameter to getAvailabilityWithTimeZones calls
- Update wrapper classes to pass mode through to underlying calendar
- Update test files to include mode in getAvailabilityWithTimeZones calls and assertions

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: use EventBusyDate with optional timeZone for getAvailabilityWithTimeZones

- Add optional timeZone field to EventBusyDate type
- Update getAvailabilityWithTimeZones return type to use EventBusyDate[]
- Update Google Calendar service and wrapper classes to use the new type

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: type errors and remove unused calendar watching methods

- Fix type errors in CalendarCacheWrapper.ts (convert null to undefined for timeZone)
- Fix type errors in getCalendarsEvents.ts (ensure timeZone is always present)
- Remove unused watchCalendar/unwatchCalendar from Calendar interface
- Remove unused startWatchingCalendarsInGoogle/stopWatchingCalendarsInGoogle from GoogleCalendarService
- Remove unused imports (uuid, uniqueBy, GOOGLE_WEBHOOK_URL, ONE_MONTH_IN_MS)

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: remove watchCalendar/unwatchCalendar from CalendarTelemetryWrapper

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: remove verbose JSDoc param comments from wrapper classes

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: make mode parameter required in getCalendar

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add required mode parameter to all getCalendar callers

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: provide default mode value in getBusyCalendarTimes

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add mode parameter to remaining getCalendar callers

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add mode parameter to vital and wipemycalother reschedule

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add mode parameter to credential-sync API endpoint

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: add 'none' mode to CalendarFetchMode and use as default

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* test: add mode parameter to getCalendarsEvents test calls

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Update packages/app-store/delegationCredential.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-08 09:07:41 -03:00
Kartik 64828abad2 fix: added seed credentials for signin (#26559) 2026-01-08 11:32:13 +00:00
Syed Ali Shahbazandcubic-dev-ai[bot] 59fca85d92 fix: use graceful filtering for previously hard failing blocked users in team events (#26446)
* init

* typefix

* --

* fix test

* update index

* cleanup

* rm unnecessary comments

* improvements

* add tests

* test fixes

* fixes

* fixes

* fixes

* add try catch to make booking fail-open

* Update packages/features/watchlist/operations/check-user-blocking.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix type

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-08 08:30:54 -03:00
27623926fc test: improve flaky E2E tests (#26473)
* fix flakes

* revert

* fix

* update

* more update

* fix

* revert

---------

Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-08 15:52:53 +05:30
Carina WollendorferandCarinaWolli a68fcf8840 fix refresh token endpoint (#26577)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-01-08 15:40:59 +05:30
Amin Jaoui ea7e5b3f19 docs: fix missing log level number in README (#26574)
The first example in the logger level documentation was missing
the number 6 before 'fatal', making it inconsistent with the
second example and the level definitions above.
2026-01-08 09:55:13 +00:00
Volnei Munhoz 2b8a0a4d80 chore: biome ternary rules changes (#26576) 2026-01-08 09:15:34 +00:00
Hariom BalharaandDevin AI 2f92563606 refactor: Use confirmHandler directly in link and verify-booking-token routes (#26567)
Refactors the link and verify-booking-token API routes to call confirmHandler directly instead of using the tRPC caller pattern. This simplifies the code by removing the need for session getter, legacy request building, and context creation.

Changes:
- apps/web/app/api/link/route.ts: Use confirmHandler directly with ctx and input
- apps/web/app/api/verify-booking-token/route.ts: Use confirmHandler directly with ctx and input
- Updated tests to mock confirmHandler instead of tRPC caller

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 08:23:48 +00:00
Benny JooandDevin AI f5d345b133 refactor: remove @calcom/web imports from @calcom/features and add @calcom/testing package (#26480)
* fix: remove @calcom/web imports from packages/features to eliminate circular dependency

- Migrate UserTableUser and MemberPermissions types to packages/features/users/types/user-table.ts
- Migrate useGeo hook to packages/features/geo/GeoContext.tsx
- Migrate buildLegacyRequest to packages/lib/buildLegacyCtx.ts
- Migrate Calendar component to packages/features/calendars/weeklyview/components/
- Move test utilities (bookingScenario, fixtures) to packages/features/test/
- Update all imports in packages/features to use new locations
- Add re-exports in apps/web for backward compatibility

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: delete original implementation files and fix type issues

- Delete original calendar component files in apps/web (keep only re-export stubs)
- Migrate OutOfOfficeInSlots to packages/features/bookings/components
- Convert apps/web OutOfOfficeInSlots to re-export stub
- Fix className vs class issue in Calendar.tsx
- Fix @calcom/trpc import violation in user-table.ts by using structural type

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing isGroup and contains fields to UserTableUser attributes type

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update customRole type to match actual Prisma Role model

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix build

* fix

* fix

* cleanup weeklyview

* fix

* refactor to mv MemberPermissions to types package

* add types dependency to features

* fix

* fix

* fix

* fix

* fix

* fix

* rename

* rename

* migrate

* migrate

* migrate

* fix

* fix

* fix

* refactor: move test utilities from packages/features/test to tests/libs

- Move bookingScenario utilities to tests/libs/bookingScenario
- Move fixtures to tests/libs/fixtures
- Update all imports in packages/features test files to use new location
- Update all imports in apps/web test files to use new location
- Eliminates duplication of test utilities between packages/features and apps/web

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: correct relative import paths for tests/libs in test files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: replace test utility implementations with re-exports to tests/libs

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: fix test import paths and move signup handler tests to apps/web

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: move buildLegacyCtx to packages/lib and restore handlers to packages/features

- Move buildLegacyCtx from apps/web/lib to packages/lib to break circular dependency
- Update apps/web/lib/buildLegacyCtx.ts to re-export from @calcom/lib
- Restore signup handlers and tests to packages/features/auth/signup/handlers
- Update handler imports to use @calcom/lib/buildLegacyCtx instead of @calcom/web/lib/buildLegacyCtx

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update recurring-event.test.ts imports to use tests/libs path

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: delete test re-export files and update imports to use tests/libs directly

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update remaining test imports to use tests/libs directly

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update handleRecurringEventBooking calls to match function signature (1 arg)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* remove

* migrate tests

* migrate tests

* refactor: update test mock imports by removing  and using async  for mock creators.

* fix type errors

* fix: add type assertion for MockUser in p2002.test-suite.ts

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: restore locale import in compareReminderBodyToTemplate.test.ts using relative path

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* feat: create @calcom/testing package and migrate tests from /tests directory

- Created new @calcom/testing package in /packages/testing
- Moved all files from /tests to /packages/testing
- Updated all imports across the codebase to use @calcom/testing alias
- Removed /tests directory at root level

This allows other packages like @calcom/features and @calcom/web to import
testing utilities using the @calcom/testing alias instead of relative paths.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix: add missing useBookings export to @calcom/atoms package

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing useCalendarsBusyTimes and useConnectedCalendars exports to @calcom/atoms

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* chore: add @calcom/testing as explicit devDependency to packages that use it

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: move setupVitest.ts into @calcom/testing package

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* chore: add biome rules to restrict @calcom/testing imports

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* rename libs to lib

* rename libs to lib

* add rule

* add rule

* refactor: remove @calcom/features imports from @calcom/testing

- Move mockPaymentSuccessWebhookFromStripe to fresh-booking.test.ts
- Replace ProfileRepository.generateProfileUid() with uuidv4()
- Clone Tracking type into @calcom/testing/src/lib/types.ts
- Update imports in expects.ts and getMockRequestDataForBooking.ts
- Move source files into src/ folder
- Move CalendarManager mock to @calcom/features

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add explicit exports for nested paths in @calcom/testing

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* improve

* improve

* fix

* fix

* fix type checks

* fix type checks

* fix type checks

* fix tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 16:59:11 +09:00
Joe Au-Yeung 04e447058c fix: Add copy-app-store-static to docker file (#26565)
* Add `copy-app-store-static` step

* Biome formatting
2026-01-08 04:30:02 -03:00
Joe Au-YeungandDevin AI 0cf5de5ef8 fix: log Zoom token refresh errors at ERROR level (#26547)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-07 21:49:11 +00:00
Pedro Castro 2aed9908b7 fix: replace gray-matter with direct yaml.load for js-yaml 4.x compatibility (#26555)
gray-matter uses yaml.safeLoad() which was removed in js-yaml 4.x, causing 500
errors on app store pages after the js-yaml 4.1.1 update (CWE-1321 fix)

- Add parseFrontmatter function using yaml.load with JSON_SCHEMA
- Add type guard for safe type narrowing
- Add unit tests for frontmatter parsing and security
- Remove gray-matter dependency
2026-01-07 15:16:26 -03:00
Anik Dhabal Babu f54a3d1d0c test: all flaky unit tests (#26558) 2026-01-07 17:53:19 +00:00
2d19003e8a style: use Tailwind color tokens instead of hardcoded hex values (#26557)
Replace hardcoded hex colors with their exact Tailwind equivalents:
- text-[#111827] → text-gray-900
- text-[#6B7280] → text-gray-500
- text-[#374151] → text-gray-700
- border-[#D1D5DB] → border-gray-300

This improves consistency with the rest of the codebase which
already uses these tokens (e.g., text-gray-500 is used 107 times).

Files changed:
- apps/web/modules/videos/views/videos-single-view.tsx
- companion/app/(tabs)/(event-types)/index.tsx
- companion/components/booking-list-screen/BookingListScreen.tsx
- companion/components/event-type-detail/tabs/AdvancedTab.tsx
- companion/components/screens/AvailabilityListScreen.tsx
- companion/components/screens/BookingDetailScreen.android.tsx

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Dylan Tarre <timecreepsby@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-07 17:37:07 +00:00
Eunjae Lee ae6e0689f4 docs: update google calendar guide (#26549)
* docs: update google calendar doc

* update page name and include .env in seed-app-store.ts

* add onre more step

* update
2026-01-07 17:28:44 +00:00
Pallav cdd946cf39 refactor: single line app feature desc (#26553) 2026-01-07 17:27:52 +00:00
Anik Dhabal Babu cd6dbd53ff fix: prevent disabled apps from appearing in app store category pages (#26551) 2026-01-07 16:55:06 +00:00
Volnei Munhoz 444b7b7231 Add flex biome adoption (#26550) 2026-01-07 17:33:19 +01:00
4585d7402d fix: BOOKING_PAID webhook & workflow isn't triggering after payment successful (#26044)
* fix booking paid webhook

* Update handlePaymentSuccess to include updatedBooking status

* Fix videoCallUrl undefined error in BOOKING_PAID workflow trigger

- Import getVideoCallUrlFromCalEvent to properly compute meeting URL
- Use conditional metadata to avoid passing undefined videoCallUrl
- Matches original handleConfirmation.ts behavior

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Add missing schedulingType to calendarEventForWorkflow

- Added schedulingType field to match original handleConfirmation.ts behavior
- This field was present in the original implementation but missing in the refactor

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Fix paymentMetadata nullability to match original behavior

- Changed from ?? null to optional chaining (undefined) to match original handleConfirmation.ts
- This ensures webhook consumers using z.string().optional() schemas continue to work
- undefined values are omitted from JSON, while null values would be explicitly included

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Fix type errors: add schedulingType to getBooking and use null for metadata

- Added schedulingType to getBooking.ts eventType select to make it available
- Changed paymentMetadata to use ?? null instead of undefined for type compatibility
- The metadata type expects { [key: string]: string | number | boolean | null }

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* await

* add tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-07 15:00:54 +00:00
Eunjae Lee f9635df629 chore: load .env for seed-insights.ts (#26545) 2026-01-07 14:39:41 +00:00
2cadc0b1e9 fix: remove shouldServeCache in getCalendarEvent getAvailability call (#26541)
* fix: remove shouldServeCache in getCalendarEvent getAvailability call

* test: remove shouldServeCache parameter from getAvailability test expectations

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-07 19:55:47 +05:30
Udit Takkar 0d905a6c11 fix: add arrayLimit (#26542) 2026-01-07 14:23:38 +00:00
Dhairyashil Shinde dcf10935de 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.
2026-01-07 16:03:01 +02:00
4571215794 feat(calendar-subscription): add telemetry metrics for cache performance and webhook calls (#26501)
* feat(calendar-subscription): add telemetry metrics for cache performance and webhook calls

- Add Sentry span telemetry to CalendarCacheWrapper.getAvailability() and getAvailabilityWithTimeZones() to measure:
  - Cache fetch duration (cacheFetchDurationMs)
  - Original calendar fetch duration (originalFetchDurationMs)
  - Number of calendars from cache vs original source
  - Number of events from each source
  - Whether cache was used (cacheUsed)

- Add Sentry span telemetry to CalendarSubscriptionService.processWebhook() to track:
  - Provider (google_calendar, office365_calendar)
  - Success/failure status
  - Processing duration (durationMs)
  - Error messages on failure
  - Channel ID and selected calendar ID

- Create telemetry module with types, sentry-span, and no-op-span implementations

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor(calendar-subscription): move telemetry to @calcom/lib for reusability

- Add withSpan helper to @calcom/lib/sentryWrapper for reusable telemetry
- Update CalendarCacheWrapper to use withSpan from @calcom/lib
- Update CalendarTelemetryWrapper to use withSpan from @calcom/lib
- Update CalendarSubscriptionService to use withSpan from @calcom/lib
- Remove old telemetry module from calendar-subscription feature
- Add telemetry tracking when cache is disabled for performance comparison

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix(calendar-subscription): only apply telemetry wrapper when Sentry is configured

- Fix unit test failures by checking if Sentry is configured before wrapping
- Remove ESLint inline rules from getCalendar.ts

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor(calendar-subscription): move CalendarTelemetryWrapper to telemetry directory

- Move CalendarTelemetryWrapper from cache/ to telemetry/ directory
- Update import path in getCalendar.ts

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* feat(telemetry): add console fallback when Sentry is not configured

- Add console logging fallback in development mode when Sentry is not configured
- Create isTelemetryEnabled() helper to check if telemetry should be enabled
- Update getCalendar.ts to use isTelemetryEnabled() helper
- Logs span name, operation, duration, and attributes to console via @calcom/lib/logger

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor(calendar-subscription): wrap all calendars with CalendarTelemetryWrapper

- CalendarTelemetryWrapper now wraps ALL cache-supported calendars with cacheEnabled parameter
- CalendarCacheWrapper keeps cache-specific metrics with distinct op (calendar.cache.internal.*)
- CalendarTelemetryWrapper uses canonical op (calendar.getAvailability) for consistent querying
- Nested spans: outer telemetry wrapper measures end-to-end, inner cache wrapper measures cache internals

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-07 11:27:40 +00:00
Adarsh Tiwari c3668d3664 fix: added team badge in event types (#26536)
* added team badge in event types

* added icon into the badge
2026-01-07 16:38:57 +05:30
61a932f8f5 feat: OAuth2 controller api v2 + refactor oAuth Trpc handlers (#25989)
* feat(api-v2): add OAuth2 controller skeleton for auth module

- Add new OAuth2 module under /auth with controller, service, repository, and DTOs
- Implement skeleton endpoints:
  - GET /v2/auth/oauth2/clients/:clientId - Get OAuth client info
  - POST /v2/auth/oauth2/clients/:clientId/authorize - Generate authorization code
  - POST /v2/auth/oauth2/clients/:clientId/exchange - Exchange code for tokens
  - POST /v2/auth/oauth2/clients/:clientId/refresh - Refresh access token
- Create input DTOs for authorize, exchange, and refresh operations
- Create output DTOs for client info, authorization code, and tokens
- Register OAuth2Module in endpoints.module.ts

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: add missing functions to platform libraries

* feat(api-v2): integrate OAuthService from platform-libraries into OAuth2 controller

- Add OAuthService export to platform-libraries
- Refactor OAuth2Service to use OAuthService.validateClient() and OAuthService.verifyPKCE()
- Remove duplicate local implementations of validateClient and verifyPKCE methods

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat(api-v2): use local validateClient and verifyPKCE implementations

- Remove OAuthService export from platform-libraries (will be deprecated)
- Reimplement validateClient and verifyPKCE methods locally in OAuth2Service
- Use verifyCodeChallenge and generateSecret from platform-libraries directly

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor(api-v2): separate repositories for OAuth2, access codes, and teams

- Create AccessCodeRepository for access code Prisma operations
- Add findTeamBySlugWithAdminRole method to TeamsRepository
- Move generateAuthorizationCode, createTokens, verifyRefreshToken to OAuth2Service
- Update OAuth2Repository to only contain OAuth client operations
- Update OAuth2Module to import TeamsModule and provide AccessCodeRepository

Addresses PR review comments to properly separate concerns

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat(api-v2): implement JWT token creation and verification for OAuth2

- Implement createTokens method using jsonwebtoken to sign access and refresh tokens
- Implement verifyRefreshToken method to verify JWT refresh tokens
- Add ConfigService injection for CALENDSO_ENCRYPTION_KEY access
- Import ConfigModule in OAuth2Module for dependency injection

Based on logic from apps/web/app/api/auth/oauth/token/route.ts and
apps/web/app/api/auth/oauth/refreshToken/route.ts

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: refactor and dayjs import fix

* feat(api-v2): add ApiAuthGuard to getClient endpoint and e2e tests for OAuth2

- Add @UseGuards(ApiAuthGuard) to getClient endpoint for authentication
- Add comprehensive e2e tests for all OAuth2 endpoints:
  - GET /v2/auth/oauth2/clients/:clientId
  - POST /v2/auth/oauth2/clients/:clientId/authorize
  - POST /v2/auth/oauth2/clients/:clientId/exchange
  - POST /v2/auth/oauth2/clients/:clientId/refresh
- Tests cover happy paths and error cases (invalid client, invalid code, etc.)

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore(api-v2): hide OAuth2 endpoints from Swagger documentation

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* hide endpoints from doc

* fix(api-v2): address PR feedback for OAuth2 controller

- Fix P0 critical bug: token_type field name mismatch in DecodedRefreshToken interface
- Add @Equals('authorization_code') validation to exchange.input.ts grantType
- Add @Equals('refresh_token') validation to refresh.input.ts grantType
- Add @IsNotEmpty() validation to get-client.input.ts clientId
- Add @Expose() decorators to all output DTOs for proper serialization
- Add security test assertion to verify clientSecret is not returned in response

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* feat(api-v2): implement redirect behavior for OAuth2 authorize endpoint

- Update authorize endpoint to return HTTP 303 redirect with authorization code
- Add exact match validation for redirect URI (security requirement)
- Implement error handling with redirect to redirect URI and error query params
- Add state parameter support for CSRF protection
- Update e2e tests to verify redirect behavior (303 status, Location header, error redirects)

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor(api-v2): address PR feedback for OAuth2 authorize endpoint

- Make redirectUri a required input parameter (remove optional fallback)
- Move buildRedirectUrl and mapErrorToOAuthError to oauth2Service
- Add return statements to res.redirect() calls
- Simplify controller by delegating redirect URL building to service

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* wip move code outside of api v2

* feat(oauth): wire up dependency injection for OAuthService and repositories

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: oAuthService used in routes

* fix imports

* fix(api-v2): return 404 for invalid client ID instead of redirect in authorize endpoint

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api-v2): fix E2E test URL paths and remove bootstrap() in authenticated section

- Remove bootstrap() call in authenticated section to match working test pattern
- Change URL paths from /api/v2/... to /v2/... in authenticated section
- Keep bootstrap() and /api/v2/... paths in unauthenticated section

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api-v2): mock getToken from next-auth/jwt for E2E tests

- Add jest.mock for next-auth/jwt getToken function
- Mock returns null for unauthenticated tests
- Mock returns { email: userEmail } for authenticated tests
- Remove withNextAuth helper since ApiAuthGuard uses ApiAuthStrategy
  which calls getToken directly, not NextAuthStrategy

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix tests and code review

* cleanup generate secrets

* cleanup controller

* chore: remove console.log from OAuthService.validateClient

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* Update apps/web/app/api/auth/oauth/refreshToken/route.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix(api-v2): add bootstrap() to authenticated E2E tests and update URL paths to /api/v2/

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* Merge remote-tracking branch 'origin/devin/oauth2-controller-skeleton-1765988792' and remove console.log from token route

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: remove dead code

* refactor

* refactor: generateAuthCode trpc handler and getClient trpc handler

* remove pkce check for refreshToken endpoint

* Update packages/trpc/server/routers/viewer/oAuth/getClient.handler.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor: error handling

* refactor: error handling

* refactor: error handling

* remove console log

* provide redirectUri in generateAuthCodeHandler

* provide redirectUri in authorize view

* refactor: replace HttpError with ErrorWithCode in OAuth files

- Update OAuthService to use ErrorWithCode instead of HttpError
- Update mapErrorToOAuthError to check ErrorCode instead of status codes
- Update token/route.ts and refreshToken/route.ts to use ErrorWithCode
- Add ErrorWithCode export to platform-libraries
- Use getHttpStatusCode to map ErrorCode to HTTP status codes

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update generateAuthCode handler to use ErrorWithCode instead of HttpError

The handler was still checking for HttpError in its catch block, but OAuthService
now throws ErrorWithCode. This caused the error messages to be lost and replaced
with 'server_error' instead of the specific error messages.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update OAuth2 controller to use ErrorWithCode instead of HttpError

The controller was still checking for HttpError in its catch blocks, but OAuthService
now throws ErrorWithCode. This caused all errors to return 500 Internal Server Error
instead of the correct HTTP status codes (400, 401, 404).

Also added getHttpStatusCode export to platform-libraries.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add explicit unknown type annotation to catch blocks in OAuth2 controller

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: change NotFoundException to HttpException in authorize endpoint

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: handle err with ErrorWithCode in authorize endpoint catch block

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: move errorWithCode

* fix: error code rfc

* fix: no need to handle errors there is a middleware

* refactor errors

* refactor errors

* refactor redirecturi and state from api

* refactor: address PR comments for OAuth2 controller

- Remove unused GetOAuth2ClientInput class
- Change API tag from 'Auth / OAuth2' to 'OAuth2'
- Move OAuthClientFixture to separate fixture file (oauth2-client.repository.fixture.ts)
- Add 'type' property to OAuth2ClientDto for confidential/public client type
- Rename 'clientId' to 'id' in OAuth2ClientDto (using @Expose mapping)
- Clean up duplicate provider declarations in oauth2.module.ts
- Update e2e tests to use new fixture and verify type property

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-07 08:05:21 -03:00
Hariom Balhara ca32f04cc1 chore: Integrate booking cancellation audit (#26458)
## What does this PR do?
> **⚠️ Note: This PR does not enable booking audit in production.** The `BookingAuditTaskerProducerService` has an [`IS_PRODUCTION` guard](https://github.com/calcom/cal.com/blob/integrate-booking-creation-reschedule-audit/packages/features/booking-audit/lib/service/BookingAuditTaskerProducerService.ts#L106-L108) that skips audit task queueing in production environments. This allows the integration to be tested in development before enabling it in production.

Integrates audit logging for booking cancellations, following the pattern established in PR #26046 for booking creation/rescheduling audit.

- Related to #25125 (Booking Audit Infrastructure)

### Changes:
- Add audit logging for single booking cancellation via `onBookingCancelled`
- Add audit logging for bulk recurring booking cancellation via `onBulkBookingsCancelled`
- Pass `userUuid` and `actionSource` from webapp cancel route (WEBAPP)
- Pass `userUuid` and `actionSource` from API-v2 bookings service (API_V2)
- Create `getAuditActor` helper to derive actor from userUuid or create synthetic guest actor
- Add `getUniqueIdentifier` helper for generating unique actor identifiers
- Add warning log when `actionSource` is "UNKNOWN" for observability
- Add integration tests for booking cancellation audit

### Audit Data Captured:
- `cancellationReason` (simple string value)
- `cancelledBy` (simple string value)  
- `status` (old → new, e.g., "ACCEPTED" → "CANCELLED")

### Updates since last revision:
- Simplified `CancelledAuditActionService` schema: `cancellationReason` and `cancelledBy` are now stored as simple nullable strings instead of change objects (old/new), since cancellation is a one-time event where tracking previous values doesn't apply
- Added integration tests for cancelled booking audit in `booking-audit-cancelled.integration-test.ts`
- Added `getUniqueIdentifier` helper function in actor.ts for generating unique identifiers with prefixes

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Cancel a single booking via the webapp - verify audit record is created with actor and actionSource="WEBAPP"
2. Cancel a single booking via API v2 - verify audit record is created with actionSource="API_V2"
3. Cancel all remaining bookings in a recurring series - verify bulk audit records are created with shared operationId
4. Cancel via unauthenticated cancel link - verify guest actor is created with synthetic email (prefixed with "param-" or "fallback-")
5. Run integration tests: `yarn test packages/features/booking-audit/lib/service/__tests__/booking-audit-cancelled.integration-test.ts`

## Human Review Checklist

- [ ] Verify `onBookingCancelled` and `onBulkBookingsCancelled` methods exist in `BookingEventHandlerService`
- [ ] Review the `getAuditActor` fallback logic - creates synthetic email with "fallback-" or "param-" prefix when no userUuid available
- [ ] Confirm the simplified schema for `cancellationReason`/`cancelledBy` (no longer tracking old→new) is intentional
- [ ] Note: Audit logging calls are awaited directly - if audit service fails, the cancellation will fail. Confirm this is the desired behavior.
- [ ] Verify `CancelledAuditDisplayData` type no longer includes `previousReason` and `previousCancelledBy` fields

---

Link to Devin run: https://app.devin.ai/sessions/42404e76a66946fe9e46fa07fb12e779
Requested by: @hariombalhara (hariom@cal.com)
2026-01-07 16:15:57 +05:30
Dhairyashil Shinde 9e84f59216 feat(companion): UI Enhancements for Android and Extension (#26434)
* feat: companion-android-ui-upgrade version 1

* recurrings and unconfirmed booking filter and page implementation

* add badge and links to event type list page

* address cubics comments

* feat(companion): unify dropdown menu for Android and extension (#26486)

* feat(companion): unify dropdown menu for Android and extension

- Merge Android-specific dropdown implementations into base component files
- EventTypeListItem: Add DropdownMenu with Preview, Copy link, Edit, Duplicate, Delete actions
- BookingListItem: Add DropdownMenu with booking actions (reschedule, edit location, add guests, etc.)
- RecurringBookingListItem: Add DropdownMenu with recurring booking actions
- AvailabilityListItem: Add DropdownMenu with Set as Default, Duplicate, Delete actions
- BookingDetailScreen: Add DropdownMenu in header for Android with AlertDialog for cancel confirmation
- Delete all .android.tsx files as implementations are now unified

* fix(companion): fix typecheck errors after dropdown unification

- Remove unused props from EventTypeListItem.ios.tsx (copiedEventTypeId, handleEventTypeLongPress)
- Remove unused onActionsPress prop from BookingListItem.ios.tsx
- Remove copiedEventTypeId and handleEventTypeLongPress props from index.ios.tsx and index.tsx
- Remove onLongPress and onActionsPress props from BookingListScreen.tsx
- Remove handleScheduleLongPress, setSelectedSchedule, setShowActionsModal props from AvailabilityListScreen.tsx
- Fix BookingDetailScreen.tsx to use correct action property names (reschedule.visible instead of canReschedule, etc.)

* fix(companion): remove unused code after dropdown unification

- Remove unused handleEventTypeLongPress function and ActionSheetIOS import from index.ios.tsx
- Remove unused copiedEventTypeId state, handleEventTypeLongPress function, and ActionSheetIOS import from index.tsx
- Prefix unused setSelectedBooking with underscore in BookingListScreen.tsx
- Remove unused handleScheduleLongPress function and ActionSheetIOS import from AvailabilityListScreen.tsx

* feat(companion): unify booking filter UI for Android and extension

- Remove SegmentedControl from web/extension booking list page
- Use Header dropdown for booking status filter on both Android and web
- Use unified event type filter dropdown for both platforms
- Remove unused showFilterModal state and related code
- Pass filterOptions, activeFilter, and onFilterChange to Header for all platforms

* fix(companion): add header padding for web/extension to prevent button clipping

- Add headerLeftContainerStyle and headerRightContainerStyle with 12px padding for web platform
- Applied to root Stack and all nested tab Stack layouts
- Fixes issue where header buttons were touching edges and getting chopped off on extension/web
- Android remains unaffected as the fix is web-only

* fix(companion): add HeaderButtonWrapper for web-only header padding

- Create HeaderButtonWrapper component that adds 12px margin on web only
- Wrap all header buttons with HeaderButtonWrapper to prevent clipping
- Revert invalid screenOptions changes that caused typecheck errors
- Apply fix to all screens with native header buttons:
  - reschedule.tsx, edit-location.tsx, add-guests.tsx
  - mark-no-show.tsx, view-recordings.tsx, meeting-session-details.tsx
  - event-type-detail.tsx, BookingDetailScreen.tsx, profile-sheet.tsx
  - edit-availability-day.tsx, edit-availability-name.tsx, edit-availability-override.tsx

* update more ui-ux

* address cubics comments

* address cubics comments & open event type list page first for inttial render of app
2026-01-07 07:19:07 -03:00
Benny Joo 6d2491b394 refactor: Clean up the /tests in the root (#26525)
* refactor: Delete mockTRPCContext and mockData, and relocate mockStripeSubscription to stripe mock.

* chore: Delete unused Stripe, video client, and reminder scheduler mock files.
2026-01-07 07:18:15 -03:00
110491ecb9 fix: generate compliant passwords using meeting_password_requirement (#26148)
* fix(zoomvideo): generate compliant passwords using meeting_password_requirement

- Add meetingPasswordRequirementSchema to parse Zoom's password policy settings
- Implement validatePasswordAgainstRequirements() to check if a password meets the policy
- Implement generateCompliantPassword() to create passwords that comply with the policy
- Update translateEvent() to use getCompliantPassword() which validates the default password
  or generates a new compliant one based on meeting_password_requirement
- Add meeting_password_requirement to the settings API filter
- Improve error handling for non-JSON responses in OAuthManager (XML validation errors)

This fixes the frequent 'Error in JSON parsing Zoom API response' errors caused by
Zoom returning XML validation errors when the password doesn't comply with the
account's password policy (e.g., numeric-only requirement).

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: use cleaner single-pass consecutive character check

- Replace nested-loop O(n*k) implementation with single-pass O(n) helper
- Add proper guard for consecutiveLength < 4 (Zoom allows 0, 4-8)
- Move consecutive check before only_allow_numeric to apply it for all cases
- Fix edge-case bug where consecutiveLength 1-3 could incorrectly reject passwords

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Optimize OAuth response handling

Refactor OAuth response validation to read body only once.

* Improve error handling in Zoom API response parsing

Refactor error handling for Zoom API response parsing to improve logging and clarity.

* Improve compliant password generation logic

Enhance password generation to avoid consecutive characters when numeric only is required.

* Remove password requirement handling from VideoApiAdapter

Removed meeting password requirement schema and related functions for password validation and generation.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-07 09:51:30 +00:00
Hariom Balhara 010ac9e8f2 Make booking-audit integration test utils reusable (#26526) 2026-01-07 14:22:09 +05:30
Pedro CastroandMorgan 701c4cdb76 perf: batch booking queries in output service (#25900)
Replace N sequential queries with single batch queries in:
- getOutputRecurringBookings
- getOutputRecurringSeatedBookings

Uses existing batch repository methods. Reduces database roundtrips
from O(n) to O(1) for recurring booking lookups

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-07 08:41:09 +00:00
Pedro Castro 01be9f1ef2 fix: validate owner email on platform org creation (#26286)
Remove isPlatform bypass from owner verification to ensure users can only create organizations where they are the designated owner. Add test coverage for create and intentToCreateOrg handlers:

- Regression tests for isPlatform bypass fix
- Happy path for admin creating org for another user
2026-01-06 22:46:44 -03:00
Pedro Castro 30ef38804c refactor: use structured logger in video adapters (#26285)
- Remove debug console.log/console.error statements
- Add logger.debug for observability (meeting lifecycle events)
- Add logger.error with safe error pattern (message + name only)
- Fix error messages to avoid exposing response details
- Remove redundant try/catch blocks (errors propagate naturally)
2026-01-06 22:29:17 -03:00
Pedro CastroandAlex van Andel 0df161ef26 fix(ci): use env vars for input interpolation in workflow run steps (#26520)
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2026-01-06 22:56:59 +00:00
b8b9251f76 fix: Support 10-digit phone numbers for Ivory Coast (+225) (#26465)
* fix: update ivory coast mask to 10 digits

* update formating for Benin numbers

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-01-06 22:31:21 +00:00
Alex van Andel 1ebe7aa8ab chore: release v6.0.8
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-06 22:23:31 +00:00
Pedro Castro 170203051f fix: handle existing users on invite token flow (#26217)
* fix(auth): validate user before signup with invite token

Validate if user already exists before creating account when
signing up with team or organization invite tokens. Existing users
are redirected to login to accept the invitation.

- Add user existence check in signup handlers
- Return 409 for existing users with redirect to login
- Extract signup fetch logic to dedicated module
- Add e2e test coverage

* fix(auth): address code review feedback

- Fix fetchSignup tests to use vi.spyOn for proper mock restoration
- Add content-type validation before parsing JSON response
- Guard against undefined error in Stripe callback
- Use t() for localized error message
- Fix race condition in handlers by catching P2002 on create

* fix(auth): address additional code review feedback

- Add INVALID_SERVER_RESPONSE constant to follow established pattern
- Check error.meta.target includes email before returning USER_ALREADY_EXISTS
to avoid false positives from other unique constraint violations
- Add select: { id: true } to user.create calls since downstream functions only
need the user id

* test: add unit tests for P2002 handling in signup handlers

- Add shared test suite covering all P2002 edge cases
- Ensure 409 only for email constraint violations
- Fix non-token paths to use atomic create + catch pattern

* fix: update error message copy per review feedback

* fix(auth): address code review feedback and prevent orphan Stripe customers

- Add user existence check before Stripe customer creation (token flow)
- Add select clause to user.create for consistency
- Fix showToast argument order (pre-existing bug)
- Use toHaveURL instead of waitForURL in E2E tests

* fix(auth): resolve 500 errors by fixing Prisma error detection across module boundaries

The instanceof check for PrismaClientKnownRequestError fails when different
Prisma client instances are loaded. Added fallback check by constructor name

* fix(auth): validate invitedTo before upsert on team invite signup

* test(auth): update P2002 tests for new invite flow

P2002 tests now use non-token flow since token flow uses upsert
Added tests for invitedTo validation on invite signup

* fix(auth): add guards and P2002 handling per review feedback

- Guard existingUser check with if (foundToken?.teamId)
- Guard username check with if (username) for premium flow
- Add `select` clause to findFirst/findUnique queries
- Add try-catch on upsert for race condition P2002 errors

* fix(auth): narrow P2002 handling to email/username targets
2026-01-06 22:10:36 +00:00
8b5d9202db refactor: convert PrismaAttributeToUserRepository to accept Prisma as dependency (#26515)
* refactor: convert PrismaAttributeToUserRepository to accept Prisma as dependency

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use Prisma types from generated client instead of custom types

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 18:09:07 +00:00
Eunjae LeeandDevin AI 6fa525812c docs: add DTO location and naming conventions to knowledge base (#26478)
* docs: add DTO location and naming conventions to knowledge base

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: clarify DTO location rules for new features vs refactored code

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: simplify DTO location - all DTOs go in packages/lib/dto/

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 15:02:55 -03:00
eacfcd15a4 feat: Hubspot write to meeting object (#26039)
* feat: Hubspot write to meeting object

* fix: translate hardcoded strings and remove debug console.log

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor

* fix: improve static value detection for placeholder replacement

- Changed condition from startsWith/endsWith to includes('{') to properly detect embedded placeholders
- Strings like 'Hello {name}!' are now correctly processed for placeholder replacement
- Pure placeholder tokens that can't be resolved return null
- Partially resolved values are returned as-is

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor: split WriteToObjectSettings into types and utils files

- Extract interfaces, enums, and type definitions to WriteToObjectSettings.types.ts
- Extract constants and utility functions to WriteToObjectSettings.utils.ts
- Update main component to use the new utility functions
- Improves code organization and maintainability

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* revert: restore original static value detection logic

Per user request - the startsWith/endsWith check was intentional

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* test: add unit tests for HubSpot CRM service

Tests cover:
- ensureFieldsExistOnMeeting: field validation against HubSpot properties
- getTextValueFromBookingTracking: UTM parameter extraction
- getTextValueFromBookingResponse: placeholder replacement
- getDateFieldValue: date field resolution for different date types
- getFieldValue: main field value resolution for all field types
- generateWriteToMeetingBody: write-to-meeting body generation
- getContacts: contact search functionality

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: correct type errors in HubSpot CRM service tests

- Import WhenToWrite enum from crm-enums
- Replace string literals with WhenToWrite.EVERY_BOOKING enum values
- Add missing whenToWrite property to field config objects

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: use type casting for intentional type errors in tests

- Cast numeric fieldValue to string for testing non-string handling
- Cast invalid field type string to CrmFieldType for testing unsupported types

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: prevent unhandled promise rejections in HubSpot CRM tests

- Re-apply mockGetAppKeysFromSlug implementation in beforeEach to ensure
  mock is always set correctly after clearAllMocks
- Change vi.resetAllMocks() to vi.clearAllMocks() to preserve mock
  implementations between tests
- Add explicit types to satisfy biome lint rules
- This fixes the 'Cannot read properties of undefined (reading client_id)'
  errors that were causing CI to fail with exit code 1

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor: convert HubSpot tests to black-box testing through public methods

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: properly type mock CalendarEvent in HubSpot tests

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: properly type TFunction in mock CalendarEvent

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: graceful owner fail test

* refactor

* fix: type check

* fix: remove null fields

* Update packages/app-store/hubspot/lib/CrmService.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-06 14:58:46 -03:00
Peer RichelsenandDevin AI 8ad5f7bf55 feat: add organization banner to user profile page (#26514)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 17:26:49 +00:00
Eunjae LeeandDevin AI f4248bf20d feat: implement FeatureOptInService (#25805)
* feat: implement FeatureOptInService WIP

* clean up

* feat: consolidate feature repositories and add updateFeatureForUser

- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename updateFeatureForUser to setUserFeatureState

Rename to match the convention used for setTeamFeatureState

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState

* fix integration tests

* clean up logics

* update services and router

* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array

- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add getFeatureStateForTeams for batch querying multiple teams

- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: combine org and team state queries into single call

- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use team.isOrganization and clarify computeEffectiveState comment

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use MembershipRepository.findAllByUserId with isOrganization

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add featureId validation using isOptInFeature type guard

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* less queries

* add fallback value

* fix type error

* move files

* add autoOptInFeatures column

* use autoOptInFeatures flag within FeatureOptInService

* add setUserAutoOptIn and setTeamAutoOptIn

* fix computeEffectiveState logic

* rewrite computeEffectiveState

* clean up integration tests

* clean up in afterEach

* fix type error

* refactor: use FeaturesRepository methods instead of direct Prisma calls

Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.

Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts

This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* fix the logic

* extract some logic into applyAutoOptIn()

* remove wrong code

* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union

- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests

* fix type error

* use Promise.all

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 16:55:53 +01:00
cal-com-ci[bot]andLingo.dev 750408ec21 feat: update translations via @LingoDotDev (#26497)
Co-authored-by: Lingo.dev <support@lingo.dev>
2026-01-06 15:01:45 +00:00
5794584624 chore: remove Mintlify AI chat from CMD+K widget (#26485)
* chore: remove Mintlify AI chat from CMD+K widget

- Remove MintlifyChat component and related state from Kbar.tsx
- Delete packages/features/mintlify-chat directory (MintlifyChat.tsx, util.ts)
- Delete apps/web/app/api/mintlify-chat API routes and tests
- Delete packages/lib/server/mintlifyChatValidation.ts
- Remove Mintlify-related env vars from .env.example and turbo.json
- Refactor Kbar.tsx to fix lint issues (explicit types, exports at end)

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: use ReactNode import instead of JSX from react

The JSX type is not exported from 'react' module. Use the global
JSX.Element type (available in React projects) and import ReactNode
for the children prop type.

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat: add all event-types and upcoming bookings to KBar

- Increase event types limit from 10 to 100 to show more event types
- Add useUpcomingBookingsAction hook to fetch and display upcoming bookings
- Bookings show title, date, and time in KBar search results
- Navigate to booking details page when selecting a booking

Co-Authored-By: peer@cal.com <peer@cal.com>

* Revert "feat: add all event-types and upcoming bookings to KBar"

This reverts commit 69d03397e3820e45e7207eb55b38117d269eae5e.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 14:37:33 +00:00
81b5d62f07 feat(api): add team event-types webhooks controller (#26449)
* feat(api): add team event-types webhooks controller

- Add TeamsEventTypesWebhooksController for managing webhooks on team event types
- Add IsTeamEventTypeWebhookGuard for authorization
- Add TeamEventTypeWebhooksService for business logic
- Register new controller in TeamsEventTypesModule
- Enable unsafeParameterDecoratorsEnabled in biome.json for NestJS support

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test(api): add e2e tests for team event-types webhooks controller

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api): restrict team event-type webhooks to admins/owners only

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api): use regular imports instead of type imports for DI and DTOs

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix(api): use regular imports for DI in guard file

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: circular depndency in modules

* delete teams in test

* fix roles guard

* fix biome

* fix guard

* resolve type import

* resolve review feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 11:23:18 -03:00
Pedro Castro 208a9eaa80 chore(auth): add error logging for saml-idp silent failures (#26484)
* chore(auth): add error logging for saml-idp silent failures

* chore(auth): add warn-level logging for saml-idp silent failures

* chore(auth): change 'No user found' log to warn level

* chore(auth): add warn-level logging for silent auth failures

- saml-idp authorize: credentials, code, token, userInfo, user lookup
- callbacks:signIn: account type, email, name, catch-all
- callbacks:jwt: unknown account type (info → warn)
- saml:profile: missing email from IdP
- getServerSession: user not found for valid token
2026-01-06 13:27:12 +00:00
Keith Williams 9e0ba5045e chore: change API codeowner to Foundation (#26504) 2026-01-06 12:55:18 +00:00
Udit Takkar 437d7d9e40 perf: improve cal video webhook (#26495)
* perf: improve cal video webhook

* save format

* refactor: use errorMs
2026-01-06 15:52:18 +04:00
Hariom Balhara a056c3217e chore: Add impersonation context support to booking audit (#26014)
## What does this PR do?

Adds infrastructure to track impersonation context in booking audit records and displays it in the UI. When an admin impersonates another user and performs booking actions, the audit system now:
- Records the **admin** as the actor (who actually performed the action)
- Stores the **impersonated user's UUID** in a separate `context` field
- Displays **"Impersonated By"** in the booking logs UI when viewing audit details

This separation ensures audit trail integrity (the admin is accountable) while preserving full context about whose account was being used.

### Changes
- Added `uuid` to `impersonatedBy` session object for actor identification
- Added `uuid` to top-level `User` type in next-auth types for session enrichment
- Added `context Json?` field to `BookingAudit` Prisma model
- Added `BookingAuditContextSchema` for type-safe context handling with `actingAsUserUuid` field
- Updated producer service interface and implementation to pass context through all queue methods
- Updated consumer service to persist context to database
- Updated repository to store and fetch context in BookingAudit records
- Added `impersonatedBy` field to `EnrichedAuditLog` type in `BookingAuditViewerService`
- Added `enrichImpersonationContext` method to resolve impersonated user details
- Updated booking logs UI to display "Impersonated By" in expanded details
- Added `impersonated_by` translation key

Link to Devin run: https://app.devin.ai/sessions/3f1252527aef4ead9401bdf055c0817b
Requested by: hariom@cal.com (@hariombalhara)

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - internal infrastructure change
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Verify type checks pass: `yarn type-check:ci --force`
2. Verify existing audit tests still pass: `TZ=UTC yarn test`
3. To fully test impersonation context display:
   - Have an admin impersonate a user
   - Perform a booking action (create, cancel, reschedule)
   - Navigate to the booking's audit logs
   - Expand the details for the action
   - Verify "Impersonated By" row appears showing the impersonated user's name
   - Verify the BookingAudit record has:
     - `actorId` pointing to the admin's AuditActor
     - `context` containing `{ actingAsUserUuid: "<impersonated-user-uuid>" }`

## Human Review Checklist

- [ ] Verify the `context` field schema design is appropriate for future extensibility
- [ ] Confirm the `uuid` addition to User type in next-auth doesn't break existing auth flows
- [ ] Check that the optional `context` parameter doesn't break existing queue method callers
- [ ] Verify no migration file is needed (or if squashing is handled separately)
- [ ] Verify the UI displays "Impersonated By" correctly when impersonation context is present
- [ ] Confirm `enrichImpersonationContext` handles edge cases (null context, invalid context, deleted user)

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings
2026-01-06 16:16:18 +05:30
fca818a275 test: fix unit test flake (#25557)
* fix: revalidate teams cache after accepting invite via token

When a user accepts a team invite via token on the /teams page, the
teams cache was not being invalidated. This caused the page to show
stale data (empty list) while the sidebar correctly showed the teams.

This fix adds a call to revalidateTeamsList() after processing an
invite token, ensuring the cache is invalidated and fresh data is
fetched immediately.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: revalidate teams cache after creating team in onboarding flow

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Remove comments on teams cache revalidation

Removed comments about revalidating teams cache after invite processing.

* fix unit test flake

* Remove unused import in useCreateTeam hook

Removed unused import for revalidateTeamsList.

* Remove unused import for revalidateTeamsList

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 11:14:28 +05:30
Anshumancanrock 6672fd4c3d fix: "New" button sizing inconsistent between Workflows and Event Types pages (#26066)
* fix: consistent button sizing between fab and button variants on desktop

* fix: consistent button sizing between fab and button variants on desktop

* fix(ui): align New button sizing across pages

* fix: New button sizing inconsistent between Workflows and Event Types pages

* Update Button.tsx
2026-01-06 03:08:20 +00:00
Benny Joo 6ed18bba53 fix: atoms build by updating import paths (#26489)
* fix build

* fix build
2026-01-06 02:55:42 +00:00
Pedro Castro 920320d49b fix(auth): fix SAML tenant extraction and validation (#26482)
- Extract tenant from userInfo in saml-idp (IdP-initiated)
- Add profile.requested?.tenant fallback for OAuth (SP-initiated)
- Block invalid tenant format in hosted (security)
2026-01-05 18:52:48 +00:00
Volnei Munhoz 66b398b4ed Disable noReactSpecificProps as we use react (#26479) 2026-01-05 18:02:56 +00:00
e0fd01e377 feat: add lightweight E2E session warmup page (#26451)
* feat: add lightweight E2E session warmup endpoint

- Add /api/__e2e__/session-warmup endpoint that triggers NextAuth session loading
- Update apiLogin fixture to use the new endpoint instead of navigating to /settings/my-account/profile
- The endpoint is gated by NEXT_PUBLIC_IS_E2E=1 (already set in playwright.config.ts)
- This reduces overhead in E2E tests by avoiding loading a full UI page just to warm up the session

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move session warmup endpoint to App Router

- Move /api/__e2e__/session-warmup from pages/api to app/api
- Use App Router patterns (NextResponse, buildLegacyRequest)
- Maintains same functionality for E2E session warming

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* rename path

* refactor: switch from API route to minimal SSR page (Option 2)

- Replace /api/e2e/session-warmup API route with /e2e/session-warmup page
- Use App Router page pattern with getServerSession for session warmup
- Update apiLogin fixture to navigate to the page instead of API request

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* revert users fixture but with a new url

* render nothing on success

* clean up

* trying something

* Revert "trying something"

This reverts commit 2ae2f7dcb42612e54eb072a9f09857272020889a.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-05 16:22:52 +00:00
Pedro Castro 23848e7503 chore(deps): update dependencies and add version constraints (#26390)
- Update sanitize-html to 2.17.0
- Remove unused Storybook dependencies from @calcom/ui
- Add resolutions for consistent dependency versions
- Clean up packageExtensions
2026-01-05 13:00:55 -03:00
Benny JooandDevin AI 404d46c991 refactor: Move trpc-dependent components from features to web [2] (#26420)
* fix

* move event types components to web

* update import paths

* mv apps components

* migrate form builder

* fix

* mv sso

* fix

* mv

* update import paths

* update import paths

* mv

* mv

* mv

* fix

* update Booker

* fix

* fix

* fix

* fix

* mv video

* mv embed components to web

* update import paths

* mv calendar weekly view components

* update import paths

* fix

* fixp

* fix

* fix

* fix

* fix: update FormBuilder imports to use @calcom/features/form-builder

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update broken import paths after file migrations

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: correct import paths for platform atoms and moved components

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: apply CSS type fixes and add missing atoms exports

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: resolve type errors in test files after component migrations

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: resolve remaining type errors in test files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* migrate

* fix: resolve type errors in test and mock files

- Add missing bookingForm, bookerFormErrorRef, instantConnectCooldownMs to Booker.test.tsx bookings prop
- Add all required BookerEvent properties to event.mock.ts
- Add vi import from vitest to all mock files
- Fix date parameter types in packages/dayjs/__mocks__/index.ts
- Add verificationCode and setVerificationCode to test-utils.tsx mock store
- Remove children.type access in Section.tsx mock to fix type error
- Fix lint issues: remove unused React imports, use import type where needed, add return types
- Add biome-ignore comments for pre-existing lint warnings in test files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* migrate

* migrate

* migrate

* update import paths

* update import paths

* update import paths

* fix

* migrate data table

* migrate data table

* fix

* fix

* fix

* migrate insights components

* migrate insights components

* fix

* mv

* update import paths

* fix

* fix

* fix

* fix

* fix

* fix: resolve type errors in test mocks

- Booker.test.tsx: Add all required UseFormReturn methods to bookingForm mock
- event.mock.ts: Fix entity, subsetOfHosts, instantMeetingParameters, fieldTranslations, image types
- dayjs/__mocks__/index.ts: Use Object.assign for proper typing of mock properties
- Section.tsx: Change 'class' to 'className' in JSX with biome-ignore comment

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing hasDataErrors and dataErrors to bookings.errors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing loadingStates properties to bookings mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing slots properties (setTentativeSelectedTimeslots, tentativeSelectedTimeslots, slotReservationId)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update quickAvailabilityChecks to include utcEndIso and use valid status type

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing bookerForm properties (formName, beforeVerifyEmail, formErrors)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing UseFormReturn properties to bookerForm.bookingForm mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add hasFormErrors and formErrors to bookerForm.formErrors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add hasFormErrors and formErrors to bookerForm.errors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing isError property to mockEvent

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use complete BookerEvent mock in Booker.test.tsx

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use branded bookingFields type in event mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing schedule mock properties (isError, isSuccess, isLoading, dataUpdatedAt)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* revert

* fix

* fix

* fix

* fix build

* fix

* fix

* fix

* fix: correct AddMembersWithSwitch test wrapper to use initial assignAllTeamMembers value

- Fixed test wrapper to initialize useState with componentProps.assignAllTeamMembers
  instead of hardcoded false, allowing tests to properly test different states
- Updated test expectations for ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_NOT_APPLICABLE
  state to match actual component behavior (toggle should be present and checked)
- Fixed 'should show Segment when toggled on' test to start with assignAllTeamMembers: false
  to properly test the flow of enabling it
- Added explicit types to satisfy biome lint requirements

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use JSX.Element instead of React.JSX.Element for type compatibility

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-05 12:53:51 -03:00
Keith WilliamsandDevin AI 3d73238c00 fix: remove installation requirement from trusted bot check (#26466)
* fix: remove installation requirement from trusted bot check

The installation object is not present in the webhook payload when
GitHub Apps add labels via pull_request_target events. This caused
graphite-app[bot] to fail the authorization check and fall through
to the human permission check, which doesn't work for bots.

The fix removes the installation requirement and relies on:
- sender.type === 'Bot'
- sender.login matching the trusted bot list

This is secure because the sender fields come from GitHub's webhook
payload and cannot be forged by contributors.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: add extra logging about sender type

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove senderId from logging

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Update run-ci.yml

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-05 15:19:39 +00:00
bbfb17ae5c feat: update translations via @LingoDotDev (#26445)
Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-05 15:18:03 +00:00
Keith WilliamsandDevin AI 3ab6d9096e fix: cancel running CI workflow before re-triggering and allow trusted GitHub Apps (#26461)
* fix: cancel running CI workflow before re-triggering and allow trusted bots

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove hardcoded bot allowlist, keep only cancel-and-rerun improvement

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add app_id verification for trusted GitHub Apps (Graphite)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: simplify trusted bot check to use sender type, login, and installation context

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove unnecessary comments

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-05 11:58:20 -03:00
Pedro Castro 0109427d04 fix(auth): make identityProviderId lookup case-insensitive (#26405)
SAML IdPs may send NameIDs with different casing than stored, causing login failures.
Aligns with the existing case-insensitive email lookup pattern
2026-01-05 14:00:11 +00:00
sean-brydonandDevin AI f8e70517d1 fix: add @calcom/trpc#build dependency to @calcom/web#dev task (#26460)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-05 13:43:53 +00:00
Hariom Balhara e61e66ec34 chore: Ensure that uuid is available in server session[Booking Audit Prerequisite] (#25963)
## What does this PR do?

Similar to #25721, adds uuid in session so that BookingAudit has it readily available

Adds the user's UUID to the booking metadata by:
1. Extending the NextAuth `User` interface to include an optional `uuid` property from PrismaUser
2. Making `uuid` required on `Session.user` via intersection type (`User & { uuid: PrismaUser["uuid"] }`)
3. Adding `uuid` to the session user object in `getServerSession.ts`
4. Adding `uuid` to the `AdapterUser` transformation in `next-auth-custom-adapter.ts`
5. Passing `userUuid` from the session to the booking creation flow
6. Updating the API key verification flow to include `uuid` in the user data (repository, service, and type definitions)
7. Adding `req.userUuid` as a required field on the request object (like `req.userId`)
8. Adding `uuid` to mock session objects in web app routes and test context
9. Adding `uuid` to the `findByEmailAndIncludeProfilesAndPassword` query in UserRepository

Also removes commented-out code that was placeholder for future work and fixes lint warnings for unused variables.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Verify that the NextAuth session callback is already populating the `uuid` field on the user object
2. Create a booking and confirm `userUuid` is included in the booking metadata
3. Test API v1 endpoints (`/api/invites` POST and `/api/teams/[teamId]/publish`) to verify they receive the uuid from the authenticated user
4. Check that the booking flow works correctly with the new parameter
5. Test SAML login flow to verify session still works correctly (uuid is resolved from database after authentication)

## Human Review Checklist

- [ ] Verify the NextAuth session callback populates `uuid` - if not, this change will pass `undefined` at runtime
- [ ] Confirm `userUuid` is consumed downstream in the booking service
- [ ] Verify that `PrismaApiKeyRepository.findByHashedKey()` correctly fetches the user's uuid from the database
- [ ] Verify the discriminated union type in `ApiKeyService.ts` ensures `result.user` is always defined when `result.valid` is true
- [ ] Confirm all API v1 endpoints using `req.userUuid` go through the `verifyApiKey` middleware
- [ ] Verify `UserRepository.findByEmailAndIncludeProfilesAndPassword()` includes `uuid` in the select clause
- [ ] Verify SAML login still works correctly - uuid is now optional on User interface so SAML providers don't need to supply it at profile stage

## Updates since last revision

- **Made uuid optional on User, required on Session**: Changed the type strategy so `uuid` is optional on the NextAuth `User` interface but required on `Session.user` via intersection type. This allows SAML providers to not supply uuid at the profile stage while ensuring uuid is always present on the session after the user is resolved from the database.
- **Removed uuid from SAML functions**: Since uuid is now optional on User, the SAML profile and authorize functions no longer need to include it.

---

Link to Devin run: https://app.devin.ai/sessions/97e5603b719a420b9b35041252c9db26
Requested by: hariom@cal.com (@hariombalhara)
2026-01-05 17:24:30 +05:30
Hariom BalharaandDevin AI 9d39590510 feat: create BookingHistoryViewerService to combine audit logs with routing form submissions (#26045)
* feat: create BookingHistoryViewerService to combine audit logs with routing form submissions

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor(booking): rename audit log query and enhance type safety

- Updated the booking logs view to use the new getBookingHistory query instead of getAuditLogs.
- Introduced DisplayBookingAuditLog type for improved clarity in BookingAuditViewerService.
- Refactored BookingHistoryViewerService to utilize the new DisplayBookingAuditLog type and added sorting functionality for history logs.
- Adjusted related types and methods to ensure consistency across services.

* refactor(routing-forms): streamline imports and enhance type definitions

- Consolidated type exports and imports from the features library for better organization.
- Removed redundant type definitions and functions in zod.ts, findFieldValueByIdentifier.ts, getFieldIdentifier.ts, and parseRoutingFormResponse.ts.
- Introduced new utility functions for handling field responses and parsing routing form responses.
- Improved type safety and clarity across routing form response handling.

* fix: remove double prefix from uniqueId in form submission entry

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* 1c97f9cc5d50416788c01876fe539bcc9750e9b2 (#26453)

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-05 11:11:05 +00:00
a7fd7890a7 feat: integrate BookingHistory with Bookings V3 design (#26301)
* Integrate BookingHistory with Bookings V3 design

* Enhance booking features by integrating booking audit functionality

- Updated the booking page to retrieve user feature statuses for "bookings-v3" and "booking-audit".
- Modified BookingDetailsSheet and BookingListContainer components to accept and utilize the new bookingAuditEnabled prop.
- Adjusted the BookingHistory display logic to conditionally render based on the bookingAuditEnabled state.
- Refactored SegmentedControl to support generic types for better type safety.

This change improves the user experience by allowing conditional access to booking audit features based on user permissions.

* Refactor BookingDetailsSheet to manage active segment state with Zustand store

- Removed local state management for active segment in BookingDetailsSheet and integrated Zustand store for better state synchronization.
- Introduced useActiveSegmentFromUrl hook to sync active segment with URL query parameters.
- Updated BookingDetailsSheet to handle derived active segment logic based on bookingAuditEnabled state.
- Adjusted SegmentedControl to ensure it defaults to "info" when activeSegment is null.

This refactor enhances the maintainability and responsiveness of the booking details component.

* refactor: rename useBiDirectionalSyncBetweenZustandAndNuqs to useBiDirectionalSyncBetweenStoreAndUrl

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-05 16:21:35 +05:30
87cf3210dc feat: queue or cancel payment reminder flow (#24889)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2026-01-05 08:10:55 +00:00
Anik Dhabal Babu acee514c42 fix: show empty screen from event type availability tab (#26396)
* fix

* update

* fix

* Remove copying of App Store static files step

Removed step to copy App Store static files from the workflow.
2026-01-05 10:40:14 +05:30
Keith WilliamsandDevin AI 64b2cf0577 fix(ci): add yarn prisma generate before cache key generation (#26439)
This ensures consistent cache keys between the Build Web App job and E2E
shards by running yarn prisma generate before generating the cache key.

The issue was that packages/prisma/enums/index.ts is:
1. Generated by yarn prisma generate
2. In .gitignore (not committed to git)
3. Included in the SOURCE_HASH (matches packages/**/**.[jt]s)
4. NOT excluded from the hash

E2E jobs already run yarn prisma generate before cache-build, but the
Build Web App job did not, causing different cache keys in the same
workflow run.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-04 21:38:22 -03:00
Keith WilliamsandDevin AI aca3b1ecdb fix(ci): delete old prod build caches on cache miss (#26437)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-04 18:26:01 -03:00
Hariom Balhara 897c9d65f0 fix(auth): enhance SAML login handling by introducing userId field and updating JWT token structure (#26428) 2026-01-04 19:44:54 +00:00
Dhairyashil Shinde c1e5e0ae66 feat(companion): new availability detail and actions pages for ios (#26424)
* version 1

* version 1.1

* better code

* covered all edge cases

* address cubics comments

* address cubics comments
2026-01-04 12:48:37 -03:00
Abhay Mishra f9dc3f2f9c fix(seed): add missing Host entries for seeded round‑robin team events (#26426) 2026-01-04 10:00:37 +00:00
Kartik Labhshetwar c6e74e6e25 fix: add vertical spacing when hovered (#26419) 2026-01-03 21:30:31 +00:00
Beto 285f161e68 refactor(companion): event type details screen improvements (#26415)
* refactor(companion): move EventTypeDetail component to a new file and update routing

* refactor(companion): format code for better readability in TabLayout and EventTypeDetail components

* refactor(companion): improve code formatting and readability in EventTypeDetail component

* refactor(companion): enhance code readability and formatting in EventTypeDetail component

* refactor(companion): improve code formatting and readability in EventTypeDetail component

* refactor(companion): enhance code formatting and readability in EventTypeDetail component

* refactor(companion): improve code formatting and readability in TabLayout component
2026-01-03 17:54:37 +00:00
shashank-100 9c08c5fed1 fix: patch React 19 vulnerabilities by upgrading to 19.2.3 (#26411)
* security: patch React 19 vulnerabilities by upgrading to 19.2.3

* chore: revert lingo.dev upgrade
2026-01-03 14:20:08 +00:00
Beto 0c724dd229 fix: update bundle identifier (#26402) 2026-01-03 18:40:28 +05:30
Eesh Midha 78826a37a1 fix: Make incomplete booking form mobile-responsive (#26413) 2026-01-03 13:02:14 +00:00
Joe Au-Yeung 048a9b04fa chore: add logging in next-auth (#26404)
* Add logging in next-auth
* Add logging at other return
2026-01-02 20:30:09 -03:00
Dhairyashil Shinde 60a4d3f2b4 feat(companion): Add DropdownMenu and Alert Dialog for Android (#26385)
* feat(companion): add DropdownMenu for Android event types list

Replace Alert.alert with react-native-reusables DropdownMenu component
for Android event type list items, providing a native-feeling menu
experience that matches iOS functionality.

Changes:
- Install react-native-reusables dropdown-menu component and dependencies
  (lucide-react-native, tailwindcss-animate, class-variance-authority,
  clsx, tailwind-merge)
- Create EventTypeListItem.android.tsx with DropdownMenu implementation
  - Single ellipsis button triggers dropdown menu
  - Menu includes: Preview, Copy link, Edit, Duplicate, Delete
  - Delete action marked as destructive variant
  - Proper safe area insets handling
- Add PortalHost to app/_layout.tsx for portal rendering support
- Create lib/utils.ts with cn() helper for className merging
- Update global.css with theme CSS variables (popover, border, accent,
  destructive, etc.) for dropdown menu styling
- Update tailwind.config.js with theme colors and tailwindcss-animate plugin
- Update metro.config.js with inlineRem: 16 for proper rem unit handling
- Remove Android Alert.alert fallback from event types index.tsx
- Fix lint issues in generated dropdown-menu.tsx (remove unnecessary fragments)

The Android experience now matches iOS with a single menu button that
opens a dropdown containing all event type actions, replacing the
previous Alert.alert dialog and separate action buttons.

Refs: https://reactnativereusables.com/docs/components/dropdown-menu

* adjust with of menu

* feat(companion): add DropdownMenu for Android booking and availability list items

- Add BookingListItem.android.tsx with DropdownMenu for booking actions
- Add BookingDetailScreen.android.tsx with DropdownMenu in header
- Add AvailabilityListItem.android.tsx with DropdownMenu for schedule actions

Actions include: Reschedule, Edit Location, Add Guests, View Recordings,
Meeting Session Details, Mark as No-Show, Report Booking, Cancel Event
for bookings; Set as Default, Duplicate, Delete for availability schedules.

* fix lint issues

* feat(android): replace native alerts with AlertDialog and Toast in event types

- Install AlertDialog and Alert components from react-native-reusables
- Create Android-specific event types screen (index.android.tsx)
- Replace native Alert.alert() with AlertDialog for delete confirmation
- Add inline validation errors (red border + error text) in create modal
- Implement Toast snackbar for success/error notifications (no layout shift)
- Auto-dismiss toast after 2.5 seconds
- Fix React Compiler compatibility by removing animated refs

This provides a more consistent and polished UI experience on Android,
matching the design system used in other parts of the app.

* feat(android): add AlertDialog for availability delete and booking cancel

- Add index.android.tsx for availability with AlertDialog for delete confirmation
- Add index.android.tsx for bookings with AlertDialog for cancel (with reason input)
- Both screens include Toast snackbar for success/error notifications
- Follows the same pattern as event types Android implementation

* feat(companion): add DropdownMenu and AlertDialog for Android

- Replace native Alert.alert context menus with DropdownMenu component
  for event types, bookings, and availability lists
- Replace FullScreenModal with AlertDialog for create/delete/cancel flows
- Add toast notifications for success/error feedback on Android
- Set consistent 380px max-width for all AlertDialogs
- Fix layout headers showing "index" text on event-types and availability
- Create Android-specific More screen with AlertDialog logout confirmation

Uses react-native-reusables components for polished Android UI

* better code

* fix cubics comments

* refactor(android): revert delete confirmations to native Alert.alert()

- Logout: reverted to native Alert.alert() (simple yes/no)
- Event Types Delete: reverted to native Alert.alert() (simple yes/no)
- Availability Delete: reverted to native Alert.alert() (simple yes/no)

Keep AlertDialog only where user input is needed:
- Event Types Create (has TextInput for title)
- Availability Create (has TextInput for name)
- Bookings Cancel (has TextInput for cancellation reason)

* refactor(android): remove redundant index.android.tsx files

The main index.tsx files already handle Android via Platform.OS checks.
Android-specific behavior for actions is in the list item components:
- EventTypeListItem.android.tsx
- BookingListItem.android.tsx
- AvailabilityListItem.android.tsx

This consolidates the code and reduces duplication.

* corrected the implementation both native and alert dialog

* address cubics comments

* fix lint issue and address cubic comments
2026-01-02 19:05:26 -03:00
Manas Kenge c58e0ca783 fix: Custom time input for availability (#26373)
* add custom time input

* add unit test

* add validation logic
2026-01-02 18:06:01 +00:00
Alex van Andel 0099c72f53 chore: release v6.0.7
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2026-01-02 16:32:27 +00:00
Pedro Castro 421936dc14 fix(auth): resolve session user by token subject ID (#26399)
* fix(auth): align session user resolution with token subject

* test(auth): add unit tests for getServerSession user resolution
2026-01-02 16:31:08 +00:00
Ram Shukla 6a6b98388a matched colour of icons across website (#26394) 2026-01-02 14:52:14 +00:00
Anik Dhabal Babu e9fac51f99 feat(ci): skip API v2 breaking changes check when unrelated files change (#26393) 2026-01-02 10:47:12 -03:00
Volnei Munhoz a1e5384859 Prefix node protocol (#26391) 2026-01-02 12:47:00 +00:00
Volnei Munhoz fed6899c36 disable noExcessiveLinesPerFunction-off-for-tests for tests (#26388) 2026-01-02 10:56:24 +00:00
Manas Kenge 8bc710eb6e fix: make delete confirmation consistent across schedules (#26300)
* add delete dialog

* add types
2026-01-02 10:54:40 +00:00
Anik Dhabal Babu 9d5983d32d test: flaky e2e tests (#26386) 2026-01-02 07:08:11 -03:00
18b041514f refactor(ui): remove unused components and exports (#26222)
Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-02 04:11:14 +00:00
Keith Williams c7a80abcba chore: Make atoms cache-key more reusable (#26384) 2026-01-02 02:48:04 +00:00
Keith WilliamsandDevin AI 20c67ef101 fix: handle non-deterministic AES-256-CBC decryption in crypto test (#26383)
AES-256-CBC doesn't guarantee throwing on wrong key decryption - it depends
on whether the decrypted bytes happen to have valid PKCS#7 padding. The test
now verifies that decryption either throws OR returns a value different from
the original plaintext.

This fixes flaky test failures that started appearing after the Vitest 4.0
upgrade, where the 'Closing rpc while fetch was pending' error was a secondary
symptom of the test failure causing worker teardown during module loading.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-01 23:18:35 -03:00
Keith WilliamsandDevin AI 966d4b5cc6 fix: address flaky E2E tests (#26374)
* fix: address flaky E2E tests

- booking-pages.e2e.ts: Use selectFirstAvailableTimeSlotNextMonth helper instead of brittle nth(1) selector to avoid race condition where time slots become unavailable
- fixtures/users.ts: Add retryOnNetworkError helper to handle transient ECONNRESET errors during apiLogin
- lib/testUtils.ts: Add waitForLoadState('networkidle') to goToUrlWithErrorHandling to ensure page is fully loaded before checking URL
- teams.e2e.ts: Add explicit wait for publish button visibility before clicking to avoid timeout
- unpublished.e2e.ts: Change from parallel to serial mode to avoid database deadlocks from concurrent writes

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: consolidate unpublished.e2e.ts tests to reduce concurrent DB writes

Instead of using serial mode, consolidate related tests into single test
functions that share setup data. This reduces concurrent users.create()
and users.deleteAll() calls from 7 to 3, significantly reducing the
chance of database deadlocks while maintaining parallel execution.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: only fail goToUrlWithErrorHandling on main navigation requests

The previous fix was incorrectly resolving the promise when any request
failed (like images, RSC requests, etc.), causing the URL check to fail.

Now we only consider it a navigation failure if:
- request.isNavigationRequest() is true
- request.frame() === page.mainFrame()

Also added a resolved flag to prevent multiple resolutions and removed
the networkidle wait which was causing issues.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-01 23:17:01 -03:00
Keith WilliamsandDevin AI af110633c1 refactor: detach yarn prisma generate from yarn-install action (#26382)
* refactor: detach yarn prisma generate from yarn-install action

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add run-prisma-generate input for backward compatibility

The yarn-install action now has a run-prisma-generate input that defaults
to true for backward compatibility. This ensures CI works correctly since
workflow files are pulled from the base branch (main) while actions are
pulled from the PR branch.

Workflows that have explicit yarn prisma generate steps now set
run-prisma-generate: false to avoid running it twice after merge.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: completely remove prisma generate from yarn-install action

Remove all prisma-related code from the yarn-install action:
- Remove the run-prisma-generate input parameter
- Remove the Generate Prisma client step

Remove explicit yarn prisma generate steps from all workflow files.

Prisma generation is now handled by the postinstall script in package.json
which runs 'turbo run post-install' after yarn install. This triggers
@calcom/prisma#post-install which runs 'prisma generate && prisma format'.

This makes the yarn-install action have no knowledge of Prisma at all,
as requested.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add generic post-install step to ensure generated files are up-to-date

When all caches are hit, yarn install completes quickly without running
the postinstall script. This means generated files (like Prisma types)
may not be created.

Add a generic 'turbo run post-install' step that runs after yarn install
to ensure all post-install tasks complete regardless of cache state.
This keeps the action from having Prisma-specific knowledge while
ensuring the post-install pipeline runs.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: remove post-install step from yarn-install action

Remove the turbo run post-install step as requested. The yarn-install
action now only handles yarn install with caching, with no knowledge
of post-install tasks or Prisma generation.

Let CI show what fails without explicit post-install handling.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Add back Prisma schema loaded from schema.prisma

✔ Generated Prisma Client (6.16.1) to ./generated/prisma in 442ms

✔ Generated Zod Prisma Types to ./zod in 1.43s

✔ Generated Kysely types (2.2.0) to ./../kysely in 271ms

✔ Generated Prisma Enum Generator to ./enums/index.ts in 176ms where needed

* Adding Prisma schema loaded from schema.prisma

✔ Generated Prisma Client (6.16.1) to ./generated/prisma in 451ms

✔ Generated Zod Prisma Types to ./zod in 1.40s

✔ Generated Kysely types (2.2.0) to ./../kysely in 271ms

✔ Generated Prisma Enum Generator to ./enums/index.ts in 205ms where needed for E2E

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-01 23:00:56 -03:00
Beto 919827707f feat: add .easignore file to manage EAS build uploads for the companion app (#26375)
- Introduced a new .easignore file to specify which files and directories to ignore during EAS builds.
- Configured to only upload the companion app folder while excluding unnecessary build artifacts and dependencies.
2026-01-02 00:40:17 +00:00
Keith WilliamsandDevin AI b66797a3af fix: remove PR/commit-specific keys from docs-build cache (#26379)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-02 00:21:04 +00:00
Volnei Munhoz 94f18f6f9c chore: disable lint staged from merge main (#26380) 2026-01-01 21:13:12 -03:00
Keith WilliamsandDevin AI 64dcf5d3f6 fix: add cleanup and mock embed-iframe to prevent test teardown leak (#26377)
* fix: add cleanup and mock embed-iframe to prevent test teardown leak

The CancelBooking.cancellationFee.test.tsx was causing an unhandled jsdom
exception during test teardown due to the @calcom/embed-core/embed-iframe
module scheduling timers that would fire after the jsdom environment was
destroyed.

Changes:
- Mock @calcom/embed-core/embed-iframe to prevent sdkActionManager from
  scheduling timers during tests
- Add afterEach cleanup to ensure React Testing Library properly cleans up
  between tests
- Remove unused React import

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add afterAll cleanup to restore scrollIntoView and unmock embed-iframe

Add proper cleanup in afterAll to:
- Restore Element.prototype.scrollIntoView to its original value
- Call vi.unmock for embed-iframe to avoid polluting other tests in the same worker

This prevents cross-test pollution that was causing flaky 'Closing rpc while fetch was pending' errors in other test files running in the same Vitest worker.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add cleanup to TestFormDialog and defer imports in editLocation.handler tests

- TestFormDialog.test.tsx: Add fake timers and flush pending timers before cleanup
  to prevent Radix FocusScope setTimeout from firing after jsdom teardown
- editLocation.handler.test.ts: Remove top-level imports to prevent watchlist
  module loading during test collection (tests are already skipped)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: defer imports in confirm.handler.test.ts to prevent Salesforce GraphQL module loading

Tests are already skipped, so imports are not needed during collection phase.
This prevents 'Closing rpc while fetch was pending' errors from Salesforce GraphQL module imports.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-02 00:10:55 +00:00
Keith WilliamsandDevin AI 8ef7b56b37 feat: re-trigger pr.yml when ready-for-e2e label is added (#26376)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-01 20:42:12 -03:00
Pedro Castro 40dd546429 chore(deps): update dependencies and add version constraints (#26328)
* chore(deps): update dependencies and add version constraints

 - Update direct dependencies: body-parser, @nestjs/swagger, react-use, trigger.dev
 - Add resolutions for consistent dependency versions across the monorepo
 - Add packageExtensions to ensure compatible transitive dependency versions

* fix: upgrade rollup resolution from 3.29.5 to 4.22.4

 Rollup 3.x is incompatible with vite 5.x which requires rollup ^4.20.0.
 The previous resolution caused CI failures due to missing ./parseAst
 export

* fix: update axios resolution to 1.13.2

Align resolution with direct dependency in apps/api/v2.
Both versions include the fix, but 1.13.2 is newer and
avoids an unnecessary downgrade
2026-01-01 23:18:53 +00:00
Beto 6bdb08317d feat(companion): update app logo and splash screen (#26372)
* feat(companion): add ios logo

* update app.json to use new icon for iOS

* refactor: update app.json and icon.json for improved formatting and naming consistency

* feat: add expo-splash-screen plugin and update app.json configuration

* chore: update adaptive icon

* chore: update adaptive icon
2026-01-01 18:49:52 -03:00
Dhairyashil ShindeandVolnei Munhoz 6339f77efc feat(companion): booking actions ios ui update (#26307)
* feat(companion): add native iOS UI components for modals and pickers

- Add LogoutConfirmModal.ios.tsx using native Alert.alert()
- Add BookingModals.ios.tsx using native Alert.prompt() for reject modal
- Add RescheduleScreen.ios.tsx using @expo/ui/swift-ui DateTimePicker

These iOS-specific implementations provide native glass UI experience
instead of custom React Native modals.

* fix(companion): use correct DatePicker API from @expo/ui/swift-ui

- Change import from DateTimePicker to DatePicker
- Use onDateChange instead of onDateSelected
- Use displayedComponents as array instead of string
- Use selection instead of initialDate

* feat(companion): add native Android DateTimePicker for RescheduleScreen

- Use @expo/ui/jetpack-compose DateTimePicker for native Android date/time selection
- Use variant='picker' with showVariantToggle=false for consistent UI
- Use displayedComponents='date' for date picker and 'hourAndMinute' for time picker
- Use is24Hour=true for 24-hour time format

* Revert "feat(companion): add native Android DateTimePicker for RescheduleScreen"

This reverts commit 95677679c2e86889b935e658fac011ae9669fa10.

* adjust date and time picker for ios, and use native ios ui for delete event type

* feat(companion): add native Android DateTimePicker and web HTML inputs for RescheduleScreen

- Add RescheduleScreen.android.tsx using @react-native-community/datetimepicker for native Android date/time pickers
- Update RescheduleScreen.tsx to use native HTML date/time inputs on web/extension
- Install @react-native-community/datetimepicker package

* fix lint errors

* use expos date and time picker for android

* address cubics comments

* remove dependancy causing android build fail

* fix versions

* custom date and time picker for android

* fix react compiler memo issue

* address cubics commments

* feat(companion): convert booking action pages to native iOS bottom sheets (#26366)

* feat(companion): add native iOS bottom sheet for meeting session details

* move file to correct location, remove bg and use glass ui bg

* feat(companion): convert booking action pages to iOS bottom sheets

- Add iOS-specific bottom sheet implementations for:
  - edit-location (detents: 0.5, 0.7)
  - mark-no-show (detents: 0.4, 0.6)
  - view-recordings (detents: 0.7, 0.9)
  - add-guests (detents: 0.6, 0.8)
  - reschedule (detents: 0.8, 0.95)
- Move route files from (tabs)/(bookings)/ to root app/ level
- Register screens in root _layout.tsx with platform-specific options
- Update navigation paths from nested to root level
- Remove migrated screens from bookings _layout.tsx

* updated booking actions pages to use glass ui bottom sheet

* new ui for booking actions ready

* add biome file

* fix event type detail react compiler issue

* update button style

* fix black flash ui

* use glass ui buttons for Availability and event type detail page

* fix lint issue

* address cubics comments

* make booking actions ui transparent

* remove black flash and keep transparent ui

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-01 18:48:30 -03:00
bbf9274d37 chore: upgrade Vitest to 4.0.16 and Vite to 6.4.1 (#26351)
* chore: upgrade Vitest to 4.0.16 and Vite to 6.4.1

- Update vitest from 2.1.9 to 4.0.16
- Update @vitest/ui from 2.1.9 to 4.0.16
- Update vitest-fetch-mock from 0.3.0 to 0.4.5
- Update vitest-mock-extended from 2.0.2 to 3.1.0
- Update vite from 4.5.14/5.4.21 to 6.4.1 across all packages
- Update @vitejs/plugin-react to 5.1.2
- Update @vitejs/plugin-react-swc to 4.2.2
- Update @vitejs/plugin-basic-ssl to 2.1.0
- Update vite-plugin-dts to 4.5.4
- Rename vitest.config.ts to vitest.config.mts for ESM compatibility
- Add globals: true to vitest config

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: address Vitest 4.0 and Vite 6 breaking changes

- Convert arrow function mockImplementation patterns to regular functions
  (Vitest 4.0 breaking change: arrow functions can't be constructor mocks)
- Fix CSS imports with ?inline suffix for Vite 6 compatibility
- Add biome override to disable useArrowFunction rule for test files
- Fix syntax errors in test files introduced by regex replacements

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: fix remaining Vitest 4.0 constructor mock patterns

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: fix more Vitest 4.0 constructor mock patterns and exclude API v2 spec files

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert more arrow function mocks to regular functions for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert more arrow function mocks to regular functions for Vitest 4.0

- Fix CrmService.integration.test.ts jsforce.Connection mock
- Fix RetellSDKClient.test.ts Retell mock
- Fix RetellAIService.test.ts CreditService mocks
- Fix GoogleCalendarSubscriptionAdapter.test.ts CalendarAuth mock

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert Google Calendar and OAuthManager arrow function mocks for Vitest 4.0

- Fix googleapis.ts Calendar, OAuth2Client, and JWT mocks
- Fix utils.ts JWT mock
- Fix OAuthManager.ts defaultMockOAuthManager mock

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add React plugin, jsdom environment, and fix more constructor mocks for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert HostRepository PrismaClient mock to regular function for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add useOrgBranding mock to React component tests for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: update TestFunction type for Vitest 4.0 compatibility

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert listBookingReports constructor mocks to regular functions for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert UserRepository constructor mock to regular function for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert OrganizationPaymentService constructor mock to regular function for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert more constructor mocks to regular functions for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add apps/web path aliases to vitest config

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: fix test issues for Vitest 4.0 compatibility

- Fix Response constructor 204 status code issue in testUtils.ts
- Fix FeaturesRepository mock persistence in handleNotificationWhenNoSlots.test.ts
- Add @vitest-environment node directive to formSubmissionUtils.test.ts
- Fix document.querySelector mock in embed.test.ts

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: clear EventManager spy between tests for Vitest 4.0 compatibility

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: update TeamRepository mock pattern for Vitest 4.0 compatibility

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert RoutingFormResponseRepository mock to regular function for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: convert more constructor mocks to regular functions for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: fix mock reset and spy clear issues for Vitest 4.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: fix remaining test failures for Vitest 4.0 upgrade

- Fix booking-validations.test.ts: convert UserRepository mock to regular function
- Fix route.test.ts: update 500 error test to mock ImageResponse instead of fetch
- Fix users-public-view.test.tsx: add missing mocks for getOrgFullOrigin and useRouterQuery
- Add @calcom/web path alias to vitest config

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add vitest-mocks for generated files that don't exist in CI

- Add svg-hashes.json mock for route.test.ts
- Add tailwind.generated.css mock for embed.test.ts
- Update vitest config to use mock files

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: update vitest config aliases for CI compatibility

- Use array format for aliases to ensure proper ordering
- Add @calcom/platform-constants alias to resolve from source
- Add @calcom/embed-react alias to resolve from source
- Ensure svg-hashes.json mock alias is matched before @calcom/web

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add @calcom/embed-snippet alias for CI compatibility

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Fix wrong test

* fix: migrate from CLI flags to VITEST_MODE env var for Vitest 4.0

Vitest 4.0 no longer allows custom CLI flags like --packaged-embed-tests-only.
This change migrates to using VITEST_MODE environment variable instead:
- VITEST_MODE=packaged-embed for packaged embed tests
- VITEST_MODE=integration for integration tests
- VITEST_MODE=timezone for timezone-dependent tests

Updated vitest.config.mts to handle mode-based include/exclude patterns.
Updated CI workflows and package scripts to use the new env var approach.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: return default include pattern instead of undefined in vitest config

The getTestInclude() function was returning undefined for the default case,
but Vitest 4.0 expects an array. This caused 'resolved.include is not iterable'
error in CI.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: always set INTEGRATION_TEST_MODE for jsdom environment

The getBookingFields.ts file checks for INTEGRATION_TEST_MODE to allow
server-side imports in the jsdom environment. Without this, tests fail
with 'getBookingFields must not be imported on the client side' error.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: support legacy CLI flags for backwards compatibility with main workflow

The CI runs workflows from main branch, which uses the old CLI flag approach
(yarn test -- --integrationTestsOnly). This commit adds backwards compatibility
by checking both VITEST_MODE env var and process.argv for the legacy flags.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-01 18:16:10 -03:00
Beto b8e9b9eb3f refactor(companion): remove react-native-context-menu-view dependency and enhance profile button with user avatar support (#26357)
- Removed `react-native-context-menu-view` from `package.json` and `bun.lock`.
- Updated profile button in `Availability`, `EventTypesIOS`, and `More` components to display user avatar if available, enhancing user experience.
- Cleaned up code formatting for better readability.
2026-01-02 01:48:34 +05:30
Mohit Balwani 02a86f1db0 fix: replace title with aria-label to avoid multiple tooltips (#26370) 2026-01-01 20:02:30 +00:00
Benny Joo d97a55ed6d chore: Bump biome rule level from warn to error for rules that prevent circular dependency between packages (#26364) 2026-01-01 16:48:16 +00:00
Keith WilliamsandDevin AI 50675593fa refactor: simplify api-v1-production-build cache key for durability (#26365)
* feat: add cache-api-v1-build-key action for durable caching

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: simplify cache key inline instead of separate action

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-01 14:22:03 +00:00
128d15ea8f fix: ensure proper async handling in delegation credentials (#25898)
* fix: ensure proper async handling in ensureDefaultCalendars

Replace forEach(async...) with Promise.allSettled to ensure:
- Caller properly awaits completion
- Errors are captured and logged
- All users are processed even if some fail

Adds unit tests for ensureDefaultCalendars

* fix: use correct Jest assertion pattern for async test

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 19:30:26 +00:00
Pedro CastroandKeith Williams b08997b553 fix: remove debug logs and clean up verbose logging (#25896)
- Remove debug console.log statements in calendar and video adapter services
- Clean up verbose request/response logging in OAuth controllers
- Remove leftover debug prefixes

Ensure only necessary data is captured in observability systems

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-31 19:12:28 +00:00
Keith WilliamsandDevin AI 486817a688 fix: add timeout: 0 to E2E assertions that check for absence of elements (#26353)
This fixes hanging E2E tests where assertions like toHaveCount(0) and
not.toBeVisible() would wait for the full timeout (10s in CI, 120s locally)
before failing, instead of failing immediately.

These assertions are 'state check' assertions that verify an element is
already absent or hidden, rather than waiting for it to become so.
Adding { timeout: 0 } makes them fail immediately if the condition is not met.

Files updated:
- locale.e2e.ts: 16 instances of toHaveCount(0)
- booking-seats.e2e.ts: 8 instances of toHaveCount(0)
- organization-redirection.e2e.ts: 3 instances of toHaveCount(0)
- organization-creation-flows.e2e.ts: 5 instances of not.toBeVisible()
- insights-charts.e2e.ts: 1 instance of toHaveCount(0)
- bookings-list.e2e.ts: 1 instance of toHaveCount(0)
- availability.e2e.ts: 1 instance of toHaveCount(0)
- managed-event-types.e2e.ts: 1 instance of toHaveCount(0)
- team-invitation.e2e.ts: 1 instance of toHaveCount(0)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 14:58:20 -03:00
BetoandVolnei Munhoz 4563194fcf feat(companion): update deps to sdk 55 canary (#26348)
* update deps

* chore: remove companion biome configuration and update main biome.json ignore patterns

* chore: update expo and react dependencies in bun.lock

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2025-12-31 16:38:15 +00:00
Keith WilliamsandDevin AI c959fffb12 fix: reduce default Playwright test timeout from 60s to 30s in CI (#26345)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 13:33:13 -03:00
Volnei Munhoz ed14219e44 upgrade typescript (#26347) 2025-12-31 13:32:55 -03:00
Keith WilliamsandDevin AI 59ba1754fe fix: use stable test dates in duplicate API calls E2E tests (#26349)
The tests were failing on December 31 because they used new Date() which
caused month boundary issues with the prefetch logic. This change uses
a fixed future date (July 2030) to ensure consistent test behavior
regardless of when the tests are run.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 13:05:11 -03:00
Keith WilliamsandDevin AI 16f6099e46 ci: simplify DB cache key and skip yarn-install on cache hit (#26344)
* ci: skip yarn-install in setup-db when DB cache exists

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: skip entire setup-db job when DB cache exists

This saves ~35-40s per workflow run by:
1. Adding DB cache lookup to prepare job (lookup-only mode)
2. Skipping the entire setup-db job when cache exists (avoids postgres container startup)
3. Keeping the yarn-install skip in setup-db.yml as a fallback

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: simplify DB cache key and skip yarn-install on cache hit

- Remove commit SHA and PR number from cache key for better reuse
- Cache key now only depends on prisma schema/migrations hash
- Skip yarn-install in setup-db when DB cache exists (saves ~17s)
- Revert changes to pr.yml required job logic

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: move DB cache lookup to prepare step and skip cache-db on hit

- Move cache lookup to pr.yml prepare step for early detection
- Pass db-cache-hit output to setup-db.yml as input
- Skip yarn-install and cache-db action when cache exists
- setup-db job still runs and reports success (no required job changes)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: skip container initialization when DB cache exists

- Rename setup-db to setup-db-seed (only runs on cache miss)
- Add lightweight setup-db wrapper job that always returns success
- When cache exists: setup-db-seed is skipped, setup-db returns success
- When cache miss: setup-db-seed runs with postgres, setup-db checks result
- This avoids postgres container startup (~17-20s) when cache exists

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: add cache-db-key action for consistent cache key generation

- Create cache-db-key action to generate DB cache key in one place
- Update cache-db action to use cache-db-key for consistency
- Update pr.yml prepare step to use cache-db-key for lookup
- This ensures the lookup key always matches the actual cache key

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: remove runner.os from cache-db-key

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: simplify setup-db by removing wrapper job

- Remove setup-db wrapper job and rename setup-db-seed back to setup-db
- setup-db is now skipped when cache exists (no container startup)
- Update required check to allow skipped for setup-db when cache hit

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: revert to two-job pattern for setup-db

- setup-db-seed: only runs on cache miss (has postgres container)
- setup-db: wrapper that always runs and reports success
- This ensures downstream jobs (Tests, Production builds) are not skipped
- Reverts required check to simple setup-db.result != 'success'

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: single setup-db job with conditional steps on cache hit

- Removed two-job pattern (setup-db-seed + wrapper)
- Single setup-db job calls setup-db.yml reusable workflow
- Pass DB_CACHE_HIT input from prepare job's db-cache-hit output
- Skip yarn-install and cache-db steps when cache hit (~17s savings)
- Container still starts (will optimize in follow-up)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 19:47:31 +05:30
Tamal ChakrabortyandAnik Dhabal Babu 6451b7e013 fix: removed weird scrollbar from apps/intalled/ navigation (#26336)
* fix: removed weird scrollbar from apps/intalled navigation

* revert accidental changes to ./yarn.lock

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-31 13:57:39 +00:00
3704324474 feat: update translations via @LingoDotDev (#26340)
Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-31 13:31:47 +00:00
17224d9df3 ci: reduce e2e-api-v2 test overhead with caching and Jest optimizations (#26331)
* perf: increase E2E test shards from 4 to 6 for faster CI

Increase the number of parallel E2E test shards from 4 to 6 to reduce
overall CI wall-clock time. Each shard runs on a separate 4-vCPU runner
with 4 workers, so adding more shards increases total parallelism.

This should reduce E2E test time from ~3 minutes per shard to ~2 minutes
per shard by distributing tests across more parallel jobs.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* update

* fix

* update

* readd

* final update

* fix flake

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 10:19:09 -03:00
Keith WilliamsandDevin AI c47c6f2909 perf: optimize postgres health check in all CI workflows (#26343)
* perf: optimize postgres health check in e2e workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* perf: optimize postgres health check in all e2e workflows

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 09:54:56 -03:00
Keith Williams 38890de7f1 chore: Use 8 shards for main E2E tests (#26342)
* chore: Use 6 shards for main E2E tests

* Update .github/workflows/e2e.yml
2025-12-31 09:44:52 -03:00
Kartik LabhshetwarandDhairyashil Shinde fdb4cc5f70 fix: replace scroll-bar with no-scrollbar in AvailableTimeSlots component (#26339)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-31 10:25:37 +00:00
spandev 11150309d4 fix: added message in schedule bulk update (#26334) 2025-12-31 10:02:40 +00:00
Tamal Chakraborty 582e547bea Fix: Changed Delete My Account button from primary to Destructive (#26326) 2025-12-31 04:02:27 +00:00
Anik Dhabal Babu fee19654b0 fix: meetin url (#26321) 2025-12-31 03:53:38 +00:00
Pedro Castro 4226dfb05f fix(ci): improve security for external contributions (#26327)
- Remove pull_request_review trigger
- Add trust-check job to validate PR authors before running CI
- Create run-ci.yml workflow for maintainer approval via label
- Use workflow run timestamp to prevent backdating attacks
- Add per_page and in-progress checks for robustness
2025-12-31 00:16:52 -03:00
Volnei Munhoz 8bed6b0899 Spread biome errors (#26329) 2025-12-30 23:38:43 +00:00
Keith WilliamsandDevin AI b4790dd2aa refactor: move deps job to prepare job step to save ~20s per workflow (#26320)
* refactor: move deps job to prepare job step to save ~10s per workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove unused yarn-install.yml workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-30 14:44:23 -03:00
Anik Dhabal Babu 77ff8607d1 test: flaky unit test (#26310)
* fix: wip

* test

* Change pull_request to pull_request_target in workflow

* test

* update

* fix unit test flakes

* Update cache path to exclude node_modules

Remove node_modules from cache path in action.yml
2025-12-30 14:20:29 -03:00
Keith WilliamsandDevin AI bc6ff386a4 refactor: move eventTypeSlug and eventTypeLocations to @calcom/lib/zod (#26115)
* refactor: move eventTypeSlug and eventTypeLocations to @calcom/lib/zod

Move shared Zod schemas from @calcom/prisma/zod-utils to @calcom/lib/zod
to avoid prisma imports in non-repository code.

Changes:
- Create packages/lib/zod/eventType.ts with eventTypeSlug, eventTypeLocations,
  and EventTypeLocation type
- Re-export from @calcom/prisma/zod-utils for backwards compatibility
- Update packages/features/eventtypes/lib/schemas.ts to import from @calcom/lib/zod
- Remove unused slugify function from zod-utils.ts

This allows files like schemas.ts to avoid importing from @calcom/prisma,
which helps maintain the architectural boundary that prisma should only
be imported in repository code.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: remove barrel file and use explicit imports

Address PR feedback:
- Delete packages/lib/zod/index.ts barrel file
- Update imports to use explicit path @calcom/lib/zod/eventType
- Simplify EventTypeLocation type to use z.infer

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: use explicit type definition with z.ZodType for eventTypeLocations

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-30 13:03:10 -03:00
319d9858d4 fix: improve Insights empty state responsive design at 320px (#26203)
* fix: improve Insights empty state responsive design at 320px

* Update apps/web/modules/shell/UpgradeTip.tsx

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-30 12:37:46 -03:00
Keith WilliamsandDevin AI 1dbbc934cc chore: use lookup-only cache check to skip deps job downloads (#26314)
* fix(ci): skip yarn install in deps job when cache is hit

The Install Dependencies / Yarn install & cache step in pr.yml is primarily
for populating the cache when nothing is cached. When cache keys are found,
we can skip the actual yarn install and let the workflow carry on quickly.

This adds a skip-install-if-cache-hit parameter to the yarn-install action
that allows skipping the install when node_modules cache is hit. This is
enabled for the deps job in yarn-install.yml but not for other jobs that
actually need node_modules for their work.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(ci): also skip playwright install in deps job when cache is hit

Extends the skip-install-if-cache-hit parameter to the yarn-playwright-install
action as well, so both yarn install and playwright install are skipped in the
deps job when their respective caches are hit.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(ci): use lookup-only cache check to avoid downloading 1.2GB

When skip-install-if-cache-hit is true, use actions/cache/restore@v4 with
lookup-only: true to check if caches exist without downloading them. This
avoids downloading ~1.2GB of cache data when we just want to verify caches
exist in the deps job.

The flow is now:
1. If skip-install-if-cache-hit is true, run lookup-only checks for all caches
2. If all caches hit, skip the entire restore + install flow (no downloads)
3. If any cache misses, fall back to normal restore + install + save behavior

This optimization only applies when skip-install-if-cache-hit is set to true,
so other jobs that need node_modules continue to work normally.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Apply suggestion from @keithwillcode

* Apply suggestion from @keithwillcode

* Apply suggestion from @keithwillcode

* Apply suggestion from @keithwillcode

* fix(ci): address @cubic-dev-ai feedback on cache conditions

1. yarn-install: Add 'all-caches-check' step to compute whether all three
   caches hit (not just node_modules). This ensures we only bail out when
   everything is cached, matching the PR description.

2. yarn-playwright-install: Fix backward compatibility for install step.
   In default mode, check playwright-cache.outputs.cache-hit (the restore step).
   In skip mode, check playwright-cache-check.outputs.cache-hit (lookup-only).

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-30 12:29:33 -03:00
cal-com-ci[bot]andLingo.dev 3410ae6795 feat: update translations via @LingoDotDev (#26315)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-12-30 15:28:55 +00:00
cal-com-ci[bot]andLingo.dev d3e5cfb311 feat: update translations via @LingoDotDev (#26313)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-12-30 14:29:47 +00:00
Keith WilliamsandDevin AI 7985732683 chore: Delete cache-build cache entries on PR close (#26312)
* chore: Delete cache-build cache entries on PR close

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: Extract cache-build key generation into reusable action

- Create .github/actions/cache-build-key to generate cache keys
- Update cache-build action to use the shared key action
- Update delete workflow to use the shared key action
- Checkout PR head SHA in delete workflow for correct hash computation

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: Remove PR head SHA checkout per review feedback

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: Use prefix-based cache deletion for simpler cleanup

- Use useblacksmith/cache-delete prefix mode to delete all caches matching branch
- Remove dependency on cache-build-key action for deletion
- No checkout needed since we're just using the branch name as prefix

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: Simplify cache key by removing Linux and node version segments

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-30 11:24:33 -03:00
2b61bddf7b feat: add completed onboarding column to organization members table (#25582)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2025-12-30 10:57:49 -03:00
Anik Dhabal BabuandKeith Williams cc8da034c0 test: flaky e2e tests (#26308)
* fix another

* fix flakes

* Update apps/web/playwright/fixtures/apps.ts

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* fix

* fix

* test fix

* fix test

* tweak

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-30 13:45:01 +00:00
Udit TakkarandSyed Ali Shahbaz 2c7cb530a1 fix: add eventTypeId and eventTypeSlug guard (#25773)
* fix: add eventTypeId and eventTypeSlug guard

* chore: update test

* refactor: improvemnt

* revert:

---------

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2025-12-30 10:33:38 -03:00
Volnei Munhoz c52eff65a2 chore: fix biome warnings/errors (#26295)
* Fix icon-names

* make all errors into warns

* Minimal fix to mock
2025-12-30 11:46:26 +00:00
Keith WilliamsandDevin AI e4753778fe fix(ci): use getCollaboratorPermissionLevel for trust check (#26306)
* fix(ci): use GitHub App token for team membership check

The default GITHUB_TOKEN doesn't have org-level permissions to query
team membership via the teams.getMembershipForUserInOrg API. This causes
the API to return 404 even for valid team members, making the trust check
incorrectly fail for core team members.

This change generates a short-lived GitHub App token with org-level access
to properly verify team membership.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(ci): use getCollaboratorPermissionLevel for trust check

Replace the team membership check (teams.getMembershipForUserInOrg) with
getCollaboratorPermissionLevel which works with the default GITHUB_TOKEN.

This approach:
- Checks if users have write/maintain/admin access to the repo
- Works without requiring a GitHub App token with org-level permissions
- Is semantically correct: if someone can push to the repo, they're trusted

The previous approach using teams.getMembershipForUserInOrg required
org-level permissions that the default GITHUB_TOKEN doesn't have,
causing 404 errors even for valid team members.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-30 08:04:09 -03:00
Pedro Castro ae14e10b24 fix(ci): verify org membership when author_association fails (#26296)
* fix(ci): verify org membership via API when author_association fails

* refactor: use core team membership check instead of
    org membership
2025-12-30 10:23:02 +00:00
Manas Kenge 7c1a3b0c15 fix dialog (#26298) 2025-12-30 07:49:46 +00:00
Peer RichelsenandDevin AI ec90c1ae24 fix: display full URLs in workflow links (#26292)
- Exclude 'link' toolbar item from Editor for all workflow actions (not just SMS)
- Add replaceCloakedLinksInHtml utility to sanitize HTML and replace cloaked links with visible URLs
- Apply sanitization to email content before sending in all workflow email paths

This ensures recipients can see the actual destination of URLs, helping them identify potentially malicious links.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-30 01:53:04 -03:00
ccc8c2b566 fix: add security gate for external contributor PRs (#26293)
This change adds a trust-check job that gates CI for external contributors:

- Trusted contributors (OWNER, MEMBER, COLLABORATOR) can run CI immediately
- External contributors require approval from a core team member (write access or higher)
- Approval must be for the current commit SHA (stale approvals are ignored)
- Added pull_request_review trigger so CI runs when approval is given
- The required job now fails with a clear message for untrusted PRs

Co-authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Pedro Castro <pedro@cal.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-29 22:31:11 -03:00
e4b0a1b941 chore: restore production build cache with stable key using actions/cache (#26276)
* fix: align env vars between Production Builds and E2E workflows for turbo cache sharing

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: move E2E-specific env vars to step-level for turbo cache alignment

Instead of adding env vars to production-build-without-database.yml (which
caused DB calls during build), move the E2E-specific env vars from workflow-level
to step-level in e2e.yml. This ensures the cache-build step has the same env
context in both workflows, enabling turbo remote cache sharing.

Env vars moved to step-level:
- DATABASE_DIRECT_URL (to cache-db and Run Tests steps)
- E2E_TEST_MAILHOG_ENABLED (to Run Tests step)
- EMAIL_SERVER_* (to Run Tests step)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: restore production build cache with stable key using actions/cache

- Restore artifact caching for .next, dist, and .turbo directories
- Use actions/cache@v4 (accelerated by Blacksmith on their runners)
- Design stable cache key scoped to branch:
  - Includes branch name (head_ref for PRs, ref_name for pushes)
  - Hashes yarn.lock for dependency changes
  - Hashes source files in apps/web and packages/*/src
  - Excludes generated directories (prisma/zod, kysely) that caused instability
- Add restore-keys for partial cache hits
- Only run yarn build on cache miss
- Revert e2e.yml env var changes (no longer needed with artifact caching)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: simplify restore-keys to single fallback

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove restore-keys entirely for exact cache matching only

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use broader package pattern with exclusions for generated prisma files

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add exclusions for prisma/generated and prisma/client directories

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix: add .json and .css patterns to cache hash for config and style changes

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-29 21:59:00 -03:00
spandev 23c4e7edef fix: no result for oo headline (#26289) 2025-12-30 00:51:28 +00:00
Benny JooandDevin AI 00e5770273 refactor: Move attribute and routing-forms code from app-store/lib to features (#26025)
* mv

* wip

* wip

* wip

* wip

* plural

* fix: resolve TypeScript type errors for attribute refactoring

- Add TransformedAttributeOption type to handle transformed contains field
- Update imports to use routing-forms Attribute type where needed
- Fix getValueOfAttributeOption to use TransformedAttributeOption type
- Update AttributeOptionValueWithType to use TransformedAttributeOption
- Fix pre-existing lint warnings (any -> unknown, proper type casting)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* cleanup

* cleanup

* fix

* fix

* fix

* fix

* fix

* fix: add explicit type annotation to reduce callback in getAttributes.ts

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use RouterOutputs from @calcom/trpc/react for consistent type inference

- Update AppPage.tsx to use RouterOutputs from @calcom/trpc/react instead of inferRouterOutputs<AppRouter>
- Update MultiDisconnectIntegration.tsx to use the same RouterOutputs type source
- Add eslint-disable comments for pre-existing warnings (useEffect deps, img elements)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: explicitly type attribute property in AttributeOptionAssignment

The attribute property from Pick<AttributeOption, 'attribute'> was typed as
'unknown' because Prisma relations don't have explicit types when picked.
This explicitly defines the attribute shape with id, type, and isLocked
properties that are used in assignValueToUser.ts.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: remove unused assignedUsers from AttributeOptionAssignment Pick

The assignedUsers property was not being used in the code but was required
by the Pick type, causing a type mismatch when the actual data from the
database query didn't include it.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update import path for AttributeOptionAssignment and BulkAttributeAssigner types

The types.d.ts file was moved from packages/lib/service/attribute/ to
packages/app-store/routing-forms/types/. Updated the import path in utils.ts
to point to the new location.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 21:51:06 -03:00
Anik Dhabal Babu 5f0e408d2f fix: hide expected webServer errors in E2E tests to reduce noise (#26251)
* fix: e2e failure in CI

* fix
2025-12-29 21:47:02 -03:00
Anik Dhabal Babu ff9d88479c test: few more e2e flakes (#26278)
* test: few more e2e flakes

* fix another
2025-12-29 19:58:15 -03:00
7c373ddad6 feat: Introduce biome (#25664)
* Configure biome

* Fix companion build

* fix: remove generated files from formatter ignore list to enable proper formatting

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add explicit stripe dependency to @calcom/features to fix type resolution

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: rename const require to nodeRequire in generate-swagger.ts to avoid TypeScript reserved identifier conflict

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add guard for document in makeBodyVisible to prevent test environment teardown errors

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: replace ESLint with Biome CLI in embed-code-generator.e2e.ts

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: address cubic review comments

- Fix invalid --reporter-path Biome CLI option by using shell redirection
- Fix packages/lib lint report filename (app-store.json -> lib.json)
- Add typescript-eslint and eslint back to companion for lint:react-compiler
- Add missing restricted import rules to biome.json:
  - packages/lib: add ../trpc/** and @trpc/server restrictions
  - packages/trpc: add ../apps/web/** restriction

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: regenerate companion bun.lock after adding eslint dependencies

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Remove remaining eslint things

* add tailwind directives

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 19:41:41 -03:00
Anik Dhabal BabuandDevin AI 96dc3b5cc6 fix: improve test isolation for managed event type e2e tests (#26283)
- Move managedEventTypeSlug generation inside beforeAll to ensure uniqueness across test runs
- Add deleteAllTeamEventTypes method to EventTypesRepositoryFixture
- Explicitly delete all team event types in afterAll before deleting teams

This fixes flaky tests in organizations-member-team-admin-event-types.e2e-spec.ts
where the managed event type creation was intermittently failing with 400 Bad Request.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 16:12:01 -03:00
Keith WilliamsandDevin AI ed53b4dbe3 chore: reduce release-docker workflow permissions to minimum required (#26277)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 16:20:08 +00:00
Kartik Labhshetwar aae93cd268 fix: add destructive color and rounded-t-none to user dropdown button (#26275) 2025-12-29 16:03:54 +00:00
Kartik Labhshetwar 07108c4139 fix: update NewApiKeyButton with size and variant props (#26272) 2025-12-29 15:36:56 +00:00
Keith Williams 7dd9e7f23a chore: Give Unit Tests job more vCPUs (#26273) 2025-12-29 15:20:21 +00:00
Keith WilliamsandDevin AI c36165bcfd fix: remove nested turbo run for copy-app-store-static to fix remote caching (#26270)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 15:04:11 +00:00
Keith Williams 108e7381d0 perf: Use Blacksmith Docker caching (#26252) 2025-12-29 11:40:58 -03:00
Anik Dhabal Babu 25345aba3c test: falky e2e tests (#26269) 2025-12-29 14:27:21 +00:00
Adarsh Tiwari 7eef3d33c5 responsive button (#26259) 2025-12-29 11:12:51 -03:00
Keith WilliamsandDevin AI e94ea4d4b8 fix: exclude .next/node_modules from yarn cache to prevent corruption (#26268)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 11:10:00 -03:00
Dhairyashil Shinde b8e34bdc06 feat(companion): new booking details page and long press feature for ios (#26264)
* longpress ios - event type, booking, availability

* new booking details page for ios

* remove comments

* address cubics comments

* use lowercase type same as api v2
2025-12-29 18:57:48 +05:30
Keith WilliamsandDevin AI 3f003bafe5 feat: add PUSH_IMAGE input for docker builds (#26254)
* feat: add PUSH_IMAGE boolean input to release-docker workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: simplify push-image expression to always return string

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: make RELEASE_TAG input work for manual workflow triggers

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add postMessage listener to capture __iframeReady events early

This fixes a race condition in the embed E2E tests where the __iframeReady
event could fire before the Cal.ns[namespace] API was ready to receive it.

The fix adds a window.message listener immediately in the addInitScript that
captures __iframeReady events directly from postMessage, which doesn't depend
on the namespace API being ready. This ensures window.iframeReady is set
even if the event fires before the Cal API listener is attached.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Revert "fix: add postMessage listener to capture __iframeReady events early"

This reverts commit fdd02fcf1e5286f2b3b36a9f4c9889b269720845.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 10:25:33 -03:00
Keith Williams e38ef5edef chore: Reduce actions cost (#26260) 2025-12-29 13:20:01 +00:00
Keith WilliamsandDevin AI 4226d2262d fix: add postMessage listener to capture __iframeReady events early (#26258)
This fixes a race condition in the embed E2E tests where the __iframeReady
event could fire before the Cal.ns[namespace] API was ready to receive it.

The fix adds a window.message listener immediately in the addInitScript that
captures __iframeReady events directly from postMessage, which doesn't depend
on the namespace API being ready. This ensures window.iframeReady is set
even if the event fires before the Cal API listener is attached.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 18:35:50 +05:30
Volnei Munhoz 00c7415e28 chore: companion package versions fixed (#26261)
* companion versions fixed

* lock it right way

* Fix bun.lock
2025-12-29 09:07:24 -03:00
Keith WilliamsandDevin AI 4128a9b4fb refactor: use explicit type annotations for TUpdateInputSchema to reduce type inference complexity (#26133)
* refactor: use explicit type annotations for TUpdateInputSchema to reduce type inference complexity

This change significantly reduces TypeScript type-checking time by:
1. Defining explicit TypeScript types instead of using z.infer<> on complex schema chains
2. Using z.ZodType<T> annotations on schemas to prevent TypeScript from inferring through .extend(), .partial(), .merge() chains
3. Removing the dependency on EventTypeSchema from @calcom/prisma/zod/modelSchema which pulls in many dependencies

The schema still validates all fields at runtime - only the compile-time type inference is optimized.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update BookingFieldInput and users types to fix type errors

- BookingFieldInput now includes name, hidden, required properties with index signature
- users type changed from (string | number)[] to number[]
- Zod schema updated to use z.array(z.number()) for users field
- Removed unused stringOrNumber import

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: handle bookingFields null case with Prisma.DbNull for JSON field compatibility

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove index signature from BookingFieldInput for API v2 DTO compatibility

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove useless JSDoc comments per PR feedback

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* test: add unit tests for aiPhoneCallConfig transformation in ZUpdateInputSchema

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* test: add unit tests for bookingFields null to Prisma.DbNull transformation

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove comments from update.handler.test.ts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: scope test describe block to update.handler per PR feedback

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 07:40:49 -03:00
Keith WilliamsandDevin AI 55805f081d fix: add artifact handling for API v2 E2E tests (#26249)
* fix: add artifact handling for API v2 E2E tests

- Add jest-junit reporter to generate JUnit XML test results
- Update workflow to upload from correct path (apps/api/v2/test-results)
- Add if-no-files-found: ignore and retention-days: 30 for consistency

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 02:22:38 -03:00
Keith WilliamsandDevin AI 2a6a8e635c chore: migrate GitHub workflows from Buildjet to Blacksmith (#26247)
* chore: migrate GitHub workflows from Buildjet to Blacksmith

- Replace buildjet-*vcpu-ubuntu-2204 runners with blacksmith-*vcpu-ubuntu-2204
- Replace buildjet/cache@v4 with actions/cache@v4
- Replace buildjet/setup-node@v4 with actions/setup-node@v4
- Replace buildjet/cache-delete@v1 with useblacksmith/cache-delete@v1
- Rename delete-buildjet-cache.yml to delete-blacksmith-cache.yml

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: bump Blacksmith runners to Ubuntu 24.04

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Reduce 16vcpu to 4vcpu for the API v2 E2E

* Remove 8vcpu usage

* chore: switch Blacksmith runners to ARM architecture

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: switch Blacksmith runners back to AMD (remove -arm suffix)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: improve test cleanup to cover all bookings including reassignment-created ones

- Changed afterEach cleanup to find all bookings by eventTypeId instead of tracking bookingIds
- This ensures bookings created indirectly by managedEventManualReassignment are also cleaned up
- Removed problematic prefix-based deleteMany calls that could affect parallel tests
- Fixes idempotencyKey collision errors on high-parallelism CI runners

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: improve icons screenshot test stability with deviceScaleFactor and increased threshold

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: cap Playwright workers to 4 to match vCPU allocation on Blacksmith runners

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 05:12:31 +00:00
Keith Williams b6e0182002 chore: Fix peer dependencies in yarn.lock (#26250) 2025-12-29 05:05:34 +00:00
spandev b372477aa0 fix: save button in availibility disabled when no changes (#26174)
* fix: save button in availibility disabled when no changes

* fix: updated comparison logic

* fix: changed logic from and to or
2025-12-29 04:15:51 +00:00
Eesh Midha 77f99b636c fix: add proper disabled-state styling to Select component (#25697)
* fix: add proper disabled-state styling to Select component using state.isDisabled

* chore: apply hover:border-subtle since disabled items are not clickable and only hover state should change the border
2025-12-29 01:07:01 -03:00
Keith Williams 716e66b0c3 chore: Use relative imports for @calcom/prisma inside of @calcom/prisma (#26245)
<!-- This is an auto-generated description by cubic. -->
## Summary by cubic
Switch @calcom/prisma to use relative imports for client and enums. This removes self-references, stabilizes builds, and improves type resolution.

- **Refactors**
  - Replaced imports from "@calcom/prisma/*" with local "./client" and "./enums" across extensions, selects, mocks, and availability check.
  - Updated safeJSONStringify parameter type from any to unknown.
  - Minor formatting cleanup in zod-utils.

<sup>Written for commit 85c0a7b75fb1291be5b848a73d1ccb5543283f49. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-12-29 00:52:12 -03:00
Keith Williams 83dcb71947 perf: Improve apps/web tsconfig.json (#26246) 2025-12-29 00:31:25 -03:00
Pedro CastroandKeith Williams 5fe54fd3f2 fix(schedules): add missing await on async permission check (#26218)
The hasReadPermissionsForUserId function is async but was being
   called without await in two locations.

   This aligns with the existing correct usage in
   ScheduleRepository.findManyDetailedScheduleByUserId

   - Add await to getAllSchedulesByUserId.handler.ts
   - Add await to ScheduleRepository.findDetailedScheduleById
   - Refactor ScheduleRepository tests to use shared prismaMock
   - Add new handler test with authorization coverage

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-28 23:47:08 -03:00
cal-com-ci[bot]andLingo.dev 1c6f5d9ec0 feat: update translations via @LingoDotDev (#26219)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-12-29 02:18:32 +00:00
309340d3f3 fix: add missing peer dependencies and fix inconsistent peer dependency declarations (#26244)
* fix: add missing peer dependencies and fix inconsistent peer dependency declarations

- @calcom/ui: Move react from dependencies to peerDependencies (was inconsistent with react-dom being a peer)
- @calcom/emails: Move react and react-dom to peerDependencies
- @coss/ui: Add react and react-dom as peerDependencies (uses lucide-react and @base-ui/react)
- @calcom/app-store: Add react, react-dom, zod as peerDependencies (depends on @calcom/features which has these peers)
- @calcom/platform-libraries: Add react, react-dom, stripe, zod as peerDependencies (depends on @calcom/features)
- @calcom/features: Add next as peerDependency (depends on @calcom/trpc which has next as peer), update react/react-dom to flexible version ranges
- @calcom/features/ee: Add react, react-dom, react-hook-form as peerDependencies (uses @calcom/ui and @hookform packages)

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add more peer dependencies for PnP compatibility

Additional changes:
- @calcom/app-store: Move stripe from dependencies to peerDependencies
- @calcom/ui: Move @tanstack/react-query to peerDependencies (singleton pattern)
- @calcom/trpc: Move @tanstack/react-query to peerDependencies (singleton pattern)
- @calcom/atoms: Move @tanstack/react-query to peerDependencies (singleton pattern)
- @calcom/stripepayment: Add react, react-dom, stripe as peerDependencies
- @calcom/caldavcalendar: Add react, react-dom, react-hook-form as peerDependencies
- @calcom/exchange2013calendar: Add react, react-dom, react-hook-form as peerDependencies
- @calcom/exchange2016calendar: Add react, react-dom, react-hook-form as peerDependencies
- @calcom/ics-feed: Add react, react-dom, react-hook-form as peerDependencies

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: revert dependency moves for packages with own builds

Packages with their own build step should not have dependencies
moved to peerDependencies as they need those deps at build time.

Reverted:
- @calcom/trpc: Keep @tanstack/react-query out of peerDependencies
- @calcom/atoms: Restore @tanstack/react-query to dependencies
- @calcom/stripepayment: Restore stripe to dependencies

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-28 21:29:44 -03:00
Dhairyashil Shinde 49ae10149f feat(companion): iOS native UI components and simplified event type creation (#26240)
ios:


https://github.com/user-attachments/assets/efdfd3e3-239f-4cbf-be1a-7784d1df1851


android:



https://github.com/user-attachments/assets/a8e22a5c-60f3-4fb6-8923-b8a786bceb0c




## Overview

This PR introduces native iOS UI components, refactors the profile menu, and simplifies the event type creation flow for a more native iOS experience.

## Key Changes

### iOS Native UI Components
- **iOS-specific Event Types Page**: Added native Stack.Header, glass UI, and context menus for iOS
- **Platform-specific Profile Sheet**: Created separate implementations for iOS (formSheet) and Android/Web (modal)
- **Bottom Glass UI Navbar**: Updated bottom navigation bar with glass UI styling for iOS
- **Native iOS Alerts**: Replaced custom modals with native `Alert.prompt` for event types and availability pages

### Profile Menu Refactor
- Restructured More page with folder layout and native iOS header support
- Added profile button to More page header on iOS with glass UI
- Added "Copy public page link" and "Roadmap" options to profile sheet
- Refactored Header component: removed inline profile modal, now uses route-based navigation
- Updated Availability page with New menu and profile button in header
- Fixed "My Settings" URL to use `/general` endpoint
- Removed "Profile" item from More section menu
- Updated tab layout to support `(more)` folder structure

### Simplified Event Type Creation
- Reduced event type creation to only require title input
- Auto-generate slug from title using slugify utility
- Set default duration to 15 minutes
- Leave description empty (users can edit later)
- Applied to both iOS and Android/Web platforms

### UI Improvements
- Updated login button styling: changed background color to pure black (#000000) with white text for better contrast
2025-12-28 18:48:48 -03:00
Tamal Chakraborty 3fc847c9f7 fix insight routing ui mergin bug (#26237) 2025-12-28 20:34:44 +00:00
Tamal Chakraborty 0be0928e66 add ui fix for availability page (#26235) 2025-12-28 20:32:28 +00:00
Dhairyashil Shinde 9203cb262c feat(companion): component improvements, migrate to path aliases, expo-haptics, expo-image (#26226)
* react compiler

* remove compilation mode 'all', it will use infer by default

* feat(companion): add theme tokens, path aliases, and component improvements

- Extend tailwind.config.js with Cal.com brand color tokens (cal.text, cal.bg, cal.border, cal.accent, cal.brand)
- Create theme/colors.ts for JS usage where Tailwind classes can't be used
- Configure path aliases in tsconfig.json (@/components, @/hooks, @/utils, etc.)
- Add expo-image and expo-haptics dependencies
- Enhance AppPressable with Reanimated animations (opacity + scale) and haptic feedback
- Extract shared logic from BookingListItem into useBookingListItemData hook and BookingListItemParts
- Extract shared logic from EventTypeListItem into useEventTypeListItemData hook and EventTypeListItemParts
- Extract shared logic from AvailabilityListItem into AvailabilityListItemParts
- Update all list item components to use new theme tokens instead of hardcoded hex values

* fix react compiler non memo issue

* feat(companion): migrate to path aliases and expo-image

- Remove theme/colors.ts and theme/index.ts (defer dark mode to future PR)
- Replace colors import with hardcoded hex values in components
- Migrate all files to use path aliases (@/components/*, @/hooks/*, etc.)
- Migrate SvgImage to use expo-image for better performance
- Update tsconfig.json to remove @/theme/* alias

* fix(companion): add path aliases to extension tsconfig

Add baseUrl and paths configuration to tsconfig.extension.json to support
path aliases in shared types used by the extension build.
2025-12-28 08:08:33 -03:00
Abhishek b6b0492362 fix:gap at webhook form actions (#26233) 2025-12-28 09:41:48 +00:00
Abhishek 95f98eb58e fix: gap between giphy gif setup buttons (#26232) 2025-12-28 09:01:00 +00:00
Dhairyashil Shinde 4036fb6d08 feat(companion): react compiler (#26221)
* react compiler

* remove compilation mode 'all', it will use infer by default
2025-12-27 16:06:00 -03:00
samaRandDhairyashil Shinde 7fdfd0d6a0 fix: prevented overflow in WelcomeToCalcomModal by adjusting dialog content styles (#26202)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-27 17:52:07 +00:00
Dhairyashil Shinde 2a84d46fe9 feat(companion): add Biome for linting and formatting (#26214)
* feat(companion): add ESLint with Prettier integration

- Add ESLint with eslint-config-expo/flat for SDK 55
- Integrate Prettier via eslint-plugin-prettier
- Configure environment-specific settings for Node.js config files and browser extension
- Add lint script to package.json
- Fix Prettier formatting issues in AvailabilityTab.tsx and types/index.ts

* fix(companion): use bun lockfile instead of npm

- Remove package-lock.json that was accidentally committed
- Update bun.lock with ESLint dependencies

* fix(companion): fix all ESLint errors (16 total)

- Fix unescaped entities in JSX (react/no-unescaped-entities):
  - app/(tabs)/(event-types)/index.tsx: escape quotes in delete confirmation
  - components/LoginScreen.tsx: escape apostrophe in "Don't have an account"
  - components/NetworkStatusBanner.tsx: escape apostrophes in offline message
  - components/booking-modals/BookingModals.tsx: escape apostrophe in rejection message
  - components/event-type-detail/tabs/AdvancedTab.tsx: escape quotes and apostrophes
  - components/screens/AvailabilityListScreen.tsx: escape quotes in delete confirmation

- Fix react-hooks/rules-of-hooks in RescheduleScreen.tsx:
  - Move useMemo calls before conditional early return to ensure hooks
    are called in the same order on every render

* fix(companion): fix all ESLint warnings (68 total)

- Fix import/no-named-as-default warnings by using named imports
- Fix @typescript-eslint/no-unused-vars warnings by removing unused imports/variables
- Fix react-hooks/exhaustive-deps warnings with eslint-disable comments
- Convert unused error variables in catch blocks to bare catch
- Remove unused imports (useRouter, Alert, useSafeAreaInsets, etc.)
- All ESLint checks now pass with 0 errors and 0 warnings

* feat(companion): add pre-commit lint check with --max-warnings=0

- Add companion lint check to root lint-staged.config.mjs
- Runs 'bun run lint -- --fix --max-warnings=0' for companion files
- Follows same pattern as apps/packages lint check
- Supports SKIP_WARNINGS=1 env var to bypass warning check if needed
- Commit will fail if any ESLint errors or warnings are present

* fix(companion): restore state variables and imports removed during ESLint fixes

- Restore locationAddress, locationLink, locationPhone state variables in event-type-detail.tsx (still used in fetchEventTypeData)
- Restore Alert import in BookingListScreen.tsx (still used for report booking)
- Add eslint-disable comments for the restored state variables since they're only used by setters

* test

* test

* fix eslint pre commit check

* fix: In React Native, HTML entities like &apos; are rendered literally as text, not decoded like in web browsers

* refactor(companion): remove ESLint and Prettier config in preparation for Biome

* feat(companion): add Biome for linting and formatting

- Install @biomejs/biome with exact version pinning (2.3.10)
- Add biome.json with formatting settings matching previous Prettier config
- Add lint, format, check, and check:ci scripts to package.json
- Update lint-staged to use Biome instead of Prettier
- Remove Prettier and prettier-plugin-tailwindcss dependencies
- Delete .prettierrc.js configuration file

* style(companion): apply Biome formatting and fix lint-staged config

- Update lint-staged to use 'biome format' instead of 'biome check'
  (pre-commit should only format, not lint)
- Apply Biome formatting to all companion files

* feat(companion): configure Biome for strict linting with pre-commit enforcement

- Apply Biome unsafe fixes (unused imports, optional chaining, etc.)
- Configure biome.json rules to disable overly strict rules for existing code:
  - noExplicitAny, noArrayIndexKey, useIterableCallbackReturn (suspicious)
  - useExhaustiveDependencies, noUnusedFunctionParameters (correctness)
  - noStaticOnlyClass (complexity)
  - noNonNullAssertion (style)
  - noStaticElementInteractions (a11y)
- Update lint-staged to use 'biome check --write --error-on-warnings'
  (pre-commit now runs both formatting AND linting, fails on warnings)

* fix(companion): enable noNonNullAssertion rule and fix all violations

- Enable noNonNullAssertion rule in biome.json (set to 'error')
- Fix 7 violations across the codebase:
  - hooks/useBookings.ts: Add runtime check before API call
  - hooks/useEventTypes.ts: Add runtime check before API call
  - hooks/useSchedules.ts: Add runtime check before API call
  - extension/entrypoints/content.ts: Add null checks for cache and getAttribute

* fix(companion): enable noStaticOnlyClass and noStaticElementInteractions rules

- Enable noStaticOnlyClass rule in biome.json
- Enable noStaticElementInteractions rule in biome.json
- Convert CalComAPIService from static class to object literal pattern
- Convert WebAuthService from static class to object literal pattern
- Add role="tooltip" to Tooltip.web.tsx for accessibility

* fix(companion): resolve TypeScript type errors in useEffect dependencies and remove unused state property

* fix(companion): enable noUnusedFunctionParameters rule and fix 9 violations

* fix(companion): enable noUnusedVariables rule and fix 4 violations

* fix(companion): enable useIterableCallbackReturn rule and fix 11 violations

* fix(companion): enable useExhaustiveDependencies rule and fix 7 violations

* fix(companion): enable noArrayIndexKey rule and fix 10 violations

* fix(companion): enable noExplicitAny rule and fix all violations

- Enable noExplicitAny rule in biome.json
- Replace any types with proper specific types across all files:
  - calcom.ts: Add proper type definitions for API responses and inputs
  - event-types.types.ts: Add BookingLimitsCount, BookingLimitsDuration, ConfirmationPolicy types
  - buildPartialUpdatePayload.ts: Fix type mismatches for booking limits functions
  - booking-actions.ts: Add proper types for booking action handlers
  - BookingDetailScreen.tsx, MarkNoShowScreen.tsx: Add types for attendee data
  - AvailabilityListItem.ios.tsx, BookingListItem.ios.tsx: Import SFSymbols7_0 type
  - extension/content.ts: Fix slot types and __cleanup invocation issues
- Remove unused imports and interfaces

* address cubics comments

* add useHookAtTopLevel rule
2025-12-27 08:19:53 -03:00
38e4c568b8 fix: add undeclared dependencies and remove unused/misplaced dependencies (#26205)
* chore: lock all package versions to match yarn.lock

This commit pins all dependency versions in package.json files to exact
versions matching the yarn.lock file, removing ^ and ~ prefixes.

Changes:
- Locked 427 dependencies across 47 package.json files
- Versions now match exactly what is resolved in yarn.lock
- Ensures reproducible builds and prevents unexpected version drift

This change improves build reproducibility by ensuring that the versions
specified in package.json files match exactly what yarn.lock resolves to.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add undeclared dependencies to trpc, ui, and platform-types packages

- @calcom/trpc: add cookie, uuid and their type definitions
- @calcom/ui: add Lexical packages, Radix UI components, classnames, sonner, react-easy-crop, zod
- @calcom/platform-types: add @nestjs/common, @nestjs/swagger, libphonenumber-js, luxon, zod

These dependencies were being used in the code but not declared in package.json,
relying on hoisting from other packages.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: update yarn.lock after adding undeclared dependencies

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: upgrade Prisma versions in example apps and pin remaining @types/node

- Upgraded @prisma/client to 6.16.1 in example apps to match main app
- Pinned @types/node to 20.17.23 in atoms, libraries, and example apps
- Pinned @types/react to 18.0.26 and @types/react-dom to 18.2.6 in example apps

Addresses PR review comments about Prisma version mismatch and unpinned @types/node

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: remove unused and misplaced dependencies

Removed unused dependencies:
- @calcom/web: mime-types, posthog-node, react-date-picker, react-multi-email, react-phone-number-input, recoil, @vercel/edge-functions-ui, lottie-react, jotai
- @calcom/features: @lexical/react, lexical, akismet-api, stripe-event-types

Removed misplaced dependencies from @calcom/web (already in @calcom/ui):
- @radix-ui/react-avatar, @radix-ui/react-dialog, @radix-ui/react-dropdown-menu
- @radix-ui/react-hover-card, @radix-ui/react-id, @radix-ui/react-popover
- @radix-ui/react-slider, @radix-ui/react-switch, @radix-ui/react-toggle-group
- react-colorful

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add back jotai and react-phone-number-input dependencies

These dependencies were incorrectly removed in the previous commit:
- jotai: Required as peer dependency by @daily-co/daily-react
- react-phone-number-input: CSS imported in WorkflowStepContainer.tsx

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: update yarn.lock after Prisma version upgrade

Updates yarn.lock to reflect:
- @prisma/client upgraded from 6.7.0 to 6.16.1 in example apps
- Removed unused @prisma/client@6.7.0 resolution

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: align dependency versions per PR review feedback

- @nestjs/common: 10.0.0 -> 10.3.3 in platform-types (match api-v2)
- cookie: ^0.7.0 -> 0.7.0 in trpc (pin exact version)
- uuid: ^8.3.2 -> 8.3.2 in trpc (pin exact version)
- @types/cookie: ^0.6.0 -> 0.6.0 in trpc (pin exact version)
- @types/uuid: ^8.3.4 -> 8.3.4 in trpc (pin exact version)

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: move root dependencies to proper packages

- Remove all dependencies from root package.json (they were misplaced)
- Add @evyweb/ioctopus, city-timezones, date-fns-tz, p-limit to @calcom/features
- @daily-co/daily-js already exists in @calcom/web
- @vercel/functions already exists in @calcom/features
- date-fns already exists in @calcom/ui

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-26 23:02:24 -03:00
Alex van Andel ab64019e27 chore: release v6.0.6
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-27 00:34:40 +00:00
Syed Ali Shahbaz 8b7497b8cd chore: Return webhook version in the header (#26139)
* init

* add tests

* fix type

* type fix

* fix

* fix tests

* fix test
2025-12-27 00:31:20 +00:00
Dhairyashil Shinde 18017b5320 feat(companion): TypeScript best practices improvements (#26206)
* feat(companion): TypeScript best practices improvements

- Add separate tsconfig.extension.json for extension code typechecking
- Add typecheck scripts: typecheck, typecheck:extension, typecheck:all
- Create ambient declarations for browser extension APIs (browser.d.ts)
- Create type definitions for attendee and google-calendar types
- Replace all @ts-ignore with @ts-expect-error or remove where ambient declarations cover them
- Replace any types with proper types in AuthContext, webAuth, buildPartialUpdatePayload
- Fix implicit any errors in extension content.ts
- Update deepEqual function to use unknown instead of any for better type safety

All typechecks now pass for both app and extension code.

* feat(companion): enable full TypeScript strict mode (#26208)

* feat(companion): enable strictNullChecks and strictFunctionTypes

Phase 1 of strict mode enablement for the companion app.

Changes:
- Enable strictNullChecks and strictFunctionTypes in tsconfig.json
- Fix null check for scheduleDetails in fetchScheduleDetails
- Add explicit type annotations to limits arrays in event-type-detail.tsx
- Filter conferencing options with null appId before passing to buildLocationOptions
- Update LimitsTab interface to use union type for field parameter
- Add optional chaining for onEdit, onDuplicate, onDelete in EventTypeListItem.ios.tsx
- Add explicit type annotations to options arrays in AvailabilityListScreen.tsx
- Add explicit type annotations to dateOptions and timeOptions in RescheduleScreen.tsx
- Fix type guard return types in calcom.ts to explicitly return boolean

All typechecks pass for both app and extension code.

* feat(companion): enable full strict mode and fix any types (Phase 2 + Step 7)

Phase 2: Enable full strict mode
- Replace strictNullChecks + strictFunctionTypes with strict: true
- Fix implicit any errors in Alert.prompt callbacks (BookingDetailScreen, useBookingActions)

Step 7: Fix metadata any types in type definition files
- Update UserProfile.metadata to Record<string, unknown>
- Update CreateEventTypeInput.metadata to Record<string, unknown>
- Update Booking.responses to Record<string, unknown>

All typechecks pass for both app and extension code with full strict mode enabled.

* use JSON.stringify()

* fix restores the recursive key comparison with sorted keys

* prevents false positives when objects have different keys

* feat(companion): add tree shaking optimization scripts (#26212)

* feat(companion): add tree shaking optimization scripts

Add npm scripts to enable Expo's experimental tree shaking for production builds:
- export: Basic expo export command
- export:ios / export:android: Platform-specific exports
- export:optimized: Export with tree shaking enabled (all platforms)
- export:optimized:ios / export:optimized:android: Platform-specific with tree shaking

Bundle size improvement measured:
- Baseline: 5.48 MB (1804 modules)
- With tree shaking: 5.25 MB (1831 modules)
- Reduction: ~230 KB (4.2% smaller)

Also documented tree shaking configuration options in .env.example for:
- npm scripts (recommended)
- Manual env var setting
- EAS build profile configuration

* revert .env.example file

* revert .env.example file
2025-12-26 17:13:50 +00:00
Pedro Castro ab512ea263 chore: bump package versions (#26211)
* chore: bump package versions

- @nestjs/common 10.4.20
- @nestjs/platform-express 10.4.20
- @jsforce/jsforce-node 3.10.10
- dompurify 3.3.1
- @dub/embed-react 0.0.18
- @dub/embed-core 0.0.18
- http-proxy-middleware 2.0.9
- action-download-artifact v6

* fix: align NestJS core packages to same version

Update @nestjs/core and @nestjs/testing to 10.4.20 to match
@nestjs/common and @nestjs/platform-express versions
2025-12-26 13:38:25 -03:00
Volnei MunhozandDevin AI 44586c7dec chore: lock all package versions to match yarn.lock (#26204)
This commit pins all dependency versions in package.json files to exact
versions matching the yarn.lock file, removing ^ and ~ prefixes.

Changes:
- Locked 427 dependencies across 47 package.json files
- Versions now match exactly what is resolved in yarn.lock
- Ensures reproducible builds and prevents unexpected version drift

This change improves build reproducibility by ensuring that the versions
specified in package.json files match exactly what yarn.lock resolves to.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-26 11:54:30 -03:00
Anik Dhabal Babu 38efed4f56 ci: create new workflow for API v2 unit tests (#26189)
* playwright

* Remove copy-app-store-static from web server command

* check

* test

* api v2 unit test
2025-12-26 14:08:32 +00:00
Dhairyashil Shinde 91af737a7c feat(companion): linkedin plugin (#26193)
* feat/companion-extension-linkedin-plugin

* better alignment

* better code
2025-12-26 17:33:00 +05:30
Alex van Andel 6daac15bea fix: GH based cronjobs in EU (#25992)
* fix: GH based cronjobs in EU

* Some fixups

* Some further fixes
2025-12-26 11:43:28 +00:00
Kartik LabhshetwarandDhairyashil Shinde 3f093ef625 fix: add hover transparency and rounded top to ApiKeyListItem actions (#26150)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-25 16:28:52 +00:00
Kartik Labhshetwarandcubic-dev-ai[bot] 21958dd511 fix: improve mobile responsiveness for workflows page (#24257)
* refactor: update WorkflowPage layout, add tooltip to name, adjust badge styling

* Update packages/features/ee/workflows/pages/workflow.tsx

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* chore: removing tooltip

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-25 18:58:01 +05:30
Dhairyashil Shinde d51237844c feat(companion): implement comprehensive booking actions system (#26185) 2025-12-25 04:50:14 +01:00
Yash Gupta b002d7d797 fix: prevent WelcomeToCalcomModal footer overflow (#26186)
* fix: prevent WelcomeToCalcomModal footer overflow

* fix: removes extra space
2025-12-25 04:27:53 +05:30
8befcced39 ci: shard API v2 E2E tests into 4 parallel jobs (#26183)
* ci: shard API v2 E2E tests into 4 parallel jobs

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* check

* Fix typo in workflow name from 'Update' to 'Updatee'

* Rename workflow from 'PR Updatee' to 'PR Update'

* update

* test

* update

* fix

* update

* check

* remove

* revert

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-24 10:46:49 -03:00
Hariom Balhara 49d5f204f0 Add use client at the top and ignore warnings (#26184) 2025-12-24 10:42:57 +00:00
Anik Dhabal Babu c2b7dcb900 fix: flaky E2E tests on filter segment (#26182)
* fix: flaky e2e tests on filter segment e2e

* check

* Click first event type in advanced page test
2025-12-24 07:24:13 -03:00
Keith WilliamsandDevin AI b773b23ebb refactor: Remove buildjet cache from cache-build action (#26181)
* refactor: Remove buildjet cache from cache-build action

The buildjet cache was causing cache misses due to unstable hashFiles()
keys that included generated Prisma files. Since we now use Turbo Remote
Caching, the buildjet cache is redundant and was causing more problems
than it solved.

This simplifies the cache-build action to just run yarn build, relying
on Turbo Remote Caching for build artifact caching.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: Preserve original name and description in cache-build action

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-24 09:19:28 +05:30
Pedro Castro 99b82c55d5 chore: update direct dependencies (#26172)
Updates:
- vite: 4.5.3→4.5.14, 5.4.6→5.4.21
- nodemailer: 6.7.8→7.0.11
- @playwright/test: 1.45.3→1.55.1
- next-auth: 4.22.1→4.24.13
- class-validator: 0.14.0→0.14.3
- dompurify: 3.2.3→3.3.1

Includes type fixes for next-auth adapter compatibility
2025-12-23 23:42:55 -03:00
Keith WilliamsandDevin AI 054a0fa7db refactor: Add dedicated setup-db job to eliminate cache race condition (#26171)
* refactor: Add dedicated setup-db job to eliminate cache race condition

- Create new setup-db.yml workflow that runs cache-db action
- Update pr.yml to add setup-db job that runs before all E2E jobs
- Update integration-test, e2e, e2e-api-v2, e2e-app-store, e2e-embed,
  and e2e-embed-react jobs to depend on setup-db instead of build-api-v1
- Add setup-db to required job needs list and result check

This eliminates the race condition where multiple jobs could try to
write to the same database cache simultaneously.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: Remove DB parts from api-v1-production-build.yml

The database setup is now handled by the dedicated setup-db job,
so the postgres service and cache-db action are no longer needed
in the API v1 build workflow.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Apply suggestion from @keithwillcode

* Made integration tests dependency consistent

* refactor: Remove unnecessary env vars from setup-db.yml

Only keep the env vars needed for database setup:
- CALENDSO_ENCRYPTION_KEY (for db-seed)
- DATABASE_URL / DATABASE_DIRECT_URL (for database connection)
- TURBO_TOKEN / TURBO_TEAM (for turbo caching)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: Add back E2E_TEST_CALCOM_QA_* env vars needed by db-seed

These env vars are used by scripts/seed.ts to create the QA user
with Google Calendar credentials during database seeding.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: Restore postgres service and cache-db to api-v1-production-build.yml

The API v1 build still needs a database to run properly. Restored the
postgres service and cache-db action, and added dependency on setup-db
so it waits for the database cache to be created first.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* E2E for API v2 no longer waiting on API v2 build

* Reordering the jobs by dependencies

* add GOOGLE_API_CREDENTIALS env var to setup db

* Added back all env vars to setup-db

* fix: Include commit SHA in cache-db key to invalidate cache on new commits

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: Strip back setup-db.yml env vars to minimal set needed for db-seed

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-23 22:39:26 -03:00
Pedro CastroandKeith Williams cd6c5fe6df chore: remove unused dependencies (#26169)
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
* chore: remove unused dependencies

- Remove msw from apps/web (test was disabled with test.fixme)
- Remove integrations.e2e.ts (unused test file depending on msw)
- Remove jsforce from apps/api/v2 (never imported, salesforce uses @jsforce/jsforce-node)
- Remove rollup-plugin-node-builtins and vite-plugin-node-polyfills from atoms (never used)
- Remove fs/path/os aliases from atoms vite.config.ts

Resolves: #76, #118, #354 (partial), #356, #347, #266

* fix(companion): remove unused glob dependency

Glob was declared as devDependency but never imported in companion code
Resolves dependabot alerts #465, #460

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-23 21:38:38 -03:00
Alex van Andel 83aadf0213 chore: release v6.0.5 2025-12-24 00:37:16 +00:00
Alex van Andel 7f59a1f058 Revert "perf: (googlecalendar): batch freebusy calls by delegation credential (#24331)"
This reverts commit 253c33df33.
2025-12-24 00:35:18 +00:00
Keith Williams 5322d9640b chore: Change API v2 depends on for CI (#26170) 2025-12-23 23:19:51 +00:00
8ac3d423cb fix: When checking email domains to block replace includes with endsWith (#26166)
* Lint fixes

* Replace `includes` with `endsWith`

* Fix typo

* test: add tests for email domain blocking fix

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-23 19:56:43 -03:00
Alex van Andel 14edd6c42f chore: release v6.0.4
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-23 20:55:12 +00:00
Keith WilliamsandDevin AI 1c5f05638f fix: search by branch instead of SHA in E2E report workflow_dispatch (#26168)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-23 20:51:14 +00:00
fe4017f302 docs: clarify tRPC architecture - packages/features vs apps/web/modules (#26155)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-23 19:38:09 +00:00
BetoandDhairyashil Shinde 2abfae7f13 feat(companion): Booking details screen navigation header improvements (#26163)
* feat(companion): restructure booking detail components and enhance type safety

- Migrate BookingDetail component to a new file structure under (tabs)/(bookings) for better organization.
- Introduce a new BookingDetailScreen with improved header and menu options.
- Update app.json to enable typed routes and enhance TypeScript configuration in tsconfig.json.
- Remove the old booking-detail.tsx file to clean up the codebase.
- Adjust imports and routing to reflect the new structure, ensuring all components are properly linked.

This refactor aims to improve maintainability and clarity in the booking detail flow.

* add header options

* refactor(booking-detail): rename "Standalone Actions" menu to "Danger Zone" for clarity

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-23 19:35:55 +00:00
Dhairyashil Shinde 75d8300635 fix/companion-consider-all-profile-links (#26158) 2025-12-23 19:24:26 +00:00
Volnei Munhoz 67f20f4503 fix: Change matcher params for CI changes matcher (#26162)
* Change matcher params

* upgrade dorny

* Fix predicated-quantifier

* Fix predicated-quantifier
2025-12-23 19:20:06 +00:00
Keith Williams d6376c6d70 chore: CODEOWNERS Change Platform -> Consumer (#26160) 2025-12-23 19:18:42 +00:00
Keith WilliamsandDevin AI 9256d306b9 ci: make E2E report jobs non-blocking by moving to separate workflow (#26157)
* ci: make E2E report jobs non-blocking by moving to separate workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: minimize permissions in e2e-report workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: refactor to reuse existing workflow files via workflow_call

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: add workflow_dispatch trigger for manual testing of E2E report workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: simplify workflow_dispatch to only require pr_number input

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* ci: remove secrets inheritance from merge-reports for fork PR security

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-23 19:16:36 +00:00
Anik Dhabal Babu b62493235c fix: all the e2e flakes visible (#26161)
* fix: all th e2e flakes

* check

* fix
2025-12-23 18:55:37 +00:00
Anik Dhabal Babu f35b36fafa add appId fallback for appName in event results (#26146) 2025-12-23 17:20:28 +00:00
Anik Dhabal Babu 2689cdfdff perf: pass app data to OmniInstallAppButton to avoid redundant API calls (#26156)
* perf: pass app data to OmniInstallAppButton to avoid redundant API calls

* Clean up comments in OmniInstallAppButton component

Removed comment about pre-fetched app data and fetching logic.
2025-12-23 16:49:34 +00:00
Dhairyashil ShindeandPallav efcf68869d fix: Routing page horizontal scroll for small mobile devices (#24663)
* fix: horizontal scroll for small mobile devices

* address cubics comments

* fix disable form toggle

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-12-23 16:23:50 +00:00
Benny JooandDevin AI 8afe87ff75 refactor: Move trpc-dependent components from features to web [1] (#25859)
* refactor: migrate UnconfirmedBookingBadge from features to apps/web

Move UnconfirmedBookingBadge.tsx from packages/features/bookings/ to
apps/web/modules/bookings/components/ as part of the architectural
refactor to remove trpc client imports from the features layer.

Also removes unused preserveBookingsQueryParams function from Navigation.tsx.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: move shell navigation and badges to apps/web

Move shell navigation components and trpc-using badges from
packages/features to apps/web/modules to fix circular dependency:

- Move navigation folder to apps/web/modules/shell/navigation/
- Move TeamInviteBadge.tsx to apps/web/modules/shell/
- Create Shell wrapper in apps/web that provides MobileNavigationContainer
- Update all Shell imports in apps/web to use the new wrapper
- Remove MobileNavigationContainer default from features Shell.tsx
- Fix pre-existing lint warnings in touched files

This establishes the pattern for migrating React components that use
trpc hooks from the features layer to the web app layer, ensuring
proper dependency direction: apps/web imports from packages/features,
never the reverse.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: move SideBar.tsx to apps/web to fix build error

SideBar.tsx was importing Navigation from the moved navigation folder,
causing a build error. Moving SideBar.tsx to apps/web and updating the
features Shell to not have a default SidebarContainer fixes this.

The web Shell wrapper now provides both the default SidebarContainer
and MobileNavigationContainer, maintaining the injection pattern.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* revert

* revert

* revert

* wip

* wip

* wip

* wip

* wip

* wip

* not used anywhere

* wip

* wip

* wip

* wip

* fix

* fix

* wip

* wip

* wip

* wip

* wip

* fix

* fix

* fix

* fix

* migrate

* migrate admin-adpi

* wip

* feat: migrate organization settings components from packages/features to apps/web/modules

- Migrate profile.tsx, appearance.tsx, general.tsx, privacy.tsx, guest-notifications.tsx, delegationCredential.tsx, other-team-members-view.tsx, other-team-profile-view.tsx
- Migrate attributes directory (AttributesForm.tsx, DeleteAttributeModal.tsx, ListSkeleton.tsx, attributes-create-view.tsx, attributes-edit-view.tsx, attributes-list-view.tsx)
- Migrate admin directory (AdminOrgEditPage.tsx, AdminOrgPage.tsx, WorkspacePlatformPage.tsx)
- Update all page imports to use new paths from ~/settings/organizations/
- Update relative imports in migrated files to use @calcom/features paths
- Fix lint warnings in migrated files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update test import path after migration

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: remove unnecessary test-setup import (already in vitest config)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* wip

* refactor: delete original files after migration to apps/web/modules

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* fix

* fix

* fix

* fix

* wip

* refactor more

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* mv

* update import paths

* wip

* wip

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* mv

* mv

* mv

* fix

* wip

* wip

* fix

* fix

* fix

* fix: make test mocks resilient to vi.resetAllMocks()

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: fix AttributeForm test failures

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* refactor: move ee files to apps/web/modules/ee/ folder

- Move teams, workflows, and organizations folders to apps/web/modules/ee/
- Add LICENSE file to apps/web/modules/ee/
- Update all import paths from ~/teams/ to ~/ee/teams/
- Update all import paths from ~/settings/organizations/ to ~/ee/organizations/
- Remove duplicate MemberInvitationModal copy.tsx file

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: move useHasPaidPlan and dependent files to apps/web/modules

- Move useHasPaidPlan.ts from packages/features/billing/hooks to apps/web/modules/billing/hooks
- Move intercom files from packages/features/ee/support to apps/web/modules/ee/support
- Move ContactMenuItem.tsx and dependencies (freshchat, helpscout, zendesk) to apps/web/modules/ee/support
- Move ViewRecordingsDialog.tsx and RecordingListSkeleton to apps/web/modules/ee/video
- Move CalVideoSettings.tsx to apps/web/modules/eventtypes/components/locations
- Move CreateOrEditOutOfOfficeModal.tsx to apps/web/modules/settings/outOfOffice
- Refactor UpgradeTeamsBadge to accept props and create wrapper in apps/web/modules/billing
- Update all callers to use new file locations
- Add eslint-disable comments for pre-existing lint warnings

This fixes the tRPC server build failure caused by circular dependency where
the server build was traversing into packages/features and pulling in React
hooks that depend on @calcom/trpc/react types.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: correct UpgradeTeamsBadge import path to use package export

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix: pass plan state through SelectProps to UpgradeTeamsBadge

- Add upgradeTeamsBadgeProps field to ExtendedOption type in Select component
- Update OptionComponent to spread upgradeTeamsBadgeProps to UpgradeTeamsBadge
- Update getOptions.ts to accept PlanState object and include upgradeTeamsBadgeProps
- Update WorkflowStepContainer.tsx to pass planState to getWorkflowTriggerOptions/getWorkflowTemplateOptions
- Update WorkflowDetailsPage.tsx to pass upgradeTeamsBadgeProps in transformed action options
- Update AddActionDialog.tsx interface and mapping to include upgradeTeamsBadgeProps
- Add eslint-disable comments for pre-existing React Hook dependency warnings

This fixes the UpgradeTeamsBadge refactoring issue where the badge was always showing
'upgrade' text instead of the correct text based on plan state (trial_mode, inactive_team_plan, etc.)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update import paths to use /ee/ folder for workflows and organizations

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update workflow component imports to use /ee/ folder

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing types.ts for LocationInput.tsx

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: extract BookingRedirectForm type to shared location

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* wip

* wip

* fix: update BookingRedirectForm import to use local types file

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* wip

* fix

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-23 12:22:26 -03:00
Pedro CastroandKeith Williams 7847177e8b fix(api): accept avatar URLs and use email for user creation (#25629)
* fix(api): fix user creation with avatarUrl and username

- avatarValidator: accept URLs in addition to base64 images
- organizations-users-service: use email for user creation instead of username

The avatarValidator was incorrectly rejecting valid URLs even though the API documentation shows URL examples and all e2e tests use URLs.

The user creation was failing when username was provided because createNewUsersConnectToOrgIfExists requires a valid email, not username. The username is correctly applied via updateOrganizationUser after creation.

Fixes user creation endpoint POST /v2/organizations/{orgId}/users

* test(api): add tests for avatar validator fixes

  Add comprehensive test coverage for avatarValidator changes:

  - Unit tests: 18 scenarios covering valid/invalid URLs and base64 images
  - E2E tests: user creation with username + avatarUrl (URL and base64)
  - Security validation: reject unsafe protocols and malformed data
  - Error message verification for validation failures

  Addresses testing requirements from code review

* fix(api): enhance avatar validator security per code review

  - Reject HTTP URLs, accept only HTTPS for security and browser compatibility
  - Reject empty strings and whitespace (use null to reset avatar)
  - Update validation message to clarify HTTPS requirement
  - Add test coverage for new security restrictions

 Addresses security feedback from code review regarding mixed content vulnerabilities and clearer API semantics for avatar reset

* refactor(api): simplify avatarValidator null check

Remove redundant null/undefined check since @IsOptional decorator already skips validation for undefined values. Updated test mock to include @IsOptional to match real DTO usage

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-23 15:07:14 +00:00
Hariom BalharaandDevin AI 866c8c046d fix: create host records when team membership transitions to accepted via PATCH (#26138)
The PATCH endpoint for /v2/teams/:teamId/memberships/:membershipId had a bug
where host records for assignAllTeamMembers event types were not created when
a membership transitioned from accepted=false to accepted=true.

The bug was caused by incorrect operation ordering:
1. Update membership (first update)
2. Get current membership (gets already-updated state)
3. Update membership again (second update)
4. Check if transition happened (condition never fires)

Fixed by reordering to match the org-scoped controller pattern:
1. Get current membership BEFORE any updates
2. Update membership
3. Compare and call updateNewTeamMemberEventTypes if transition occurred

Also added an e2e test to verify host records are created when membership
transitions from accepted=false to accepted=true via PATCH.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-23 10:46:14 +00:00
Kartik LabhshetwarandDhairyashil Shinde 96f8a89efa fix: replace console logging with logger across services and features (#26127)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-23 08:24:23 +00:00
Kartik Labhshetwar a2cb529d62 fix: update CommandInput styling for focus and transition (#26055) 2025-12-23 13:16:55 +05:30
9c680838b6 fix(companion): improve code clarity and type safety in components (#26062)
- Remove 'as any' type assertion in LoginScreen.tsx, use Platform.OS check
- Fix malformed className string in LogoutButton.tsx (extra quotes)
- Remove @ts-ignore comments in Tooltip.tsx with proper web-specific types
- Replace 'any' type with Schedule type in AvailabilityTab.tsx
- Replace 'any' type with 'string' for SF Symbol icons in EventTypeListItem.ios.tsx
- Remove console.log error handling in SvgImage.tsx
- Extract duplicated formatDuration function to use shared utility from formatters.ts
- Extract repeated inline styles to sectionDividerStyle constant in AvailabilityTab.tsx

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2025-12-23 00:26:16 +00:00
Dhairyashil ShindeandPeer Richelsen 6650fdb9ef refactor(companion): extract AvailabilityDetailScreen with AppPressable migration (#26106)
* refactor(companion): extract AvailabilityDetailScreen with AppPressable migration

Apply Phases 2, 3, 4 to availability-detail.tsx:
- Phase 2: Extract screen logic (~995 lines) to components/screens/AvailabilityDetailScreen.tsx
- Route file is now a minimal ~35 line wrapper with Stack.Screen config
- Phase 3: ScrollView+map pattern kept (7 days is a fixed small list, FlatList not needed)
- Phase 4: Migrate all TouchableOpacity to AppPressable (63 instances)

Follows the same pattern as EventTypeDetailScreen extraction.

* fix(companion): add GlassView header with Save button to AvailabilityDetailScreen (#26107)

* refactor(companion): extract BookingDetailScreen with AppPressable migration (#26108)

* refactor(companion): extract AvailabilityListScreen with AppPressable migration (#26109)

* fix(companion): add GlassView header with Save button to AvailabilityDetailScreen

* refactor(companion): extract BookingDetailScreen with AppPressable migration

* refactor(companion): extract AvailabilityListScreen with AppPressable migration

* refactor(companion): Standardized error handling with dev-only debug logs (#26110)

* address cubics comments

* address cubics comments

* addressed typecheck erros

* removed localhost from wxt.config for chrome extension

* declare FullScreenModal  FullScreenModalProps

---------

Co-authored-by: Peer Richelsen <peer@cal.com>

* add loggers for dev env

---------

Co-authored-by: Peer Richelsen <peer@cal.com>

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
2025-12-22 22:47:55 +00:00
Dhairyashil Shinde 9909ac53fc fix: use app name instead of app slug in email (#25285)
* fix: google calender name in email

* fix: google calender name in email

* cleaner code

* test: add test for human-readable app name in appsStatus
2025-12-23 03:41:08 +05:30
Anik Dhabal Babu f598a8ebdd ci: skip merge & report publishing when all E2E tests pass (#23552)
* fix

* Refactor PR workflow to use pull_request_target

Updated the GitHub Actions workflow

* update

* Update PR workflow trigger and permissions

Changed event trigger from 'pull_request_target' to 'pull_request' and removed branch restrictions.

* test

* revert
2025-12-22 19:31:43 +00:00
23920fe9ce fix: Org/team admin or owner should be marked as ‘no show’ in a member’s booking (#26009)
* fix: update tempOrgRediret on updating s
lug

* Update packages/trpc/server/routers/viewer/organizations/adminUpdate.handler.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor

* fix

* fix

* revert

* fix handle no show

* revert

* Remove metadata from organization query selection

Removed metadata selection from organization query.

* use repo

* update

* Update packages/features/bookings/lib/checkIfUserIsAuthorizedToManageBooking.ts

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>

* update

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2025-12-22 15:42:20 -03:00
Anik Dhabal Babu 33eee8dfc3 fix: Email reminder issue with seated event (#26136)
* fix emailworkflow reminder attendee

* update
2025-12-22 18:26:40 +00:00
Amit Sharma f5b9b6b0f9 feat: store ads clickid when creating an account (#25763)
* feat: store ads clickid when creating an account

* fix: type check

* fix: google campaignId not being added to stripe

* remove tracking in stripe app
2025-12-22 23:29:51 +05:30
b664857809 feat: set HubSpot meeting owner from cal's organizer (#25998)
* feat: add HubSpot owner(organizer in cal)

* refactor: improve logging and token handling in HubSpot integration

* Update packages/app-store/hubspot/lib/CrmService.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* feat: enhance error handling for missing scopes

* refactor

* remove unused

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
2025-12-22 22:52:04 +05:30
Anik Dhabal Babu c746fdcdfe ix disable cancelling persistence and rescheduling toggle (#26131) 2025-12-22 15:31:16 +00:00
76b53eb3d4 chore: remove webpack config and convert next.config to TypeScript (#26126)
* chore: remove webpack experimental flags from apps/web

- Remove webpackMemoryOptimizations and webpackBuildWorker from experimental config
- Remove unused DefinePlugin for process.env.BUILD_ID (not used anywhere in codebase)
- Remove unused buildId parameter from webpack function signature

These webpack-specific experimental flags were showing up during dev mode
even though Turbopack is used for development. The flags only apply to
production webpack builds and their presence in the config was confusing.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: remove webpack function for full Turbopack build

- Remove entire webpack function (IgnorePlugin, PrismaPlugin, resolve.fallback, sideEffects)
- Remove unused PrismaPlugin import
- Turbopack handles all bundling without webpack configuration

Benchmark shows no performance regression:
- Main (with webpack): 67s compile
- Full webpack removal: 69s compile

Both fail at same pre-existing TypeScript error on main branch.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: convert next.config.js to TypeScript

- Convert CommonJS require() to ES6 imports
- Add proper TypeScript types for config and plugins
- Remove /* eslint-disable */ comment
- Keep all existing functionality intact

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* conditional load axiom

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-22 12:23:00 -03:00
Amit Sharma 090247a058 fix: event type not installed apps list empty (#26128) 2025-12-22 13:37:52 +00:00
Hariom BalharaandDevin AI e23354b48b fix: ESC key handler only works once in embed modal (#25615)
* fix: ESC key handler only works once in embed modal

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Fix bug found by cubic and add tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-22 10:06:09 -03:00
Syed Ali Shahbaz 0b7f51410a chore: Add webhook version documentation link to webapp (#26121)
* init

* further improvement
2025-12-22 10:22:41 +00:00
Anik Dhabal Babu 31da9eaa8f fix: e2e flakes on analytics apps tests (#26119)
* test

* test

* fix flakes
2025-12-22 15:30:01 +05:30
192d927232 fix: align page headers by removing py-2 padding from ShellMain (#26084)
* fix: align insights header with other pages by using ShellMainAppDir

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: remove py-2 padding from ShellMain to align with ShellMainAppDir

Co-Authored-By: peer@cal.com <peer@cal.com>

* address cubics comment - keep sticky bg, only remove padding

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2025-12-22 09:31:56 +00:00
Rajiv Sahal f9ff3248e5 feat: endpoint to update location for existing booking (#25367)
* feat: init endpoint to update booking location

* chore: update controller

* chore: DTOs for update location endpoint

* chore: add update booking method

* fix: refactor

* feat: service update booking location

* chore: update platform libraries

* chore: update exports

* chore: e2e tests for updating booking location endpoint

* chore: update e2e tests for updating booking location endpoint

* chore: update bookings module

* fixup

* chore: update configs

* fixup: revert changes

* chore: remove unused handlers

* fix: update inputs

* refactor: booking location service

* fixup

* revert: unnecessary changes

* chore: cleanup

* fix: e2e tests

* chore: implement cubic feedback

* chore: implement feedback

* fixup

* chore: more PR feedback
2025-12-22 09:25:00 +00:00
mintlify[bot] 6ebd401953 Update docs/developing/guides/automation/webhooks.mdx (#26118)
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2025-12-22 09:20:07 +00:00
mintlify[bot]andSyed Ali Shahbaz d69ba02851 Add versioned webhook payload reference with interactive selection (#26008)
* Update docs/developing/guides/automation/webhooks.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/developing/guides/automation/webhooks.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/developing/guides/automation/webhooks.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/developing/guides/automation/webhooks.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/developing/guides/automation/webhooks.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Update docs/developing/guides/automation/webhooks.mdx

Co-Authored-By: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>

* Documentation edits made through Mintlify web editor

* Documentation edits made through Mintlify web editor

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2025-12-22 06:19:02 +00:00
Keith WilliamsandDevin AI 851cca25aa perf: add z.ZodType annotations to high-impact schemas (#26114)
* perf: add z.ZodType annotations to high-impact schemas

Add explicit type annotations to reduce TypeScript type inference overhead
and .d.ts file bloat in the tRPC package.

Changes:
- packages/prisma/zod-utils.ts: Add EventTypeLocation type and annotate eventTypeLocations schema
- packages/features/eventtypes/lib/schemas.ts: Add TEventTypeDuplicateInput and TCreateEventTypeInput types with annotations
- packages/app-store/routing-forms/zod.ts: Add FieldOption, TNonRouterField, TRouterField, TField, TFields types with annotations for zodField and zodFields

These schemas feed into multiple tRPC routers and were identified as high-impact
targets for reducing type checking time and declaration file sizes.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: replace z.infer with explicit types and define EventTypeLocation locally

Address PR feedback:
- Replace z.infer<typeof calVideoSettingsSchema> with explicit CalVideoSettings type
- Define EventTypeLocation type locally instead of importing from prisma
- Add z.ZodType annotation to calVideoSettingsSchema

Note: Still importing Zod schemas from @calcom/prisma/zod-utils for validation.
Awaiting guidance on whether to move those to @calcom/lib.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 23:15:04 -03:00
ee6989a575 refactor: split raqbUtils into server and client modules to fix RAQB import in server context (#26112)
* refactor: add server and client raqbUtils modules

Add two new modules to split RAQB utilities:
- raqbUtils.server.ts: Server-safe utilities without RAQB runtime
- raqbUtils.client.ts: Client-only utilities requiring RAQB runtime

This enables server-side code to import RAQB utilities without
pulling in the react-awesome-query-builder runtime library.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: update imports to use server/client raqbUtils modules and fix lint warnings

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: fix type errors in getLuckyUser.ts and remove dead code in RouteBuilder.tsx

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-22 02:00:19 +00:00
Keith WilliamsandDevin AI 545eed9b0d fix: always fetch fresh PR labels to avoid stale event payload data (#26113)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-22 01:06:05 +00:00
Volnei MunhozandDevin AI 40883386f0 fix: address peer dependency issues across the monorepo (#26105)
MOVE:
- Move @next/third-parties from root to apps/web (only used there)
- Remove date-fns-tz from root, add date-fns and date-fns-tz to root deps

REMOVE:
- Remove sonner from packages/lib (not used there, already in apps/web)
- Remove next-seo from packages/ui (not used there, already in apps/web)
- Remove next-auth from apps/api/v2 (only used for User type in tests)

ADD peerDependencies:
- packages/ui: add react-dom
- packages/features: add react, react-dom, react-is, date-fns-tz, stripe, zod
- packages/platform/atoms: add react-dom
- packages/trpc: add next, react, react-dom

ADD dependencies:
- apps/web: add @next/third-parties, i18next, react-i18next
- apps/api/v2: add axios (required by @nestjs/axios)

FIX:
- apps/api/v2: replace next-auth User type with @calcom/prisma/client User

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 23:20:49 +00:00
0673d667f8 feat: upgrade api/v1 and example apps to Next.js 16.1.0 (#26104)
* feat: upgrade api/v1 and example apps to Next.js 16.1.0

- Update apps/api/v1 to Next.js 16.1.0
- Rename middleware.ts to proxy.ts per Next.js 16 migration
- Add turbopack config to next.config.js
- Update packages/platform/examples/base to Next.js 16.1.0
- Add eslint-disable to config files (following apps/web pattern)

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: update yarn.lock for Next.js 16.1.0 upgrade

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 18:19:18 -03:00
a2e2b7ff97 chore: upgrade yarn from 3.4.1 to 4.12.0 (#26102)
* chore: upgrade yarn from 3.4.1 to 4.12.0

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: update engines.yarn to match upgraded version

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 17:20:56 -03:00
Keith WilliamsandDevin AI 127b7d5532 ci: consolidate changes and check-label jobs into prepare (#26101)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 19:51:37 +00:00
a9a3389039 feat: upgrade apps/web to Next.js 16.1.0 (#26093)
* feat: upgrade apps/web to Next.js 16.1.0

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: enable Turbopack for Next.js 16.1 production builds

- Add turbopack: {} config to next.config.js to enable Turbopack for builds
- Fix re-exported config errors in webhook API routes by defining config locally
  - alby/webhook.ts
  - btcpayserver/webhook.ts
  - paypal/webhook.ts
  - stripepayment/webhook.ts

Turbopack requires route segment configs to be statically analyzable,
so they cannot be re-exported from other modules.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update revalidateTag calls for Next.js 16.1 API changes

Next.js 16.1 changed the revalidateTag signature to require a second
argument (profile). Using 'max' profile as recommended by Next.js docs
for stale-while-revalidate semantics.

Updated files:
- app/(booking-page-wrapper)/team/[slug]/[type]/actions.ts
- app/(use-page-wrapper)/(main-nav)/teams/actions.ts
- app/(use-page-wrapper)/settings/(settings-layout)/developer/api-keys/actions.ts
- app/(use-page-wrapper)/settings/(settings-layout)/organizations/roles/actions.ts
- app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/actions.ts
- app/cache/travelSchedule.ts

Also cleaned up next.config.js turbopack config formatting.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add profile parameter to revalidateTag in membership.ts for Next.js 16.1

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix routing form

* refactor: rename middleware.ts to proxy.ts per Next.js 16 migration

Next.js 16 has deprecated the 'middleware' file convention and renamed it to 'proxy'.
This change follows the official migration guide:
https://nextjs.org/docs/messages/middleware-to-proxy

Changes:
- Renamed apps/web/middleware.ts to apps/web/proxy.ts
- Renamed the middleware function to proxy
- Updated CODEOWNERS reference
- Updated comment reference in logout page

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-21 16:31:48 -03:00
Eesh MidhaandDhairyashil Shinde 4b4565b19d fix: constrain AddActionDialog overflow and footer behavior (#26087)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-21 17:08:37 +00:00
Keith WilliamsandDevin AI 2da6f5b3b1 fix: remove labeled trigger to prevent workflow reruns on non-E2E labels (#26099)
When any label is added to a PR, the workflow was re-running and causing issues
because the E2E check would fail for non-ready-for-e2e labels.

This change removes 'labeled' from the trigger types entirely. Users can now:
1. Add the ready-for-e2e label to a PR
2. Click 'Re-run all jobs' in GitHub Actions UI to trigger E2E tests

This is simpler and avoids the complexity of trying to maintain previous check
status when non-E2E labels are added.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 15:54:35 +00:00
Volnei Munhoz d61a613911 fix: use idiomatic dorny/paths-filter exclusion pattern (#26097) 2025-12-21 14:49:43 +00:00
Keith WilliamsandDevin AI 09f2aa113b fix: resolve lint warnings in web app (#26017)
* fix: resolve lint warnings in web app

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove unused isReadPermission variable

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove unused loading state entirely

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 14:38:27 +00:00
f7bb2683cb ci: skip Playwright install on cache hit (#26060)
* update

* Add cache-db action to e2e workflow

* fix: remove cache-db from prepare job (requires Postgres service)

The prepare job doesn't have a Postgres service container, so cache-db
was failing with 'connection refused' when trying to run psql.

cache-db should only run in the e2e shards which have the Postgres service.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* update

* Update e2e.yml

* Add newline at end of e2e.yml file

* fix

* Fix indentation in e2e.yml for retention-days

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 10:58:41 -03:00
83ee986bbd fix: lock package versions and organize devDependencies (#26095)
* fix: lock package versions to exact versions from yarn.lock

Replace version ranges (^, ~) with exact resolved versions from yarn.lock
to ensure consistent dependency resolution across all environments.

This change affects 26 package.json files with 89 version updates including:
- TypeScript: ^5.9.0-beta -> 5.9.2
- Zod: ^3.22.4 -> 3.25.76
- React: ^18 -> 18.2.0
- Various Radix UI, Vite, PostCSS, and other dependencies

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: preserve npm alias format for @radix-ui packages

The previous commit incorrectly converted npm aliases like
'npm:@radix-ui/react-dialog@^1.0.4' to just '1.0.4', which broke
yarn install as it tried to find non-existent packages.

This fix restores the npm alias format while keeping the pinned versions:
- @radix-ui/react-dialog-atoms: npm:@radix-ui/react-dialog@1.0.4
- @radix-ui/react-tooltip-atoms: npm:@radix-ui/react-tooltip@1.0.6

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor: move dev dependencies to devDependencies section

Move 26 dependencies that are clearly development-only to the
devDependencies section across 10 packages:

- Testing: @types/jest, jest, ts-jest, @golevelup/ts-jest
- Build tools: typescript, ts-node, concurrently, dotenv-cli
- Linting: eslint-*, eslint-config-*, eslint-plugin-*
- Types: @types/express, @types/turndown, @types/uuid

This improves dependency organization and ensures production builds
don't include unnecessary development dependencies.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-21 10:18:07 -03:00
Dhairyashil Shinde c8af45537a fix: three dots icon missing for ios availability (#26094) 2025-12-21 12:54:13 +00:00
19ac0139c1 fix: Remove all links legacyBehavior (#25585)
* Remove all links legacyBehavior

* fix: resolve type errors in Button and Dropdown when using Link without legacyBehavior

- Button.tsx: Only pass ref to button element, not to Link (Link manages its own anchor)
- Dropdown.tsx: Strip ref from props when using Link to avoid type incompatibility

This fixes the type errors that were causing API V1 and V2 builds to fail.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: only pass disabled and type props to button element, not to Link

Link component doesn't accept disabled or type props, so these should only be passed when rendering a button element.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: strip ref from passThroughProps when rendering Link

The passThroughProps spread was including a ref property that's incompatible with Link's expected ref type. This strips the ref when rendering a Link component.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: use type assertion for React.createElement props to handle union types

The Button component uses a union type for props that can be either Link or button props. TypeScript can't narrow the union type properly when using React.createElement with a dynamic element type, so we use a type assertion to cast the props to the correct type.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: render Link and button separately to avoid type conflicts

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: preserve data-testid when rendering Button as Link

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 12:40:27 +00:00
Dhairyashil Shinde 067fa7e137 feat(companion): Add Google Calendar mark no-show functionality (#26085) 2025-12-21 13:30:31 +01:00
Beto aa127b2c2b refactor: (companion) (iOS) create an ios screen for specific native logic (#26081)
* create an ios screen for specific native logic

* feat: update bookings layout to conditionally show header on iOS

* feat: add useActiveBookingFilter hook for managing booking filter state

- Introduced a new hook, useActiveBookingFilter, to manage the active booking filter state and provide related utilities.
- Added filter options for "upcoming", "unconfirmed", "past", and "cancelled" bookings.
- Updated index.ts to export the new hook and its types for UI state management.

* refactor: streamline booking filter management and remove unused code

- Integrated the useActiveBookingFilter hook to manage booking filter state, simplifying the filter logic.
- Removed redundant state variables and functions related to booking filters.
- Cleaned up the code by eliminating unused imports and commented-out code sections.
- Updated the booking fetching logic to utilize the new filter parameters directly.

* refactor: move meeting URL extraction and info retrieval to utility module

- Extracted meeting URL extraction and meeting info retrieval logic into a new utility module, meetings-utils.ts.
- Updated index.ios.tsx and index.tsx to utilize the new getMeetingInfo function from the utility module, simplifying the component code.
- Removed redundant helper functions from the component files to enhance maintainability.

* refactor: extract empty state content logic into utility module

- Moved the getEmptyStateContent function from the Bookings component files to a new utility module, bookings-utils.ts, to enhance code reusability and maintainability.
- Updated index.ios.tsx and index.tsx to utilize the new utility function, simplifying the component code and improving clarity.
- Removed redundant empty state logic from the component files.

* refactor: enhance booking filtering and utility functions

- Updated the Bookings component to utilize new utility functions for filtering bookings by event type and search queries, improving code clarity and maintainability.
- Moved formatting functions (formatTime, formatDate, formatMonthYear, getMonthYearKey) and grouping logic (groupBookingsByMonth) to the bookings-utils module, centralizing related functionality.
- Removed redundant code from the Bookings component files, streamlining the overall structure.

* refactor: implement booking actions hook for improved management

- Introduced a new `useBookingActions` hook to centralize booking-related actions such as rescheduling, confirming, and rejecting bookings, enhancing code organization and reusability.
- Updated the `Bookings` component to utilize the new hook, simplifying the component logic and reducing redundancy.
- Removed outdated state management and functions related to booking actions, streamlining the overall code structure.

* refactor: consolidate booking components and enhance structure

- Refactored the Bookings component to utilize a new BookingListScreen component, improving code organization and readability.
- Introduced BookingListItem for individual booking rendering, streamlining the rendering logic and enhancing maintainability.
- Removed redundant state management and functions from the Bookings component, simplifying the overall structure.
- Updated modal handling for booking actions, rescheduling, and rejection to improve user experience and code clarity.

* feat: add BookingListItem component for enhanced booking display

- Introduced a new BookingListItem component for rendering individual booking details, improving modularity and reusability.
- Implemented context menu actions for booking management, including rescheduling, editing location, and adding guests.
- Updated type definitions for BookingListItemProps to include additional action handlers for better functionality.
- Refactored existing BookingListItem component to utilize the new props structure, enhancing clarity and maintainability.

* refactor: simplify layout and styling in BookingListItem and BookingListScreen components

- Updated the BookingListItem component to streamline the layout by reducing padding and adjusting the gap between elements.
- Modified the BookingListScreen component to remove unnecessary horizontal padding in the content container style, enhancing the overall layout consistency.
2025-12-21 11:38:42 +00:00
51bce6763f refactor: split tRPC build into server and react phases (#26082)
* refactor: import AppRouter from generated types instead of server source

This change improves tRPC build performance by having the client-side code
import AppRouter from pre-generated type declarations instead of traversing
the entire server router tree.

Changes:
- Create type bridge file at packages/trpc/types/app-router.ts
- Update packages/trpc/react/trpc.ts to import from the bridge
- Update .gitignore to only ignore types/server (generated files)
- Update eslint.config.mjs to only ignore types/server (generated files)

The type bridge provides:
1. Faster typechecking - avoids parsing 458 server files
2. Stable import location that's easy to lint against
3. Single place to adjust if generated path changes

Build order is already enforced in turbo.json (type-check depends on @calcom/trpc#build).

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: move bridge file to react/ to avoid TS5055 error

Move the AppRouter type bridge file from types/app-router.ts to react/app-router.ts
to avoid the TS5055 'Cannot write file because it would overwrite input file' error.

The issue was that placing the bridge file in types/ caused TypeScript to treat
the generated .d.ts files as input files during the tRPC build, then fail when
trying to emit to the same location.

By placing the bridge in react/ (which is excluded from the tRPC server build),
the bridge file is only used by client code and doesn't interfere with the
server type generation.

Changes:
- Move bridge file from types/app-router.ts to react/app-router.ts
- Update import in react/trpc.ts to use ./app-router
- Revert .gitignore to ignore all of types/ (generated files)
- Revert eslint.config.mjs to ignore all of types/**

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: split tRPC build into server and react phases

- Create tsconfig.server.json for server-only type generation
- Create tsconfig.react.json for react/client type generation
- Update build script to run server build first, then react build
- Remove || true so build properly fails on errors
- This allows react code to import from generated server types

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: split @calcom/trpc exports to separate server and react entrypoints

- Remove react exports from @calcom/trpc root (index.ts)
- Update 89 files to import from @calcom/trpc/react instead of @calcom/trpc
- This fixes the boundary leak where server builds were pulling in react code
- Server build no longer compiles react/app-router.ts, fixing the chicken-and-egg
  issue where react code needed generated server types that didn't exist yet

This improves TypeScript build performance by preventing the server type
generation from traversing the entire react/client type graph.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: import WorkflowType from lib/types instead of React component

This fixes a boundary leak where the server build was pulling in React
components through the WorkflowRepository import chain. By importing
WorkflowListType from lib/types instead of WorkflowListPage.tsx, the
server build no longer traverses React component files.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: extract server-safe types to prevent boundary leaks in tRPC build

- Extract ChildrenEventType to lib/childrenEventType.ts (server-safe)
- Extract Slots type to calendars/lib/slots.ts (server-safe)
- Create types.server.ts files for eventtypes and bookings
- Update server code to import from server-safe type files
- Update DatePicker.tsx to use extracted Slots type
- Update app-store utils to use BookerEventForAppData type

This prevents the server build from pulling in React files through
transitive imports from @calcom/features barrel exports.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update Segment.test.tsx mock path to @calcom/trpc/react

The test was mocking @calcom/trpc but importing from @calcom/trpc/react.
After the entrypoint separation, the mock path needs to match the import path.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: temporarily restore || true to unblock PR merge

The pre-existing Prisma type errors (~345 errors) will be addressed in a follow-up PR.
This allows the two-phase build architecture changes to be merged first.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Run trpc build as part of API v2 build

* Removed the bridge file

* refactor: extract event type schemas to server-safe file

- Create packages/features/eventtypes/lib/schemas.ts with createEventTypeInput and EventTypeDuplicateInput
- Update types.ts to re-export schemas from the new server-safe location
- Update tRPC schema files to import from schemas.ts instead of types.server.ts
- Delete types.server.ts (was duplicating ~200 lines unnecessarily)

This keeps the server build graph clean while avoiding code duplication.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Removed the optionality of the tRPC builds

* Removed the extra command for API v2

* refactor: rename calendars/lib/slots.ts to types.ts

Per Keith's feedback, renamed the file to types.ts since it contains type definitions.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Added back tRPC build:server for API v2

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-20 23:43:04 -03:00
Keith WilliamsandDevin AI 0e3696f20c chore: dedupe yarn.lock to remove duplicate package versions (#26068)
* chore: dedupe yarn.lock to remove duplicate package versions

- Consolidated 762 duplicate package versions
- Reduced yarn.lock from 51,211 lines (1.7MB) to 44,471 lines (1.5MB)
- Removed 7,071 lines (~200KB) of redundant dependency entries
- Major packages deduplicated include: resolve, semver, type-fest, commander, glob, lru-cache, dotenv, @babel/* packages, typescript, tslib, postcss, and many more

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: resolve type errors in managed event types and react-select components

- Add Zod-compatible versions of allManagedEventTypeProps and unlockedManagedEventTypeProps
  that only include scalar fields (excludes Prisma relation fields)
- Update handleChildrenEventTypes.ts and queries.ts to use the new Zod-compatible props
- Fix react-select CSS type errors in Select.tsx files by using Object.assign
  instead of spread operator to avoid TypeScript type inference issues
- Fix lint warning in updateNewTeamMemberEventTypes by using if statement

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: derive eventType parameter type from actual query result

Use Awaited<ReturnType<typeof getEventTypesToAddNewMembers>>[number] to ensure
type safety at call sites, avoiding Prisma type namespace mismatches.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: disable turbo cache for @calcom/trpc#build to prevent stale type errors

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: correct field names in API v1 validation schemas

- Remove timeZone from booking schema (field doesn't exist on Booking model)
- Remove bookingId from destination-calendar schema (field doesn't exist, only booking relation)
- Change avatar to avatarUrl in user schema (correct field name)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use Object.assign for react-select styles to fix TypeScript spread type errors

The spread operator causes TypeScript to compute an incompatible type with
CSSObjectWithLabel due to the accentColor property. Using Object.assign
preserves the correct type inference.

Fixed files:
- FormEdit.tsx
- DestinationCalendarSelector.tsx (features and platform)
- TimezoneSelect.tsx
- ApiKeyDialogForm.tsx
- Select.tsx (features/form)
- WebhookForm.tsx

Also fixed pre-existing lint warnings:
- Constant truthiness in label assignment
- Unused variant parameter

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove extra fields from allManagedEventTypePropsForZod to match original behavior

The Zod-compatible version should only include scalar fields that were in the
original allManagedEventTypeProps. Removed instantMeetingScheduleId, profileId,
rrSegmentQueryValue, and assignRRMembersUsingSegment which were incorrectly
added and caused test failures by including extra fields in Prisma update payloads.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove access to fields not in Zod schema

- Remove unnecessary destructuring of profileId and instantMeetingScheduleId
  from managedEventTypeValues in handleChildrenEventTypes.ts (these fields
  are already sourced from other variables)
- Set rrSegmentQueryValue to undefined directly in queries.ts instead of
  accessing it from managedEventTypeValues (not applicable for managed children)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add name property to mock credentials and revert turbo cache change

- Add name property to MockCredential type and factory function in
  InstallAppButtonChild.test.tsx to match expected credentials type
- Revert turbo cache disable for @calcom/trpc#build (per review comment)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: revert API v1 validation changes and restore eslint comment

- Revert API v1 validation changes (booking.ts, destination-calendar.ts,
  user.ts) since API v1 is deprecated and these could be breaking changes
- Restore eslint-disable comment for @typescript-eslint/no-empty-function
  in Select.tsx that was accidentally removed

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add inputs to @calcom/trpc#build to properly invalidate cache

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: properly fix API v1 validation schemas for stricter zod 3.25.76

The yarn dedupe upgraded zod from 3.22.4 to 3.25.76, which has stricter
.pick() typing that now properly rejects picking non-existent fields.

Changes:
- user.ts: Pick avatarUrl (actual Prisma field) and extend with avatar
  for API v1 backward compatibility
- booking.ts: Remove timeZone from pick (not a field on Booking model,
  only exists in nested attendees/user objects)
- destination-calendar.ts: Remove bookingId from pick (not a field on
  DestinationCalendar model)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove turbo.json inputs for @calcom/trpc#build to use cached artifacts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use robust selector for react-select option in routing forms E2E test

The previous selector used .nth(1) which assumed the email text appeared
exactly twice in the DOM in a specific order. This broke when react-select
was upgraded from 5.7.2 to 5.8.0 via yarn dedupe.

The new approach waits for the react-select listbox to appear and clicks
the option within it, which is more robust against DOM structure changes.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-20 23:30:03 -03:00
github-actions[bot] f846126a2d chore: version packages (#25833)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-20 22:05:28 +00:00
Keith WilliamsandDevin AI 825f55c0a1 fix: extract shared types to non-React modules to fix circular dependencies (#26083)
- Move InvalidAppCredentialBannerProps to packages/features/users/types/invalidAppCredentials.ts
- Add WorkflowListType to packages/features/ee/workflows/lib/types.ts
- Update server file imports to use new type locations
- Update React component imports to re-export from new locations

This fixes circular dependencies where server files were importing from React
component modules that import from @calcom/trpc, creating:
server -> component -> @calcom/trpc -> react -> server (circular)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 01:43:49 +05:30
Pedro Castro 9ae2381755 fix(auth): validate IdP authority before SAML account linking (#26005)
* fix(auth): validate IdP authority before SAML account linking

Adds verification that SAML IdP is authoritative for the email domain
before allowing account conversion

* fix(auth): deny by default on missing SAML tenant + optimize membership query

 - Block account conversion when tenant is missing (deny by default)
 - Replace JOIN + ILIKE with two indexed lookups for O(1) performance

* refactor(auth): apply data minimization to security logs
2025-12-20 17:45:18 +00:00
Anik Dhabal Babu a37805439b fix: fix credential type mismatch in AppPage component (#25802)
* test

* update

* Refactor create-event-type.input.ts for slug handling

Removed unused import and transformation for slug.

* Remove slugify transformation from slug field

Removed slugify transformation from slug property.

* Remove slugify transformation from slug field

Removed slugify transformation from slug property.
2025-12-20 17:11:35 +00:00
253c33df33 perf: (googlecalendar): batch freebusy calls by delegation credential (#24332)
* perf(googlecalendar): batch freebusy calls by delegation credential

- Group selectedCalendars by delegationCredentialId before making API calls
- Make one batched freebusy query per delegation credential group
- Reduces total API calls while respecting credential boundaries
- Maintains existing caching behavior per group
- Updated both getAvailability and getAvailabilityWithTimeZones methods
- Added groupCalendarsByDelegationCredential helper method
- Handles edge case when no calendars provided but fallbackToPrimary is true
- Fixed linting issue: replaced hasOwnProperty with 'in' operator

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* test(googlecalendar): add test for delegation credential batching

- Verify calendars are grouped by delegationCredentialId
- Ensure exactly 3 API calls made for 3 delegation credential groups
- Confirm all busy times from different groups are properly returned
- Fix type-safety issues by replacing 'as any' with proper type constraints
- Fix ESLint warnings: unused variables and any types in mock functions

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix(googlecalendar): ensure fallback logic works with empty calendar groups

- Handle empty calendar groups by ensuring at least one iteration
- Add test for chunking groups larger than 50 calendars
- Verify all delegation credential batching logic works correctly

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: fix remaining type errors from merge conflict resolution

- Changed getCacheOrFetchAvailability to getFreeBusyData in getAvailabilityWithTimeZones
- Removed orphaned merge conflict marker in test file

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: reset test file to original PR version and update method name

- Reset CalendarService.test.ts to original PR version (0e9eb9e97a)
- Updated getCacheOrFetchAvailability to getFreeBusyData to match main branch

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: reset test file to main branch version

The original PR's test file had tests for caching features that have been
removed from main. Reset to main's version to fix type errors.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* test(googlecalendar): add tests for delegation credential batching logic

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Revamp devin's implementation

* Remove comsoles.log

* fix(tests): update delegation credential batching tests to match reimplementation

- Remove tests for private methods that no longer exist (groupCalendarsByDelegationCredential, chunkArray)
- Update getAvailability test to verify calendar fetching without expecting multiple API calls per delegation credential
- Keep existing tests for fallback to primary calendar and non-google calendar handling

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Remove dead code

* improve documentation

* docs: add README explaining Google Calendar availability batching feature

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* docs: translate README to English

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* docs: move README to calendar-batch package with comprehensive documentation

- Remove README from googlecalendar lib (wrong location)
- Add comprehensive README to packages/features/calendar-batch/
- Document CalendarBatchService and CalendarBatchWrapper
- Explain how getCalendar() integrates with batching
- Include architecture, data model, and performance considerations

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: address cubic-dev-ai review comments

- Remove misleading comment from getCalendar.ts cache block
- Fix typo 'optmization' -> 'optimization' in comment
- Add comprehensive tests for CalendarBatchWrapper batching behavior
  - Test separate calls for calendars without delegationCredentialId
  - Test batching calendars with same delegationCredentialId
  - Test chunking into groups of 50 for API limits
  - Test mixed calendars handling
  - Test fallbackToPrimary with empty array
  - Test result flattening from batched calls
  - Test pass-through methods delegation

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add shouldServeCache param to CalendarBatchWrapper and verify batching call count

- Fix CalendarBatchWrapper.getAvailability signature to match Calendar interface (add shouldServeCache param)
- Update CalendarBatchWrapper tests to pass shouldServeCache parameter
- Add integration test in CalendarService.test.ts that verifies CalendarBatchWrapper makes separate API calls for different delegationCredentialIds (call count assertion)
- This fixes the getCalendarsEvents test failures caused by signature mismatch

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Improve CalendarBatchImplementation

* test: add shouldServeCache forwarding and order-independent batching verification tests

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* test: make CalendarBatchWrapper tests order-independent

Refactored tests to avoid relying on Promise.all execution order:
- 'should make separate calls for calendars without delegationCredentialId'
  now uses set comparison instead of toHaveBeenNthCalledWith
- 'should batch calendars with the same delegationCredentialId together'
  now finds calls by delegation credential instead of call order

This addresses Sean's review comment about potential flakiness due to
Promise.all not guaranteeing execution order of parallel promises.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Remove hardcoded ID

* test: add comprehensive tests for resolveCalendarServeStrategy

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* feat: use Promise.allSettled for partial failure handling in CalendarBatchWrapper

- Changed Promise.all to Promise.allSettled in getAvailability and getAvailabilityWithTimeZones
- Returns partial results when some batches fail instead of failing entirely
- Logs warnings for failed batches with error details
- Added tests for partial failure scenarios

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* test: add comprehensive tests for getAvailabilityWithTimeZones

- Added batching behavior tests (separate calls, batching by delegationCredentialId, chunking)
- Added partial failure handling tests (partial results, all fail, no throw)
- Added edge case test for underlying calendar not implementing the method
- Total: 24 tests now covering both getAvailability and getAvailabilityWithTimeZones

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add required serviceAccountKey fields to delegatedTo mock objects

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add missing client_id and private_key to serviceAccountKey mock

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: keith@cal.com <keithwillcode@gmail.com>
2025-12-20 13:45:44 -03:00
ed0c9392a9 fix: E2E flakes after splitting the tests (#26059)
* fix: split confirm-emails e2e test to authenticate as booking owner

The test was flaky because it authenticated as an admin user (authEmail)
but created bookings for different users (emailsEnabledSetup.user and
emailsDisabledSetup.user). When confirming/declining bookings, the
ApiAuthGuard + BookingUidGuard rejected requests with 401 because the
authenticated user wasn't the booking owner.

The fix splits the test into two separate describe blocks, each with its
own app instance that authenticates as the actual booking owner. This
ensures the authenticated user always matches the booking owner.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: add unauthenticated app for attendee reschedule test

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: use real API key authentication instead of withApiAuth mock

- Replace withApiAuth mock with real API key authentication using ApiKeysRepositoryFixture
- This avoids Passport strategy registration conflicts between test suites
- For attendee reschedule test, use unauthenticated request (no auth header) since endpoint uses OptionalApiAuthGuard
- Remove separate unauthenticatedApp instance as it's no longer needed

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix flakes

* update

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-20 13:04:21 -03:00
Anik Dhabal Babu 0098b076a1 fix: cache build error on CI (#25958)
* fix(slots): hide out-of-office slots across timezones

* update

* fix build error
2025-12-20 15:24:56 +00:00
sean-brydon 95a4567f35 perf: use compound key (#25970) 2025-12-20 14:57:55 +00:00
spandevandDhairyashil Shinde d8ddb466b0 fix: slots in email embed sorted (#25676)
* fix: slots in email embed sorted

* fix: removed mutating of original array

* fix: incorrect access of sortedTimes

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-20 13:12:50 +00:00
Benny Joo 6e5b812286 fix: add missing Korean translation (#26075) 2025-12-20 15:02:03 +05:30
Alex van Andelandcubic-dev-ai[bot] 8568cab283 fix: Handle error when no default calendar exists for a o365 account (#26074)
* fix: Handle error when no default calendar exists for a o365 account

* Update packages/app-store/office365calendar/api/callback.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-20 06:33:46 +00:00
Alex van Andel 8d04a23bce chore: release v6.0.3
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-20 01:00:01 +00:00
dd8477c0bf fix(typo): correct spelling of organization in error message (#26035)
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-20 00:16:18 +00:00
BetoandDhairyashil aebfd4919b feat(companion): Update availability screen to use liquid glass (#26041)
* Use previous header for android

* use activity instead of ternary statements

* update layout to use header buttons in availability screen

* fix styles and add context menu

* add set as default action

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2025-12-19 19:05:26 +00:00
Dhairyashil Shinde 69a857ad98 feat(companion): Multi-browser extension support (Chrome, Firefox, Safari, Edge, Brave) and fix text node errors (#26063)
* feat(companion): add multi-browser OAuth support for extension

- Add browser-specific OAuth client ID and redirect URI configuration
- Support Chrome, Firefox, Safari, Edge, and Brave browsers
- Add build scripts for each browser target (ext:build-{browser})
- Fix Brave Shields compatibility for production builds
- Add EXTENSION_SETUP.md documentation

BREAKING CHANGE: None - backward compatible with existing Chrome config

* fix(companion): replace && conditional rendering with ternary operators

Replace all `{condition && (<Component />)}` patterns with explicit
`{condition ? (<Component />) : null}` syntax across the companion app.

This fixes "Unexpected text node: . A text node cannot be a child of
a <View>" errors that occur with react-native-css-interop when using
&& conditional rendering in React Native web builds.

Files updated:
- app/event-type-detail.tsx (16)
- app/booking-detail.tsx (10)
- app/(tabs)/bookings.tsx (8)
- app/(tabs)/availability.tsx (6)
- app/availability-detail.tsx (5)
- app/(tabs)/(event-types)/index.tsx (4)
- components/event-type-detail/tabs/LimitsTab.tsx (9)
- components/event-type-detail/tabs/BasicsTab.tsx (3)
- components/event-type-detail/tabs/AdvancedTab.tsx (3)
- components/event-type-detail/tabs/RecurringTab.tsx (1)
- components/event-type-detail/tabs/AvailabilityTab.tsx (1)
- components/event-type-list-item/EventTypeListItem.ios.tsx (3)
- components/BookingActionsModal.tsx (2)
- components/Tooltip.tsx (1)
- components/LocationsList.tsx (1)
- components/Header.tsx (1)
- components/EmptyScreen.tsx (1)

* correct command for edge

* dont break ci

* deslop ai
2025-12-19 23:50:20 +05:30
Pedro Castro af4a10c008 fix(seo): prevent booking confirmation pages from being indexed (#26058)
Booking confirmation pages contain PII (names, emails, phone numbers)
and should not be indexed by search engines

- Add robots noindex to /booking/[uid]/page.tsx
- Add robots noindex to /booking/[uid]/embed/page.tsx

Follows same pattern as not-found.tsx
2025-12-19 13:34:49 -03:00
Pedro Castro 90a83a611c docs: add ListEventTypes atom documentation (#25775)
- Add list-event-types.mdx with Quick start, Props, Demo video, and Combining with EventTypeSettings sections
- Add list_event_types_light.png screenshot
- Update mint.json navigation to include new page
2025-12-19 13:23:07 -03:00
sean-brydon b33d8c64df add turbo repo (#26051) 2025-12-19 14:27:19 +00:00
Carina WollendorferandCarinaWolli 73b276015c fix: remove pkce check for refreshToken endpoint (#26050)
* remove pkce check for refreshToken endpoint

* adjust e2e tests

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-12-19 15:18:49 +01:00
Abhishek 9c223fc718 fix: settings icon at app setup - event types (#26048)
* fix/setting-icon-app-card

* fix: settings icon app card
2025-12-19 14:13:58 +00:00
Eesh MidhaandRajiv Sahal 6910b85301 refactor(dialog): standardize icon container styling (#26036)
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2025-12-19 19:22:04 +05:30
125ed4f6f7 feat: update favicons with new Cal design (#25392)
* feat: add environment-based favicons (prod vs dev)

- Add cal-prod.png (dark/gray) favicon for production environments
- Add cal-dev.png (red) favicon for development/localhost environments
- Update FAVICON_16 and FAVICON_32 constants to switch based on IS_PRODUCTION

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat: add higher resolution icons for all icon types (apple-touch, android-chrome, mstile)

- Add 180x180 apple-touch-icon for prod and dev
- Add 150x150 mstile icons for prod and dev
- Add 192x192 and 256x256 android-chrome icons for prod and dev
- Update all icon constants to use IS_PRODUCTION switching

Co-Authored-By: peer@cal.com <peer@cal.com>

* refactor: simplify favicon to single new design

- Remove environment-based favicon switching
- Update all icon files with new Cal favicon design
- Remove dev/prod icon variants
- Update constants to use static icon paths

Co-Authored-By: peer@cal.com <peer@cal.com>

* feat: add favicon.ico with new Cal favicon design

Co-Authored-By: peer@cal.com <peer@cal.com>

* chore: update favicon icons with final design

Co-Authored-By: peer@cal.com <peer@cal.com>

* chore: update favicon icons with final design v3

Co-Authored-By: peer@cal.com <peer@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-19 13:12:14 +00:00
Kartik Labhshetwar 2cab5475ce fix: improve CustomEmailTextField styling and focus behavior (#26024) 2025-12-19 13:08:28 +00:00
Syed Ali Shahbaz 5032d2716d fix: Add email to user select in credential to ensure consistent type (#26020)
* Add email to user select

* type fix
2025-12-19 13:03:04 +00:00
3ccf001e1d fix: add name property to delegation credentials for type compatibility (#26022)
* fix: add name property to delegation credentials for type compatibility

The MultiDisconnectIntegration component expects credentials with user.name property,
but delegation credentials only had user.email. This caused a type mismatch when
spreading both credential types together in appCredentialsByType handler.

Added name: null to the delegation credentials user object to ensure type compatibility.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: update getUserDisplayName to check value instead of just property existence

The narrowing logic was causing TypeScript to infer 'never' type because
after adding name property to delegation credentials, the 'name in user'
check always passes. Now we check if name has a truthy value before using it.

Also fixed lint warning by using optional chaining for onSuccess callback.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add explicit return type and typeof checks to getUserDisplayName

The function now has an explicit return type of string | null and uses
typeof checks to ensure proper type narrowing. This prevents TypeScript
from inferring a wider return type that includes {} when the user object
has properties with non-string types.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* test: update delegation credential test to include name property

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-19 12:21:48 +00:00
4c282ea9ca feat: add promotion codes support to SMS credit purchases (#23774)
Co-authored-by: peer@cal.com <peer@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-19 08:57:13 -03:00
Anik Dhabal Babu 1135e47338 fix: render markdown in custom page redirect messages (#25987)
Before:-
<img width="1986" height="762" alt="image (26)" src="https://github.com/user-attachments/assets/90e16a5c-a8f1-4269-8873-8854a82c012e" />
<img width="3456" height="2068" alt="image (27)" src="https://github.com/user-attachments/assets/6714a1d5-454d-4fe7-b6ce-84120353a10a" />
After:-
<img width="977" height="456" alt="Screenshot 2025-12-17 at 9 09 22 PM" src="https://github.com/user-attachments/assets/449611ab-8d84-41e2-a342-0e334562cec5" />
2025-12-19 16:44:06 +05:30
Udit TakkarandAnik Dhabal Babu 68e670ae06 fix: hide OOO slots across timezones (#25966)
* fix: use organizer timezone

* fix: use organizer timezone

* fix: use organizer timezone

* fix type error

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-19 08:12:39 -03:00
sean-brydon 8b13979a41 chore: implement posthog tracking company email upgrade point (#25977)
* implement posthog tracking

* track dismiss
2025-12-19 10:39:30 +00:00
4beebd227b fix: flaky E2E tests and refactor (#25974)
* fix: flaky E2E tests and refactor

* fix

* fix: week limit tests to use same week for pre-booking and UI booking

The week limit tests were failing because the pre-booking was created in
week 1 but the UI booking was done in week 2. Since weekly limits are
per-week, the pre-booking didn't count toward the limit in week 2.

Fixed by keeping both bookings in the same week:
- Pre-booking on Monday (satisfies daily limit, counts toward weekly)
- UI booking on Tuesday (same week, hits weekly limit of 2)

This ensures the weekly limit is properly tested and all remaining
weekdays in the week get blocked after hitting the limit.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-19 07:35:47 -03:00
Prateek Dwivedi 853358d9c4 fix(logging): replace console.log with logger.error in editLocation handler (#26037) 2025-12-19 08:15:44 +00:00
PallavandAnik Dhabal Babu 7dcf4ee5c8 fix: prevent custom calendar for team event (#26033)
* fix: prevent custom calendar for team event

* Remove commented-out disableRescheduling code

Removed commented-out code for disabling rescheduling.

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-19 07:22:27 +00:00
42f2c170aa feat: add coss-ui core package (#25984)
* Install/add components in base coss-ui package

* fix components imports

* add yarn script to pull

* Update packagejson

* remove skeleton duplicates

* feat: allow importing components with the cli

* fix: update exports in package.json to reference styles.css instead of globals.css

* add lucide dep

* refactor: re-pull components

* refactor: remove unused registries section from components.json

* refactor: implement changes suggested by Volnei

* refactor(wip): implemet coss ui components on the profile page

* fix src/src problem

* update command to overwrite existing components

* pulled from registry

* restore globals.css

* feat: add pull script

* feat: enhance pull script with validation and error handling

* remove duplicate components

* refactor: reimport coss component and fix ts errors

* fix: components pulling

* chore: regenerate yarn.lock

* chore: remove tailwindcss/forms

* trying different moduleResolution

* TypeScript requires module to also be "NodeNext".

* remove unnecessary changes

* type fixes plus resolve @coss/ui

* use bundler tsconfig

* add missing deps to features and ui

* Add bundler to other packages

* fix module enext resolution with bundler

* remove reduant files

* remove package json from features

* revert unrelated change to the PR

---------

Co-authored-by: pasqualevitiello <pasqualevitiello@gmail.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2025-12-18 19:57:21 +00:00
Peer RichelsenandDhairyashil 3423777ee3 feat: gmail, outlook, yahoo links during email verification (#26038)
* added gmail, outlook, yahoo links during email verification

* added proton

* enable for self-hosters too

* undo i18n

* Discard changes to companion/bun.lock

* nit

* refactor: code quality improvments

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2025-12-18 19:56:38 +00:00
Dhairyashil ShindeandVolnei Munhoz c8a8c37b45 fix(companion): prevent localhost URL from being baked into production extension builds (#26032)
* fix(companion): separate dev and prod build scripts to prevent localhost in production

- Add ext:build-dev and ext:build-prod scripts with clear separation
- Add BUILD_FOR_STORE flag to force production URL in store builds
- Add visual build indicators (store / dev) for clarity
- Prevent EXPO_PUBLIC_COMPANION_DEV_URL from leaking into production builds

* update commands to work for ci

* update version

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2025-12-18 19:19:04 +00:00
Benny JooandAnik Dhabal Babu f291c1c4e7 fix: add mergeWithEnglishFallback for i18n translations (#26016)
* fix

* fix

* fix

* fix

* Improve translation cache handling in i18n.ts

Refactor translation cache retrieval and fallback logic.

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-18 16:47:54 +00:00
Hariom BalharaandDevin AI 71792bdeaa fix: ensure linkFailed event fires for 404, 500, and 403 errors in embeds (#25261)
- Add CalComPageStatus handling in NotFound and ErrorPage components using useLayoutEffect
- Remove redundant pageStatus logic from PageWrapperAppDir.tsx since App Router error/notFound pages set status themselves
- Refactor embed-iframe.ts: split checkPageStatusAndHandleError into hasPageError() and handlePageError()
- Add page status checks before firing linkReady to catch errors set after initialization
- Ensures linkFailed event fires correctly for all error status codes in embed scenarios

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-18 16:30:32 +00:00
Eunjae Lee 945ded951f fix: integration test of booking audit service (#26027) 2025-12-18 15:26:03 +00:00
Pedro CastroandMorgan 975fb21d86 feat(atoms): add ListEventTypes atom to enable event type management (#25047) (#25113)
* feat: add ListEventTypes atom (#25047)

* feat: add ListEventTypes atom for Platform (#25047)

- Add EventTypeListItem component in @calcom/features
- Add ListEventTypesPlatformWrapper with delete functionality
- Implement useAtomGetAllEventTypes hook
- Update backend to include slug, description, length
- Add 11 unit tests (65% coverage)
- Add 3 i18n keys

No breaking changes. Backward compatible.

* refactor(eventtypes): improve EventTypeListItem readability

- Extract EventTypeContent and EventTypeActions sub-components
- Add formatEventTypeDuration helper (90min → '1h 30m')
- Use Badge for duration display (consistency with EventTypeDescription)
- Use polymorphic Wrapper component (DRY)
- Add comprehensive tests
- Reduce main component size

Addresses @volnei feedback

* refactor: replace window.confirm with ConfirmationDialog

- Replace native window.confirm with ConfirmationDialogContent

- Update test mocks for Dialog components

- Fix HTML nesting (div instead of p for Badge container)

- Follows Cal.com pattern from AvailabilitySettings

Addresses @ThyMinimalDev feedback

* fix: add aria-label to options button for accessibility

* test: update getBulkEventTypes test to include new fields (description, slug, length)

* refactor: move EventTypeListItem to atoms package

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-12-18 12:24:41 -03:00
Anik Dhabal Babuandcubic-dev-ai[bot] b20b52a1f8 fix: update tempOrgRediret on updating org slug (#25838)
* fix: update tempOrgRediret on updating s
lug

* Update packages/trpc/server/routers/viewer/organizations/adminUpdate.handler.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor

* fix

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-18 13:18:56 +00:00
Benny Joo 176aeaafd8 refactor: trpc test file is importing @calcom/web (#25979)
* add eslint config

* refactor test
2025-12-18 10:10:46 -03:00
Anik Dhabal Babu 9ba867922a fix type error (#26021) 2025-12-18 12:55:54 +00:00
Hariom BalharaandDevin AI f1011ddd08 chore: Improves the core booking audit architecture by adding new capabilities and simplifying the existing interfaces. (#25872)
* feat(booking-audit): extract core audit system changes from PR 25125

This PR extracts core audit infrastructure changes without integration changes:

1. New action services introduced:
   - SeatBookedAuditActionService
   - SeatRescheduledAuditActionService

2. Simplification of ActionService interface:
   - Streamlined IAuditActionService interface
   - Reduced TypeScript burden with cleaner type definitions

3. ActionSource support:
   - Added BookingAuditSource enum (API_V1, API_V2, WEBAPP, WEBHOOK, UNKNOWN)
   - Added source and operationId fields to BookingAudit model

4. New AuditAction types:
   - SEAT_BOOKED
   - SEAT_RESCHEDULED
   - APP actor type

5. New BookingAuditAccessService:
   - Permission-based access control for audit logs
   - Added readTeamAuditLogs and readOrgAuditLogs permissions

6. Fixes in the logs viewer flow:
   - Enhanced BookingAuditViewerService with improved filtering
   - Local AttendeeRepository for actor enrichment

Changes are contained within packages/features/booking-audit with minimal
outside changes (permission registry only).

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor(booking-audit): streamline action handling and enhance localization

- Replaced action icon retrieval with a mapping object for improved clarity and performance.
- Introduced constants for actor role labels to simplify role retrieval.
- Added new localization strings for audit log permission errors and organization requirements.
- Updated various service and repository interfaces to enhance type safety and clarity.
- Removed deprecated architecture documentation and adjusted related imports for consistency.

These changes aim to improve code maintainability and user experience in the booking audit system.

* fix(booking-audit): enhance actor role localization and operation ID tracking

- Updated actor role labels in the booking logs view to use lowercase for consistency.
- Improved localization by wrapping actor role display in a translation function.
- Added operationId field to audit logs for better correlation of actions across multiple bookings.
- Enhanced BookingAuditViewerService to include operationId in enriched audit logs.
- Updated integration tests to verify consistent operationId across related audit logs.

These changes aim to improve localization accuracy and facilitate better tracking of user actions in the booking audit system.

* feat: integrate credential repository and enhance app actor handling

- Added CredentialRepository to manage app credentials, including a method to find credentials by ID.
- Updated BookingAudit system to support app actors identified by credential ID, improving actor attribution and audit clarity.
- Introduced a new utility function to map app slugs to display names, enhancing the user experience in audit logs.
- Modified relevant interfaces and types to accommodate the new credential handling and app actor structure.
- Enhanced BookingAuditViewerService to display app names based on credentials, ensuring accurate representation in audit logs.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-18 12:46:24 +00:00
9019be58ed fix: allow required check to pass when E2E tests are skipped due to missing label (#26006)
* fix: allow required check to pass when E2E tests are skipped due to missing label

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* revert: remove unnecessary integration-test condition change

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* chore: trigger fresh CI run

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* all should pass to allow merge

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-18 08:49:12 -03:00
Eunjae LeeandDevin AI cef8610925 feat: add enabled column to UserFeatures and TeamFeatures for tri-state semantics (#25765)
* feat: add enabled column to UserFeatures and TeamFeatures for tri-state semantics

- Add enabled Boolean column to UserFeatures model with default true
- Add enabled Boolean column to TeamFeatures model with default true
- Update FeaturesRepository to use tri-state semantics:
  - enabled=true: feature is explicitly enabled
  - enabled=false: feature is explicitly disabled (blocks inheritance)
  - No row: inherit from team/org level
- Update SQL queries to check enabled=true for feature access
- Add enableFeatureForTeam method to interface and implementation

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update comments

* add integration tests

* add more test

* select enabled only

* no @default(true)

* fix types and tests

* add missing enabled

* add missing enabled

* rename enableFeatureForTeam to updateFeatureForTeam and support FeatureState

* refactor: rename updateFeatureForTeam to setTeamFeatureState

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix integration test

* fix tests

* add more tests

* add missing enabled

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-18 07:16:20 -03:00
Syed Ali Shahbaz 056922b6ee feat: add webhook versioning (#23861)
* add webhook version schema

* version the code

* update version from numeric to date val

* migration

* update schema and build factory

* update string

* move version picker

* tooltip instead of infobadge

* --

* fix type

* --

* fix type

* fix type

* --

* fix messed up merge

* improvements to payloadfactory

* extract version off of DB and instead keep it in IWebhookRepository

* fix webhookform

* fix type safety and routing ambiguity

* scalable with easier factory extensions and base definition

* fix types

* --

* --

* clean up prisma/client type imports

* fix

* type fix

* type fix

* cleanup

* add tests and registry changes

* unintended file inclusion

* type-fix

* select in repo

* --

* explicit return type

* --

* fix type

* fixes

* feedback 1

* feedback 2

* use enum instead of string

* fixes
2025-12-18 09:36:22 +02:00
Dhairyashil Shinde 42bd4b4057 fix: make isReschedule required in checkIfBookerEmailIsBlocked (#26002) 2025-12-17 19:52:10 -03:00
sean-brydonandcubic-dev-ai[bot] 64767cec4f chore: add onboarding events in posthog (#25981)
* add onboarding events in posthog

* Update apps/web/modules/onboarding/organization/teams/organization-teams-view.tsx

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-17 22:43:54 +00:00
Volnei MunhozandPeer Richelsen e84550ba76 chore: Isolate companion build (#25985)
* Isolate companion build

* Fix typo

* Update .github/workflows/pr.yml

* Improve branch protection

* integration tests missing

* fix typo

* fix to only have required

* fix to only have required

* fix to only have required

* adjust to keep as before

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2025-12-17 22:42:10 +00:00
Keith Williams e6d0253950 chore: Change atoms build command to build-npm (#25996)
* chore: Change atoms build command to build-npm to avoid turbo compilations

* Updated turbo.json atoms#build reference

* Updated atoms production build for CI
2025-12-17 16:30:54 -03:00
Dhairyashil ShindeandPeer Richelsen 471d1caac9 fix(companion): Fix Gmail OAuth integration (#25978)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2025-12-17 15:13:54 -03:00
Keith WilliamsandDevin AI 15b1675db1 perf: reduce TypeScript type bloat in tRPC package via z.ZodType annotations (#25845)
* fix: prevent Prisma conditional types from leaking into .d.ts files

This PR addresses TypeScript performance issues caused by Prisma's conditional types leaking through the type graph:

1. Replace Prisma.UserGetPayload with explicit UpdatedUserResult type in updateProfile.handler.ts
2. Replace Prisma.EventTypeGetPayload with explicit UpdatedEventTypeResult type in update.handler.ts
3. Replace Prisma.OutOfOfficeEntryGetPayload with explicit OOOEntryResult type in outOfOfficeCreateOrUpdate.handler.ts
4. Replace Prisma.CredentialGetPayload with explicit Credential type in getUserConnectedApps.handler.ts
5. Fix inconsistent DI usage in EventTypeRepository - use this.prismaClient instead of global prisma singleton

These changes prevent massive recursive Prisma types from propagating through the type graph and being emitted in .d.ts files, which improves TypeScript performance.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: correct reasonId type to number | null in OOOEntryResult

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* perf: add z.ZodType annotations to reduce .d.ts file sizes

- Annotate exported Zod schemas with z.ZodType<T> to prevent full Zod generic tree from being emitted in declaration files
- eventTypes/types.d.ts reduced from 231KB to 115KB (50% reduction)
- _app.d.ts reduced from 782KB to 753KB (3.7% reduction)
- viewer/_router.d.ts reduced from 722KB to 695KB (3.7% reduction)
- workflows/getAllActiveWorkflows.schema.d.ts significantly reduced
- routing-forms/formMutation.schema.d.ts significantly reduced

Files modified:
- packages/trpc/server/routers/viewer/eventTypes/types.ts
- packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.schema.ts
- packages/trpc/server/routers/apps/routing-forms/formMutation.schema.ts
- packages/features/eventtypes/lib/types.ts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* perf: comprehensive z.ZodType annotations to reduce .d.ts file sizes

Applied z.ZodType<T> annotations to 89 schema files across the tRPC package.
This prevents TypeScript from emitting the full Zod generic tree in .d.ts files,
reducing declaration file sizes for downstream consumers.

Files modified include schemas in:
- viewer/teams (round-robin, managed events, invitations, etc.)
- viewer/bookings (get, find, confirm, etc.)
- viewer/eventTypes (get, delete, getByViewer, etc.)
- viewer/workflows (list, delete, verify, etc.)
- viewer/auth (changePassword, verifyPassword, etc.)
- viewer/apiKeys (create, delete, edit, etc.)
- viewer/sso (get, update, delete, updateOIDC)
- viewer/oAuth (addClient, generateAuthCode)
- viewer/calendars (setDestinationCalendar)
- viewer/deploymentSetup (update, validateLicense)
- apps/routing-forms (formQuery, deleteForm, etc.)
- publicViewer (submitRating, markHostAsNoShow, etc.)
- loggedInViewer (eventTypeOrder, routingFormOrder, etc.)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: revert slots/types.ts z.ZodType annotation that caused type mismatch

The slots/types.ts schema has a transform that converts duration from
string to number, which makes the z.ZodType<T> annotation incompatible.
Reverting to original to fix Unit test failure.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use 3-generic z.ZodType pattern for schemas with .default() modifiers

For schemas with .default() modifiers, the input and output types differ:
- Input type: field is optional (what callers send)
- Output type: field is required (what handlers receive after parsing)

This commit:
1. Fixes get.schema.ts (offset has .default(0))
2. Fixes removeMember.schema.ts (isOrg has .default(false))
3. Fixes resendInvitation.schema.ts (isOrg has .default(false))
4. Fixes listMembers.schema.ts (limit has .default(10))
5. Fixes getByViewer.schema.ts (limit has .default(10))
6. Reverts eventTypes/types.ts (complex transforms hard to model)
7. Reverts features/eventtypes/lib/types.ts (complex transforms hard to model)

The 3-generic pattern z.ZodType<Output, z.ZodTypeDef, Input> properly models
the difference between input and output types while still preventing the full
Zod generic tree from being emitted in .d.ts files.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use 3-generic z.ZodType pattern for schemas with transforms/defaults

- organizations/update.schema.ts: orgId has .transform() that converts string to number, so input type is string | number but output type is number
- publicViewer/event.schema.ts: fromRedirectOfNonOrgLink has .default(false), so input has it optional but output has it required

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use 3-generic z.ZodType pattern for updateProfile.schema.ts

Address reviewer feedback: isDeleted field in secondaryEmails has .default(false),
so input type has it optional but output type has it required.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove explanatory comments from schema files

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use 3-generic z.ZodType pattern for addClient.schema.ts enablePkce field

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: address Hariom's PR feedback

- Rename TGetInputSchemaInput to TGetInputRawSchema in get.schema.ts
- Use Prisma-free JsonValue type from @calcom/types/Json in updateProfile.handler.ts
- Fix publish.schema.ts with 3-generic pattern for z.coerce.number()

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add sort field to TGetInputSchema types

Added sort field to both TGetInputRawSchema and TGetInputSchema types
to match the Zod schema that was updated in main branch.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-17 15:06:57 -03:00
Calcom Bot c20f6cbdd6 feat: update translations via @LingoDotDev (#24385)
Hey team,

[**Lingo.dev**](https://lingo.dev) here with fresh translations!

### In this update

- Added missing translations
- Performed brand voice, context and glossary checks
- Enhanced translations using Lingo.dev Localization Engine

### Next Steps

- [x] Review the changes
- [x] Merge when ready
2025-12-17 13:30:35 -03:00
Benny Joo 03dd0c1501 refactor: Move SelectedCalendarRepository and WorkflowRelationsRepository from /lib to /features (#25982)
* wip

* wip
2025-12-17 16:05:03 +00:00
Beto 84ecb0e568 chore(companion): update dependencies to latest expo canary version (#25948)
* chore: update dependencies and update event types screen header

* refactor: simplify EventTypeListItem component by removing unused imports and code

- Removed unnecessary imports such as Tooltip and Svg.
- Cleaned up the component by eliminating commented-out code and unused props.
- Streamlined the button rendering in the context menu for better readability.

* feat: enhance EventTypes header with blur effect and clean up code

- Added blurEffect property to Stack.Header for improved visual aesthetics.
- Removed commented-out code to streamline the EventTypes component.
- Updated search bar properties for better user experience.

* refactor: update TabLayout and EventTypes for improved platform handling

- Simplified TabLayout by removing the liquid glass effect check and adding a WebTabs fallback for web support.
- Updated EventTypes header to conditionally apply blur effect based on liquid glass availability, enhancing visual consistency across platforms.

* feat: enhance TabLayout with MaterialCommunityIcons for improved UI

- Updated TabLayout to use MaterialCommunityIcons for tab icons, enhancing visual consistency.
- Added softwareKeyboardLayoutMode to app.json for better keyboard handling on mobile devices.

* feat: update TabLayout to prevent transparent background on iOS 18

- Added disableTransparentOnScrollEdge prop to NativeTabs to ensure a solid background on iOS 18 and older versions.
2025-12-17 15:37:52 +00:00
Anik Dhabal BabuandDevin AI 27775e5d03 fix: preserve newlines and links in calendar event descriptions (#25868)
The event type description is stored as HTML from the rich text editor.
When converting to plain text for calendar events, the HTML tags were
being stripped without preserving the formatting, causing:
- Newlines to be lost (text runs together)
- Links to be broken

This fix:
- Converts <br>, </p>, </div>, </li>, </h1-6> tags to newlines
- Preserves links in readable format: 'text (url)' or just 'url'
- Normalizes multiple newlines to max 2 for cleaner output

Affects all calendar integrations (Google, Outlook, etc.)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-17 15:02:12 +00:00
Benny Joo 0986864835 refactor: Move PrismaRoutingFormRepository from lib to /features/routing-forms (#25975)
* wip

* update import paths
2025-12-17 14:26:17 +00:00
Benny Joo cb7844fd22 refactor: Migrate repositories/services from /lib to /features (#25925)
* deployment

* update imports

* booking report

* update import paths

* watch list

* watch list

* api key

* api key

* selected slots

* wip

* event type translation

* work flow step

* booking reference

* fix tests

* fix

* fix

* migrate

* wip

* address

* fix
2025-12-17 14:14:50 +00:00
Eunjae LeeandDevin AI aaaff0705b fix(bookings): enable past date selection for cancelled bookings (#25644)
* refactor(data-table): clean up DateRangeFilter range options

- Replace 'past' | 'custom' with 'past' | 'future' | 'any' | 'customOnly'
- Add direction field to PresetOption for preset compatibility filtering
- Derive presets visibility automatically based on compatible presets
- Update bookings list to use new range values:
  - past -> 'past'
  - upcoming -> 'future'
  - unconfirmed/recurring/cancelled -> 'any'

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(playground): add DateRangeFilter playground page with E2E tests

- Add playground page at /settings/admin/playground/date-range-filter
- Demonstrate all 4 range options: past, future, any, customOnly
- Add link to playground index page
- Add E2E tests for presets visibility and date restrictions

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix(playground): use correct meta.filter pattern for column filter config

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up the playground esign

* add unit tests instead of e2e

* fix the implementation

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-17 13:47:51 +00:00
Benny Joo dd27d077ca refactor: Create TravelScheduleRepository and PrismaOrgMembershipRepository in /features (#25853)
* move repo to travelSchedule

* update imports

* mv

* update imports
2025-12-17 10:24:44 -03:00
Carina WollendorferandCarinaWolli 5fe3714edd feat: auto skip consent screen for trusted oauth clients (#25640)
* auto constent for trusted clients

* add loading state

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-12-17 13:00:12 +00:00
Eunjae LeeandDevin AI e0a28af46e feat(bookings): conditionally show heading/subtitle based on view (#25889)
* feat(bookings): conditionally show heading/subtitle based on view

- Add heading and subtitle props back to ShellMainAppDir in page.tsx
- Use headerClassName marker to identify the heading element
- Add useLayoutEffect in BookingCalendarContainer to hide heading when calendar view is mounted
- Restore heading visibility when switching back to list view

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(bookings): extract shell heading visibility into reusable hook

- Create useBookingsShellHeadingVisibility hook with explicit visible parameter
- Move visibility logic from BookingCalendarContainer to BookingsContent
- Use data attribute to track if we hid the header (idempotent/Strict-Mode-safe)
- Explicit show/hide based on view state instead of relying on unmount

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor(bookings): simplify shell heading visibility hook

Remove HIDDEN_DATA_ATTR tracking since the header wrapper won't have
a hidden class from any other source

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-17 12:46:12 +00:00
Kartik Labhshetwar 970af8bd6a fix: change button color to destructive in WorkflowListPage (#25965) 2025-12-17 12:42:00 +00:00
Dhairyashil Shinde 2f1dd92677 feat(companion): open cal.com/app on new tab and fix extension/mobile UX issues (#25962)
* feat(companion): improve extension UX for new tab and fix mobile app issues

- Open cal.com/app when extension clicked on restricted pages (chrome://newtab, etc.)
- Auto-open sidebar when redirected to cal.com/app with ?openExtension=true
- Fix duplicate search bar in event types on web/extension
- Fix tab order mismatch on extension (Event Types, Bookings, Availability, More)
- Add logout confirmation modal for web since Alert.alert doesn't work
- Default COMPANION_DEV_URL to empty string for production builds

* fix(companion): use URL API for query parameter cleanup

Replace regex-based URL cleanup with URL API to properly handle
all query parameter positions. The previous regex produced invalid
URLs when openExtension=true was the first of multiple parameters
(e.g., ?openExtension=true&foo=bar became &foo=bar instead of ?foo=bar). fix(companion): wait for page load before auto-opening sidebar

Fix race condition where sidebar wouldn't auto-open on first visit
to cal.com/app. On uncached pages, now waits for the load event
before opening, while cached pages use a shorter delay.
2025-12-17 17:14:37 +05:30
Udit Takkar 61c8c9d970 chore: pass guests (#25961) 2025-12-17 11:43:42 +00:00
Abhishek 0604c960a4 fix: popover ios issue (#25696)
* fix: popover ios issue

* add comments

* more comments
2025-12-17 10:14:56 +00:00
Eunjae Lee c361b9bbc5 chore: enable booking redesign for e2e (#25642)
* enable bookings-v3 feature flag for e2e tests WIP

* fix e2e

* update comments
2025-12-17 10:09:09 +00:00
Volnei Munhoz c2d275551a Remove next build eslint and ts checks disabled for CI (#25950) 2025-12-17 03:43:00 +00:00
Volnei Munhoz 0ea7f1944f fix types (#25952)
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-17 02:56:15 +00:00
Alex van Andel 1af7bfa20e chore: release v6.0.2 2025-12-17 02:38:43 +00:00
Volnei Munhoz 641b249e92 chore: release amd as latest (#25949)
* release amd as latest

* remove dockerfile change

* Apply suggestions from code review

changed from linux/amd64 to amd64

* Revert removed comment

* introduce latest as parameter

* introduce latest as parameter
2025-12-17 02:35:55 +00:00
Volnei Munhoz f3f5725563 chore/fix onboarding types (#25951) 2025-12-17 02:09:26 +00:00
Dhairyashil Shinde a2a77376b3 fix: companion extension oauth (#25939)
* fix: companion extension oauth

* fix: ios build

* address cubics comments
2025-12-16 22:22:44 +00:00
Hariom Balhara ee298af4eb fix: update email validation to include pm.me and other email provider domain (#25879)
* fix: update email validation to include pm.me domain and improve error handling in extractDomainFromEmail function

* feat(organizations): add pm.me and additional personal email domains

- Add pm.me (ProtonMail short domain) to personal email providers list
- Add googlemail.com, ymail.com, msn.com, mac.com, and other common personal email domains
- Add Mail.com variants (email.com, post.com, consultant.com, etc.)
- Add protonmail.ch, gmx.de, naver.com, and other regional providers
- Update all three locations: utils.ts, orgCreationUtils.ts, and test file
- Fix ESLint warnings for unnecessary escape characters in regex
2025-12-16 18:45:35 +00:00
Rakshit Sisodiya 47a5fc7bf7 fix: allow organizations to sign up with existing usernames (#25941)
* fix: allow organizations to sign up with existing usernames

- Update usernameCheck to check organization context when currentOrgDomain is provided
- Organizations can now use usernames that exist in other orgs or global namespace
- Only checks username availability within the specific organization
- Fixes issue where org signups were blocked by global username conflicts

Refs #25800

* Update username.ts
2025-12-16 17:47:59 +00:00
Volnei Munhoz a1a5f2477d fix check types (#25907) 2025-12-16 17:07:32 +00:00
sean-brydon 94e0d476d9 fix: skip plan on invite to team (#25924)
* fix: skip plan on invite to team

* address cubic
2025-12-16 14:44:35 +00:00
45fcabef8c chore: replace GH_ACCESS_TOKEN with GitHub App token (#25518)
* chore: replace GH_ACCESS_TOKEN with GitHub App token

Replace personal access token (GH_ACCESS_TOKEN) with GitHub App token
generation using actions/create-github-app-token@v1 for improved security.

Updated workflows:
- draft-release.yml
- post-release.yml
- cleanup.yml
- cleanup-report.yml
- publish-report.yml
- i18n.yml

Benefits:
- Short-lived tokens (1 hour) vs long-lived PATs
- Fine-grained, scoped permissions
- Not tied to individual user accounts
- Better audit trail

Required setup:
- Create a GitHub App with contents:write permission
- Install the app on calcom/cal.com and calcom/test-results-2
- Add RELEASE_APP_ID and RELEASE_APP_PRIVATE_KEY secrets

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* chore: rename secrets to CI_CAL_APP_ID and CI_CAL_APP_PRIVATE_KEY

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* chore: use reusable workflow from calcom-ci-secrets for token generation

This isolates the GitHub App private key in a separate repository,
ensuring that compromised actions in cal.com can only access short-lived
tokens, not the key itself.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* chore: use explicit secret passing instead of secrets: inherit

Only pass the two required secrets (CI_CAL_APP_ID, CI_CAL_APP_PRIVATE_KEY)
to the reusable workflow instead of inheriting all secrets.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* chore: remove secrets block - using environment secrets from calcom-ci-secrets

Secrets are now loaded from the ci-github-app environment in
calcom-ci-secrets, so cal.com workflows no longer need to pass them.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* chore: revert to explicit secret passing

Environment secrets in cross-repo reusable workflows don't work as expected.
Secrets must be passed explicitly from the caller repository.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* chore: generate GitHub App token directly in workflows

Remove dependency on calcom-ci-secrets reusable workflow.
Token generation is now inline using actions/create-github-app-token
pinned to SHA 7e473efe3cb98aa54f8d4bac15400b15fad77d94 (v2.2.0).

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-16 14:12:56 +00:00
Anik Dhabal Babu 593ed461c8 slugify lenient (#25923) 2025-12-16 14:01:54 +00:00
Morgan b8827aca52 fix: atoms css scoping (#25921)
* fix: atoms css scoping

* fixup! fix: atoms css scoping
2025-12-16 19:20:46 +05:30
Benny JooandVolnei Munhoz c3bcd623f6 refactor: create CreditsRepository in /features/credits (#25843)
* mv test

* mv repo

* update imports

* Update packages/features/ee/billing/api/webhook/_checkout.session.completed.ts

Co-authored-by: Volnei Munhoz <volnei@cal.com>

* fix test

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2025-12-16 10:42:27 -03:00
Kartik Labhshetwar 272cf43322 fix: add dark mode support to emptypage skeleton and layout (#25913)
* fix: add dark mode support to emptypage skeleton and layout

* style: remove dark blur effect from EmptyPage component

* style: add dark mode divide subtle to EmptyPage component
2025-12-16 12:45:23 +00:00
Anik Dhabal Babu a8e2ba4663 Revert "fix: improve E2E test stability and reduce flakiness (#25897)" (#25919)
This reverts commit b83f8dd6b8.
2025-12-16 12:30:50 +00:00
3082d6c2f3 feat: export all booking question fields in csv for non seated events in insights (#25837)
* feat(insights): include all booking question fields in CSV export for non-seated events

- For non-seated events: export all custom booking question fields (phone, text, number, select, multiselect, url, checkbox, textarea) excluding system fields
- For seated events: preserve existing behavior (only phone-type fields)
- Add extractFieldValue helper to handle all field value types
- Fix phone fallback logic to only use actual phone field values
- Optimize cache lookup with single get() instead of has() + get()

* refactor(insights): extract CSV data transformation logic into separate module

- Extract manipulation logic from getCsvData into csvDataTransformer.ts
- Add extractFieldValue, isSystemField, and other helper functions
- Add processBookingsForCsv and transformBookingsForCsv functions
- Add comprehensive snapshot tests with dummy data
- Tests demonstrate how input becomes output for various scenarios

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix(insights): update BookingWithAttendees type to match Prisma query result

- Change noShow field type from boolean to boolean | null
- Fixes type error TS2345 in InsightsBookingBaseService.ts

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: eunjae@cal.com <hey@eunjae.dev>
2025-12-16 10:35:21 +00:00
Benny JooandDevin AI f98acb7301 refactor: migrate workflows utilities from trpc to features layer (#25534)
* refactor: migrate workflows utilities from trpc to features layer

Move workflow utility functions from packages/trpc/server/routers/viewer/workflows/util.ts
to packages/features/ee/workflows/lib/workflowUtils.ts to break circular dependencies.

Functions migrated:
- isAuthorized
- getAllWorkflowsFromEventType
- scheduleWorkflowNotifications
- scheduleBookingReminders

Changes:
- Created new workflowUtils.ts in features layer with migrated functions
- Added getBookingsForWorkflowReminders to WorkflowRepository (no prisma outside repositories)
- Updated all imports in features layer to use new location
- Updated trpc util.ts to re-export from features for backward compatibility
- Fixed pre-existing lint warning (any -> unknown) in handleMarkNoShow.ts

This is part of the effort to remove circular dependencies between
packages/features and packages/trpc.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: remove re-exports from trpc util.ts, update imports to use features layer

Per user request, removed the backward compatibility re-exports from
packages/trpc/server/routers/viewer/workflows/util.ts and updated all
imports in the trpc package to import directly from the features layer.

Files updated to import from @calcom/features/ee/workflows/lib/workflowUtils:
- confirm.handler.ts (getAllWorkflowsFromEventType)
- delete.handler.ts (isAuthorized)
- update.handler.ts (isAuthorized, scheduleWorkflowNotifications)
- getAllActiveWorkflows.handler.ts (getAllWorkflowsFromEventType)
- get.handler.ts (isAuthorized)
- util.test.ts (isAuthorized)
- delete.handler.test.ts (isAuthorized)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update test imports to use features layer for workflow utilities

Updated test files to import scheduleBookingReminders and
scheduleWorkflowNotifications from @calcom/features/ee/workflows/lib/workflowUtils
instead of @calcom/trpc/server/routers/viewer/workflows/util.

Files updated:
- packages/features/ee/workflows/lib/test/workflows.test.ts
- packages/features/tasker/tasks/scanWorkflowBody.test.ts

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: split workflowUtils.ts into individual files

Split the monolithic workflowUtils.ts into separate files for each function:
- isAuthorized.ts - Authorization check for workflow access
- getAllWorkflowsFromEventType.ts - Get workflows for an event type
- scheduleWorkflowNotifications.ts - Schedule workflow notifications
- scheduleBookingReminders.ts - Schedule booking reminders

The workflowUtils.ts now re-exports from these individual files for
backward compatibility.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix import

* fix more

* wip

* wip

* remove workflowUtils

* wip

* refactor deleteRemindersOfActiveOnIds

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-16 10:17:46 +00:00
Anik Dhabal Babu 4e3ce77de4 fix: custom replyTo is not set (#25867) 2025-12-16 04:20:03 +00:00
InD3v 0b5b76d594 fix: adjust padding in timezone select, event advanced edit icon, and sidebar bottom nav (#25877) 2025-12-16 01:11:10 +00:00
Pallav b6935666e5 fix: disable button routing (#25894) 2025-12-16 01:10:37 +00:00
Alex van Andel b25a2bf202 chore: release v6.0.1
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-16 01:09:06 +00:00
Abhishek 06d4c7d102 fix lint (#25870) 2025-12-16 01:08:05 +00:00
Dhairyashil Shinde 5b9dd09f0d feat(holidays): improve UI/UX and add contextual emojis (#25895)
* refactor(holidays): improve code quality and address PR review feedback

- Move HolidaysView.tsx from /features to /apps/web/modules following
  the pattern of keeping trpc-using components in /apps/web/modules
- Fix prisma import to use named import: `import { prisma }`
- Fix timezone bug in checkConflicts: use dayjs.utc() for consistent
  date boundaries regardless of server timezone
- Fix toggleHoliday validation to include both current and next year
  holidays, matching the holidays displayed to users
- Implement dependency injection pattern for holiday repository:
  - Create PrismaHolidayRepository with instance methods
  - Add HOLIDAY_REPOSITORY DI token and module
  - Update containers to load holiday repository module
  - Update calculateHolidayBlockedDates to use injected repository
- Remove stale HOLIDAY_CACHE_DAYS env declaration (now a constant)
- Update tests to mock repository instead of prisma directly

* feat(holidays): improve UI responsiveness and add country flags

- Add country flag emojis to holidays dropdown using Unicode regional
  indicator symbols
- Handle edge cases for religious holidays (Hindu, Christian, etc.)
  which dont have 2-letter country codes
- Increase country dropdown width to 180px for better readability
- Make OOO/Holidays tabs responsive: use Select dropdown on mobile,
  ToggleGroup on desktop
- Make + Add button responsive: show only + icon on mobile,
  full text on desktop
- Fix PrismaHolidayRepository import to use @calcom/prisma for
  consistency with other repositories

* feat(holidays): add contextual emojis for holidays

- Add keyword-based emoji mapping for 80+ holidays
- Display holiday emojis in styled containers on settings page
- Add country flag emojis to dropdown using Unicode regional indicators
- Use dynamic emojis on booking page unavailable dates

* fix(holidays): address PR review feedback

- Fix emoji ordering: move Chinese/Lunar New Year before generic new year to prevent incorrect match
- Fix i18n: use t() instead of hardcoded text more in conflict warning
- Fix a11y: use sr-only pattern for mobile button to maintain screen reader accessibility

* fix failing test: packages/features/availability/lib/calculateHolidayBlockedDates.test.ts

* fix failing test: packages/features/availability/lib/calculateHolidayBlockedDates.test.ts

* fix failing tests and builds
2025-12-16 00:40:04 +00:00
Alex van Andel db2caa17ce fix: Allow single-label domains and missing dots (#25899) 2025-12-16 05:10:22 +05:30
b83f8dd6b8 fix: improve E2E test stability and reduce flakiness (#25897)
* fix: improve E2E test stability and reduce flakiness

- Replace hardcoded waits with proper Playwright waitFor assertions in slot selection
- Add explicit waits for calendar and time slot elements to be visible before clicking
- Replace fixed 2s wait in gotoRoutingLink with networkidle wait
- Replace fixed 5s email wait with retry logic (10 retries, 500ms intervals)
- Use unique usernames with timestamps to avoid parallel test collisions
- Use features fixture instead of direct prisma calls for feature flag mutations
- Fix login.e2e.ts to use unique username instead of hardcoded 'pro'
- Fix signup.e2e.ts to use unique usernames and proper feature flag handling
- Remove unused 'users' parameter from tests that don't need it

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* perf: replace waitForTimeout with smart waits for faster E2E tests

- Replace 30 waitForTimeout calls with proper Playwright waits
- Use waitFor({ state: 'visible' }) for element visibility
- Use waitForLoadState('networkidle') for page load completion
- Use waitForFunction for localStorage state changes

Performance improvements:
- limit-tab.e2e.ts: 10s fixed wait -> element visibility wait
- booking-duplicate-api-calls.e2e.ts: 5s fixed wait -> networkidle
- change-theme.e2e.ts: 3s fixed wait -> localStorage state check
- team-invitation.e2e.ts: multiple 500ms-3s waits -> element waits
- booking-seats.e2e.ts: 2s waits -> dropdown visibility waits
- embed-code-generator.e2e.ts: 1s waits -> iframe visibility waits
- organization-privacy.e2e.ts: 500ms waits -> element/networkidle waits
- organization-invitation.e2e.ts: 500ms-1s waits -> element waits
- analyticsApps.e2e.ts: 1s wait -> networkidle
- integrations.e2e.ts: 1s wait -> calendar element wait
- fixtures/apps.ts: 1s waits -> element visibility waits

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-15 20:19:47 -03:00
Beto 883ac103f8 fix: android redirect (#25888)
* fix android redirect

* remove logs
2025-12-15 18:14:42 +00:00
Volnei Munhoz d13adc8ffd Fix user parameter (#25884) 2025-12-15 18:07:28 +00:00
Kartik Labhshetwar d64255be47 fix: change sidebar hover background to subtle when locale ready (#25876) 2025-12-15 17:50:03 +00:00
Alex van Andel 5c5d221c76 chore: release v6.0.0
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-15 17:40:14 +00:00
Alex van Andel 852daa0175 chore: release v6.0.0 2025-12-15 17:16:33 +00:00
Volnei Munhoz 1123b56a09 chore/upgrade_deps (#25873) 2025-12-15 17:04:17 +00:00
Dhairyashil Shinde 12e07f20d4 feat: Add Holidays feature to block availability on public holidays (#25561)
* feat: add holidays feature for automatic availability blocking- Add UserHolidaySettings model for storing user preferences- Generate static holiday data for 20 countries using date-holidays- Create HolidayService for runtime holiday queries- Add TRPC router with endpoints for country selection and holiday toggles- Create Holidays tab UI in Availability page with conflict warnings- Integrate holiday blocking into getUserAvailability calculation- Show holiday indicator on blocked dates in booker page- Add warning in OOO modal when dates overlap with holidays

* feat: add optimizations, tests, and code quality improvements

- Add memoization/caching to HolidayService for better performance
- Optimize checkConflicts DB query with OR conditions for specific dates
- Add HolidayService unit tests (10 tests)
- Add error handling with Alert component for failed queries
- Memoize HolidayListItem component to prevent unnecessary re-renders
- Extract magic numbers into constants.ts
- Use TRPCError consistently in handlers
- Add missing i18n keys for error messages
- Update handlers to follow Cal.com patterns (default exports, minimal comments)
- Add regeneration instructions in constants

* refactor: replace static JSON with Google Calendar API integration

- Add GoogleHolidayService to fetch holidays from Google Calendar public calendars
- Add HolidayCache Prisma model for caching API responses
- Add GOOGLE_CALENDAR_API_KEY and HOLIDAY_CACHE_DAYS env variables
- Support 38 countries via Google Calendar holiday calendars
- Update HolidayService methods to async with database caching
- Update all TRPC handlers for async holiday methods
- Fix UI to display holiday dates correctly
- Remove static holidays.json and generate script

* use we instead of calcom in i18n message

* address cubics comments

* move holidays from availability to ooo

* public holidays filter for holidays

* follow i18n _one and _other pattern

* remove holiday feature flag

* revert lint command code change

* revert lint command code change 2.0

* revert lint command code change 3.0

* bye bye my christmas emoji :crying-emoji

* remove comments

* refactor(holidays): add repository pattern, split services, and add tests

- Create HolidayRepository for database operations
- Split GoogleHolidayService into GoogleCalendarClient and HolidayCacheService
- Add dependency injection to HolidayService and HolidayCacheService
- Update TRPC handlers to use HolidayRepository
- Add tests for HolidayRepository and calculateHolidayBlockedDates
- Update calendar IDs to use official holiday format (244 countries + religions)

* fix: address PR review feedback

- Remove unused date-holidays package
- Add pluralization for and_more_holidays_with_conflicts translation
- DRY: spread GOOGLE_RELIGIOUS_HOLIDAY_CALENDARS into GOOGLE_HOLIDAY_CALENDARS
- Add select to userHolidaySettings query in getUserAvailability
- Optimize checkConflicts with pre-computed timestamps

* refactor(holidays): apply proxy pattern and move logic to service

- Rename HolidayCacheService to HolidayServiceCachingProxy (proxy pattern)
- Remove HOLIDAY_CACHE_DAYS env var, use constant directly
- Add isSupportedCountry() method to HolidayService
- Add getUserSettings() and updateSettings() to HolidayService
- Move toggleHoliday logic from handler to service
- Move checkConflicts logic from handler to service
- Add findBookingsInDateRanges() to HolidayRepository
- Simplify all handlers to just call service methods

* feat(bookings): add backend validation to prevent booking on holidays

Adds explicit holiday conflict validation during booking creation to
handle the race condition where a host enables a holiday after a guest
selects a date but before they submit the booking.

Changes:
- Add checkHolidayConflict validation with HolidayRepository integration
- Integrate ensureNoHolidayConflict in RegularBookingService
- Add BookingOnHoliday error code with proper HTTP 400 response
- Handle holiday error display in BookEventForm with name interpolation
- Hide trace ID for expected validation errors
- Add unit tests for holiday conflict validation

* fix failing type check

* fix: address PR review comments for holiday feature

- Change error code from BAD_REQUEST to INTERNAL_SERVER_ERROR in
  toggleHoliday handler (errors are internal failures, not bad input)
- Refactor ensureNoHolidayConflict to use Promise.all for parallel
  user checking instead of sequential loop

* refactor: use Promise.all with logging in loop for holiday check

- Check all users in parallel using Promise.all
- Log conflicts inside the loop as they are detected
- Wait for all checks to complete before throwing error

* fix(holidays): use host timezone for holiday conflict checks

The holiday feature was checking booking dates against holidays using
server/local timezone instead of the host's timezone. This caused
bookings near midnight boundaries to incorrectly pass or fail the
holiday check.

Example: A booking at Dec 24th 8PM UTC (which is Dec 25th in IST)
was not being blocked for an Indian host with Christmas as a holiday.

Changes:
- Add .utc() to holiday date formatting for consistency
- Fetch host's timezone in checkHolidayConflict
- Convert booking time to host's timezone before comparison
- Add findUserSettingsWithTimezone to HolidayRepository
- Update error message to clarify it's the host's local time
- Add timezone edge case tests

* fix(holidays): align holiday blocking with OOO pattern for consistent timezone handling

- Simplify calculateHolidayBlockedDates to match OOO pattern using dayjs.utc()
- Fix date range query to use full day bounds (startOfDay/endOfDay) so holidays
  stored at midnight UTC are correctly found during booking validation
- Remove separate checkHolidayConflict booking-time validation - holidays now
  block through oooExcludedDateRanges like OOO does
- Remove getHolidayOnDate from HolidayService (no longer needed)
- Remove findUserSettingsWithTimezone from HolidayRepository (no longer needed)
- Clean up related tests

Holiday blocking now works exactly like OOO:
1. Holidays are added to datesOutOfOffice in calculateHolidayBlockedDates
2. buildDateRanges processes them via processOOO with .tz(timeZone, true)
3. oooExcludedDateRanges excludes those dates from availability
4. ensureAvailableUsers uses oooExcludedDateRanges to block bookings

This ensures consistent timezone handling where Dec 25th blocks all hours
of Dec 25th in the host's timezone, regardless of booker's timezone.

* update test

* update .env.example file
2025-12-15 16:39:10 +00:00
Carina WollendorferandCarinaWolli 18415e35a7 fix browser extension redirect (#25885)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-12-15 16:32:59 +00:00
Udit Takkar 856792e1e7 fix: slots ooo bug (#25878) 2025-12-15 16:19:11 +00:00
52d5261b51 feat(booking): implement cross-page/week navigation in booking details sheet with view persistence (#25545)
* display UTM parameters

* persist view (list | calendar) in localStorage

* move to next page on clicking "next" of last item in the page

improve navigation

^ Conflicts:
^	apps/web/modules/bookings/components/BookingCalendarContainer.tsx

* fix navigation on calendar view

* Delete apps/web/modules/bookings/NAVIGATION_IMPLEMENTATION.md

* avoid page size being 0

* check feature flag on user level

* use map to improve useBookingListData

* address feedback

* feat(bookings): add smart navigation for calendar view

- Add sort option to tRPC bookings.get schema and handler
- Create NAVIGATION_PROBE_WINDOW_MONTHS constant (3 months)
- Create useNearestFutureBooking hook to find nearest future booking
- Create useNearestPastBooking hook to find nearest past booking
- Update useCalendarNavigationCapabilities to use probe results
- Update BookingCalendarContainer to wire up probe hooks

This enables the booking details sheet to:
- Disable next/prev buttons when no bookings exist in that direction
- Jump directly to the week containing the nearest booking

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix type error

* feat: add booking selection state when using slideover (#25637)

* implement booking selection when using slideover

* remove pixel shift

* fix

* auto scroll to selected event on calendar

* make DateValues header sticky when scrolling

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>

* prefetch previous / next weeks on calendar view

* clean up classes

* handle "fetched & but no data" situation more correctly in useCalendarAutoSelector

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-12-15 16:04:00 +00:00
Morgan 53776d28e6 fix: atoms vite config (#25883)
* fix: atoms vite config

* fixup! fix: atoms vite config

* fixup! fixup! fix: atoms vite config
2025-12-15 12:31:31 -03:00
Volnei Munhoz 2b666f3e91 Fix CI for Companion (#25886) 2025-12-15 15:22:35 +00:00
Anik Dhabal Babu 7562ad2a16 refactor: Fix N+1 queries and optimize database operations (#25813)
* refactor: prisma N+1 Queries

* addressed review
2025-12-15 14:14:19 +00:00
Volnei Munhoz 5626bceeff fix companion CI (#25881) 2025-12-15 11:00:50 -03:00
Dhairyashil Shinde e312d1c044 feat: add gradient indicator for scrollable event descriptions (#25460)
* feat: add gradient indicator for scrollable event descriptions

- Create EventDescription component with dynamic gradient overlay
- Show gradient only when description content overflows (180px max-height)
- Use Tailwind v4 gradient utilities for optimal styling
- Replace inline description rendering in EventMeta with new component
- Minimal implementation: 28 lines, no useEffect, single state variable

* add top gradient and optimize ScrollableWithGradients component

* add top gradient and optimize ScrollableWithGradients component

* refactor: extract reusable ScrollableWithGradients component with top/bottom gradients

* adjust gradient fades
2025-12-15 14:14:28 +01:00
Dhairyashil ShindeandAnik Dhabal Babu 9050f9b61f fix: dynamic group organizer order (#25474)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-15 11:28:45 +00:00
2218a45d83 feat: extract core booking audit infrastructure from PR 25125 (#25729)
* feat: extract core booking audit infrastructure from PR 25125

This PR contains only the core booking audit infrastructure changes from PR 25125,
excluding integration changes with booking flows.

Included:
- All packages/features/booking-audit/* (core audit services, actions, repository)
- packages/features/di/containers/BookingAuditViewerService.container.ts
- packages/features/tasker/tasker.ts (audit task types)
- packages/features/bookings/lib/types/actor.ts (actor types for audit)
- packages/features/bookings/repositories/BookingRepository.ts (getFromRescheduleUid method)
- apps/web/modules/booking/logs/views/booking-logs-view.tsx (UI for viewing audit logs)
- apps/web/public/static/locales/en/common.json (translations)

Excluded (integration changes):
- packages/trpc/server/* (tRPC handlers)
- packages/features/ee/round-robin/* (round-robin integration)
- packages/features/bookings/lib/handleCancelBooking.ts
- packages/features/bookings/lib/handleConfirmation.ts
- packages/features/bookings/lib/onBookingEvents/BookingEventHandlerService.ts
- packages/features/bookings/lib/service/RegularBookingService.ts
- apps/api/v2/* (API v2 integration)

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: make booking audit interfaces backwards-compatible with main

- Add queueAudit method back to BookingAuditProducerService interface for backwards compatibility
- Implement queueAudit method in BookingAuditTaskerProducerService
- Make userTimeZone parameter optional in BookingAuditViewerService
- Add BookingAuditTaskProducerActionData type for legacy queueAudit method
- Use any generics in BookingAuditActionServiceRegistry (matching PR 25125)
- Fix type assertions in BookingAuditTaskConsumer

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix switch eslint and ts

* feat: enhance BookingAuditViewerService with logging and type improvements

- Added ISimpleLogger dependency to BookingAuditViewerService for better error handling.
- Updated actor type in enriched audit logs to use AuditActorType for improved type safety.
- Replaced console.error with logger for error reporting when no rescheduled log is found.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-12-15 10:51:30 +00:00
Udit Takkar 4e1d05a7e7 feat: dist tracing 4 (#25574)
* feat: distributed tracing 2

* feat: distributed tracing 2

* refactor: feedback

* refactor: feedback

* fix: type error

* fix: trpc error

* feat: distributed tracing - 3

* chore: translation

* refactor: improvements

* fix: feedback

* chore: remove

* feat: dist tracing 4

* fix: type errors

* fix: type errors

* fix: remove string type

* fix: type errors
2025-12-15 10:43:22 +00:00
devin-ai-integration[bot]andlauris@cal.com 0d4108dd69 chore: bump @calcom/atoms version to 2.1.0 (#25831)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: lauris@cal.com <lauris@cal.com>
2025-12-15 09:26:47 +00:00
Dhairyashil Shinde 6e2e826001 fix(ooo): make show note publicly consistent across all booking views (#25827)
- Update weekly view to display OOO when showNotePublicly is true
- Update column view to include days with public notes in schedule
- Add notes and showNotePublicly props to weekly view calendar
- Disable show note publicly checkbox when notes field is empty
2025-12-15 10:24:10 +01:00
Anik Dhabal Babu 84a4dd4147 fix: one integration test flake (#25832) 2025-12-15 09:09:01 +00:00
Benny JooandVolnei Munhoz deca7ce40a refactor: move calAIPhone-specific repositories to features from lib (#25840)
* add prisma agent repository to features

* add

* wip

* wip

* wip

* Update apps/web/app/api/webhooks/retell-ai/route.ts

Co-authored-by: Volnei Munhoz <volnei@cal.com>

* ts fix

* ts fix

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2025-12-15 13:43:24 +05:30
5394d80969 chore: Cleanup some outdated pages files (#25600)
* chore: Cleanup some outdated pages files

* revert: endpoint

* revert: endpoint

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-12-15 09:16:59 +05:30
Udit Takkar fd8f2a9ff6 fix: checkout session completed (#25767)
* fix: checkout session completed

* refactor: code quality
2025-12-15 09:12:13 +05:30
Alex van Andel 28f9c8f4cf chore: release v5.9.15
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-15 00:14:28 +00:00
Volnei Munhoz 37884d26e3 chore: bump next versions (#25864) 2025-12-15 00:13:42 +00:00
Peer Richelsen e46df92492 small wxt related fixes (#25866) 2025-12-14 21:01:08 +01:00
Beto 35cf827cb1 feat(companion): Event types screen update (#25847) 2025-12-14 20:59:48 +01:00
Beto e9c3d7e40c feat: upgrade to sdk 55 canary (#25810) 2025-12-14 20:15:40 +01:00
Dhairyashil Shinde c218a0afad feat(companion): Add caching, redesign ui, and refactor code (#25654) 2025-12-14 14:53:38 +00:00
Keith Williams b9a09117e3 chore: Remove team-labels action (#25862) 2025-12-14 14:31:13 +00:00
an_ifrah24 550caa6665 fix: added conditional check for the unkey logger to reduce the number of logs (#25858) 2025-12-14 12:35:57 +00:00
Benny Joo a8f43da472 refactor: Move Users Admin TRPC router from features package to trpc layer (#25816)
* move users admin router to trpc package

* users admin router

* update import path

* fix
2025-12-14 08:45:20 -03:00
43b6c63294 refactor: Move insights trpc router from features package to trpc layer (#25778)
* update imports

* move trpc router from features to trpc

* update imports

* wip

* update imports

* wip

* wip

* wip

* fix import

* create objectToCsv.ts

* rename

* fix: restore proper types and static imports in insights handlers

- Add proper type definitions for all handler options instead of using 'any'
- Restore static imports for PermissionCheckService and MembershipRole
- Remove dynamic imports that were introduced during refactoring

This ensures the refactoring is pure with no behavioral changes.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update getEventTypeList import path after utils.ts deletion

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* remove handlers

* fix

* refactor

* wip

* rm

* wip

* select only needed + fix type error

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2025-12-14 08:44:36 -03:00
Benny Joo 9ef650ceed refactor: Move OrganizationOnboardingRepository from lib to /features/organizations (#25854)
* mv organization onboarding repository

* update imports
2025-12-14 08:42:21 -03:00
Benny Joo e394a03365 refactor: create DestinationCalendarRepository in /features/calendars (#25851)
* mv destination calendar repo

* fix
2025-12-14 08:41:13 -03:00
Benny Joo 972f983824 refactor: create PrismaOOORepository in /features/ooo (#25850)
* move to features

* update imports
2025-12-14 08:39:58 -03:00
sean-brydon 68a8fade89 add tests (#25566) 2025-12-14 19:14:15 +09:00
Benny Joo d81993892a refactor: create HostRepository in /features/host (#25842)
* mv test

* mv host repository

* update imports
2025-12-13 11:04:57 +00:00
Eesh MidhaandUdit Takkar d034e7aff7 fix: enforce team-only access on premium toggles in cal video (#25680) (#25681)
* fix(cal-video): enforce team-only access on premium toggles

* fix(cal-video): disable redirect URL field and add upgrade badge for non-team users

* chore: improvments

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
2025-12-12 21:04:30 +00:00
sean-brydon 13103c0881 feat: Improve error handling in ratelimit (#25223)
* Improve error handling in ratelimit

* Update route.ts

* Update route.ts

* Update route.ts

* address feedback
2025-12-12 20:39:23 +00:00
Dhairyashil Shinde 983af06787 fix: allow two dots in exclude email (#24968)
* add test and fix two dots bug in exclude email

* add test and fix two dots bug in exclude email
2025-12-13 02:06:42 +05:30
Benny Joo 29076d681b refactor: create CalVideoSettingsRepository in features package (#25841)
* add new repo

* wip
2025-12-12 19:53:28 +00:00
3cadf105d5 feat: add skipContactCreation toggle to EventTypeAppCard component (#25756)
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-12-12 18:55:19 +00:00
Peer Richelsen 411483a447 added OAuth badges (#25830) 2025-12-12 17:11:21 +00:00
Kartik Labhshetwar 223c967f81 style: add spacing and rounded corners to toolbar dropdown items (#25829) 2025-12-12 15:59:24 +00:00
Carina WollendorferandCarinaWolli 440b69138e treat web version as extension (#25834)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-12-12 15:05:33 +00:00
5a3f15357c fix: filter slots by requested date range to prevent date override leakage (#25822)
* fix: filter slots by requested date range to prevent date override leakage

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: move filterSlotsByRequestedDateRange to private method

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-12 11:28:07 -03:00
Anik Dhabal Babu e46c1bb40c fix delete payment app (#25801) 2025-12-12 14:24:45 +00:00
Anik Dhabal Babu 758b820a92 fix: slugified eventype slug (#25791) 2025-12-12 14:02:00 +00:00
sean-brydon b46fb82695 feat: minium reschedule notice on events (#25575)
* wip

* add i18n and essential tests

* fix UI and add migration

* fixes

* add logic on book event

* restore comment

* remove dev debug box

* extract min reschedule notice to util

* one more replace

* add to disable reschedule component

* tidy up state

* restore lock

* restore file

* fix zod utils

* respond to cubic feedback

* fix type error

* unit tests

* add zod util

* build tests with nul minReshceuldeNotice

* fix stuff
2025-12-12 10:53:01 -03:00
Alex van Andel 71c9567169 fix: Lazy loaded Stripe proxy to avoid crash on BillingService instantiation (#25400) 2025-12-12 19:18:06 +05:30
Hariom BalharaandDevin AI 5918e66cc5 docs: link embed events to help center to avoid duplicate maintenance (#25811)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-12 13:41:15 +00:00
2ad24048b6 fix: use relative redirects in booking confirmation routes to fix localhost redirect issue (#25794)
* fix: use relative redirects in booking confirmation routes to fix localhost redirect issue

When Cal.com runs behind a reverse proxy, request.url may return the internal
server URL (localhost:3000) instead of the external URL. This causes users to
be redirected to localhost after confirming bookings via email links.

This fix changes the redirect URLs from using url.origin (which could be
localhost) to using relative URLs via new URL(path, request.url). This ensures
the browser resolves the redirect against whatever domain the user actually
requested, fixing the issue for self-hosted deployments behind proxies.

Fixes #20358

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* test: add tests for booking confirmation redirect URL construction

Add unit tests for verify-booking-token and link API routes to ensure:
- Redirect URLs preserve the request origin (not hardcoded localhost)
- Redirect URLs use the correct booking path (/booking/{uid})
- Error messages are properly encoded in query params
- POST handler returns correct 303 status code

These tests verify the fix for #20358 where users were redirected to
localhost:3000 instead of the proper production URL after confirming
bookings via email links.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: add second argument to GET/POST calls in test files to fix type errors

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-12 19:02:54 +05:30
Lauris SkraucisandPallav a69fe2ed00 docs: how to fetch managed event type slots (#24977)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-12-12 14:12:59 +02:00
sean-brydon a5000cb3b7 fix not found nc command (#25823) 2025-12-12 12:05:01 +00:00
Anik Dhabal Babu eb0cf10f67 fix: webhook template (#25783) 2025-12-12 11:55:09 +00:00
Eunjae Lee 728e1173cb chore: update AGENTS.md on running unit tests for specific test name (#25820) 2025-12-12 11:48:30 +00:00
Lauris Skraucis b4e773da69 chore: atoms rrHostSubsetIds changelog for release (#25819) 2025-12-12 10:49:19 +00:00
Hariom BalharaandDevin AI bf38eb8cb1 refactor: Use sessionStorage instead of localStorage for decoy booking data (#24450)
* feat: Add async spam check integration and decoy booking response

- Integrate SpamCheckService with handleNewBooking workflow
- Implement parallel spam check execution for minimal performance impact
- Add decoy booking response with localStorage-based success page
- Extract organization ID from event type for org-specific blocking
- Add comprehensive test coverage for spam detection scenarios
- Create reusable components for booking success cards
- Implement fail-open behavior to never block legitimate bookings

This builds on the spam blocker DI infrastructure from PR #24040 by
adding the actual integration into the booking flow and implementing
the decoy response mechanism to avoid revealing spam detection to
malicious actors.

Related: #24040
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Do checks in paralle

* Fix leaking host name in title

* Reduce expoiry time localstorage

* refactor: Use sessionStorage instead of localStorage for decoy booking data

- Replace localStorage with sessionStorage for automatic expiration on tab close
- Remove timestamp tracking and TTL logic (no longer needed)
- Improve privacy by auto-clearing data when browser tab/window closes
- Update documentation to reflect sessionStorage behavior

This change addresses privacy concerns by ensuring decoy booking data
(including attendee email) is automatically removed when the user closes
the tab, rather than persisting for 5 minutes or requiring manual cleanup.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: Add sessionStorage wrapper to webstorage module

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Reset RegularBookingService.ts to main's version exactly

* feat: Add 5-minute expiration timeout to decoy booking data

- Adds timestamp to DecoyBookingData interface
- Checks expiration when retrieving booking data
- Automatically removes expired data from sessionStorage
- Provides defense-in-depth against potential misuse
- Works alongside sessionStorage auto-clear on tab close

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-12 07:42:44 -03:00
Hariom Balhara 010ee0d066 add-tests- usePrefetch (#23918) 2025-12-12 07:39:57 -03:00
sean-brydon f0a7d69c7e fix (#25818) 2025-12-12 10:26:56 +00:00
Anik Dhabal Babu cb2509683d fix: unit test flake (#25780) 2025-12-12 10:28:29 +05:30
Alex van Andel e2ac05e82f chore: release v5.9.14
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-12 00:52:39 +00:00
Volnei Munhoz 34ab02702e fix react version (#25809) 2025-12-12 06:15:25 +05:30
Pasquale Vitiello 1da118a534 chore: update Next.js (#25807) 2025-12-12 00:42:45 +00:00
Kartik LabhshetwarandDhairyashil acf2f53daf fix: hide insights submenu for free users (#25754)
* fix: hide insights submenu for free users

* fix: allow navigation access while plan pending

* refactor: update upgrade link to insights in navigation

* fix: addressed all the issues

* fix: prevent flash of premium features for free users during loading

Change from optimistic to pessimistic loading so free users don't
briefly see the Insights submenu while plan status is being fetched.

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2025-12-11 21:04:13 +00:00
Kartik LabhshetwarandUdit Takkar c7bb28d64c fix: show hidden badge on mobile view for event types (#25701)
* fix: show hidden badge on mobile view for event types

* fix: update event type hidden toggle in infinite list

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-12-11 20:31:51 +00:00
Kartik Labhshetwarandcubic-dev-ai[bot] 8dc8d87ad0 feat: add time shift badge for recurring events with shifted local times (#25568)
* feat: highlight recurring bookings with time shift badge across DST

* Update packages/lib/__tests__/timeShift.test.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor: show time shift badge only on first shift in bookings view and occurrences

* refactor: update recurring bookings display logic and wrap booking title text

* refactor: add getFirstShiftFlags helper for time shift flags and update components

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-11 20:18:00 +00:00
Udit Takkar da4fec9c27 chore: add missing translation (#25753) 2025-12-12 01:45:43 +05:30
Hariom BalharaandDevin AI 0ecfd78e47 fix: Update timeZoneSchema to handle +00:00 timezone case and maintain IANA compliance (#25776)
* fix: Update timeZoneSchema to handle +00:00 timezone case and maintain IANA compliance

* fix: Use superRefine to properly handle +00:00 timezone and transform to UTC

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: Add logging for non-IANA timezone cases

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Simplify timeZoneSchema to use .refine() instead of superRefine

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* chore: Remove warn log for +00:00 timezone to avoid spam

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* chore: Remove logger from timeZone schema

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-11 19:46:13 +00:00
Udit Takkar f007fe8407 feat: system admin blocklist backend (#25077)
* feat: admin blocklist backend

* chore:

* refactor: use DI

* fix: tests

* refactor; improve error

* refactor; improve error

* perf: use bulk

* chore: some more

* refactor: feedback

* test: update test

* refactor: improvements

* refactor: improvements

* fix: remove

* refactor: move to service

* refactor: move to service

* chore: add logs

* refactor: remove default
2025-12-11 19:41:29 +00:00
Kartik LabhshetwarandDhairyashil e1324bd9c3 fix(settings): improve spacing between navigation child items (#25631)
* fix(settings): improve spacing between navigation child items

* chore: removing prettier formatting

* style: update dropdown item class names for consistent rounding

* style: add spacing and hover margin to navigation items

* style: add hover margin top to navigation item

* apply same ui changes for team profile menu

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2025-12-11 19:09:32 +00:00
Alex van Andel ca152d73f2 chore: release v5.9.13
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-11 12:44:04 +00:00
Hariom Balhara 6f0c09d2be feat: add booker lifecycle SDK events for embed tracking (#25569)
* feat: add embed prerendering support and enhance event handling

- Introduced `useIsEmbedPrerendering` hook to determine if the embed is in prerender mode.
- Updated `useAvailabilityEvents` to prevent firing events during prerendering.
- Added `bookerLoadedEvent` and `availabilityRefreshed` types to `EventDataMap`.
- Implemented `useFirebookerLoadedEvent` to manage firing the booker loaded event conditionally.
- Refactored event firing logic in `useSchedule` and `BookerWebWrapper` components to utilize new hooks.

* feat: add embed prerendering support and enhance event handling

- Introduced `useIsEmbedPrerendering` hook to determine if the embed is in prerender mode.
- Updated `useAvailabilityEvents` to prevent firing events during prerendering.
- Added `bookerLoadedEvent` and `availabilityRefreshed` types to `EventDataMap`.
- Implemented `useFirebookerLoadedEvent` to manage firing the booker loaded event conditionally.
- Refactored event firing logic in `useSchedule` and `BookerWebWrapper` components to utilize new hooks.

* feat: enhance embed event handling and introduce link reopening detection

- Added `useEmbedReopened` hook to track when the embed is reopened.
- Updated `BookerWebWrapper` to reset event firing state upon embed reopening.
- Refactored event firing logic to use `bookerViewed` instead of `bookerLoadedEvent`.
- Introduced scheduling for event firing in `useSchedule` to ensure correct order of events during prerendering.

* feat: add lifecycle diagrams for inline and modal embeds

- Introduced `inline-embed-lifecycle.mermaid` and `modal-embed-lifecycle.mermaid` files to visualize the lifecycle events and states of inline and modal embeds.
- Updated `LIFECYCLE.md` to reference the new diagrams and provide a clearer explanation of the embed lifecycle processes.
- Added `modal-prerendering-flow.mermaid` to illustrate the prerendering flow for modal embeds.
- Enhanced the routing playground with new features and improved event handling for availability and booking events.

* refactor: update event handling for booker lifecycle events

- Replaced `availabilityLoaded` event with `bookerReady` to better reflect the state when the booker view is fully loaded and ready for interaction.
- Updated related documentation and diagrams to reflect changes in event triggers and descriptions.
- Adjusted internal state management to track `viewId` instead of `reopenCount` for distinguishing between initial views and reopens.
- Added tests for new event handling logic to ensure correct firing of `bookerViewed`, `bookerReopened`, and `bookerReady` events.

* refactor: enhance embed event handling and state management

- Updated event handling for booker lifecycle events, replacing `resetViewVariables` with `resetPageData` to manage page-specific state.
- Introduced new utility functions for managing event firing states and reload initiation.
- Refactored `fireBookerViewedEvent` and `fireBookerReadyEvent` to utilize the new state management functions.
- Added comprehensive tests for the updated event handling logic and state resets to ensure correct functionality across various scenarios.

* refactor: update embed iframe configuration and utility functions

- Reduced `slotsStaleTimeMs` from 30 seconds to 10 seconds and `iframeForceReloadThresholdMs` from 100 seconds to 30 seconds for improved responsiveness.
- Refactored utility functions to use `isBrowser` for client-side checks instead of `isClientSide`.
- Removed unused `isPrerendering` function and updated related documentation for clarity.
- Enhanced event handling by exporting `useBookerEmbedEvents` from the appropriate module for better accessibility.

* refactor: update embed iframe configuration and utility functions

- Reduced `slotsStaleTimeMs` from 30 seconds to 10 seconds and `iframeForceReloadThresholdMs` from 100 seconds to 30 seconds for improved responsiveness.
- Refactored utility functions to use `isBrowser` for client-side checks instead of `isClientSide`.
- Removed unused `isPrerendering` function and updated related documentation for clarity.
- Enhanced event handling by exporting `useBookerEmbedEvents` from the appropriate module for better accessibility.

* fix cubic feedback
2025-12-11 09:11:38 -03:00
Dhairyashil Shinde f6642c17f8 feat: optimize getLuckyUser to skip data fetching for single user (#25337)
- Add early return when only one user is available
- Prevents unnecessary database queries, calendar API calls, and OOO checks
- Add comprehensive test to verify optimization works correctly

Fixes #19503 [CAL-5212]
2025-12-11 08:50:57 -03:00
Dhairyashil Shinde 26b4385679 feat: Add public OOO notes display on booking pages (#25471)
* feat: ooo message on booking page

* make ooo days selectable even when no redirect booking

* handle long notes

* remove unused i18n key

* Private notes stay private on the server, No accidental data leaks through client-side payloads

* address cubics comments

* fix: replace toggle with checkbox for OOO note visibility

- Replace Switch with Checkbox for "show note publicly" option
- Remove "OOO Message:" prefix from displayed notes on booking page
- Update i18n text to "Show note on public booking page"
- Remove unused ooo_message i18n key

* fix the accessibility issue by using proper htmlFor and id association

* only allow selecting OOO dates when the note is public
2025-12-11 11:31:59 +00:00
Dhairyashil Shinde b220420630 fix: reset Cloudflare Turnstile token on signup errors (#24927)
* fix: cloudflare turnstile token reset

* fix: silently reset turnstile on invalid token error

* refactor: remove unused forwardRef logic from Turnstile component

- Remove forwardRef, useImperativeHandle, and useRef imports
- Remove unused TurnstileInstance type export
- Simplify to a plain function component
- The ref-based reset was replaced by key-based remount in signup-view

* refactor: remove redundant cfToken validation check

The submit button is already disabled when cfToken is missing,
making this defensive check unreachable during normal form flow.

* revert prettier formatiing

* chore: revert yarn.lock changes

* refactor(auth): use shared constant for cloudflare token error message

Replace hardcoded "Invalid cloudflare token" string with an exported
constant to prevent silent breakage if the error message changes.
2025-12-11 16:45:01 +05:30
Morgan 7d5e9a4e0e chore: hide rrHostSubsetIds and rrHostSubsetEnabled from api docs for now (#25769) 2025-12-11 11:12:10 +00:00
Rajiv Sahal 5253f26c94 fix: css for checkbox in light mode (#25782) 2025-12-11 10:48:59 +00:00
sean-brydon 9b09544c62 fix: try submit instead of form manual submition (#25789)
* try submit

* add toaster and logs
2025-12-11 10:35:09 +00:00
44104e1ba4 feat: gated features modal (#25296)
* feat: Modal for gated features

* use zustand

* refactor

* Apply suggestions from code review

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Update packages/ui/components/card/Card.tsx

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* dismiss button fix and url fix

* fix: broken redirect to teams

* fix: type check and review comments

* add learn more tracking back

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-12-11 11:14:31 +01:00
Kartik Labhshetwar 191dcc45b5 style: add mb-2 to workflows page flex container (#25787) 2025-12-11 10:07:31 +00:00
Benny Joo 5de8576473 remove duplicate code for buildBaseWhereCondition (#25779) 2025-12-11 08:25:19 +00:00
Udit Takkar 6440c60c96 fix: use safeStringify (#25766) 2025-12-11 07:27:33 +00:00
Alex van Andel 016ae6ea4b fix: Add orgSlug to slots.getSchedule call (#25397)
* fix: Add orgSlug to slots.getSchedule call

* Don't pass null if orgSlug is missing
2025-12-11 16:10:40 +09:00
AbhishekandDhairyashil Shinde d3f7308b9f fix(validation): disallow whitespace-only team name (#25467)
* fix(validation): disallow whitespace-only team name

* fix validation at team profile

* fix validation for title at event type

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-11 07:09:05 +00:00
Anik Dhabal Babu 060176cd08 Fix: Hide team members in social preview when team is private (#25770) 2025-12-11 04:17:56 +00:00
Dhairyashil Shindeandcubic-dev-ai[bot] a306a77678 feat: Include booking question response in csv file from insights page (#25454)
* feat: booking-question-phone-csv-insights-page

* feat: Include booking question responses in insights CSV download (#25453)

- Add custom question responses to CSV export
- Parse booking responses and eventType bookingFields
- Filter out system fields (email, name, etc.)
- Map field names to display labels
- Add dynamic columns for each custom question

Performance optimizations:
- Cache parsed bookingFields by eventTypeId (99% fewer parsing operations)
- Use Map for O(1) field label lookups (100x faster than array.find)
- Single-pass data processing (75% fewer iterations)
- Optimized attendee processing (67% reduction in loops)
- Reduced memory allocations (3x less memory usage)

Estimated 3-5x performance improvement for large datasets

* refactor: Remove optimization-related comments, keep code flow comments

* fix: Include attendee phone numbers in CSV export

- Add phoneNumber field to attendees and seatsReferences query
- Collect phone numbers from attendees during processing
- Add attendeePhone1, attendeePhone2, etc. columns to CSV output
- Fixes missing attendee phone numbers in insights CSV download

* fix: Handle falsy values correctly in custom responses

Previously, falsy values like 0 or false were incorrectly skipped
because !answer treats them as empty. This caused issues with:
- Numeric answers: 0, -1, etc.
- Boolean answers: false
- Empty strings: '' (intentionally skipped)

Now explicitly check for null, undefined, empty arrays, and empty strings
while allowing legitimate falsy values (0, false) to pass through.

Co-authored-by: cubic-dev-ai[bot] <cubic-dev-ai[bot]@users.noreply.github.com>

* feat(insights): add phone numbers to CSV export

- Add attendeePhone1, attendeePhone2, etc. columns with fallback to booking responses
- Add columns for custom phone-type booking questions
- Exclude system phone fields (attendeePhoneNumber, smsReminderNumber) from duplicate columns

* fix: address PR review comments

- Move SYSTEM_PHONE_FIELDS constant to packages/lib/bookings/SystemField.ts
- Restore comments

---------

Co-authored-by: cubic-dev-ai[bot] <cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-10 14:51:09 +00:00
Eunjae Lee 3986d61f40 feat(bookings): improve bookings redesign (#25251)
* use booking.uid instead of booking.id for url param

* show timezone on calendar

* fix type

* restore horizontal tab and remove header and subtitle

* clean up sidebar items

* fix event propagation from attendees

* fetch all statuses except for cancelled on calendar view

* clean up styles of the badges on BookingListItem

* fix useMediaQuery

* add close button to the header

* add assignment reason to the details sheet

* use separator row

* use ToggleGroup for the top bookings tab

* move ViewToggleButton

* resize the action button

* remove wrong prop

* fix type error

* fix type error

* hide view toggle button on mobile (and fix the breakpoint)

* remove unused e2e tests

* fix e2e tests

* hide toggle button when feature flag is off

* update skeleton

* improve attendees on booking list item and slide over

* improve attendee dropdown

* fix type error

* move query to containers

* select attendee email

* infinite fetching for calendar view

* update styles

* fix compatibility

* fix: add backward compatibility for status field in getAllUserBookings

* increase calendar height

* fix type error

* support Member filter only for admin / owners

* add debug log (TEMP)

* add event border color

* show Reject / Accept buttons on BookingDetailsSheet

* move description section to the top

* update When section

* update style of Who section

* add CancelBookingDialog WIP

* fix CancelBookingDialog

* increase clickable area

* add schedule info section WIP

* fix flaky reject button

* fixing reschedule info WIP

* add fromReschedule index to Booking

* improve rescheduled information

* improve reassignment

* fix type error

* fix unit test

* respect user's weekStart value on the booking calendar view

* update debug log

* improve payment section

* clean up

* fix log message

* reposition filters on list view

* fix bookings controller api2 e2e test

* clean up file by extracting logic into custom hooks

* rename files

* merge BookingCalendar into its container

* extract logic into separate hook files

* remove redundant logic

* rearrange items on calendar view

* add WeekPicker

* extract filter button

* responsive header on list view

* horizontal scroll for ToggleGroup WIP

* fix type error

* fix cancelling recurring event

* address feedback

* fix e2e tests

* fix unit test

* fix e2e tests

* make hover style more visible for ToggleGroup

* fix margin on CancelBookingDialog

* update styles on the slide over (mostly font weight)

* update style of CancelBookingDialog

* update styles

* update margin top for the header

* refactor getBookingDetails handler

* fix gap in who section

* auto-filter the current user on the calendar view

* calculate calendar height considering top banners

* improve booking details sheet interaction without overlay

* update calendar event styles

* update reject dialog style

* put uid first in the query params

* fix class name

* memoize functions in useMediaQuery

* query attendee with id instead of email

* update margins

* replace TRPCError with ErrorWithCode

* move calculation outside loop

* remove dead code
2025-12-10 13:40:04 +00:00
Eunjae LeeandDevin AI 41b71d845c docs: add ErrorWithCode vs TRPCError guidelines and packages/features import restrictions (#25751)
* docs: add ErrorWithCode vs TRPCError guidelines and packages/features import restrictions

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: correct ErrorWithCode syntax with proper imports and Factory pattern

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: update AGENTS.md with ErrorWithCode guidance for non-tRPC files

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: reduce duplication by linking to knowledge-base.md for error handling details

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-10 13:39:27 +00:00
sean-brydon e6bfdd9ebb fix (#25764) 2025-12-10 13:22:40 +00:00
devin-ai-integration[bot]andlauris@cal.com f4223d1657 docs: fix grammar, redundant word, and simplify OAuth client docs (#25747)
* docs: fix grammar and redundant word in managed organizations guide

Co-Authored-By: lauris@cal.com <lauris@cal.com>

* docs: simplify OAuth client fetching paragraphs per Pedro's feedback

Co-Authored-By: lauris@cal.com <lauris@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: lauris@cal.com <lauris@cal.com>
2025-12-10 17:17:23 +05:30
Volnei Munhoz b0bf0aaec2 upgrade lingo.dev (#25748) 2025-12-10 11:41:39 +00:00
e4fde4dc16 fix: Playwright user cleanup deadlock in E2E (#25677)
* fix: increase Docker build MAX_OLD_SPACE_SIZE to 8192 to fix OOM

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-10 17:04:09 +05:30
Kartik Labhshetwar 6c21a12a88 fix(phone-input): resolve styling inconsistencies in focus states and hover effects (#25744) 2025-12-10 11:25:38 +00:00
sean-brydon 34e1122667 watch invites to ensure reactivity i (#25755) 2025-12-10 11:22:31 +00:00
6b62557a92 feat: add hostSubsetIds parameter for round robin host filtering (#25627)
* feat: add hostSubsetIds parameter for round robin host filtering

Add support for filtering round robin event type hosts via API v2.
When hostSubsetIds is provided, only the specified hosts are considered
for availability calculation and booking assignment.

Changes:
- Add hostSubsetIds to slots API input (GET /slots/available)
- Add hostSubsetIds to booking API input (POST /bookings)
- Update _findQualifiedHostsWithDelegationCredentials to filter by hostSubsetIds
- Pass hostSubsetIds through all layers: API -> tRPC -> slots/booking services

This allows API consumers to request availability and create bookings
for a subset of hosts within a round robin event type.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: add e2e tests

* chore: add enableHostSubset team event-type setting

* fixup! chore: add enableHostSubset team event-type setting

* fix tests

* fix tests

* improve isWithinRRHostSubset

* rename to rrHost subset

* fix ai review

* fix: add booker platform wrapper rrHostSubsetIds prop

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-10 10:37:39 +00:00
300b9c916d fix: preserve metadata fields during partial event type updates (#25621)
* fix: preserve metadata fields during partial event type updates

- Fix multipleDuration (lengthInMinutesOptions) being reset to undefined on partial updates
- Fix bookerLayouts being reset to undefined on partial updates
- Fix requiresConfirmationThreshold being reset to undefined on partial updates
- Add e2e test for lengthInMinutesOptions preservation

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* test: expand metadata preservation test to include bookerLayouts and confirmationPolicy

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-10 10:33:01 +00:00
devin-ai-integration[bot]andlauris@cal.com 5ac374374c chore: delete changeset files for atoms release (#25746)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: lauris@cal.com <lauris@cal.com>
2025-12-10 15:43:12 +05:30
Benny Joo 09a4247aa1 refactor: migrate schedule utils from TRPC to ScheduleRepository to break circular dependency (#24764)
* remove util files

* wip

* wip

* wip

* wip

* wip

* wip

* add test file

* refactors

* refactors

* fix type error

* simplify

* host repository test

* di
2025-12-10 12:01:48 +02:00
Volnei MunhozandDevin AI eb01e2f9d8 fix(companion): update react-native-reanimated to Expo 54 compatible version (#25741)
The Android build was failing with errors like:
- cannot find symbol: ReactViewBackgroundDrawable
- cannot find symbol: TRACE_TAG_REACT_JAVA_BRIDGE
- cannot find symbol: getRuntimeExecutor()
- no suitable method found for updateLayout

Root cause: react-native-reanimated ~3.10.1 is incompatible with React Native 0.81.5 (used by Expo SDK 54).

Fix: Update to Expo 54 bundled versions using 'npx expo install':
- react-native-reanimated: ~3.10.1 → ~4.1.1
- react-native-worklets: ^0.6.1 → 0.5.1

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-10 01:24:50 +00:00
Alex van Andel 20efb566b2 chore: release v5.9.12
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-10 01:09:32 +00:00
d9ebf26e21 chore: standarize rate limit structure (#25736)
* feat: add toggle to opt out of booking title translation in instant meetings (#25547)

* feat: add toggle to opt out of booking title translation in instant meetings

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add autoTranslateTitleEnabled to test builder

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: respect autoTranslateTitleEnabled toggle in InstantBookingCreateService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: fetch autoTranslateTitleEnabled directly in InstantBookingCreateService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: rename autoTranslateTitleEnabled to autoTranslateInstantMeetingTitleEnabled

- Renamed field to clarify it only applies to instant meeting title translation
- Moved Prisma query to EventTypeRepository.findInstantMeetingConfigById()
- Removed title translation logic from update.handler.ts (flag only controls instant meeting title)
- Updated all references across the codebase
- Added new i18n translation keys for the renamed field

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add autoTranslateInstantMeetingTitleEnabled to test destructuring patterns

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use Prisma.TeamCreateInput type for metadata in test helper

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add autoTranslateInstantMeetingTitleEnabled to mockUpdatedEventType in test

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: use generic findByIdMinimal instead of business-specific method

- Add autoTranslateInstantMeetingTitleEnabled to eventTypeSelect constant
- Remove findInstantMeetingConfigById from EventTypeRepository
- Update InstantBookingCreateService to use findByIdMinimal

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: remove autoTranslateInstantMeetingTitleEnabled from eventTypeSelect (not needed for findByIdMinimal)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add autoTranslateInstantMeetingTitleEnabled to event type form defaults

- Rename shouldTranslateTitle to shouldAutoTranslateInstantMeetingTitle for clarity
- Add autoTranslateInstantMeetingTitleEnabled to findById and findByIdForOrgAdmin selects
- Add autoTranslateInstantMeetingTitleEnabled to useEventTypeForm defaultValues

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: only update autoTranslateInstantMeetingTitleEnabled when explicitly provided

Fixes issue where omitting the field in update requests would overwrite
the saved opt-out setting with the default value (true). Now the field
is only included in the update payload when explicitly provided.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: Create standard for rate limits

---------

Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-10 01:04:21 +00:00
Volnei Munhoz cb13874574 Fix react version for lingo.dev (#25740) 2025-12-10 01:01:37 +00:00
Volnei Munhoz 1fa02d957e sync yarn.lock (#25737) 2025-12-09 20:19:22 +00:00
Benny JooandDevin AI 529ca159f7 refactor: remove TRPCError handling from getServerErrorFromUnknown (#25691)
* refactor: remove TRPCError handling from getServerErrorFromUnknown

This removes the @trpc/server dependency from packages/lib by removing
TRPCError handling from getServerErrorFromUnknown.ts.

packages/lib is meant to be a general utility library that other packages
depend on, so it shouldn't import tRPC. The callers that need to handle
TRPCError (like onErrorHandler.ts and defaultResponder.ts) already handle
it explicitly before calling getServerErrorFromUnknown, so this change
has no behavioral impact.

Changes:
- Remove TRPCError and getHTTPStatusCodeFromError imports
- Remove TRPCError instanceof check from getServerErrorFromUnknown
- Update docstring to note that TRPCError is not handled
- Remove TRPCError-related tests (they belong in the tRPC layer)
- Fix lint warnings in Prisma error tests (replace 'as any' with proper type)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* wip

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-09 16:21:55 -03:00
devin-ai-integration[bot]andlauris@cal.com be12ac75b4 docs: add managed organizations documentation (#25735)
- Create docs/platform/guides/managed-orgs.mdx with guide for creating managed organizations and their OAuth clients via the API
- Add entry to docs/mint.json navigation menu in the Platform Guides section

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: lauris@cal.com <lauris@cal.com>
2025-12-09 18:49:54 +00:00
Eunjae LeeandDevin AI 68cdfd42b1 docs: add Repository + DTO pattern guidance for Prisma type isolation (#25730)
* docs: add Repository + DTO pattern guidance for Prisma type isolation

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: add 'Why this pattern?' section explaining benefits of Repository + DTO

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: condense Repository + DTO pattern guidance for readability

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-09 18:26:02 +00:00
Pedro CastroandUdit Takkar 3ebac0194e fix: block Google Meet installation without Google Calendar dependency (#25513)
* fix: block Google Meet installation without Google Calendar dependency

  - Prevent users from installing Google Meet when Google Calendar is not connected
  - Update AppDependencyComponent to show error state for unmet dependencies
  - Fix InstallAppButtonChild to respect disabled prop from dependencies check
  - Ensure consistent dependency validation across App Store and app detail pages

  Fixes #25497

* test: add unit tests for dependency validation
- Add tests for AppDependencyComponent (8 tests)
- Add tests for InstallAppButtonChild (5 tests)
- Cover dependency blocking behavior
- Test visual state changes (bg-error/bg-subtle)

* test: resolve type-check error in InstallAppButtonChild tests

- Add complete MockCredential type definition
- Create factory function to generate typed mock credentials
- Eliminate code duplication across test cases

* fix: remove redundant disabled prop assignment

Disabled state is already passed through via props.disableInstall
which gets converted to props.disabled in InstallAppButtonWithoutPlanCheck.
This change addresses the review comment to avoid unnecessary duplication

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-12-09 17:56:20 +00:00
Rajiv Sahal 6bdf320640 fix: dont pass any default values for new oauth client creation (#25734) 2025-12-09 16:34:59 +00:00
Lauris Skraucis cdfdce533e chore: atoms release changelog and package.json (#25733) 2025-12-09 16:28:33 +00:00
PallavandAmit Sharma 5e29a7fa2a feat: add option to ignore guests in HubSpot integration and update related schemas (#25727)
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
2025-12-09 15:21:33 +00:00
Pallavandcubic-dev-ai[bot] 97377c4554 docs: updated the steps to connect hubspot (#25724)
* updated the stpes to connect the app

* chore

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-09 15:06:43 +00:00
Eunjae LeeandDevin AI acc82f808d docs: instruct to use ast-grep > ripgrep > grep for searching (#25725)
* docs: instruct to use ripgrep with grep fallback

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: update search tool preference to ast-grep > ripgrep > grep

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-09 14:13:06 +00:00
3a59cd41cc feat: add toggle to opt out of booking title translation in instant meetings (#25547)
* feat: add toggle to opt out of booking title translation in instant meetings

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add autoTranslateTitleEnabled to test builder

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: respect autoTranslateTitleEnabled toggle in InstantBookingCreateService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: fetch autoTranslateTitleEnabled directly in InstantBookingCreateService

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: rename autoTranslateTitleEnabled to autoTranslateInstantMeetingTitleEnabled

- Renamed field to clarify it only applies to instant meeting title translation
- Moved Prisma query to EventTypeRepository.findInstantMeetingConfigById()
- Removed title translation logic from update.handler.ts (flag only controls instant meeting title)
- Updated all references across the codebase
- Added new i18n translation keys for the renamed field

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add autoTranslateInstantMeetingTitleEnabled to test destructuring patterns

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use Prisma.TeamCreateInput type for metadata in test helper

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add autoTranslateInstantMeetingTitleEnabled to mockUpdatedEventType in test

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: use generic findByIdMinimal instead of business-specific method

- Add autoTranslateInstantMeetingTitleEnabled to eventTypeSelect constant
- Remove findInstantMeetingConfigById from EventTypeRepository
- Update InstantBookingCreateService to use findByIdMinimal

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: remove autoTranslateInstantMeetingTitleEnabled from eventTypeSelect (not needed for findByIdMinimal)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: add autoTranslateInstantMeetingTitleEnabled to event type form defaults

- Rename shouldTranslateTitle to shouldAutoTranslateInstantMeetingTitle for clarity
- Add autoTranslateInstantMeetingTitleEnabled to findById and findByIdForOrgAdmin selects
- Add autoTranslateInstantMeetingTitleEnabled to useEventTypeForm defaultValues

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: only update autoTranslateInstantMeetingTitleEnabled when explicitly provided

Fixes issue where omitting the field in update requests would overwrite
the saved opt-out setting with the default value (true). Now the field
is only included in the update payload when explicitly provided.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-09 13:51:51 +00:00
Anik Dhabal Babu 6ae2ce8ed9 fix: workflow email is not sending on form submission (#25722)
* fix: email not sending on form submission

* Remove handleCheckoutSessionExpired function

Removed the handleCheckoutSessionExpired function and its registration in webhookHandlers.
2025-12-09 13:24:41 +00:00
Anik Dhabal Babu 476460dad8 fix: Add custom payload template support for form submission webhooks (#25719)
* fix: Add custom payload template support for form submission webhooks

* delete

* Update applyTemplate function signature

Refactor applyTemplate function to accept specific data type.
2025-12-09 13:22:13 +00:00
Rajiv Sahal 19cadd18e3 fix: preserve description for event type (#25726) 2025-12-09 13:05:24 +00:00
Hariom Balhara e20cc960f1 feat: add uuid plumbing from API v2 to packages/features (#25721)
## What does this PR do?

This PR adds user UUID plumbing from API v2 controllers through to packages/features functions. This is preparatory work extracted from PR #25125 to support future audit logging functionality.

**Key changes:**
- API v2 controllers (2024-04-15, 2024-08-13) now extract and pass `userUuid` to downstream functions
- `handleMarkNoShow` and `CancelBookingInput` types now accept optional `userUuid` parameter
- `UserRepository.findUnlockedUserForSession` now selects `uuid` field
- Session middleware now includes `uuid` in the returned user object
- Fixed lint warning: changed `PromiseSettledResult<any>` to `PromiseSettledResult<unknown>`

**Refactoring (optimization):**
- Renamed `getOwnerId` → `getOwner` and `getOwnerIdRescheduledBooking` → `getOwnerRescheduledBooking`
- These methods now return `{ id: number; uuid: string } | null` instead of just `number | undefined`
- This eliminates redundant database calls by fetching user id and uuid in a single query

**Important:** This is plumbing-only - packages/features receives the `userUuid` but does not use it directly (note the `_userUuid` prefix). The actual audit logging usage will come in a follow-up PR.

Requested by: @hariombalhara (hariom@cal.com)

Link to Devin run: https://app.devin.ai/sessions/545209189f6347cd807bf1b336f9ac40

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. N/A - plumbing only, existing tests cover the functionality.

## How should this be tested?

1. Run type checks: `yarn type-check:ci --force`
2. Verify the changes compile without new type errors related to uuid
3. The `userUuid` parameters are optional, so existing functionality should work unchanged

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

## Human Review Checklist

- [ ] Verify the `userUuid` parameter is intentionally unused (prefixed with `_userUuid`) - this is plumbing for future audit logging
- [ ] Verify all callers of `getOwner` and `getOwnerRescheduledBooking` correctly handle the new `{ id, uuid } | null` return type
- [ ] Confirm the change from `undefined` to `null` as the "not found" return value is handled consistently
- [ ] Verify the `uuid` field exists in the User model schema
2025-12-09 17:29:55 +05:30
Hariom BalharaandDevin AI f350542d0d feat: add booking audit action services for lib/actions folder (#25720)
Extract lib/actions folder changes from booking-audit-more-infra branch:
- AcceptedAuditActionService
- AttendeeAddedAuditActionService
- AttendeeNoShowUpdatedAuditActionService
- AttendeeRemovedAuditActionService
- CancelledAuditActionService
- CreatedAuditActionService (modified)
- HostNoShowUpdatedAuditActionService
- IAuditActionService (modified)
- LocationChangedAuditActionService
- ReassignmentAuditActionService
- RejectedAuditActionService
- RescheduleRequestedAuditActionService
- RescheduledAuditActionService

Also includes common/changeSchemas.ts required for type-checks to pass.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-09 14:29:41 +05:30
Peer RichelsenandDhairyashil Shinde 257a49ce88 fix(companion): replaced localhost with prod url (#25576)
* replaced localhost with prod url

* nit

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-09 07:47:17 +00:00
sean-brydon 75b93cebdb fix: troubleshooter team events + improve race condition (#25704)
* fix query to bring back teams + fix hover state

* fix team issues with troubleshooter
2025-12-09 07:37:21 +00:00
Anik Dhabal Babu 161ebdbbec perf: Fix N+1 queries and optimize database operations (#25630)
* perf: batch database operations and fix N+1 queries

* delete

* Fix condition for checking CalVideo location activity
2025-12-09 07:32:30 +00:00
Kartik Labhshetwar 978c5bdb95 fix(insights): align call history empty state with search (#25718) 2025-12-09 07:19:10 +00:00
Alex van Andel 895d039efc chore: release v5.9.11
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-09 03:08:28 +00:00
Anik Dhabal Babu 9f566bc8fc fix: orgbanner (#25706) 2025-12-08 20:35:11 +05:30
Volnei Munhoz 518e541177 chore: upgrade husky (#25698)
* bump husky version

* fix new husky version warning

* Fix husky version
2025-12-08 10:47:29 -03:00
Anik Dhabal Babu c1be922ee1 perf: Workflows are taking too long to load (#25705)
* perf: workflows are too slow

* Refactor eventTypeRepository for improved clarity

* Reintroduce ErrorCode and ErrorWithCode imports
2025-12-08 18:31:46 +05:30
Volnei Munhoz 967bba1e80 Remove coderrabit config (#25702) 2025-12-08 12:27:28 +00:00
Hariom Balhara 0fc26f782f feat: Add support to audit and view audit log with Booking CREATED action (#25468)
## What does this PR do?

This PR introduces the booking audit infrastructure with a viewer service to fetch, enrich, and format audit logs. This is the first iteration that includes only the CREATED action with versioned schema

Note: Additional audit actions, UI improvements to match with Figma will be taken care of in followup PRs, to ensure the PR size remains as small as possible(as it is large enough already)

Demo - Loom - https://www.loom.com/share/22c2f38b052b480b8be3716e1608eaf6

### Key Changes

**New Booking Audit Package** (`packages/features/booking-audit/`):

- `BookingAuditViewerService` - Fetches, enriches, and formats audit logs for display
- `BookingAuditTaskConsumer` - Processes audit tasks asynchronously via Tasker
- `CreatedAuditActionService` (v1) - Handles RECORD_CREATED action with versioned schema

**Repository Layer**:

- `BookingAuditRepository` - CRUD operations for audit records
- `AuditActorRepository` - Actor management (users, guests, system)
- `UserRepository.findByUuid()` - User lookup for actor enrichment

**UI Components**:

- New page at `/booking/logs/[bookinguid]` for viewing audit history
- Filterable audit log list with search, type, and actor filters
- Expandable log entries showing detailed change information

**Infrastructure**:

- `bookingAudit` Tasker task type for async processing
- `booking-audit` feature flag (disabled by default)
- tRPC endpoint `viewer.bookings.getAuditLogs`

### Updates since last revision

- **Refactored `Task` class to `TaskRepository`**: Converted all static methods to instance methods following the repository pattern. A singleton `Task` is exported for backward compatibility, so existing call sites continue to work unchanged.

### Important Notes for Reviewers

- **Permission check is TODO**: `checkPermissions()` in `BookingAuditViewerService` is not yet implemented
- **Only CREATED action supported**: Other actions will throw an error - additional actions will be added iteratively in follow-up PRs
- **Feature flag controlled**: System is behind `booking-audit` flag, disabled by default
- **UI strings need i18n**: Some UI text in `booking-logs-view.tsx` may need translation

### Human Review Checklist

- [ ] Verify permission enforcement strategy for audit log access
- [ ] Review DI wiring in module files
- [ ] Confirm error handling in `BookingAuditTaskConsumer` is appropriate for retry scenarios
- [ ] Check if UI strings need to be added to translation files
- [ ] Verify `TaskRepository` refactoring maintains backward compatibility (singleton export `Task` should work for all existing call sites)

## Mandatory Tasks (DO NOT REMOVE)

- [ ] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - internal infrastructure
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

Run the integration tests:

```bash
TZ=UTC yarn test packages/features/booking-audit/lib/service/BookingAuditViewerService.integration-test.ts
TZ=UTC yarn test packages/features/booking-audit/lib/service/BookingAuditTaskConsumer.integration-test.ts
```

To test the UI:

1. Enable the `booking-audit` feature flag in the database
2. Create a booking (only CREATED action is supported in this PR)
3. Navigate to `/booking/logs/{bookingUid}` to view the audit trail

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings

<!-- Link to Devin run: https://app.devin.ai/sessions/a8ae61c253b549429401c9651dcbcf44 -->
<!-- Requested by: hariom@cal.com (@hariombalhara) -->
2025-12-08 17:38:58 +05:30
sean-brydon fadd824d12 feat: onboarding v3 QA final roast (#25667)
* remove leading none

* remove back button if coming from teams/org onboarding

* add skip now
2025-12-08 11:35:44 +00:00
Volnei MunhozandDevin AI c1b7b6e83d fix: prevent OOO dialog from closing on outside click (#25699)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-08 11:23:09 +00:00
Volnei Munhoz e82a53a442 add fallback discovery for oauth (#25656) 2025-12-08 11:15:31 +00:00
a6578fdcd2 perf: handleChildrenEventType link old event-type with workflows using create/findMany (#25653)
* perf: link old event-type with workflows using create/findMany

* test: fix handleChildrenEventTypes test mocks for new workflow linking implementation

Update test to match the new implementation that uses findMany + createMany
instead of upsert for linking workflows to old event types.

- Add mock for workflowsOnEventTypes.findMany to return empty array
- Update assertion from upsert to findMany + createMany

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-08 13:11:21 +02:00
Eunjae LeeandDevin AI 4e68bcb021 docs: improve AGENTS.md and rename .agents to agents/ (#25665)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-08 11:06:59 +00:00
1e673f1df4 perf: handleChildrenEventTypes createManyAndReturn (#25652)
* perf: handleChildrenEventTypes createManyAndReturn

* fix: update test mocks for createManyAndReturn

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use full EventType shape in createManyAndReturn mock return values

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-08 10:21:57 +00:00
Morgan b91f27dc80 perf: handleChildrenEventType eventtype user connect raw sql (#25650)
* perf: handleChildrenEventType eventtype user connect raw sql

* fixup! perf: handleChildrenEventType eventtype user connect raw sql

* remove user connect with prisma
2025-12-08 11:41:25 +02:00
Benny Joo becae27b45 refactor: migrate verifyCodeUnAuthenticated from TRPC layer to features layer (#25639)
* rm

* update test

* verifyCodeUnAuthenticated

* wip
2025-12-08 10:54:46 +02:00
Benny JooandDevin AI 584f5581fa refactor: move handleNotificationWhenNoSlots from trpc to features/slots (#25538)
Move handleNotificationWhenNoSlots.ts and its test file from
packages/trpc/server/routers/viewer/slots/ to packages/features/slots/
to resolve circular dependency issue where packages/features imports
from packages/trpc.

This file is not TRPC-specific and belongs in the features package.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-08 10:54:21 +02:00
Anik Dhabal Babu e10c4c1cb5 fix: unable to reject the booking from email (#25673)
* fix: unable to reject the booking

* Refactor error handling for booking confirmation
2025-12-08 12:32:19 +05:30
Syed Ali Shahbaz c78552ce60 fix: OnDelete SetNull for watchlist delete on watchlistAudit (#25690)
* OnDelete SetNull for watchlist delete on watchlistAudit

* make watchlistId nullable

* type fix
2025-12-08 05:22:01 +00:00
Morgan 9631d0a64b chore: update add members to team (#25685) 2025-12-08 03:48:15 +00:00
1182460d5c chore: add permission checks to invite member and list team members handlers (#25679)
* chore: update invite team member handler

* chore: update invite team member handler

* fix: add mock for PermissionCheckService in inviteMember handler tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add mocks for PBAC dependencies in inviteMember handler tests

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-07 16:32:55 +00:00
Alex van Andel aedc0f5a03 chore: release v5.9.10
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-07 14:25:55 +00:00
Keith Williams ff88ec0eae fix: Docker build OOM issues in v5.9.9 (#25678) 2025-12-07 14:22:24 +00:00
Kartik Labhshetwar 110b5ceaf6 style: adjust dark hover background for user page to subtle (#25662) 2025-12-06 13:24:41 +00:00
Kartik Labhshetwar 7c53d2c9ce fix: improve spacing in provide link to team member when OOO list (#25529) 2025-12-06 09:12:48 +00:00
Volnei Munhoz eccebff4c6 Companion build (#25648) 2025-12-05 21:22:31 +00:00
cal.com 0a36dd7f61 revert: perf: handleChildrenEventType update existing events without mapping 2025-12-05 22:24:15 +02:00
cal.com 5143083efb perf: handleChildrenEventType update existing events without mapping 2025-12-05 22:00:33 +02:00
AbhishekandDhairyashil Shinde b874e0d55a fix: data table toolbar styling (#25632)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-05 16:01:05 +00:00
Dhairyashil Shinde 3ee24586a7 feat(api): PATCH Event Type V2 API to support all current locations (#25084)
* feat(api): PATCH Event Type V2 API to support all current locations

* docs(api): update locations documentation and add E2E tests for new integrations

- Updated locations property documentation in create-event-type.input.ts
  and update-event-type.input.ts to clarify app installation requirements
- Explained that only Google Meet, MS Teams, and Zoom can be installed via API
- Noted that Cal Video is installed by default
- Added E2E tests for creating and updating event types with newly supported
  integration locations (jitsi, zoom, google-meet, whereby, huddle, element-call)
- Regenerated openapi.json with updated API documentation

Addresses feedback from Lauris regarding platform API location support.

* fix(api): use supportedIntegrations list for app validation

Updated checkAppIsValidAndConnected to use the full supportedIntegrations
list from locations.input.ts instead of hardcoded array. This allows all
27 supported conferencing apps to be set as event type locations via API,
as long as they are already connected by the user.

* fix(api): add slug mapping for all conferencing integrations

Added comprehensive slug mapping to translate API integration names
(e.g., 'facetime-video', 'whereby-video') to actual app slugs
(e.g., 'facetime', 'whereby'). This ensures the app lookup works
correctly for all 27 supported conferencing integrations.

Addresses AI bot feedback about slug mismatches.

* fix(api): add missing huddle to huddle01 slug mapping

Added mapping for huddle -> huddle01. Other apps like tandem, jitsi,
cal-video, google-meet, and zoom don't need mapping as their API names
already match their app slugs (handled by the fallback || appSlug).

* update key

* update ket

* test(api): update E2E tests to validate newly supported integrations

Replaced end-to-end tests with validation-focused tests that follow
the existing pattern. The new test creates event types with various
newly supported integrations (jitsi, whereby-video, huddle, tandem,
element-call-video) directly in the database (bypassing app connection
checks) and verifies the API correctly returns them.

This approach tests that the input validation accepts all 27 supported
integration types without requiring actual app installations in the
test environment.

* fix(api): correct slug mappings for whatsapp, shimmer, and jelly integrations

- Fixed whatsapp-video mapping from 'whatsappvideo' to 'whatsapp'
- Fixed shimmer-video mapping from 'shimmer' to 'shimmervideo'
- Fixed jelly-conferencing mapping from 'jelly-conferencing' to 'jelly'

All slug mappings now correctly match the actual app slugs in
packages/app-store/*/config.json files. This ensures proper app
validation when users create/update event types with these locations.

Addresses feedback from @pedroccastro

* updated openapi.json file because of main branch code

* test(api): add negative test for unsupported integration locations

- Added E2E test to validate 400 error when creating event type with unsupported integration
- Test verifies exact error message listing all supported integrations
- Uses imported supportedIntegrations constant for maintainability
- Follows same pattern as booking fields validation tests

Addresses feedback from @supalarry

* test(api): add negative test for patching event type with unconnected integration

- Added E2E test to validate 400 error when user tries to PATCH event type with jitsi integration they haven't connected
- Test verifies exact error message 'jitsi not connected.'
- Follows existing test patterns with proper cleanup
2025-12-05 19:51:58 +05:30
Dhairyashil Shinde b014ded5fd feat: api v2 event types ordering - user, team, org (#25177)
* feat: api-v2-event-types-ordering

* sort team and org event types

* revert: remove accidental changes to api-auth.strategy.ts

* docs: add ordering documentation and test for event types endpoints

- Added test assertion to verify event types are returned in descending order by ID (newest first)
- Added API documentation to user event types endpoint describing default ordering behavior
- Added API documentation to team event types endpoint describing default ordering behavior
- Added API documentation to organization event types endpoints describing default ordering behavior

Addresses PR feedback to document and test the ordering behavior introduced in the API v2 event types ordering feature.

* feat: add optional sortCreatedAt parameter to event types endpoints

- Add sortCreatedAt query parameter (SortOrderType: "asc" | "desc") to all event types endpoints
- Define SortOrder enum and SortOrderType in pagination.input.ts for reusability
- When not provided, no explicit ordering is applied (backward compatible)
- Update user, team, and organization event types endpoints
- Add comprehensive e2e tests for all sorting scenarios
- Fix circular dependency in platform-types import
- Thread sortCreatedAt through all service layers
- Use spread pattern for conditional orderBy to avoid empty array issues

Addresses PR feedback to make ordering opt-in rather than changing default behavior
2025-12-05 19:51:48 +05:30
Alex van Andel 46b88a3c81 chore: release v5.9.9
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-05 10:55:08 +00:00
sean-brydon c97f1928bb fixes refresh issue (#25616) 2025-12-05 09:37:35 +00:00
dea6ec5003 perf: handleChildrenEventTypes transaction (#25602)
* perf: handleChildrenEventTypes transaction

* fixup! perf: handleChildrenEventTypes transaction

* fix: e2e tests

* test: update handleChildrenEventTypes tests for createMany API

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-05 08:35:29 +00:00
Rouh 8cace7f7a0 fix (a11y): Add aria-label to progressToast close button (#25618) 2025-12-05 04:40:12 -03:00
Hariom BalharaandDevin AI b80c0692dc fix: improve Vercel domain 'forbidden' error message and add schema fields (#25520)
* fix: improve Vercel domain 'forbidden' error message

The 'forbidden' error code from Vercel is a generic permission denial,
not specifically 'domain owned by another team'. It can occur for various
reasons: wrong teamId, token lacking project access, account-level
restrictions, or domain ownership by another team.

Updated the error message to be more accurate and changed the HTTP status
code from 400 to 403 to better reflect the permission error nature.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: add message and invalidToken fields to Vercel error response schema

This allows better logging of Vercel API error responses, especially when
tokens become invalid. The new fields help with debugging permission issues.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: revert status code to 400 for Vercel forbidden errors

Keep the status code at 400 to avoid potential downstream side effects
while still using the improved error message and schema fields.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use .nullish() instead of .optional() for message and invalidToken fields

.nullish() handles both null and undefined, which is safer for API responses.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-05 05:26:42 +00:00
Kartik LabhshetwarandDhairyashil Shinde 44291be7b7 fix: show rescheduled badge on mobile view in bookings list (#25542)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-05 04:00:03 +00:00
Kartik 54440cf954 fix: weekly view slots not clickable with overlay calendar (#25484) 2025-12-04 21:11:45 +00:00
Dhairyashil Shinde 43315108a2 refactor: remove cal workflow trigger message from workflow templates (#25539)
* refactor: remove cal workflow trigger message

* remove from rating template
2025-12-04 20:45:38 +00:00
Emmanuel IsenahandDhairyashil Shinde 311b6e071d feat: support hideEventTypeDetails query param on booking pages (#25565)
* fix: lint error

* feat: support `hideEventTypeDetails` via query param

Allow the event type details to be hidden based on the
hideEventTypeDetails query parameter when not in embed mode

* feat: add hideEventTypeDetails prop to EventMeta

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-04 20:26:08 +00:00
Kartik 308c7fa12b fix: correct typos and HTML encoding in org invite emails (#25551)
* fix: correct typos and HTML encoding in org invite emails

* removed interpolation: { escapeValue: false }

* added interpolation: { escapeValue: false }
2025-12-04 19:53:44 +00:00
Anshumancanrock 51cf73218b fix: Radio buttons not filled in (CSS background-color) (#25599)
* Radio buttons not filled in (CSS background-color)

* fix: radio buttons not filled when selected in light mode
2025-12-04 19:49:02 +00:00
Joe Au-YeungandDevin AI dc44825ce5 fix: prevent overwriting existing event type values with undefined (#25624)
When updating an event type, fields like autoTranslateDescriptionEnabled
and disableGuests were being overwritten with false/default values even
when they weren't explicitly provided in the update request.

Changes:
- autoTranslateDescriptionEnabled: Only set when explicitly provided
  (not undefined) to avoid overwriting existing true values with false
- disableGuests: Only set when bookingFields is explicitly provided,
  since it's derived from the guests field in bookingFields

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-04 19:18:45 +00:00
Kartik Labhshetwar 908128ca5d style: improve dropdown option spacing and hover separation (#25605)
* feat(ui): improve dropdown option spacing and hover separation

* style: add flex column layout and spacing to timezone select scrollbar
2025-12-05 00:47:21 +05:30
Dhairyashil ShindeandPallav b12f14c538 feat: auto scroll sidebar to active team on navigation (#25555)
* feat: auto-scroll sidebar to active team on navigation

When navigating to team settings via "Edit team" from the teams list,
the sidebar now scrolls to show the selected team and expands its section.

- Extract team ID from URL path (/settings/teams/{id}/...)
- Use existing aria-controls attribute to find team element
- Scroll with smooth behavior centered in viewport

* revert formatting changes by prettier

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-12-05 00:46:18 +05:30
Anik Dhabal Babu f03e6075a2 fix: unable to confirm/reject booking from email (#25614)
* fix: unable to confirm/reject booking

* fix lint

* Refactor booking confirmation and rejection tests
2025-12-04 23:17:17 +05:30
Peer Richelsen a8aac6dc3a added eas (#25619) 2025-12-04 14:36:38 -03:00
Anik Dhabal Babu 1594567fd5 fix: issue with workflow meetingUrl (#25620) 2025-12-04 16:46:36 +00:00
Volnei Munhoz dde6e7d140 chore: bump nextjs version (#25592)
* bump nextjs version

* bump nextjs version for api v1
2025-12-04 10:46:34 -03:00
Eesh Midha d8f36d0665 fix: enable date picker taps on iOS by setting modal={false} (#25590) 2025-12-04 13:33:43 +00:00
Abhishek 9362253bfb fix: vertical tab spacing (#25612) 2025-12-04 12:56:05 +00:00
sean-brydonandEunjae Lee c91da96956 fix: reset store on getting started (#25607)
* reset store

* Update apps/web/modules/onboarding/getting-started/onboarding-view.tsx

Co-authored-by: Eunjae Lee <hey@eunjae.dev>

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2025-12-04 11:23:52 +00:00
Abhishek dbb33b9632 fix(ui): improve the alignment of api keys code (#25570)
fix: api key horizontally centered
2025-12-04 10:54:48 +00:00
Anik Dhabal Babu ead0691ea3 fix: refactored few handler and repository (#25567)
* update

* update

* refactor
2025-12-04 11:43:29 +02:00
Abir Roy e4a6b97017 fix(routing-forms): correct variable encoding and URL construction in Routing Forms Event Redirect Custom URLs (#25499)
* fix: change slugification to uri encoding

* fix: add conditional joiner symbol between event type redirect url and all other search params

* fix: update integration test to expect encoded variable

* test: add tests for query parameters joiner logic
2025-12-04 08:59:22 +00:00
sean-brydon 98b862c048 fix: form issues in QA for onboarding (#25581)
## What does this PR do?
Fixes the issue where form state wasnt corectly recorded in QA

## Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change **(video / image - any one)**.

#### Video Demo (if applicable):

- Show screen recordings of the issue or feature.
- Demonstrate how to reproduce the issue, the behavior before and after the change.

#### Image Demo (if applicable):

- Add side-by-side screenshots of the original and updated change.
- Highlight any significant change(s).

## Mandatory Tasks (DO NOT REMOVE)

- [ ] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests -->

- Are there environment variables that should be set?
- What are the minimal test data to have?
- What is expected (happy path) to have (input and output)?
- Any other important info that could help to test that PR

## Checklist

<!-- Remove bullet points below that don't apply to you -->

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my changes generate no new warnings
2025-12-04 08:58:00 +00:00
Hariom BalharaandDevin AI 78c411621e feat(embed-core): add public close() API for modal-based embeds (#24746)
* feat(embed-core): add public close() API for modal-based embeds

Add a proper public API method close() to the CalApi class that allows
users to programmatically close modal-based embeds (ModalBox and FloatingButton).

This replaces the need for the undocumented hack:
  cal.instance.actionManager.fire('__closeIframe')

The new API is cleaner and more intuitive:
  cal('close')

Key features:
- Works for modal-based embeds only (ModalBox and FloatingButton)
- Throws a clear error if called on inline embeds
- Well-documented with JSDoc comments explaining usage and limitations

Example usage:
  cal('on', {
    action: 'bookingSuccessful',
    callback: () => {
      cal('close');
    }
  });

Also fixed pre-existing lint issues: unused variable in catch block and
eslint-disable comment for missing rule definition.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor(embed-core): rename close() to closeModal() for clarity

Rename the close() method to closeModal() to make it immediately clear
from the API name itself that this method is for modal-based embeds only.

This makes the API more self-documenting:
- Before: cal('close')
- After: cal('closeModal')

Updated:
- Method name from close() to closeModal()
- JSDoc example to use cal('closeModal')
- Error message to reference closeModal()

The TypeScript types automatically recognize the new action name through
the SingleInstructionMap type system.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* cleanup

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-04 05:48:11 -03:00
Lauris Skraucis a1e1bf8b76 chore: add atoms changeset for tailwind v4 (#25577) 2025-12-04 08:42:58 +00:00
d00cf329e8 fix: workflow reminder send to all RR hosts. (#25597)
* fix: wrkflow reminder issue

* Update EmailWorkflowService.ts

* update

* Refactor team member email extraction for clarity

* add tests

* Undo changes in EmailWorkflowService

* Get team members assigned to the booking

* fix: Update test to match EmailWorkflowService behavior for ROUND_ROBIN

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Update CalendarEventBuilder tests to include host emails in attendees

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Apply suggestion from @cubic-dev-ai[bot]

Filter organizer our of `hostsToInclude`

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Only include organizer and host destination calendar

* Type fix

* Type fix

---------

Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-12-04 09:21:48 +02:00
Udit Takkar 843329ccce feat: distributed tracing - 3 (#25092)
* feat: distributed tracing 2

* feat: distributed tracing 2

* refactor: feedback

* refactor: feedback

* fix: type error

* fix: trpc error

* feat: distributed tracing - 3

* chore: translation

* refactor: improvements

* fix: feedback

* chore: remove
2025-12-04 05:51:26 +00:00
741144bff2 fix: correct busy slot title for ics feed integration troubleshoot (#23929)
* fix: correct busy slot title for ics feed integration troubleshoot

* Prevent 'as' call by wrapping getFirstPropertyValue in string

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-12-04 05:49:34 +00:00
Udit TakkarandMorgan a11f7e6510 feat: add session endpoint and booking access pbac (#24637)
* feat: add session endpoint

* fix: remove participant id

* refactor; feedback

* fix: e2e test

* refactor: add pbac

* refactor: use constant

* tests: add booking tests

* fix: conflicts

* chore: test

* fix: tests

* fix: tests

* chore: remove un necessary

* chore: docs

* fix: desc

* fix: booking-pbac gurd

* fix: booking-pbac gurd

* test: add unit tests

* fix: remove legacy pbac

* fix: chore remove

* fix: update tests

* test: add more test

* test: move it to new file

* chore: comment auth

* chore: add message

* chore: add message

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-12-04 05:45:17 +00:00
Anik Dhabal Babu 3a8bf7014c fix: add all the attendees to ics (#25601) 2025-12-04 05:38:38 +00:00
6f02fbe13b fix: expand Intercom allowed URLs and prevent double-prefixing (#25181)
Co-authored-by: peer@cal.com <peer@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-04 05:36:24 +00:00
af3f44a7f5 feat: add data region dropdown to signup page (#25127)
* feat: add data region dropdown to signup page

Add a dropdown to the signup page that allows users to select their data region (United States or European Union). When a region is selected, the user is navigated to the appropriate domain (app.cal.com or app.cal.eu).

- Add SelectField component to signup page below the description text
- Detect current domain and set appropriate default value
- Navigate to correct domain when selection changes
- Add translation strings for data_region, united_states, and european_union

Co-Authored-By: peer@cal.com <peer@cal.com>

* added localhost

* fix: improve data region dropdown - SSR hydration, query params, and self-hosted protection (#25463)

* fix/remove-eu-us-dropdown-from-self-hosted-signup

* fix: remove localhost bypass and fix SSR hydration for data region dropdown

- Remove localhost bypass from IS_CALCOM check to prevent self-hosted instances from seeing Cal.com-specific dropdown
- Fix SSR hydration mismatch by using WEBAPP_URL instead of window.location for region detection
- Fix hostname replacement to preserve query parameters by modifying hostname directly instead of entire URL string

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2025-12-04 05:34:24 +00:00
Joe Au-YeungandAnik Dhabal Babu 0605572969 fix: Log detailed error in getConnectedCalendar (#25338)
* Log error

* Reverse sent error message changes

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-03 19:51:51 +00:00
AbhishekandAnik Dhabal Babu 5ddfbcf225 fix: date picker content render issue (#25584)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-03 19:46:28 +00:00
Volnei Munhoz 2fc1078158 fix companion oidc url (#25572) 2025-12-03 19:38:41 +00:00
sean-brydon ad416ac9df fix error spam (#25591) 2025-12-03 19:36:05 +00:00
Anik Dhabal Babu 2a7439b58d fix: e2e flake (#25578) 2025-12-03 16:07:27 -03:00
Anik Dhabal Babu 8aaa84142b fix: unable to edit member as a team owner/admin (#25587)
* fix: unaable to edit member as owner/admin

* Clean up comments in EditMemberSheet.test.tsx

Removed comments explaining the fix for permissions prop.

* revert
2025-12-03 18:14:35 +00:00
Udit Takkar 059ca2503d fix: prevent clicking outside (#25588) 2025-12-03 17:57:23 +00:00
Udit Takkar 35d6c41fff feat: Disable booking emails to guests (#25217)
* feat: disable SMS org setting

* chore: undo

* fix: cal evnet

* feat: add more settings

* tests: add email manager unit tests

* fix: update

* fix: type error

* fix: test

* refactor: UI

* refactor: UI

* perf: fetch only once

* perf: fetch only once

* chore: use org

* fix: test

* test: add unit tests

* refactor: email manager

* fix: add confirmation dialog for individual checkbox

* fix: sms

* chore: common.json
2025-12-03 17:21:31 +00:00
Eunjae LeeandDevin AI 1c3ced5b70 fix: simplify date range picker to Airbnb-style selection (#25386)
* feat: simplify date range picker to Airbnb-style selection

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: apply Airbnb-style selection to allowPastDates branch

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: extract date range selection logic and add unit tests

- Extract date range selection logic into pure function (dateRangeLogic.ts)
- Remove unused allowPastDates parameter from selection logic
- Add comprehensive unit tests (11 test cases covering all scenarios)
- Simplify DateRangePicker component (30+ lines -> 5 lines)
- Improve separation of concerns: allowPastDates only controls calendar date restrictions

* style update

* feat: add hover highlighting for date range selection

When a start date is selected and user hovers over other dates,
the potential range between start and hovered date now shows
bg-emphasis background for better visual feedback.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* memoize hovering range and update styles

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-03 14:52:25 +00:00
88ce7868e8 feat: companion expo and chrome (#25022)
* feat: companion expo and chrome

* fix: api-v2-fetch-bookings (#25023)

* migrated to app expo router

* feat(companion): added availability screen and fix event type fetch (#25025)

* fix(companion): add host check in bookings (#25036)

* using liquid glass bottom nav experimental

* added action sheet

* added icons to event type tabs

* added action bar for event-type details

* long press for edit event types

* added limits

* added more limits

* added more limits

* added username to event types

* feat(companion): config to set and show all the available meeting options a user has stalled (#25081)

* feat: Add tailwind support using nativewind. (#25028)

* init nativewind

* replace styles with tailwind classes

* changes

* feat(companion): all locations options, icons, and apply nativewind to remaining files (#25143)

* feat: all locations options and icons and apply nativwind to reamaining files

* icon bug fix

* cal video icon

* other location frontend

* other location api

* address cubics comment about correctly detects SVGs

* feat(companion): edit availability (#25149)

* feat: companion-edit-availability

* date override and use correct config for patch api endpoint

* Android Alert supports a maximum of 3 buttons

* feat: companion-ui-release-1 (#25150)

* feat(companion): Add event type & schedule creation flows with API expansion (#25187)

* feat(companion): event schedule creation and apis

* profile section

* limits, advanced, recurring tab

* Clean Folder Structure

* addressed cubics comments

* fix cubiics comments

* replaced text with cal.com svg logo

* added correct more button for event-types

* added copy link button

* added extension popup

* added chrome extension sidebar

* achieved liquid glass buttons

* nit

* more progress

* fixed ios bug, added icon

* added cal icon to gmail

* nit

* nit

* added dialog for one-off meeting

* added one-time dialog

* feat(companion): gmail plugin (#25327)

* Update Cal.com Companion to version 1.7.0 with enhanced background and content scripts. The background script now handles fetching event types from the Cal.com API and improved error handling. The content script has been updated to manage sidebar visibility and respond to messages more effectively. Removed deprecated dev background script and updated manifest permissions for better functionality.

* chore: update companion .gitignore to exclude build outputs and env files

* feat: insert Cal.com event link directly at cursor position in Gmail compose

- Add insertTextAtCursor function to insert booking link where user is typing
- Automatically positions cursor after inserted link for seamless typing
- Fallback to clipboard copy if compose field not found
- Improved UX: no need to manually paste the link

* feat(companion): improve notification UI and add event types caching

- Update notification to Cal.com brand style (black bg, check icon, smooth fade)
- Change notification text to 'Link inserted' for subtlety
- Move notification to bottom-right position (matching Cal.com toasts)
- Add event types caching (5min duration) to reduce API calls
- Cache automatically refreshes on page reload
- Fix TypeScript error with composeBody.focus() type assertion

* Notification toast  border

* conditional description

* conditional description

* feat(companion): Enhance UI with action buttons, tooltips, and Gmail extension improvements (#25353)

* feat: companion-and-gmail-ui-upgrade

* feat: companion-and-gmail-ui-upgrade

* feat: companion-and-gmail-ui-upgrade

* feat: companion-and-gmail-ui-upgrade

* feat(companion): one-off links (#25355)

* added one off prototype

* resolve merge conflicts

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>

* fixed sidebar iframe

* fix: enable pointer events on sidebar while maintaining click-through on transparent area

- Added pointerEvents: 'auto' to sidebar View component in _layout.tsx
- Changed iframe width from 100% to 400px to match sidebar width
- Changed iframe pointerEvents from 'none' to 'auto' to enable clicking
- This allows sidebar items to be clickable while transparent area remains click-through

* feat(companion): center all modals on full screen in browser extension (#25380)

* fix: companion-full-width-iframe

* center the popups on extension view

* feat(companion): center all modals on full screen in browser extension

- Created FullScreenModal component that expands iframe to full width
- Updated content script to handle instant iframe expansion/collapse
- Converted 17 modals across 6 files to use FullScreenModal
- All modals now appear centered on full browser viewport
- Removed animations for instant modal appearance
- Mobile app behavior remains unchanged

Files updated:
- companion/components/FullScreenModal.tsx (new)
- companion/extension/entrypoints/content.ts
- companion/app/(tabs)/event-types.tsx (5 modals)
- companion/app/(tabs)/bookings.tsx (2 modals)
- companion/app/(tabs)/availability.tsx (3 modals)
- companion/app/booking-detail.tsx (2 modals)
- companion/app/availability-detail.tsx (4 modals)
- companion/components/Header.tsx (1 modal)

* security(companion): validate postMessage origin in content script

Add origin and source validation to postMessage listener to prevent
malicious scripts on host pages from manipulating the companion iframe.

- Verify event.source matches iframe.contentWindow
- Verify event.origin matches iframe origin (localhost:8081)
- Reject all unauthorized messages before processing

This prevents external scripts from:
- Forcing full-screen overlays
- Intercepting pointer events
- Manipulating the companion UI

* fix(companion): center 'Add new event type' modal on full screen

Replace KeyboardAvoidingView with TouchableOpacity pattern in the
create event type modal to ensure it appears centered on the full
screen like all other modals.

This was the last remaining modal that wasn't properly centered.

* fix(companion): resolve modal transition timing issue

Fixed the 'Add new event type' modal not centering properly by:

- Added 100ms delay when transitioning between modals
- Prevents conflicting expand/collapse messages
- Removed redundant postMessage calls from modal handlers
- Added max-height constraint to modal content
- Cleaned up debug console logs

The issue was that when clicking 'New Event Type' from the 'New' menu,
both modals were transitioning simultaneously, causing the create modal
to collapse immediately. The delay ensures proper sequencing.

All 17 modals now work correctly and appear centered on full screen.

* added working date range

* removed all of one-off event code

* nit

* feat(companion): Suggest `Cal.com` links and Embed using Gemini Ai in Gmail (#25406)

Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* add companion build on CI

* feat: oauth companion (#25526)

* first implemenation of oauth

* fix logout for web

* revert app name

* remove isUsingOAuth

* clean up log out button

* remove logs

* clean up authcontext

* simplify code generation

* code clean up

* clean up oauthService.ts

* oauth browser extension

* add redirect uri to .env.example

* remove api key support

* clean up _layout file

* add identity

* fix + clean up

* improvements to oauth flow

* code clean up

* remove comments

* clean up comments

* add log out dialog

* add confirm modal

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Abhijeet Singh <asingh9829@gmail.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-12-03 08:46:04 -03:00
ba3838ec0f chore: docs for BookerEmbed atom (#25541)
* chore: docs for BookerEmbed atom

* chore: PR feedback

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Update docs/platform/atoms/booker-embed.mdx

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2025-12-03 11:39:09 +00:00
sean-brydon f87d4de546 fix: UI nits in QA verison of onboarding v3 (#25532)
* fix create button

* fix subdomain prefix in orgs details view

* remove redundant text

* fix prefix on link fields

* brand mode colours

* Fix banner positioning

* remove app descrtipion plus add mr to account for button

* fix gaps

* improve free plan welcome modal
2025-12-03 09:57:01 +00:00
Alex van Andel fd6c6e6419 chore: release v5.9.8
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-03 09:25:02 +00:00
Alex van AndelandDevin AI 63d1361a7a fix: simplify credentials provider authorization flow (#25563)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-03 09:21:20 +00:00
Udit Takkar cbcd769f88 docs: add automatic no show updated docs (#25507) 2025-12-03 06:35:54 +00:00
Anik Dhabal Babu a2185d9ee0 fix: sms and whatsapp reminder issue with seated event (#25294)
* fix: sms reminder issue with seated event

* fix seated event and workflow issue

* fix whatsapp reminder

* Refactor imports in reminderScheduler.ts

* use repository
2025-12-03 04:12:38 +00:00
Anik Dhabal Babu 7a66add217 Prevent navigation for disabled booking actions (#25543) 2025-12-03 04:10:31 +00:00
Morgan 68b93385eb refactor: platform billing controller auth guards (#25559)
* refactor: platform billing controller auth guards

* fixup! refactor: platform billing controller auth guards
2025-12-02 20:38:29 +00:00
Alex van Andel e2aa6361d5 fix: config is statically analyzed, failing on build (#25558) 2025-12-02 18:38:29 +00:00
d15281160f fix: preserve seatsPerTimeSlot during partial event type updates (#25450)
* fix: preserve seatsPerTimeSlot during partial event type updates

When doing a partial update on the PATCH /v2/organizations/{orgId}/teams/{teamId}/event-types/{eventTypeId} endpoint, providing a partial body would reset seatsPerTimeSlot back to null because the transformSeatsApiToInternal function was always called even when seats was undefined.

This fix ensures that the seat options are only transformed when the seats field is explicitly provided in the update request, preserving existing values during partial updates.

Also adds e2e test to verify partial updates preserve seatsPerTimeSlot.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: handle TypeScript union type narrowing for seatsPerTimeSlot

When seats is not provided in a partial update, the transformed body
may not have seatsPerTimeSlot property. This fix uses 'in' operator
to safely check for the property before accessing it.

Also fixes the e2e test to properly narrow the union type for seats
using type guards.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: simplify seatsPerTimeSlot handling per review feedback

Per supalarry's suggestion, instead of using 'in' operator checks in
multiple validation calls, we now return {seatsPerTimeSlot: undefined}
when seats is not provided. This keeps the validation code unchanged
and only requires modifying one line in the transformation.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-02 18:38:01 +00:00
Volnei Munhoz 8b6c6273ee Fix api v1 block paths (#25554) 2025-12-02 16:53:17 +00:00
Rajiv Sahal 957d19740e feat: CalendarView atom v2 (#24896)
* refactor: make individual component for generic and event type specific calendar views

* fixup

* update examples app

* fix: show busy times from calendars in week view

* fix: use calendar busy times not working

* chore: add changesets

* fixup

* chore: implement PR feedback

* fix: merge conflicts

* chore: implement PR feedback

* fixup

* chore: implement PR feedback
2025-12-02 21:44:30 +05:30
Hariom Balhara 150e93dc6e fix: Add /router to isBookingPages to prevent 500 error on customPageMessage redirect (#25522)
* Add /router to isBookingPages

* Remove Dynamic Posthog Provider from AppProvider.tsx because that is only used by the pages router, and the pages router is only in use by the /router endpoint, which is a booking page and we havent implemented corresponding GeoProvider support for it
2025-12-02 13:51:04 +00:00
Anik Dhabal Babu 94c7bfea4d fix: display message in the response (#25102) 2025-12-02 13:46:59 +00:00
Kartik Labhshetwar dbef7644d4 fix: improve availability working hours layout spacing and editable heading icon gap (#25525)
* fix: improve availability working hours layout spacing and editable heading icon gap

* refactor: wrap DateOverride in styled container in AvailabilitySettings
2025-12-02 13:20:14 +00:00
abhix4 a843a38e67 fix: styling override at availability settings (#25521) 2025-12-02 12:41:49 +00:00
Udit Takkar 73ffd9c7b5 chore: update next (#25485) 2025-12-02 12:05:42 +00:00
2c8ff89fac perf: Calendar Cache Improvements (#25502)
* wip

* Filter only selectedCalendars where ff is enabled

* test: fix and add tests for calendar subscription cache feature

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* test: fix SelectedCalendarRepository tests for new teamIds parameter

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-02 08:11:52 -03:00
Benny JooandDevin AI 3bf2a8fa6c refactor: replace TRPCError with ErrorWithCode in packages/features (#25482)
* refactor: replace TRPCError with ErrorWithCode in packages/features

This refactor moves error handling from throwing TRPCError directly in
packages/features to throwing ErrorWithCode instead. The conversion to
TRPCError now happens at the TRPC layer.

Changes:
- Add generic ErrorCode values (Unauthorized, Forbidden, NotFound,
  BadRequest, InternalServerError) to errorCodes.ts
- Update getServerErrorFromUnknown to map new ErrorCodes to proper
  HTTP status codes
- Create toTRPCError helper in packages/trpc/server/lib
- Create errorMappingMiddleware in packages/trpc/server/middlewares
- Migrate TRPCError throws in packages/features to ErrorWithCode:
  - teamService.ts
  - getEventTypeById.ts
  - eventTypeRepository.ts
  - OrganizationPermissionService.ts
  - OrganizationPaymentService.ts
  - sso.ts
  - handleCreatePhoneCall.ts
  - userCanCreateTeamGroupMapping.ts

This improves separation of concerns by making packages/features
transport-agnostic, allowing the same feature code to be reused from
tRPC, API routes, workers, etc.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: remove isTrpcCall parameter and fix lint warning

- Remove isTrpcCall parameter from get.handler.ts call since the
  feature layer no longer needs to know about tRPC
- Fix unsafe optional chaining lint warning in getEventTypesByViewer.ts
  by precomputing usersSource variable
- Complete migration of getEventTypesByViewer.ts to ErrorWithCode

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* revert

* add eslint rule

* add comment

* fix: add isTrpcCall back to getEventTypeById interface

The user reverted the removal of isTrpcCall parameter from the handler,
so we need to add it back to the interface to fix the type error.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* test: update teamService tests to expect ErrorWithCode instead of TRPCError

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor

* wip

* feat: integrate errorMappingMiddleware into base TRPC procedure

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* connect middlewares

* revert

* revert

* refactor

* rename

* fix: handle ErrorWithCode in teams server-page error handling

The error handling was checking for TRPCError, but teamService now throws
ErrorWithCode. This caused the 'This invitation is not for your account'
error message to not be displayed when a wrong user tries to use an
invitation link.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* fix

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-02 08:11:17 -03:00
Hariom Balhara 16a4c75e1e Update yarn.lock (#25524) 2025-12-02 09:58:57 +00:00
sean-brydon f9db1d6111 fix: getTeamIdsWithPermission (#25387) 2025-12-02 06:11:56 -03:00
Anik Dhabal Babu 1d9aee7154 fix: Use booker locale for email verification email (#25420) 2025-12-02 08:25:39 +00:00
abhix4andDhairyashil Shinde 56e3a314a8 fix(ui): add missing checked state styling for event type checkbox (#25478)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-02 06:47:30 +00:00
Alex van Andel 8167fe0d05 chore: release v5.9.7
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-12-02 04:22:35 +00:00
KartikandPallav c23c2d128a fix: allow false for custom field 'fieldRequired' by using z.boolean() (#25322)
* fix: allow false for custom field 'fieldRequired' by using z.boolean()

* updated to z.boolean().optional()

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-12-02 02:46:29 +00:00
65893ae943 fix: [object object] problem (#24643)
* fix: object problem

* revert and improve logic

* revert

* fix

* Update apps/web/modules/bookings/views/bookings-single-view.tsx

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-12-02 02:32:51 +00:00
f33edb2b99 feat: Generate email workflow payload at time of sending (#25446)
* wip

* wip

* feature: Booking Tasker without DI yet

* feature: Booking Tasker with DI

* fix type check 1

* fix type check 2

* fix

* comment booking tasker for now

* fix: DI regularBookingService api v2

* fix: convert trigger.dev SDK imports to dynamic imports to fix unit tests

The unit tests were failing because BookingEmailAndSmsTriggerTasker.ts had static imports of trigger files that depend on @trigger.dev/sdk. This caused Vitest to try to resolve the SDK at module load time, even though it should be optional.

Changed all imports in BookingEmailAndSmsTriggerTasker.ts from static to dynamic (using await import()) so the trigger files are only loaded when the tasker methods are actually called, not at module load time during tests.

This fixes the 'Failed to load url @trigger.dev/sdk' errors that were causing 28+ test failures.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix unit tests

* keep inline smsAndEmailHandler.send calls

* chore: add team feature flag

* add satisfies ModuleLoader

* fix type check app flags

* move trigger in feature

* fix: add trigger.dev prisma  generator

* fix: email app statuses

* fix: CalEvtBuilder unit test

* chore: improvements, schema, config, retry

* fixup! chore: improvements, schema, config, retry

* chore: cleanup code

* chore: cleanup code

* chore: clean code and give full payload

* remove log

* add booking notifications queue

* add attendee phone number for sms

* bump trigger to 4.1.0

* add missing booking seat data in attendee

* update config

* fix logger regular booking service

* fix: prisma as external deps of trigger

* fix yarn.lock

* revert change to example app booking page

* fix: resolve circular dependencies and improve cold start performance in trigger tasks

- Convert BookingRepository import to type-only in CalendarEventBuilder.ts to eliminate circular dependency risk
- Convert EventNameObjectType, CalendarEvent, and JsonObject imports to type-only in BookingEmailAndSmsTaskService.ts
- Use dynamic imports in all trigger notification tasks (confirm, request, reschedule, rr-reschedule) to reduce cold start time
- Move heavy imports (BookingEmailSmsHandler, BookingRepository, prisma, TriggerDevLogger, BookingEmailAndSmsTaskService) inside run functions
- Eliminates module-level prisma import which violates repo guidelines and adds cold start overhead
- Reduces initial module dependency graph by deferring heavy imports (email templates, workflows, large repositories) until task execution

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: improve cold start performance in reminderScheduler with dynamic imports

- Remove module-level prisma import (violates 'No prisma outside repositories' guideline)
- Use dynamic imports for UserRepository (1,168 lines) - only loaded when needed in EMAIL_ATTENDEE action
- Use dynamic imports for twilio provider (386 lines) - only loaded in cancelScheduledMessagesAndScheduleEmails
- Use dynamic imports for all manager functions by action type:
  - scheduleSMSReminder (387 lines) - loaded only for SMS actions
  - scheduleEmailReminder (459 lines) - loaded only for Email actions
  - scheduleWhatsappReminder (266 lines) - loaded only for WhatsApp actions
  - scheduleAIPhoneCall (478 lines) - loaded only for AI phone call actions
- Use dynamic imports for sendOrScheduleWorkflowEmails in cancelScheduledMessagesAndScheduleEmails
- Significantly reduces cold start time by deferring heavy module loading until execution paths need them
- Eliminates module-level prisma import that violated repository pattern guidelines

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: improve cold start performance in BookingEmailSmsHandler with dynamic imports

- Remove module-level imports of all email-manager functions (653 LOC + 30+ email templates)
- Add dynamic imports in each method (_handleRescheduled, _handleRoundRobinRescheduled, _handleConfirmed, _handleRequested, handleAddGuests)
- Defer heavy email-manager loading until method execution
- Verified no circular dependencies between email-manager and bookings
- Significantly reduces cold start time for RegularBookingService and BookingEmailAndSmsTaskService

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use dynamic imports

* update yarn lock

* code review

* trigger config project ref in env

* update yarn lock

* add .env.example trigger variables

* add .env.example trigger variables

* fix: cleanup error handling and loggin

* fix: trigger config from env

* fix: small typo fix

* fix: ai review comments

* fix: ai review comments

* ai review

* Add `create` on `WorkflowReminderRepository`

* `sendWorkflowEmails` tasker to accept lazy payload

* Add `scheduleLazyEmailWorkflow` to `WorkflowService

* Process scheduled date in `scheduleLazyEmailWorkflow`

* Type fixes

* Use `WorkflowService` to schedule

* Refactor `scheduleEmailReminderForEvt` to use
`WorkflowService.processWorkflowScheduledDate`

* Pass seat reference to lazy scheduled workflow reminder

* Refactor `WorkflowReminderRepository` to accept prisma as constructor

* Abstract `FormSubmissionData` type

* Abstract select statement and add get by uid to `BookingRepository`

* Add `FormSubmissionData` type

* Add `findByIdIncludeStepAndWorkflow` to `WorkflowReminderRepository`

* Tasker payload to accept `workflowReminderId`

* Create `BookingSeatRepository`

* Write `workflowReminderId` to tasker payload

* Add `generateCommonScheduleFunctionParams` to `WorkflowService`

* Init

* Use services in tasker

* Abstract types

* In reminderScheduler use workflowService to generate common params

* Type fix

* Return params from emailWorkflowService.generateParametersToBuildEmailWorkflowContent

* Use emailWorkflowService to generate params

* Abstract types

* Generate email content and send in EmailWorkflowService

* Move check to caller

* Use EmailWorkflowService to generate email payload in
emailReminderManager

* Fix initalizing repository

* Use evt.videoCallData first before the booking metadata

* Only get non-deleted references to build calendar event

* Remove check for videoCallData.id

* Dynamic import credit service

* BookingRepository.getByUid to only return what we need from attendee

* Type fixes

* test: Add comprehensive tests for lazy email workflow generation and fix broken tests

- Fix prisma mocks in sms-manager.test.ts and outOfOfficeCreateOrUpdate.handler.test.ts
  to export both 'default' and named 'prisma' exports
- Add EmailWorkflowService.test.ts with 4 tests for error handling paths
- Add sendWorkflowEmails.test.ts with 7 tests for schema validation and email sending
- Add tests to WorkflowService.test.ts for scheduleLazyEmailWorkflow,
  processWorkflowScheduledDate, and generateCommonScheduleFunctionParams methods

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Write `seatReferenceUid`

* Return promise

* Fix log

* Change to `Promise.allSettled`

* Type fix

* Fix failing test

* fix: reorder workflow step checks to fix test failure

The test 'should throw error if workflow step not found on reminder' was failing because the code checked workflowStep.verifiedAt before checking if workflowStep exists. When workflowStep is null, this caused the error message to include 'undefined' instead of the expected workflow step id.

Fixed by reordering the checks:
1. First check if workflowStep exists
2. Then check if workflowStep.verifiedAt exists

Also updated the test expectation to match the correct error message.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: hbjORbj <sldisek783@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-12-02 02:25:07 +00:00
5d8c4ad13d fix: Allow i18n of form builder max/min character count. Earlier strings missed due to variable. (#22367)
* added german translation

* fixed count issue

* fixed count issue

* resolved type safety errors

* fix

* Update getBookingResponsesSchema.ts

* fixes

* removed 1 character case

* fixes

* fix

* chore

* fix

* type-check

* type-fix

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-12-02 02:24:54 +00:00
f359d37799 feat(apps): add databuddy analytics (#24689)
* feat(apps): add databuddy analytics

* Update packages/app-store/databuddy/DESCRIPTION.md

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-12-02 02:18:25 +00:00
Anik Dhabal Babu b98bb8b852 chore: profile repository refactor (#25328)
* chore: profile repository refactor

* remove comment

* remove comment

* cleaning

* review addressed

* rename the method name
2025-12-01 22:47:37 -03:00
abhix4 7ca2082c62 fix: availability cta hover state (#25504) 2025-12-01 23:50:35 +00:00
Anshumancanrock c11865fba9 fix: ProgressBar styling is hardcoded in dark mode (#25516) 2025-12-01 23:18:53 +00:00
Tamal ChakrabortyandPallav a3c0d06c13 fix: encode JWT in 2FA redirect URL to prevent invalid header error (#25331)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-12-01 17:53:39 +00:00
cd74f292ee fix: keyPress behaviour for Add Variable dropdown (#23405)
* Fixed variable dropdown

* Radix fix

* addressed coderabits comments

* Adjust styles and structure in AddVariablesDropdown

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-01 17:34:52 +00:00
Alex van AndelandAnik Dhabal Babu 2c52e31c76 chore: Pin lingo.dev version to 0.117.6 (#25475)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-01 16:59:16 +00:00
Eunjae LeeandDevin AI 6479adf14e fix: integer to text comparison in routing insights query (#25019)
* fix: integer to text comparison in routing insights query

Add explicit integer array cast to prevent PostgreSQL type mismatch error when comparing bookingUserId (integer) with user_id array values in getRoutedToPerPeriodData query

* add e2e tests

* refactor: remove LoadingInsight component and handle loading in ChartCard

- Enhanced ChartCard to render default loading UI when isPending is true
- Replaced all LoadingInsight usages with ChartCard that accepts isPending/isError props
- Removed LoadingInsight component and updated exports
- Updated 16 chart components to use the new pattern
- ChartCard now shows spinner and skeleton title during loading state

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: make children prop optional in ChartCard when isPending is true

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove unused loadingState prop from ChartCard

- Remove loadingState prop and ChartLoadingState type export
- Simplify computedLoadingState to derive state only from isPending/isError
- No functional changes - loadingState was not being used by any components
- data-loading-state attribute behavior remains unchanged for E2E tests

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove duplicate isPending early returns from chart components

- Update all 16 chart components to use single ChartCard return pattern
- Gate children rendering with !isPending && isSuccess && data checks
- Prevents data processing code from executing during loading state
- Improves code consistency and maintainability across all charts

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove redundant !isPending check from chart conditionals

- Simplify conditional rendering to use just 'isSuccess && data' or 'isSuccess'
- In TanStack Query, isSuccess and isPending are mutually exclusive
- The !isPending check was redundant since isSuccess already implies !isPending
- Applied to all 16 chart components for consistency
- Components with safe defaults (data ?? []) use just 'isSuccess'
- Components requiring data check use 'isSuccess && data'

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* revert the mistake

* apply feedback

* apply feedback

* fix e2e

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-01 15:07:57 +01:00
Rajiv Sahal 3c46c35b69 init: doc to setup platform billing locally via stripe (#25490) 2025-12-01 13:36:25 +00:00
Eunjae LeeandDevin AI 41ad0f718d refactor: use Button component instead of plain button in CopyButton (#25489)
* refactor: use Button component instead of plain button in CopyButton

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* add shrink-0 to StartIcon and EndIcon of Button

* remove unused class names

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-01 13:13:01 +00:00
Syed Ali Shahbaz 0103321b71 feat: managed event reassignment (#24809)
* init

* --

* update dialog

* reassignment

* further changes

* add unit test

* fix

* type fix??

* fix type??

* emails

* workflows

* reason recorder

* refactor reassigned email

* fix reassigned reason

* fix type

* improve dialog

* add integration tests

* -

* remove unnecessary comments --1

* removed unnecessary comments

* fix type?

* address cubic

* address feedback

* --

* fix type?

* address cubic

* type-fix?

* fix type

* further fixes

* fix location update

* type fix

* propagate error to top

* fix mocking

* fix reported bugs

* fix

* fix success page video URL

* remove PII from logs

* persist video URL

* better audit trail

* revert email function name change

* fix test

* fix flake

* di

* fixes

* extract logic and other repo access from BookingRepository

* fixes

* (☞゚∀゚)☞ udit

* integration test fixes

* mroe fixes

* extract to repo

* extract to repo --2

* fix type

* cubic

* address feedback --1

* --2

* wip

* addressed feedback

* type fixes

* type fixes

* fix issues

* feedback --1

* feedback --2

* BookingAccessService DI

* fix

* break down function into small functions

* fixes --1

* fixes

* typefix

* addressing feedback

* fix merge conflict lost change
2025-12-01 14:04:24 +04:00
Anik Dhabal Babu 38890dad30 fix: org admin/owner can access routng form (#25412) 2025-12-01 09:46:50 +00:00
spandevandAnik Dhabal Babu 0776657faf fix: made playground page use same layout as other pages (#25216)
* fix: made playground page use same layout as other pages

* update: added feature key

* Change link display from table to list format

Refactor page layout to use a list instead of a table for links.

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-12-01 09:33:46 +00:00
Dhairyashil ShindeandKeith Williams 3cf7266048 refactor: hide duplicate translations warning (#25472)
* refactor: hide duplicate translations warning

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-01 09:28:30 +00:00
Eunjae Lee 86b9aa5f23 fix: exclude AWAITING_HOST from seed-insights random status selection (#25414)
## What does this PR do?

Fixes a bug in the seed-insights script where `AWAITING_HOST` status was randomly assigned to bookings along with a `userId`, which violates the correct behavior of instant meetings.

**Problem:**
- The seed script randomly picked from all 5 booking statuses (including `AWAITING_HOST`)
- When `AWAITING_HOST` was selected, the script still assigned a `userId`
- Real instant meetings with `AWAITING_HOST` status should have `userId = NULL` until a host joins
- This created incorrect test data that doesn't match production behavior

**Solution:**
- Filter out `AWAITING_HOST` from `BookingStatus` values using `Object.values(BookingStatus).filter()`
- This approach is more maintainable than listing valid statuses explicitly - if new statuses are added in the future, they will automatically be included
- Moved `validStatusesForSeed` to module level so it's calculated once at load time instead of on every shuffle call
- Added comments explaining why this status requires special handling

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - seed script only.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. N/A - this is a seed script for test data generation.

## How should this be tested?

1. Run the seed script: `yarn seed-insights`
2. Verify no `AWAITING_HOST` bookings are created with a `userId`:
```sql
SELECT COUNT(*) FROM "Booking" 
WHERE status = 'awaiting_host' AND "userId" IS NOT NULL 
AND "createdAt" > NOW() - INTERVAL '1 day';
-- Should return 0 for newly seeded data
```
3. Verify other statuses are still generated:
```sql
SELECT status, COUNT(*) FROM "Booking" 
WHERE "createdAt" > NOW() - INTERVAL '1 day' 
GROUP BY status;
-- Should show ACCEPTED, PENDING, CANCELLED, REJECTED (but not AWAITING_HOST)
```

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings

---

> **Link to Devin run:** https://app.devin.ai/sessions/08f634e7210d415982d71c8f687b4468
> **Requested by:** eunjae@cal.com (@eunjae-lee)
2025-12-01 09:24:22 +00:00
Dhairyashil Shinde b94f107493 fix: dark-mode-multi-location-toggle-booking-page (#25469) 2025-12-01 09:21:40 +00:00
Benny Joo 4a451b411c chore: make app-store eslint config more strict to prevent circular deps (#25483) 2025-12-01 09:14:05 +00:00
sean-brydon b64cfc9e66 feat: remove min seat usage from org creation (#25448)
* remove min seat usage

* update constants and also turbo json

* Remove comments

* remove redundant tests as no min exists
2025-12-01 07:55:44 +00:00
KartikandPallav ce279da7c4 fix: stabilize date range calculation in column view (#25384)
* fix: stabilize date range calculation in column view

* fix: restore eslint-disable for scrollIntoViewSmooth

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-11-30 03:36:13 +05:30
Anshumancanrockandsean-brydon 7dbc888848 fix: End Impersonation Without Logging Out Admin (#25395)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-11-29 21:38:31 +00:00
Rajiv Sahal 8fcbf2c167 fix: Connect atoms not working inside iframe (#25418)
* fix: google connect broken for iframe
* chore: add changesets
* chore: update atoms exports
* chore: update atoms exports
2025-11-28 11:44:20 -03:00
a050ccb4ee feat: Booking EmailAndSms Notifications Tasker (#24944)
* wip

* wip

* feature: Booking Tasker without DI yet

* feature: Booking Tasker with DI

* fix type check 1

* fix type check 2

* fix

* comment booking tasker for now

* fix: DI regularBookingService api v2

* fix: convert trigger.dev SDK imports to dynamic imports to fix unit tests

The unit tests were failing because BookingEmailAndSmsTriggerTasker.ts had static imports of trigger files that depend on @trigger.dev/sdk. This caused Vitest to try to resolve the SDK at module load time, even though it should be optional.

Changed all imports in BookingEmailAndSmsTriggerTasker.ts from static to dynamic (using await import()) so the trigger files are only loaded when the tasker methods are actually called, not at module load time during tests.

This fixes the 'Failed to load url @trigger.dev/sdk' errors that were causing 28+ test failures.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix unit tests

* keep inline smsAndEmailHandler.send calls

* chore: add team feature flag

* add satisfies ModuleLoader

* fix type check app flags

* move trigger in feature

* fix: add trigger.dev prisma  generator

* fix: email app statuses

* fix: CalEvtBuilder unit test

* chore: improvements, schema, config, retry

* fixup! chore: improvements, schema, config, retry

* chore: cleanup code

* chore: cleanup code

* chore: clean code and give full payload

* remove log

* add booking notifications queue

* add attendee phone number for sms

* bump trigger to 4.1.0

* add missing booking seat data in attendee

* update config

* fix logger regular booking service

* fix: prisma as external deps of trigger

* fix yarn.lock

* revert change to example app booking page

* fix: resolve circular dependencies and improve cold start performance in trigger tasks

- Convert BookingRepository import to type-only in CalendarEventBuilder.ts to eliminate circular dependency risk
- Convert EventNameObjectType, CalendarEvent, and JsonObject imports to type-only in BookingEmailAndSmsTaskService.ts
- Use dynamic imports in all trigger notification tasks (confirm, request, reschedule, rr-reschedule) to reduce cold start time
- Move heavy imports (BookingEmailSmsHandler, BookingRepository, prisma, TriggerDevLogger, BookingEmailAndSmsTaskService) inside run functions
- Eliminates module-level prisma import which violates repo guidelines and adds cold start overhead
- Reduces initial module dependency graph by deferring heavy imports (email templates, workflows, large repositories) until task execution

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: improve cold start performance in reminderScheduler with dynamic imports

- Remove module-level prisma import (violates 'No prisma outside repositories' guideline)
- Use dynamic imports for UserRepository (1,168 lines) - only loaded when needed in EMAIL_ATTENDEE action
- Use dynamic imports for twilio provider (386 lines) - only loaded in cancelScheduledMessagesAndScheduleEmails
- Use dynamic imports for all manager functions by action type:
  - scheduleSMSReminder (387 lines) - loaded only for SMS actions
  - scheduleEmailReminder (459 lines) - loaded only for Email actions
  - scheduleWhatsappReminder (266 lines) - loaded only for WhatsApp actions
  - scheduleAIPhoneCall (478 lines) - loaded only for AI phone call actions
- Use dynamic imports for sendOrScheduleWorkflowEmails in cancelScheduledMessagesAndScheduleEmails
- Significantly reduces cold start time by deferring heavy module loading until execution paths need them
- Eliminates module-level prisma import that violated repository pattern guidelines

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: improve cold start performance in BookingEmailSmsHandler with dynamic imports

- Remove module-level imports of all email-manager functions (653 LOC + 30+ email templates)
- Add dynamic imports in each method (_handleRescheduled, _handleRoundRobinRescheduled, _handleConfirmed, _handleRequested, handleAddGuests)
- Defer heavy email-manager loading until method execution
- Verified no circular dependencies between email-manager and bookings
- Significantly reduces cold start time for RegularBookingService and BookingEmailAndSmsTaskService

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: use dynamic imports

* update yarn lock

* code review

* trigger config project ref in env

* update yarn lock

* add .env.example trigger variables

* add .env.example trigger variables

* fix: cleanup error handling and loggin

* fix: trigger config from env

* fix: small typo fix

* fix: ai review comments

* fix: ai review comments

* ai review

* prettier

---------

Co-authored-by: hbjORbj <sldisek783@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-28 14:00:04 +00:00
Pallav 2522638414 fixed description for disable rescheduling and cancelling (#25447) 2025-11-28 13:13:40 +00:00
Pasquale Vitiello 0ddb456a91 fix: video page dialog bg in light mode (#25455) 2025-11-28 12:57:33 +00:00
9048d053ac feat: posthog version upgrade and added trackings (#24401)
* posthog version upgrade and calai banner tracking

* disable posthog for EU

* bunch more posthog tracking

* Revert yarn.lock changes

* add posthog package yarn changes

* fix: add missing posthog import and fix lint warning in MemberInvitationModal

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: type check

* cubic fixes

* refactor

* remove ui playground

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-28 12:43:37 +00:00
Hariom Balhara cbc8d3d7a8 Add DI for BookingAudit (#25123) 2025-11-28 09:14:48 +00:00
e6ba89961c refactor: consolidate error handlers to use getServerErrorFromUnknown (#25114)
* refactor: consolidate error handlers to use getServerErrorFromUnknown

- Migrate server-only code to use getServerErrorFromUnknown for better error handling
- Add JSDoc documentation to both getErrorFromUnknown and getServerErrorFromUnknown
- Update webhook handlers, payment services, email service, and booking service
- Keep getErrorFromUnknown for client-side and isomorphic code
- Improve error message extraction by using err.cause?.stack instead of err.stack
- Fix ESLint warnings: replace 'any' with 'unknown' types, fix hasOwnProperty usage

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* Update packages/app-store/paypal/api/webhook.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-11-28 09:14:06 +01:00
Dhairyashil Shinde 724204843a fix: Add PBAC permission checks for insights access (#25381)
* fix: Add PBAC permission checks for insights access

- Add checkInsightsPermission() helper that properly checks insights.read permission with PBAC support
- Update userBelongsToTeamProcedure to use PBAC-aware permission check for org-level access
- Update teamListForUser query to filter teams based on insights.read permission instead of only checking base ADMIN/OWNER roles
- Maintain backward compatibility with fallback to traditional role checks (ADMIN/OWNER) when PBAC is disabled
- Org admins (base role ADMIN/OWNER) continue to have automatic insights access as a privileged position
- Team-level admins with custom roles now properly checked for insights.read permission

Fixes issue where users with custom PBAC roles couldn't access insights even if they had insights.read permission.

Related: CAL-XXXX

* perf: Optimize team permission checks to avoid N+1 queries

Replace individual permission checks per team with bulk query using getTeamIdsWithPermission().
This reduces database queries from N (one per team) to a single optimized query.

- Use PermissionCheckService.getTeamIdsWithPermission() for bulk permission checking
- Filter teams based on returned team IDs instead of individual checks
- Maintains same functionality with significantly better performance for users with many teams

* perf: Fetch only teams with insights access instead of filtering after

Move permission check before team query to filter at database level.
Previously fetched all teams then filtered in JavaScript.
Now only fetches teams the user has insights access to.

- Check permissions first using getTeamIdsWithPermission()
- Add teamId filter to membership query (teamId: { in: teamIdsWithAccess })
- Remove JavaScript filter step (done at DB level)
- Reduces data transfer and improves query efficiency
2025-11-28 02:26:04 +05:30
Udit Takkar f136b7145f chore: update transcript endpoint description (#25385)
* chore: update transcript endpoint description

* chore: update transcript endpoint description
2025-11-27 20:17:40 +00:00
Udit Takkar 179ace23e1 fix: sign upsert error (#25437) 2025-11-27 12:33:29 -05:00
Anik Dhabal Babu 3af6fee05d fix: eventypes description overflow issue (#25436)
* fix: add overflow-y-auto to prevent description text from spilling over

* Rename setter for seatedEventData in EventMeta
2025-11-27 16:29:08 +00:00
Udit Takkar 0f84cedad2 fix: signup username collision (#25435)
* fix: signup username collision

* tests: add unit tests
2025-11-27 15:41:38 +00:00
Pasquale Vitiello a23400777a fix: prevent buttons from looking active when interacting with parent divs (#25431) 2025-11-27 14:18:35 +00:00
Dhairyashil Shinde 33c3bf3558 fix: allow-reschedule-on-prevent-impersonation (#25427)
* fix: allow-reschedule-on-prevent-impersonation

* remove selfexplanatory comment
2025-11-27 11:39:40 +00:00
emrysal 2701b4de79 chore: release v5.9.6
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-27 11:05:14 +00:00
Pasquale Vitiello a9f83ac5e2 fix: minor styling issues (#25421)
* style: remove unwanted bg

* fix: adjust FAB positioning

* style: skeleton improvements

* fix: reset password button

* fix: remove left border from remove icon

* style: improve fields

* style: wrap base form styles into layer base

* style: remove email-specific focus styles from TextField component
2025-11-27 11:00:44 +00:00
sean-brydonandcubic-dev-ai[bot] ff1533d344 chore: UI Nits onboarding v3 (#25409)
* Fix UI nits

* fix bio + team name on invite orgs

* use bg-cal-muted

* Fix error from mass edit

* Update apps/web/public/static/locales/en/common.json

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix org labels

* Fix i18n

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-11-27 08:18:43 +00:00
Benny JooandDevin AI d9cddd85ff fix: break circular dependency by passing creditCheckFn in messageDispatcher (#25343)
* fix: break circular dependency in messageDispatcher via dependency injection

Break the 4-file circular dependency chain:
credit-service → reminderScheduler → smsReminderManager → messageDispatcher → credit-service

Solution:
- Add optional creditCheckFn parameter to messageDispatcher functions
- Thread creditCheckFn through the call chain: scheduleWorkflowReminders → scheduleSMSReminder/scheduleWhatsappReminder → messageDispatcher
- When creditCheckFn is provided, use it; otherwise fall back to dynamic CreditService import for backward compatibility
- This breaks the workflows → billing import while preserving immediate fallback behavior

Changes:
- messageDispatcher: Accept optional creditCheckFn parameter, use it if provided
- smsReminderManager: Thread creditCheckFn through scheduleSMSReminder
- whatsappReminderManager: Thread creditCheckFn through scheduleWhatsappReminder
- reminderScheduler: Add creditCheckFn to ScheduleWorkflowRemindersArgs and pass through processWorkflowStep

All type checks, lint checks, and unit tests pass.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* feat: wire creditCheckFn from all callers to complete circular dependency fix

- Add creditCheckFn parameter to WorkflowService.scheduleFormWorkflows
- Wire creditCheckFn from all 10 entry points that call workflow scheduling:
  * formSubmissionUtils.ts (form submissions)
  * roundRobinManualReassignment.ts (round-robin reassignment)
  * triggerFormSubmittedNoEventWorkflow.ts (form workflow trigger)
  * handleBookingRequested.ts (booking requests)
  * RegularBookingService.ts (2 calls - payment initiated & new bookings)
  * handleSeats.ts (seated bookings)
  * handleConfirmation.ts (2 calls - confirmation & payment)
  * handleMarkNoShow.ts (no-show updates)
  * confirm.handler.ts (booking rejection)
- Update test expectations to use expect.objectContaining()
- Fix pre-existing lint warning in handleMarkNoShow.ts (any type)
- This completes the messageDispatcher circular dependency fix by ensuring
  creditCheckFn is actually passed through the call chain, breaking the
  4-file circular dependency at runtime

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use generic type with type guard in logFailedResults to fix type check error

- Replace constrained type with generic type parameter
- Add proper type guard for rejected promises
- Fixes CI type check failure in handleMarkNoShow.ts:385
- Avoids 'any' type while accepting any fulfilled value shape

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* wip

* wip

* wip

* revert

* revert

* feat: wire creditCheckFn from all remaining callers to eliminate fallbacks

- Wire creditCheckFn in packages/sms/sms-manager.ts (can safely import CreditService)
- Create makeHandler factory pattern for CRON endpoints (scheduleSMSReminders.ts, scheduleWhatsappReminders.ts)
- Wire creditCheckFn from apps/web CRON routes to factories
- Add warning log in messageDispatcher when fallback is used
- Complete creditCheckFn wiring from all direct callers (activateEventType.handler.ts, util.ts)

This eliminates all fallbacks to dynamic import except as a safety net for unforeseen call sites.
The circular dependency (workflows ↔ billing) remains acceptable as discussed with user (Option C).

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* test: update formSubmissionUtils tests to expect creditCheckFn parameter

The scheduleFormWorkflows function now receives creditCheckFn as a parameter.
Updated test assertions to use expect.objectContaining() with creditCheckFn: expect.any(Function)
to account for the new dependency injection parameter.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* test: update sms-manager test to expect creditCheckFn parameter

The sendSmsOrFallbackEmail function now receives creditCheckFn as a parameter.
Updated test assertion to use expect.objectContaining() with creditCheckFn: expect.any(Function)
to account for the new dependency injection parameter. Also removed teamId: undefined
assertion as the key may be omitted entirely from the actual call.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* feat: make creditCheckFn required to fully break circular dependency

This commit completes the circular dependency fix by making creditCheckFn
required throughout the call chain, eliminating the dynamic import fallback
entirely.

Changes:
- Make creditCheckFn required in messageDispatcher functions (sendSmsOrFallbackEmail, scheduleSmsOrFallbackEmail)
- Remove dynamic import fallback and warning log from messageDispatcher
- Make creditCheckFn required in ScheduleTextReminderArgs (smsReminderManager)
- Make creditCheckFn required in processWorkflowStep and ScheduleWorkflowRemindersArgs (reminderScheduler)
- Add creditCheckFn to SendCancelledRemindersArgs and wire from handleCancelBooking

The circular dependency is now fully broken - no more dynamic imports of
CreditService from within the workflows package. All callers must explicitly
provide creditCheckFn via dependency injection.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: make creditCheckFn required in WorkflowService.scheduleFormWorkflows

This commit fixes the CI type check error by making creditCheckFn required
in WorkflowService.scheduleFormWorkflows. Previously, creditCheckFn was
optional in scheduleFormWorkflows but required in scheduleWorkflowReminders,
causing a type mismatch.

Changes:
- Make creditCheckFn required in scheduleFormWorkflows signature
- Update WorkflowService.test.ts to pass mock creditCheckFn in all test cases
- Add responseId and routedEventTypeId to test calls for completeness

All callers of scheduleFormWorkflows already pass creditCheckFn, so this
change is safe and completes the circular dependency fix.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* remove

* fix

* refactor

* refactor

* refactor

* wip

* fix

* fix

* rm

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-27 16:31:26 +09:00
Alex van Andel 1ab4b9dfab chore: Fix circular dependency in tanstack-table.d.ts (#25411)
* chore: Fix circular dependency in tanstack-table.d.ts

* fix: Re-export TextFilterOperator

* Unable to export non-type values from @calcom/types

* Refactor data-table types in a way that ensures type-safety as before

* Add FilterPopover and further fixups

* Fix further type errors missed earlier

* More hidden type errors

* Type error in useFilterValue
2025-11-26 14:05:55 -03:00
Anik Dhabal Babu f3d0475840 fix: role isn't updating properly (#25415) 2025-11-26 16:13:59 +00:00
Lauris Skraucis 061283bab9 fix: api v2 cancellation reason and by not being returned (#25413)
* fix: api v2 cancellation reason and by not being returned

* fix: e2e
2025-11-26 17:09:18 +01:00
4e0798577a feat: OAuth PKCE (#25313)
* add public client

* implement PKCE

* pass codeChallenge and codeChallengeMethod to handler

* fixes for secure oauth flow

* fix type error

* clean up refresh token endpoint

* only support S256

* fix type error

* remove comment

* add tests

* fix type errors in route.test.ts

* add missing support for refresh token

* add e2e test for public client refresh tokens

* allow pkce for confidential clients

* fix type error

* fix e2e

* fix option pkce for confidential clients

* e2e test improvements

* fix test

* remove only

* add delay

* fix e2e tests

* remove only

* don't skip pkce if codeChallenge is set

* add service functions for token endpoint

* use service function in refreshToken endpoint

* use repository

* remove return types

* e2e test fixes

* fix e2e test

* remove .only in e2e test

* remove pause

* fix error responses in token endpoints

* adjust tests to new error responses

* fix error responses

* e2e improvements

* redirect on error

* adjust tests

* Update apps/web/modules/auth/oauth2/authorize-view.tsx

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-11-26 17:02:42 +01:00
Anik Dhabal Babu c95b0833c1 fix: oauth screen go back button not functional (#25401)
* fix: oauth screen back

* update
2025-11-26 15:18:53 +00:00
sean-brydon 2a7c6590a3 feat: add permission for editUsers + implement UI (#25402)
## What does this PR do?
This PR implements attributes PBAC - router checks + UI

## Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change **(video / image - any one)**.

#### Video Demo (if applicable):

- Show screen recordings of the issue or feature.
- Demonstrate how to reproduce the issue, the behavior before and after the change.

#### Image Demo (if applicable):

- Add side-by-side screenshots of the original and updated change.
- Highlight any significant change(s).

## Mandatory Tasks (DO NOT REMOVE)

- [ ] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?
Enable PBAC on an org 
Create a custom role -> advanced -> organizations -> "editUser" 
Assign it to a user
impersonate user
test they have access to all things attributes
remove permissions
check they dont have permissions. 

## Checklist

<!-- Remove bullet points below that don't apply to you -->

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my changes generate no new warnings










<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds a new PBAC “editUsers” permission and read gating for Attributes, updating the UI and backend so users can view and edit attributes only when allowed.

- **New Features**
  - Added CustomAction.EditUsers to the permission registry for organization-scoped attribute editing.
  - Settings computes canViewAttributes and shows the Attributes tab only when allowed.
  - Members page fetches Attributes permissions and exposes canViewAttributes and canEditAttributesForUser to the UI.
  - User Edit Sheet hides attributes without read permission and shows attribute editing and the bulk “Mass Assign Attributes” action only with editUsers; other user edits depend on changeMemberRole.
  - Attributes TRPC router gates create/edit/delete/toggle via PBAC and requires organization.attributes.editUsers for assign/bulk-assign; added a helper to create PBAC-aware procedures.

- **Migration**
  - Run the new Prisma migration to seed the admin role with editUsers.
  - If using custom roles, grant Edit Users under Attributes as needed.

<sup>Written for commit 856aa2e8e1521fc22cd71cb0fa6d720036efe8a2. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-11-26 13:58:29 +00:00
Anik Dhabal Babu 7d2a06ddb6 fix: hide userresponses (#25370) 2025-11-26 13:27:13 +00:00
Lauris Skraucis d34ad2b0f6 fix: v2 api rescheduledByEmail not returned (#25103)
* fix: output

* fix: creation

* test: e2e rescheduling

* refactor: remove explicit return type

* fix: e2e

* fix: e2e

* fix: e2e

* fix: e2e tests

* fix: e2e tests

* fix: e2e

* logs: add debug logs for e2e

* debug e2e

* Revert "debug e2e"

This reverts commit 3d92d2bfbc351021ab06492b7279ed95843bf36a.

* Revert "logs: add debug logs for e2e"

This reverts commit f3b321fd96853bc2cf408c7f3667ad38d0931435.

* try to fix e2e

* extract e2e in separate file

* fix: e2e
2025-11-26 14:58:45 +02:00
Anik Dhabal Babu e06249d2df fix: wrong credentials (#25394) 2025-11-26 11:23:58 +00:00
sean-brydon a09dfe37a1 fix: redirect when creating orgs onboarding v3 (#25390)
* Fix redirect

* fix redirect
2025-11-26 09:54:16 +00:00
71e7f16b29 fix: prevent calendar credentials from leaking into video adapter calls (#25200)
* fix: prevent calendar credentials from leaking into video adapter calls

Split getCredentialAndWarnIfNotFound into two category-specific functions:
- getVideoCredentialAndWarnIfNotFound: only searches video credentials
- getCalendarCredentialAndWarnIfNotFound: only searches calendar credentials

This prevents the bug where calendar credentials (like google_calendar) were
being passed to getVideoAdapters() during booking deletion, causing
'Couldn't get adapter for googlecalendar' errors.

The root cause was the fallback logic that searched both videoCredentials
and calendarCredentials when a credential wasn't found by ID. Now each
function only searches within its own credential category and validates
the returned credential has the expected type suffix (_video/_conferencing
or _calendar).

Also fixed pre-existing ESLint warnings in EventManager.ts:
- Prefixed unused delegatedCredentialLast with underscore
- Replaced 'any' types with 'unknown' for better type safety
- Fixed unused variable warning in updateAllCalendarEvents error handler

Fixes the issue where deleteVideoEventForBookingReference could receive
a calendar credential when the video credential was missing, leading to
errors in getVideoAdapters.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor: remove shared helper and implement logic directly in each function

- Removed getCredentialInternal shared helper
- Implemented logic directly in getVideoCredentialAndWarnIfNotFound
- Implemented logic directly in getCalendarCredentialAndWarnIfNotFound
- Changed fallback to explicitly use this.videoCredentials and this.calendarCredentials

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* remove duplicate

* revert

* revert

* revert

* refactor

* add tests

* address

* clean up

* simplify

* simplify

* rename

* rename

* rename

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-11-26 00:04:21 +00:00
d6546c3107 feat: upgrade tailwind v4 (#24598)
* chore: refactor config files to prevent migration tool errors

* refactor: upgrade with the tailwind migration tool

* chore: restore pre-commit command + mc

* refactor(wip): update dependencies and migrate to Tailwind CSS v4 (mainly web)

* chore: resolve Tailwind v4 migration conflicts from merging main

* chore: remove unused Tailwind packages from config and update dependencies for v4 migration

* chore: uncomment Tailwind CSS utility classes in globals.css

* fix: resolve token conflicts between calcom and coss ui

* fix: textarea scrollbar

* Fix CUI-16

* fix: added @tailwindcss/forms plugin and cleaned up CSS classes in various components to remove unnecessary dark mode styles

* fix: selects and inputs of different sizes

* fix: remove unnecessary leading-20 class from modal titles in various components

* fix: update Checkbox component styles to remove unnecessary border on checked state

* fix: clean up styles in RequiresConfirmationController, Checkbox, and Radio components to enhance consistency

* fix: update button and filter component styles to remove unnecessary rounded classes for consistency

* fix: calendar

* fix: update KBarSearch

* fix: refine styles in Empty and Checkbox components for improved consistency

* Fix focus state email input

* fix: update button hover and active states to use 'not-disabled' instead of 'enabled'

* fix: line-height issues

* fix: update class name for muted background in BookingListItem component

* fix: sidebar spacing

* chore: update class names to use new Tailwind CSS color utilities

* fix embed

* chore: upgrade Tailwind CSS to version 4.1.16 and update related dependencies

* Map css variables and add a playground test for heavy css customization

* suggestion for coss-ui

* refactor: update CSS variable usage and clean up styles

- Replace instances of `--cal-brand-color` with `--cal-brand` in embed-related HTML files.
- Remove the now-unnecessary `addAppCssVars` function from the embed core.
- Import theme tokens in the embed core styles for better consistency.
- Clean up whitespace and formatting in CSS files for improved readability.
- Add a comment in `tokens.css` regarding its usage in both embed and webapp contexts.

* Handle within tokens.css instead of fixing coss-ui

* Remove initial, not needed. Also, remove tailwind.config.js as tailwidn scans the html automaically

* fix: examples app breaking

* fix: modal not resizing correctly

* feat: upgrade atoms to tailwind v4

* fix: atoms build breaking

* fix: atoms build breaking

* chore: upgrate examples/base to tailwind 4

* chore: update globals.css

* fix: add missing scheduler css variables

* fix: PlatformAdditionalCalendarSelector

* chore: update global styles

* chore: update tailwindcss and postcss dependencies to stable versions

* chore: remove unneeded class

* fix: dialog and toast animation

* fix: replace flex-shrink-0 with shrink-0 for consistent styling in various components

* fix: dialog modal for Apple connect

* add margin in SaveFilterSegmentButton

* Fix radix button nested states

* add cursor pointer to buttons but keep dsabled state

* Fix commandK selectors and adds cursor pointer

* Fix teams filter

* fix - round checkboxes

* fix filter checkbox

* fix select indicator's margin

* command group font size

* style: fix badge and tooltip radius

* chore: remove unneeded files

* Delete PR_REVIEW_MANAGED_EVENT_REASSIGNMENT.md

* remove ui-playground leftover

* fix: add missing react phone input styles in atoms

* Delete managed-event-reassignment-flow-and-architecture.mermaid

* fix: inter font not loading

* Add theme to skeleton container so that it can support dark mode

* fix: create custom stack-y-* utilities post tw4 upgrade

* fix: typo

* fix: atoms stack class + remove unused css file

* fix default radius valiue

* fix space-y in embed

* fix skeleton background

* Hardcode radius values to match production

* fix border in embed

* add missing externalThemeClass

* feat: create a custom stack-y-* utility

* fix: add stack utility to atom global css

* fix: Skeleton loader class modalbox

* Add stack-y utility in embed

* fix: add missing stack utilities in atoms globals.css

* update yarn.lock

* add popover portla

* update

---------

Co-authored-by: Sean Brydon <sean@cal.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
2025-11-25 17:32:28 -03:00
625c260e40 fix: OOO days not correctly blocked (#25259)
* fix: OOO check in buildSlotsWithDateRanges

* added testcase

---------

Co-authored-by: chauhan_s <somaychauhan98@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-25 20:14:05 +00:00
Amit Sharma 81224f324a feat: google ads conversion tracking (#25198)
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
* feat: google ads conversion tracking

* gaClientid

* store gclid in stripe metadata

* tracking only in the us

* track google campaign id as well

* rename gclid -> google ads

* fix: build

* fix

* refactor

* fix: type check

* fix: type check

* fix: type check

* fix: type check

* fix: store it in cookie

* refactor

* fix

* cleanup

* linked ads tracking

* refactor checkout session tracking
2025-11-25 12:58:10 +00:00
emrysal 700d8e7f30 chore: release v5.9.5 2025-11-25 12:55:45 +00:00
Anik Dhabal Babu 301376e33b fix: set new icalUid when host reassign (#25365)
* fix seated event and workflow issue

* update

* revert

* Update smsReminderNumber assignment in handleSeats
2025-11-25 11:46:35 +00:00
Anik Dhabal Babu 57476ea392 chore: team update handler refactor (#25332)
* chore: team update handler refactor

* add tests

* fix
2025-11-25 11:27:26 +00:00
Anik Dhabal Babu 9c2d7f99c2 fix: google meet link is disappear (#25368) 2025-11-25 16:25:12 +05:30
sean-brydon ef3281f06f Remove square enforcing in resizeBase64Image (#25389) 2025-11-25 16:15:57 +05:30
sean-brydon d03f45dd0f fix: Onboarding v3 - create team then invite. (#25364)
## What does this PR do?
This PR changes the order of creating the team -> paying -> invite users.

The old approach was create team -> invite -> pay. But we are matching the current implementation of how billing works with usage based billing

## How should this be tested?

Enable onboarding-v3 flag on your instance
Ensure you have stripe enabled + stripe:listen running
login as onboarding@example.com, onboarding
Go through the team setup flow
Pay
Invite
Ensure uers were added to team

Create a new account
disable billing
Test again 

## Checklist

<!-- Remove bullet points below that don't apply to you -->

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my changes generate no new warnings
2025-11-25 09:14:59 +00:00
2b2bf36703 fix: Grab booking organizer credentials when team admins request reschedule (#24645)
* Change arg name from `bookingUId` to `bookingUid`

* Lint fix

* Use `BookingRepository` to find booking to reschedule

* Move early return further up if no booking is found

* Use `PermissionCheckService` if request rescheduling a team booking

* Remove redundent check

* Remove redundent eventType query

* Using `BookingRepository` to update the booking to rescheduled

* Update type in `getUsersCredentialsIncludeServiceAccountKey` to only
require params that are required

* Get booking organizer credentials

* Type fixes

* test: Add tests for team admin request reschedule with organizer credentials

- Add test for team admin requesting reschedule with proper permissions
- Add test verifying organizer's credentials are used (not requester's)
- Add test for team member without permissions (should fail)

These tests cover the fix in PR #24645 which ensures that when a team admin
requests a reschedule, the booking organizer's credentials are used to delete
calendar events instead of the requester's credentials.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Address code review comments for request reschedule

- Change user: true to user: { select: { id, email } } to only fetch required fields
- Change eventType include to select with explicit fields including teamId
- Remove sensitive information (user object, cancellationReason) from debug log
- All integration tests passing locally

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Type fix

* Remove businesss logic references from repository methods.

* Move business logic to handler

* Type fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-25 07:27:07 +00:00
Benny Joo 272d97c0a3 fix: prevent 500 errors in round-robin scheduling from OOO calibration for single host (#25369)
* wip

* add unit test
2025-11-25 09:13:04 +02:00
emrysal f2b2b6e491 chore: release v5.9.4
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-25 01:39:25 +00:00
15ef547e41 fix: enable block calendar slots by default for required confirmations (#25239)
* fix: enable block calendar slots by default for required confirmations

* remove unnecessary wasenabled

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-11-25 00:23:40 +05:30
Eunjae Lee 251d29f65b fix: improve overlapping events with dynamic offsets and widths (#25310)
## What does this PR do?

Improves the visual presentation of overlapping calendar events in the weekly view with two key enhancements:

- **Dynamic startHour per scenario**: Each playground scenario now displays the calendar starting at an appropriate hour based
on its earliest event time, rather than always starting at 6am
- **Full width for non-overlapping events**: Single events and non-overlapping events now display at 100% width (previously
80%) for maximum visibility

## Key Changes

### Overlapping Event Layout Algorithm

Replaces the previous uniform-width, fixed-offset layout with an intelligent spread algorithm:

**Previous behavior:**
- All overlapping events: 80% width with 8% offset steps
- Events clustered on the left side

**New behavior:**
- **2 overlapping events**: 80% and 50% widths
- **3 overlapping events**: 55%, ~42%, and 33% widths
- **4+ overlapping events**: Progressive narrowing from 40% down to minimum 25%
- **Spread algorithm**: Events distribute across the full width with the last event aligned to the right edge
- **Right edge distribution**: `ri = Rmin + (Rmax - Rmin) × i/(n-1)` for even spacing

### Visual Improvements

- Single/non-overlapping events: **100% width** (was 80%)
- Overlapping events: **Variable widths** based on cascade position (leftmost events wider, rightmost narrower)
- Last overlapping event: **Aligned to right border** for maximum scatter
- Minimum width: **25%** maintained for readability

**Devin session:** https://app.devin.ai/sessions/168d2227f5304c49ae4d34d17da5b025  
**Requested by:** eunjae@cal.com (@eunjae-lee)

## Visual Demo


https://github.com/user-attachments/assets/693546fa-448d-470a-b041-c08f4697c177



## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. **N/A** - playground-only changes
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Navigate to `/settings/admin/playground/weekly-calendar`
2. Verify each scenario:
   - **Non-Overlapping Events**: Both events should be 100% width, no offset
   - **Touching Events**: Both events should be 100% width, no offset
   - **Two Overlapping Events**: First event 80% width, second 50% width aligned to right
   - **Three Overlapping Events**: Progressive narrowing with spread across full width
   - **Four Overlapping Events**: Four events spread across full width
3. Verify startHour values:
   - Most scenarios should start at 9am (events start at 10am)
   - Dense day scenario should start at 8am (events start at 9am)
   - Mixed statuses scenario should start at 1pm (events start at 2pm)
4. Test with real calendar data to ensure overlapping events look visually distinct

**Environment variables:** Standard Cal.com development setup  
**Test data:** Use playground scenarios or create overlapping events in your calendar

## Human Review Checklist

**⚠️ CRITICAL ITEMS:**

1. **Visual verification in playground** (MOST IMPORTANT):
   - Open `/settings/admin/playground/weekly-calendar`
   - Verify non-overlapping events are 100% width (not 80%)
   - Verify overlapping events spread properly across full width
   - Verify last overlapping event aligns to right edge
   - Verify each scenario starts at appropriate hour

2. **Algorithm correctness**:
   - Single events: 100% width (was 80%)
   - Two overlapping: 80%, 50% widths with last aligned to right
   - Three overlapping: 55%, ~42%, 33% widths spread across full width
   - Right-edge distribution: `ri = Rmin + (Rmax - Rmin) * i/(n-1)`

3. **Edge cases**:
   - Test with 10+ overlapping events to ensure no overflow
   - Verify minimum width (25%) is respected
   - Verify backward compatibility: custom `baseWidthPercent`/`offsetStepPercent` should use legacy behavior

4. **Type safety**:
   - `startHour` parameter now properly typed as `Hours` (union of 0-23)
   - All scenarios use valid `Hours` values

**Known limitations:**
- Local visual testing was not completed due to environment issues
- Easing curve parameters (curveExponent: 1.3) were chosen based on examples but may need visual tuning
- No E2E tests for visual appearance (only unit tests for layout calculations)

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings
2025-11-24 12:01:05 +00:00
Benny JooandDevin AI 8b652613dd fix: break circular dependency between reminderScheduler and credit-service (#25312)
* fix: break circular dependency between reminderScheduler and credit-service

- Created WorkflowReminderRepository to handle workflow reminder queries
- Refactored cancelScheduledMessagesAndScheduleEmails to accept userIdsWithoutCredits parameter
- Moved credit-checking logic from workflows to CreditService
- Changed dynamic import to static import in CreditService
- Updated tests to pass userIdsWithoutCredits parameter
- Removed unused imports (prisma, WorkflowMethods)

This creates a one-way dependency (billing -> workflows) and follows the repository pattern by removing direct Prisma usage from reminderScheduler.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: resolve type check errors in circular dependency fix

- Use MembershipRepository.listAcceptedTeamMemberIds instead of findAllAcceptedPublishedTeamMemberships
- Re-add prisma import to reminderScheduler.ts for UserRepository
- Update WorkflowReminderRepository to use WorkflowActions enum instead of string

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* refactor

* refactor

* wip

* wip

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-24 10:00:57 +02:00
8e1a0999d2 fix: added pattern checking for urls while creating a team (#24777)
* fix: added pattern checking for urls while creating a team

* update: used slugify and replace logic

* update

* Fix formatting of rules in CreateANewTeamForm

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-11-22 15:49:28 +00:00
e29aa2097e feat: Ensure teams with conflicting slugs owned by the user are migrated(handled in backend, frontend already had this restriction) (#25291)
* feat: add backend validation for conflicting team slugs during org onboarding

- Added findOwnedTeamsByUserId method to TeamRepository
- Created buildTeamsAndInvites method in BaseOnboardingService that automatically:
  - Detects teams with same slug as organization
  - Marks conflicting teams for migration (isBeingMigrated: true)
  - Filters empty team names and invite emails
- Updated BillingEnabledOrgOnboardingService to use new method
- Updated SelfHostedOnboardingService to use new method
- Added comprehensive tests for slug conflict scenarios

This ensures backend validation even if frontend is bypassed, preventing
slug conflicts during organization creation. All inheriting classes
automatically get this validation without code changes.

* refactor: use TeamRepository in listOwnedTeamsHandler

Refactored listOwnedTeamsHandler to use TeamRepository.findOwnedTeamsByUserId
instead of direct Prisma queries. This:
- Reduces code duplication
- Ensures consistency across the codebase
- Follows repository pattern
- Makes the handler more maintainable

* fix: update tests to use renamed buildTeamsAndInvites method

- Renamed testFilterTeamsAndInvites to testBuildTeamsAndInvites
- Made test wrapper method async to match the async buildTeamsAndInvites
- Added orgSlug parameter to all test calls
- Updated all 9 test cases to use await with the new method signature
- Fixed lint warnings by using proper types instead of 'any'
- Imported OnboardingIntentResult and User types
- Used Pick<User> for mockUser type
- Removed all 'as any' type casts

Fixes test failures where filterTeamsAndInvites was renamed to buildTeamsAndInvites in the base service.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: mock TeamRepository in tests to prevent database calls

Added vi.mock for TeamRepository to avoid database calls in unit tests.
The buildTeamsAndInvites method now calls ensureConflictingSlugTeamIsMigrated
which uses TeamRepository.findOwnedTeamsByUserId(). Mocking this prevents
Prisma errors in CI while keeping the tests focused on filtering logic.

The mock returns an empty array so no teams are found for migration,
allowing the tests to verify the filtering behavior without database access.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: improve readability of ensureConflictingSlugTeamIsMigrated

Refactored the conditional logic in ensureConflictingSlugTeamIsMigrated
for better readability while preserving exact behavior. Changed from
manual array manipulation to using .map() for updating team migration
status. This is a cosmetic change with no functional differences.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-22 09:07:28 +00:00
emrysal 1578dee622 chore: release v5.9.3
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-21 19:59:15 +00:00
Joe Au-Yeung e5ebf7feb4 fix: signup (#25334)
* Handle Stripe logic in `paymentCallback`

* Remove endpoint

* Do not send email verification email if premium username

* Remove logic from verify-view

* Callback send verification email

* Add `create` method to `VerificationToken` repository

* Create `VerificationTokenService`

* Early return if payment failed

* Refactor token generation

* Add tests

* Type fixes

* Type fixes
2025-11-21 19:51:19 +00:00
Rajiv Sahal 06348982a3 fix: make sure only admins and owners are authorized for team (#25333) 2025-11-21 18:44:51 +00:00
Syed Ali ShahbazandKeith Williams a7d87fc5be fix: Proxy Mintlify traffic through a Next.js API route (#25320)
* hotfix

* type fix and test fix

* update env example

* improvements

* more fix

* tada

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-11-21 18:43:09 +00:00
sean-brydonandUdit Takkar 0d77fc8474 Fix filter on invites (#25330)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-21 18:34:05 +00:00
Rajiv Sahal 0af77be127 chore: improve membership check (#25326)
* chore: improve membership check

* fix: update change role validation

* chore: add tests

* chore: update error message
2025-11-21 14:34:15 -03:00
Eunjae Lee afbfa11ab5 chore: update seed.ts (#25316)
* chore: update seed.ts

* Revert "chore: update seed.ts"

This reverts commit 2bd0c5a6dc57142632f8fbd267aa6b5eba6d1cea.

* use env vars instead
2025-11-21 16:37:57 +00:00
a7aabc8b4f fix: toggleEnabled handler (#25325)
* fix toggle enabled handler

* add tests

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-11-21 13:15:04 -03:00
sean-brydon c941192979 fix: access service class for editLocationHandler (#25315)
* fix access service class

* Move out of trpc
2025-11-21 13:13:06 -03:00
sean-brydon 44311f51ba refactor handler (#25323) 2025-11-21 15:51:23 +00:00
Morgan 0af6354954 fix: meeting ended page server component dto (#25318)
* fix: meeting ended page server component dto

* fix: repository function fetching too much
2025-11-21 15:29:53 +00:00
Joe Au-Yeung dd7c553cc3 fix: Remove hosts - verify event type belongs to event type (#25321)
* Add check that event type belongs to team

* Add `findAcceptedMembershipsByUserIdsInTeam` to `MembershipRepository`

* Validate that passed `userIds` belong to a team

* Add tests

* Typo fix
2025-11-21 10:26:22 -05:00
5cb1d4aad0 fix: Improve add users to org (#25314)
* Improve add users to org

* Improve add users to org

* test: Add comprehensive tests for handleUserEvents cross-tenant hijack prevention

- Add tests for cross-tenant hijack prevention security fix
- Test that users belonging to different organizations are blocked
- Test that users with null organizationId are blocked (prevents legacy user hijacking)
- Test that users belonging to correct organization succeed
- Test new user creation flow
- Test user activation/deactivation flows
- Test custom attribute syncing
- All 8 tests passing locally with proper type safety (no 'as any' usage)

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-21 12:18:41 -03:00
Eunjae Lee 701490a493 docs: update the app store doc regarding seed (#25317) 2025-11-21 14:45:29 +00:00
Morgan 6499243a42 fix: enable api v2 sms (#25311) 2025-11-21 13:40:27 +00:00
sean-brydonandDevin AI 3c8215add3 feat: filter out platform organizations from admin organization list (#24926)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-21 12:03:06 +00:00
mintlify[bot]andVolnei Munhoz 2bd7549f20 Add Cal.com API V1 to V2 Migration Guide (#25196)
* Update docs/api-reference/v2/migration-guide.mdx

* Update docs/api-reference/v2/v1-v2-differences.mdx

* Update docs/api-reference/v2/v1-v2-differences.mdx

* Update docs/api-reference/v2/migration-guide.mdx

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2025-11-21 11:00:00 +00:00
mintlify[bot] 629371a5f1 Documentation edits made through Mintlify web editor (#25275)
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2025-11-21 06:09:35 +00:00
dc3df122e2 feat: Add configurable trial days to org subscriptions + wizard warning (#25229)
* feat: Add trial days to organization subscriptions and workspace warning

- Add ORGANIZATION_TRIAL_DAYS environment variable for configurable trial periods
- Implement trial days in Stripe checkout session (only when env var is set)
- Add warning message to organization setup page about workspace structure
- Add translation string for organization trial workspace warning
- Add ORGANIZATION_TRIAL_DAYS to turbo.json env vars
- Fix pre-existing linting warnings in CreateANewOrganizationForm.tsx
- Add ESLint disable comments for turbo/no-undeclared-env-vars warnings

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Rename variable

* Add trial days to `purchaseTeamOrOrgSubscription`

* fix: Move organization trial warning to spot 3 below form card

- Add optional footer prop to WizardLayout component
- Use footer prop in create-new-view.tsx to render warning at spot 3
- Remove warning from inside CreateANewOrganizationForm component
- Warning now appears below the form card as requested

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: Add organization trial warning to all wizard steps

- Add warning footer to step 2 (about-view.tsx)
- Add warning footer to step 3 (add-teams-view.tsx)
- Add warning footer to step 4 (onboard-members-view.tsx)
- Add warning footer to step 5 (payment-status-view.tsx)
- Add warning footer to resume-view.tsx (step 1 resume page)
- Warning now appears on all steps of the organization creation wizard

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Correct environment variable name to STRIPE_ORG_TRIAL_DAYS

- Changed ORGANIZATION_TRIAL_DAYS to STRIPE_ORG_TRIAL_DAYS in turbo.json
- This matches the actual usage in OrganizationPaymentService.ts and payments.ts
- Ensures the environment variable is properly recognized by the build system

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: Create shared OrganizationWizardLayout component

- Create OrganizationWizardLayout component that wraps WizardLayout
- Centralizes the trial warning footer logic in one place
- Update all 6 wizard pages to use the shared component:
  - create-new-view.tsx
  - about-view.tsx
  - add-teams-view.tsx
  - onboard-members-view.tsx
  - payment-status-view.tsx
  - resume-view.tsx
- Remove duplicate useLocale/Alert imports and footer props from pages
- Simplifies maintenance by having warning logic in a single location

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Fix lint error

* Add `ORG_TRIAL_DAYS` as constant

* Add comment

* Ensure no negative number is passed

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-20 15:02:01 -03:00
176fb777fc fix: One flaky E2E tests (#24815)
* fix: exclude booking responses from calendar/CRM integrations for seated events

For seated events (events with seatsPerTimeSlot), booking responses are now excluded from being sent to calendar integrations (Google Calendar, etc.), CRM integrations (HubSpot, Salesforce, etc.), and other integrations.

This applies to both creating new seated bookings and rescheduling seated bookings.

The calendar event and CRM records are still created, but without the custom booking field responses included in the description/notes.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* test

* Refactor Office 365 Calendar OAuth redirect URI

Removed debug logging for redirect URI and client ID.

* test

* check

* Update Prisma connection logic for integration tests

Refactor database connection handling for integration tests.

* update

* Refactor conditionals and simplify role handling

* Add test comment in index.ts

* Remove integration test flag from index.ts

Remove integration test flag from database connection logic.

* update

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-20 22:10:02 +05:30
Alex van Andel ae7fd0cae2 refactor: Remove all code related to the old cache system (#25284)
* chore: Remove all code related to the old cache system

* Removed some redundant tests, some type fixes

* Further type fixes

* More type fixes re. tests

* Next iteration, couple of fixes remaining

* Remove cache from CredentialActionsDropdown

* Fix tests by mocking credential, instead of db queries

* Remove Cache DI wiring from v2

* Make sure apiv2 build passes

* Remove another cache cron

* Remove old tokens for calendar-cache v1
2025-11-20 18:02:18 +02:00
Piyanshu Saini d1184f65e2 fix(platform): show loading spinner only for selected plan, not all plans (#25290) (#25292)
## Problem
When users clicked on a plan card in the Cal.com Platform pricing UI, the loading
spinner would appear on ALL plan cards simultaneously instead of just the selected one.
This gave a confusing UX impression that all plans were being processed at the same time.

## Solution
Track the currently loading plan using a `loadingPlan` state variable that stores
which plan the user clicked on, rather than relying solely on the pending state from
the mutation hook.

## Changes
- Added `loadingPlan` state to track which specific plan is loading
- Update `loadingPlan` when a plan subscription is initiated
- Reset `loadingPlan` on error to ensure UI returns to normal state
- Modified `isLoading` prop condition to check if the current plan matches
  the `loadingPlan` before showing the spinner

This ensures that only the plan card the user clicked on displays the loading indicator,
while other plans remain in their normal state.
2025-11-20 15:25:12 +00:00
MorganandDevin AI 342e5baca2 feat: add hashedLink to BOOKING_REQUESTED webhook payload (#25274)
- Add hashedLink field to CalendarEvent type definition
- Add withHashedLink method to CalendarEventBuilder
- Pass hashedLink from booking request to CalendarEvent in RegularBookingService
- hashedLink will now be included in webhook payloads when booking via private API links

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-20 08:24:21 -03:00
chauhan_sandMorgan fbfa27735b feat: add validation for null values in bookingFieldsResponses (#25272)
* feat: add validation for null values in bookingFieldsResponses

- Add test case to verify 400 error when bookingFieldsResponses contains null values
- Create ValidateBookingFieldsResponses decorator to reject null values in booking field responses
- Apply validator to CreateBookingInput_2024_08_13.bookingFieldsResponses property
- Ensure all booking field response values are non-null strings

* feat: transform null values to empty strings in bookingFieldsResponses

- Remove ValidateBookingFieldsResponses validator that rejected null values
- Add Transform decorator to convert null values to empty strings in bookingFieldsResponses
- Update test to verify null values are transformed to empty strings instead of returning 400 error

* remove extra spaces

* test: add rescheduleReason null value test case

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-11-20 10:45:22 +00:00
emrysal 37c26793f5 chore: release v5.9.2
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-20 10:33:06 +00:00
sean-brydon 956f81fab3 chore: tidy up onboarding with new animations and illustrations (#25124)
<!-- This is an auto-generated description by cubic. -->
## Summary by cubic
Revamps onboarding with subtle route transitions, new org/teams illustrations, and clearer invite flows with real-time previews. Adds “Skip for now” on invites and guardrails to avoid incomplete team creation.

- **New Features**
  - Added email invite pages for organizations and teams with shared EmailInviteForm and RoleSelector.
  - Built a live invite browser preview that renders a 3×3 grid and updates as you type; works for orgs and teams.
  - Applied route-keyed framer-motion transitions to layout, cards, and browser views for smoother page changes.
  - Continuation prompt now detects saved org or team and routes to the right next step; localized copy.
  - Added loading state to plan selection to prevent double navigation.
  - Refreshed Organizations welcome modal with a new animated ring illustration and better scrolling.
  - Added “Skip for now” to org and team invite-by-email steps to proceed without invites.
  - Calendar browser preview now focuses on a time window around “now” for a more realistic demo.
  - Added an optional floating footer to keep actions visible on long, scrollable lists.

- **Refactors and Fixes**
  - Unified invite browser and replaced the org preview on the org email step.
  - Split and simplified legacy invite views; team and org routes are cleaner and easier to extend.
  - Streamlined the team invite step by removing a redundant action; non-admins are redirected to the email invite page.
  - Prevented creating teams with empty details by redirecting back to team details.
  - Minor UI cleanup: tighter borders, padding, and mobile max-heights across onboarding screens.
  - Hide team select on org invites when no teams exist.

<sup>Written for commit ae7f5277ab998560ae6e2f3f9144852a7b4959a7. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-11-20 10:20:38 +00:00
1dcd54aab7 feat: add avatarUrl and bio fields to /me endpoint response (#25224)
* feat: add avatarUrl to /v2/me endpoint response

- Add avatarUrl field to userSchemaResponse schema in packages/platform/types/me.ts
- Update e2e tests to verify avatarUrl is returned in GET and PATCH /v2/me responses
- Field is nullable to match User model in Prisma schema
- Fix pre-existing lint warnings by removing 'as any' type assertions in test file

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* feat: add avatarUrl to MeOutput DTO for OpenAPI docs

- Add avatarUrl field to MeOutput class in apps/api/v2/src/ee/me/outputs/me.output.ts
- Field is nullable to match the Zod schema and Prisma model
- This ensures OpenAPI documentation will include avatarUrl when regenerated

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* feat: add bio field to /v2/me endpoint response

- Add bio field to userSchemaResponse Zod schema in packages/platform/types/me.ts
- Add bio field to MeOutput NestJS DTO in apps/api/v2/src/ee/me/outputs/me.output.ts
- Update e2e tests to verify bio is returned in both GET and PATCH responses
- Field is nullable to match the User model in Prisma schema

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: chauhan_s <somaychauhan98@gmail.com>
2025-11-19 23:24:31 +00:00
68d3d9d964 docs: add Stripe Connect atom documentation (#24791)
* docs: add Stripe Connect atom documentation

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* docs: restructure Stripe Connect docs with Steps component

- Add Steps component explaining two ways to connect Stripe
- Step 1: Direct Stripe Connect atom usage
- Step 2: Event Type Settings payment tab usage
- Include code examples for both methods
- Add image placeholders for visual demonstrations
- Move advanced usage examples under separate section

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* chore: add link to stripe connect atom

* chore: update docs

* chore: implement feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 23:12:05 +00:00
717a26f223 fix: prevent bulk update of locked locations in child managed event types (#24978)
* fix: prevent bulk update of locked locations in child managed event types

- Filter out child managed event types with locked locations in getBulkUserEventTypes
- Add validation in bulkUpdateEventsToDefaultLocation to prevent updating locked fields
- Implements defense in depth with validation at multiple layers

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Abstract filtering logic

* test: add comprehensive tests for bulk location update filtering

- Add unit tests for filterEventTypesWhereLocationUpdateIsAllowed
- Add unit tests for bulkUpdateEventsToDefaultLocation
- Add integration tests for getBulkUserEventTypes
- Fix bug: change unlockedFields?.locations check from !== undefined to === true
  This ensures that locations: false is properly treated as locked, addressing
  the security issue identified in PR review comments

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: filter locked managed event types on app installation page

- Add parentId to eventTypeSelect in getEventTypes function
- Apply filterEventTypesWhereLocationUpdateIsAllowed to both team and user event types
- Only filter when isConferencing is true to avoid affecting other app types
- Fixes issue where locked managed event types were showing in the event type selection list on /apps/installation/event-types page

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix(embed-react): remove obsolete availabilityLoaded event listener

The availabilityLoaded event does not exist in the EventDataMap type system
in embed-core. This code was causing 5 TypeScript errors in CI:
- Type 'availabilityLoaded' does not satisfy constraint 'keyof EventDataMap'
- 'data' is of type 'unknown' (2 occurrences)
- Type 'availabilityLoaded' is not assignable to action union (2 occurrences)

Since this is an example file and the event is not defined in the type system,
removing this obsolete code resolves the type errors.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: correct Prisma type for metadata in test helper function

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: use flexible PrismaLike type for better test compatibility

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: properly type mock Prisma objects in test files

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: properly mock Prisma methods in test file

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Filter out metadata

* Undo change in embed file

* Address feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 15:46:05 -05:00
Alex van Andel 6818806c5e chore: No more clientside markdown when importing Checkbox (#25278) 2025-11-19 15:40:37 -03:00
Eunjae Lee dd7f108f08 fix: put booking details and calendar behind feature flag (#25175)
* Revert "fix: revert bookings redesign (#25172)"

This reverts commit 1f102bf3b4.

* add bookings-v3 feature flag

* put things behind a feature flag

* remove no longer needed test

* revert e2e tests

* put back description

* revert AvatarGroup

* apply feedback

* remove "view" booking action

* remove Alert (When the bookings query errors, this branch now renders only the alert and skips the data-table filter/segment controls. Those controls moved into BookingsList, so in error states users can no longer clear or tweak filters to recover from the failure, effectively trapping them behind the alert.)

* address feedback

* revert useMediaQuery
2025-11-19 16:27:13 +01:00
7e4d9e26c6 refactor: implement DI in team billing service and team billing data repository factory (#24803)
* Move TeamBillingRepositories

* WIP refactor team internal billing service

* Remove duplicate billing repository files

* Remove logic check in repository for billing is enabled

* Rename repository to `TeamBillingData`

* Use repository factory in main service

* Fix new import paths

* Rename  to

* Ensure `IS_TEAM_BILLING_ENABLED` is of type boolean

* Rename classes to TeamBillingService and TeamBillingServiceFactory

* Implement DI in `BookingServiceFactory`

* `TeamBillingService` use repository in `getOrgIfNeeded`

* DI `isTeamBillingEnabled` to `TeamBillingServiceFactory`

* Rename files for consistency

* Return stub BillingRepository if billing is not enabled

* Move Stripe billing service to service folder

* Rename file

* `StripeBillingService.getSubscriptionStatus` return `SubscriptionStatus`

* Type fices in StripeBillingService

* Type fix in `stubTeamBillingService`

* DI the `BillingProviderService` into the `TeamBillingService`

* Implement DI in `skipTeamTrials.handler`

* Implement DI for team billing in `inviteMember.handler`

* `skipTeamTrials.handler` use `team.isOrganization`

* Implement DI for billing in `hasActiveTeamPlan.handler`

* Type fixes

* Implement DI in `bulkDeleteUsers.handler`

* Implement `BillingProviderServiceFactory` in `updateProfile.handler`

* Implment `BillingProviderServiceFactory` in `buyCredits.handler`

* Fix import in `stripeCustomer.handler`

* Add a constructor to `teamBillingServiceFactory`

* Add DI to `PrismaTeamBillingRepository`

* Add DI to `StripeBillingService`

* Implement singleton in `BillingProviderServiceFactory`

* Add DI folder and contents to billing folder

* Use `getTeamBillingServiceFactory` in `inviteMember.handler`

* Add `saveTeamBilling` method to `ITeamBillingService`

* Implement DI in new team route

* Implement DI in `teamService`

* Implement DI in `OrganizationPaymentService`

* Implement DI in `credit-service`

* In `StripeBillingService` remove `static` from status methods

* Implemnt DI in `_invoice.paid.org`

* Refactor `hasActiveTeamPlan` to use `getTeamBillingFactory`

* Refactor `skipTeamTrials` to use `getTeamBillingFactory`

* Refactor `skipTeamTrials` to use `getTeamBillingServiceFactory`

* `stripeCustomer.handler` to use `getBillingProviderService`

* Remove old factories

* Type fix

* Remove unused factory

* Refactor `updateProfile.handler` to use `getBillingProviderService`

* Change name to `TeamBillingDataRepositoryFactory`

* Type Prisma return in `prisma.module`

* Type fix

* Refactor `buyCredits.handler` to use `getBillingProviderService`

* Refactor `credit-service` to use billing DI containers

* Type fix

* Add `getTeamBillingDataRepository`

* Refactor `_invoice.paid.org` to use DI container

* Refactor `_customer.subscription.deleted.team-plan` to use DI container

* Refactor `calcomHandler` to use DI container

* Refactor `getCustomerAndCheckoutSession` to use DI container

* Refactor `verify-email` to use DI containers

* Refactor `api/create/route` to use DI container

* Refactor downgradeUsers to use DI container

* Type fix

* Clean up console.logs

* Add await to `this.billingRepository.create` in `saveTeamBilling`

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Fix type errors

* Address comments

* fix: update tests to work with new DI pattern

- Update teamBillingService.test.ts to properly inject DI dependencies
- Remove unused billingModule import and mock
- Fix import naming in teamService.integration-test.ts (remove unused rename)
- Fix import path for TeamBillingPublishResponseStatus

All tests now properly mock IBillingProviderService, ITeamBillingDataRepository,
and IBillingRepository instead of using the old BillingRepositoryFactory pattern.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: add compatibility layer and env setup for unit tests

- Add STRIPE_PRIVATE_KEY dummy value to vitest.config.ts to prevent DI module errors
- Fix import paths in credit-service.test.ts (StripeBillingService, TeamBillingService)
- Create compatibility barrel at packages/features/ee/billing/teams/index.ts for test mocking

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: update unit tests to mock DI container properly

- Update teamService.test.ts to mock getTeamBillingServiceFactory() instead of TeamBilling.findAndInit
- Update teamService.alternative.test.ts to mock DI container
- Update credit-service.test.ts to mock getBillingProviderService() and use SubscriptionStatus enum values
- Update OrganizationPaymentService.test.ts to mock DI container instead of direct StripeBillingService import
- Remove all 'as any' type casting to comply with Cal.com coding standards
- Fix unused variable warnings by prefixing with underscore

All 53 tests now passing (16 + 1 + 30 + 6)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: update remaining unit tests to use DI pattern

- Fix StripeBillingService.test.ts to inject mock Stripe client directly
- Fix teamBillingFactory.test.ts to mock getTeamBillingServiceFactory() from DI container
- Fix skipTeamTrials.test.ts to mock DI container and use SubscriptionStatus enum

All 11 previously failing tests now pass (5 + 5 + 1)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Undo changes made to Prisma module

* fix: address test-related PR comments

- Fix OrganizationPaymentService.test.ts mock path from @calcom/ee to @calcom/features/ee
- Refactor teamBillingFactory.test.ts to test real factory logic instead of mocking container
- Remove duplicate teamBillingService.test..ts file with incorrect double-dot filename

All three test files now pass successfully with proper DI patterns.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Address feedback

* fix: update teamService integration test to mock new DI factory pattern

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: remove duplicate imports in credit-service.test.ts

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Remove unused index file

* `getBySubscriptionId` to return team or null

* Address feedback

* Merge fix

* Refactor file names

* fix: correct mockStripe variable name to stripeMock in StripeBillingService.test.ts

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: update internal-team-billing.test.ts to use new DI structure with TeamBillingService

- Replace InternalTeamBilling with TeamBillingService
- Use constructor injection with mock dependencies instead of factory pattern
- Remove BillingRepositoryFactory mock and import
- Update all test cases to use mockBillingProviderService, mockTeamBillingDataRepository, and mockBillingRepository
- Simplify saveTeamBilling tests to focus on repository.create calls
- All 11 tests now pass with the new DI structure

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: update createWithPaymentIntent.handler.test.ts to mock DI container's getBillingProviderService

- OrganizationPaymentService now uses getBillingProviderService() from DI container
- Test was mocking @calcom/features/ee/payments/server/stripe directly, which no longer works
- Added mock for @calcom/features/ee/billing/di/containers/Billing module
- Mock returns fake billing provider that delegates to mockSharedStripe
- Preserves all existing test assertions and helpers
- Fixed lint error by prefixing unused lastCreatedSessionId with underscore
- All 11 tests now pass (1 skipped as expected)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2025-11-19 10:21:22 -05:00
sean-brydonandDevin AI a7352cf587 chore: remove ui-playground app (#25266)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 14:48:47 +00:00
Peer RichelsenandEunjae Lee 5f8db0557c chore: improve floating schedule button (#23873)
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2025-11-19 14:16:32 +00:00
emrysal 88be45457f chore: release v5.9.1
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-19 14:04:07 +00:00
Alex van Andel 90a42c37fd chore: Remove next-collect package (#25146) 2025-11-19 13:54:26 +00:00
cf7430d531 fix: convert booking field label error to log.error to prevent booking failures (#25062)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-19 13:30:46 +00:00
Hariom BalharaandDevin AI 105a82f97d feat: add uuidv7 and @db.Uuid to AuditActor and BookingAudit models (#25269)
- Update AuditActor.id to use uuid(7) with @db.Uuid
- Add @db.Uuid to BookingAudit.bookingUid and actorId fields
- Create migration to convert existing TEXT columns to UUID type

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 13:17:02 +00:00
Yash fdd3d11111 Fix dynamic group meeting slots not loading (#25101) 2025-11-19 12:56:47 +00:00
emrysal e7ea1884b7 chore: release v5.9.1 2025-11-19 11:43:50 +00:00
Hariom Balhara c04402e7ee feat: [Booking Audit Stack - 1] Add Booking Audit System foundation (database schema and repositories) (#24838)
* feat: Implement Booking Audit System with database architecture and repository interfaces

- Added `ARCHITECTURE.md` detailing the design and structure of the Booking Audit System, including core tables `AuditActor` and `BookingAudit`.
- Created repository interfaces `IAuditActorRepository` and `IBookingAuditRepository` for managing audit actor and booking audit records.
- Implemented `PrismaAuditActorRepository` and `PrismaBookingAuditRepository` for database interactions.
- Defined enums for `BookingAuditType`, `BookingAuditAction`, and `AuditActorType` in the Prisma schema.
- Added migration scripts to create necessary database tables and enums for the audit system.

This commit establishes a robust framework for tracking booking-related actions, ensuring compliance and data integrity.

* feat(audit): add system actor migration
2025-11-19 08:21:34 -03:00
075d209b6f feat: remove OAuth clients link from settings navigation (#25206)
* feat: remove OAuth clients link from settings navigation

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: resolve infinite loop in sidebar close effect

Use functional state update to avoid reading sideContainerOpen in dependency array, which was causing infinite re-renders when navigating between settings pages.

Co-Authored-By: peer@cal.com <peer@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 11:09:07 +00:00
chauhan_s 26e8582302 fix: use UTC parsing for recurring booking dates to prevent timezone conversion issues (#25235)
Replace dayjs.tz() with dayjs.utc() when parsing recurring booking date strings to ensure dates are interpreted as UTC timestamps rather than being converted to the specified timezone. This prevents incorrect date/time display when the dateStr is already in UTC format.
2025-11-19 11:03:14 +00:00
Anik Dhabal Babu 9f277c5179 fix: archive meeting during host-change reschedules (#25098) 2025-11-19 10:24:50 +00:00
21411b8f93 docs: update embed-events.mdx with all currently emitted embed events (#25099)
* docs: update embed-events.mdx with all currently emitted embed events

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* docs: remove V2 suffix from event names in documentation

Per feedback, the documentation should not expose internal versioning details.
Event names are now presented as clean, non-versioned names:
- bookingSuccessful (instead of bookingSuccessfulV2)
- rescheduleBookingSuccessful (instead of rescheduleBookingSuccessfulV2)
- dryRunBookingSuccessful (instead of dryRunBookingSuccessfulV2)
- dryRunRescheduleBookingSuccessful (instead of dryRunRescheduleBookingSuccessfulV2)

Added note about using wildcard listener for future-proofing.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* docs: use V2 suffix for embed event names to match code (#25263)

* docs: update embed events to use V2 event names

- Document bookingSuccessfulV2 instead of deprecated bookingSuccessful
- Document rescheduleBookingSuccessfulV2 instead of deprecated rescheduleBookingSuccessful
- Keep dryRunBookingSuccessful and dryRunRescheduleBookingSuccessful without V2 suffix (only V2 versions exist)
- Add comprehensive event documentation with all public and internal events
- Organize events into Public Events and Internal Events sections

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use V2 suffix for dry-run event names

- Change dryRunBookingSuccessful to dryRunBookingSuccessfulV2
- Change dryRunRescheduleBookingSuccessful to dryRunRescheduleBookingSuccessfulV2
- These match the actual event names emitted in the code (only V2 versions exist)

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2025-11-19 08:54:12 +00:00
Anik Dhabal Babu 0c160de404 fix: addtinonal notes isn't visisble (#25163) 2025-11-19 08:26:40 +00:00
a0eca13c18 feat: add organization-level autofill disable setting (#23504)
* feat: add organization-level autofill disable setting

- Create DisableAutofillOnBookingPageSwitch component following existing patterns
- Add toggle to organization general page alongside other settings
- Update tRPC organizations update handler to support new field
- Add organization-level check to useShouldBeDisabledDueToPrefill hook
- Add translation keys for new autofill disable setting
- Include database migration for disableAutofillOnBookingPage field
- Maintain backward compatibility with individual field settings

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: complete autofill disable implementation

- Add disableAutofillOnBookingPage to orgSettings type definition
- Update Prisma schema with new organization setting field
- Clean up test file formatting

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: resolve tRPC mocking issues in tests and add missing disableAutofillOnBookingPage to organization repository

- Fix tRPC module mocking in useShouldBeDisabledDueToPrefill tests
- Add disableAutofillOnBookingPage to organization repository select and return statements
- All form builder tests now pass (24/24)
- Organization-level autofill disable tests working correctly

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* test: simplify autofill disable test to single focused test

- Replace multiple tests with one test that verifies org setting blocks autocomplete
- Test includes searchParams with prefill data to verify blocking behavior
- Removes unnecessary test complexity as requested

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: add missing disableAutofillOnBookingPage to organizationSettings select statements

- Add disableAutofillOnBookingPage to both parent and main organizationSettings select statements in getTeamWithMembers
- Resolves TypeScript error in getServerSideProps.tsx where MinimumOrganizationSettings type requires this property
- Ensures organization settings type compatibility across the codebase

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Remove disableAutofillOnBookingPage setting

Removed 'disableAutofillOnBookingPage' setting from organization configuration.

* update

* Remove duplicate settings in common.json

Removed duplicate entries for automatic transcription and autofill settings.

* Fix syntax error in common.json

* update

* add tests

* Remove comments for autofill disabled check

Removed comments explaining scenarios for autofill check.

* addressed review

* fix

* change

* Add handling for disableAutofillOnBookingPage input

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 08:25:46 +00:00
Anik Dhabal Babu 5cda123a4c fix test flakes (#25240) 2025-11-19 09:57:10 +02:00
Udit Takkar 6169b92e98 fix: dialog click propagation (#25154) 2025-11-19 11:34:34 +05:30
cc1efe1298 fix: Conditional fetch cache (#24816)
* Fix cache to fetch only when it's available

* Non hierarchical feature check

* Fix tests: Add missing mock method and comprehensive CalendarCacheWrapper tests

- Add checkIfUserHasFeatureNonHierarchical to features.repository mock to fix failing GoogleCalendar tests
- Add comprehensive unit tests for CalendarCacheWrapper covering:
  - Calendars with sync only (cache-only path)
  - Calendars without sync only (original calendar path)
  - Mixed calendars (both cache and original)
  - Timezone handling with UTC defaults
  - Edge cases (empty arrays, undefined methods, null ids)
- Use proper types instead of 'as any' to satisfy lint rules

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Fix: Sanitize logging to avoid exposing PII

- Replace logging full selectedCalendars objects with only calendar IDs and count
- Prevents exposure of email fields and other sensitive information in logs
- Addresses AI code reviewer feedback

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Apply suggestion from @volnei

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 01:11:52 +00:00
Joe Au-YeungandDevin AI 7635d338c0 fix: increase dropdown z-index to appear above logo (#24057)
- Change dropdown z-index from z-10 to z-50 to ensure dropdowns appear above navigation elements
- TopNav uses z-40, so dropdowns need higher z-index to be properly visible
- Fixes issue where Cal.com logo was appearing above dropdown menus

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-18 20:36:03 +00:00
Udit Takkar 03ebabd6b4 fix: transcript endpoint (#25136) 2025-11-18 21:00:38 +02:00
Anik Dhabal Babu 0ab1bd0b6c fix: correct assignment reason badge mapping (#25255) 2025-11-18 17:16:04 +00:00
Anik Dhabal Babuandcubic-dev-ai[bot] 908e5e05f2 fix: routing-form org redirects when profile slug equals legacy slug (#25003)
* fix: routing-form org redirects when profile slug equals legacy slug

* update

* Update packages/app-store/routing-forms/getEventTypeRedirectUrl.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix type error

* addressed review

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-11-18 09:12:58 +00:00
Peer Richelsen 3490272815 feat: normalize routing form identifier field with URL-safe format (#25128)
## What does this PR do?

- Fixes #25116
- Fixes [CAL-6741](https://linear.app/calcom/issue/CAL-6741/make-routing-edit-question-form-less-intrusive-on-how-it-handles-the)

https://github.com/user-attachments/assets/d78c4c62-2af5-44d8-b25c-e938cc8ddf6f


Improves the routing form field identifier auto-fill behavior to generate URL-safe identifiers from labels. Previously, the identifier field simply duplicated the label text. Now it normalizes the input to be URL-friendly.

**Changes:**
- Converts labels to lowercase with hyphens (e.g., "What is your name?" → "what-is-your-name")
- Limits identifiers to the first 5 words (e.g., "What do you work on and how can we help?" → "what-do-you-work-on")
- Updates the Identifier label to clarify it's a URL parameter with an example
- Preserves manual identifier edits when the label changes

**Link to Devin run:** https://app.devin.ai/sessions/f569297990fe4436bab1fec89d8b71ac
**Requested by:** @PeerRich (peer@cal.com)

## Key Implementation Details

The `normalizeIdentifier` function:
- Strips special characters and replaces them with spaces
- Converts to lowercase
- Splits on whitespace and takes first 5 words
- Joins with hyphens

The auto-fill logic only updates the identifier if:
1. The identifier field is empty, OR
2. The identifier matches the normalized version of the previous label

This preserves manual edits while still providing helpful auto-fill for new fields.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox. **N/A** - This is a UI behavior change that doesn't require documentation updates.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works. **Note:** No automated tests were added for this change. Manual testing is recommended.

## How should this be tested?

**Test Cases:**

1. **Basic normalization:**
   - Create a new routing form field
   - Enter label: "What is your name?"
   - Verify identifier auto-fills to: "what-is-your-name"

2. **5-word limit:**
   - Enter label: "What do you work on and how can we help?"
   - Verify identifier becomes: "what-do-you-work-on"

3. **Special characters:**
   - Enter label: "Email (required)!"
   - Verify identifier becomes: "email-required"

4. **Manual edit preservation:**
   - Enter label: "Test Field"
   - Manually change identifier to: "custom-id"
   - Change label to: "New Test Field"
   - Verify identifier stays: "custom-id" (not auto-updated)

5. **Updated label text:**
   - Verify the Identifier field label shows: "Identifier (URL Parameter, i.e.: &what-is-your-name=john-doe)"

**Environment:**
- No special environment variables needed
- Test in the routing forms builder at `/apps/routing-forms/[formId]`

## Important Review Points

⚠️ **No automated tests**: The normalization function and auto-fill behavior lack test coverage. Consider adding unit tests for edge cases.

🔍 **Auto-fill logic**: The identifier only auto-updates if it's empty or matches the previous normalized label. This preserves manual edits but may be surprising to users in some scenarios.

🌍 **Unicode handling**: Non-ASCII characters are replaced with spaces. This may not be ideal for international users with non-English labels.

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings
2025-11-18 11:24:33 +05:30
Mauryan Kansara 02dab51543 fix: Prevent silent loss of changes in routing form when only one field exists (#25197) 2025-11-18 02:02:57 +00:00
Anik Dhabal Babu 358b873aa7 fix: unable to update username (#25221)
* unable to update username

* update

* Add import for useEffect and useState hooks
2025-11-18 01:55:12 +00:00
Anik Dhabal Babu 44aa26292d fix: flaky integrations tests (#25218)
* Revert "fix: resolve flaky integration tests (#25030)"

This reverts commit 4e5d4f67d5.

* update

* test

* Remove connection pool setup in Prisma index

Set the connection pool to undefined, removing conditional pooling logic.

* update
2025-11-18 00:04:24 +00:00
b8530e2d78 fix: delegation credential error webhooks + refactor repeated code (#25232)
* fix: delegation credential error webhooks

* refactor: extract repeated delegation credential error webhook logic into helper methods

- Added private triggerDelegationCredentialError method in Office365CalendarService class
- Added triggerDelegationCredentialError helper function in TeamsVideoApiAdapter
- Replaced all 4 instances in Office365CalendarService with helper method call
- Replaced all 4 instances in TeamsVideoApiAdapter with helper function call
- Keeps code DRY by eliminating repeated if statement and webhook trigger logic

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-18 00:00:42 +02:00
Dhairyashil ShindeandPallav 7f1b94ad19 style: hide icons from booking actions dialog in mobile view (#25147)
* style: hide icons from booking actions dialog in mobile view

* apply correct padding in mobile view

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-11-17 20:50:41 +00:00
Dhairyashil ShindeandMorgan 801ba50221 fix: empty event type array if no username (#25178)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-11-18 01:39:03 +05:30
spandevandDhairyashil Shinde 74af23136c fix: empty screen added in routing position page when no options are present (#25170)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-11-17 20:06:39 +00:00
Anik Dhabal Babu da9ee5c186 chore: Update test results repository to test-results-2 (#25199) 2025-11-17 23:06:03 +05:30
037cb8ee2a feat: add defaultPhoneCountry prop with ISO 3166-1 alpha-2 type safety (#25204)
* feat: add defaultPhoneCountry prop to BookerPlatformWrapper

- Add defaultPhoneCountry to BookerStore type and implementation
- Add defaultPhoneCountry prop to BookerPlatformWrapper types
- Pass defaultPhoneCountry through store initialization
- Update PhoneInput to use defaultPhoneCountry from store
- Support default phone country extension for phone inputs in booker form

* feat: add strict typing for defaultPhoneCountry with ISO 3166-1 alpha-2 codes

- Define CountryCode type using ISO 3166-1 alpha-2 country codes
- Update defaultPhoneCountry prop type in BookerPlatformWrapper to use CountryCode
- Update defaultPhoneCountry type in BookerStore to use CountryCode
- Ensures type safety by only allowing valid country codes like 'us', 'gb', 'ee', etc.
- Fix lint warnings by prefixing type-only constants with underscore

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: export CountryCode from store to avoid duplication

- Export CountryCode type from packages/features/bookings/Booker/store.ts
- Import CountryCode in packages/platform/atoms/booker/types.ts from store
- Remove duplicate CountryCode definition from types.ts
- Maintains single source of truth for country code type definition

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add type-safe casts for CountryCode in PhoneInput

- Import CountryCode type from store
- Add explicit type annotation to useState<CountryCode>
- Add safe type casts with isSupportedCountry validation
- Validate navigator.language country code before using it
- Fixes CI type error: string not assignable to CountryCode

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* docs: add defaultPhoneCountry prop documentation and changeset

- Add defaultPhoneCountry prop to booker.mdx documentation
- Add changeset for minor version bump
- Document ISO 3166-1 alpha-2 country code support

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2025-11-17 15:56:10 +00:00
sean-brydon f0e10129a1 test: Improve create teams handler tests (#25213)
I am refactoring create teams handler to a service in another PR - thought we should improve the test in the mean time.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Expand and restructure tests for createTeamsHandler to cover auth, org/slug validation, team creation and migration, redirects, credits, invites, and subscriptions. This improves reliability ahead of the service refactor.

- **Refactors**
  - Rewrote tests into scenario-based suites for Authorization, Organization Validation, Slug Validation, Team Creation/Migration, Redirects, and Edge Cases.
  - Added helpers (createTestProfile, flexible createScenario/createTestMembership) and organization/profile support to model slug collisions.
  - Assert TRPCError codes/messages and redirect records; cover platform orgs, unpublished/non-existent teams, and empty names.
  - Mocked Stripe subscription cancel and inviteMembersWithNoInviterPermissionCheck; verified credit transfer and owner memberships.

<sup>Written for commit 8c216c670faa85bf9a06a8895030f40808fdda0e. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-11-17 11:08:33 +00:00
Dhairyashil ShindeandPallav 7c5731e893 fix: german-translation-link-meeting (#25210)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-11-17 10:57:58 +00:00
spandevandPallav 1012f2f153 fix: made show all columns work correctly (#25106)
* fix: made show all columns work correctly

* test: added test for show all columns in ColumnVisibilityButton

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-11-15 22:01:01 +00:00
Emmanuel IsenahandDhairyashil Shinde d6f6be7d50 fix: correct square image validation logic in resizeBase64Image (#25130)
The validation was comparing image height to itself instead of comparing height to width, causing the square check to always pass even for non-square images.

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-11-16 01:50:50 +05:30
emrysal 9e10dfd77b chore: release v5.9.0
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-15 14:39:17 +00:00
spandevandEunjae Lee 82782fcf77 fix: added timezonebadge to insights/routing which appears on timezone mismatch (#25138)
* fix: added timezonebadge to insights/routing which appears on timezone mismatch

* update: removed user repository and directly used prisma

* clean up code

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2025-11-14 18:15:34 +00:00
emrysal 2477220d2d chore: release v5.8.14
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-14 17:45:48 +00:00
Anik Dhabal Babu 89fe869766 fix: Improve MS Teams app guidance in App Store (#25173) 2025-11-14 17:39:32 +00:00
Eunjae Lee 1f102bf3b4 fix: revert bookings redesign (#25172)
* Revert "refactor: extract logic as bookingDetailsSheetStore (#25129)"

This reverts commit 7a0b8a9eba.

* Revert "feat: bookings page redesign v3 with calendar view (#24664)"

This reverts commit 89230474a5.
2025-11-14 17:24:31 +00:00
Eunjae Lee 7a0b8a9eba refactor: extract logic as bookingDetailsSheetStore (#25129)
* refactor: extract logic as bookingDetailsSheetStore

* clean up

* revert something

* provide store from context
2025-11-14 14:50:20 +00:00
Anik Dhabal Babu 8043505f3a fix: prevent modal clicks from closing when used in booking list (#25153) 2025-11-14 11:47:34 +00:00
Eunjae Lee 919fc3cdd5 chore: fix seed-insights.ts (#25018) 2025-11-14 10:50:30 +01:00
Eunjae Lee d7e6334ccb refactor: remove useInsightsParameters() (#25020)
* refactor: remove useInsightsParameters (no longer needed)

* remove log
2025-11-14 10:50:22 +01:00
Hariom BalharaandDevin AI 06e5c9803a fix: allow whitelisted paths like onboarding as team/user slugs on org domains (#24984)
* fix: allow whitelisted paths like onboarding as team/user slugs on org domains

- Add whitelistedPaths array to pagesAndRewritePaths.js with 'onboarding'
- Update getRegExpMatchingAllReservedRoutes to accept exclusions parameter
- Modify org route patterns to exclude whitelisted paths from reserved routes
- Add tests to verify onboarding can be used as a slug on org domains
- Fixes issue where acme.cal.com/onboarding would 404

This allows teams/users on org domains to use 'onboarding' as their slug
while still preserving the /onboarding app route on non-org domains.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Remove accidental change by AI

* Add special character handling test

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-14 15:10:59 +09:00
emrysal 528b27f31e chore: release v5.8.13
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-14 02:32:38 +00:00
Alex van Andel 4282cd221c fix: NextJS does not support non-ascii in NextResponse headers (#25148)
* fix: NextJS does not support non-ascii in NextResponse headers

* Fixed type error
2025-11-14 01:27:17 +00:00
Dhairyashil ShindeandPallav 38738c1a3a fix: learn more link missing in add question (#25104)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-11-14 04:57:31 +05:30
Alex van Andel b5dcc7a991 fix: change edge runtime to prevent weird header override in unkey sdk (#25140) 2025-11-13 22:47:07 +00:00
Joe Au-YeungandDevin AI 5ceda11a0b fix: add 'use client' to routing-forms components to resolve React error 185 (#25107)
Adds 'use client' directive to FormInputFields.tsx and widgets.tsx in the
routing-forms package. These components use React hooks (useLocale, setState)
but were missing the client directive, causing React error 185 (invalid hook
call) in production builds due to Next.js App Router bundling differences.

The error only occurred in production, not local dev, because production
builds optimize and bundle packages differently. The widgets.tsx file uses
the useLocale hook in the Button component, and FormInputFields.tsx passes
state setters to child components.

Fixes the reroute dialog error reported in production.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-13 18:36:46 +00:00
787828d0ca feat: Toggle auto adding users to an org if they signup without an invite (#25051)
* Remove auto adding users to an org

* Update tests

* Fix tests

* fix: Update organization invitation E2E tests to not expect auto-accept before signup

- Changed isMemberShipAccepted expectations from true to false before signup
- Users with emails matching orgAutoAcceptEmail are no longer auto-accepted
- They must explicitly accept the invitation after signup
- Fixed lint warnings for unused parameters

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: Update E2E tests to expect pending membership after signup without auto-accept

Since auto-accept functionality was removed, users with emails matching
orgAutoAcceptEmail are no longer automatically accepted into organizations
after signup. They remain in pending state until explicitly accepted.

Updated assertions in:
- 'nonexisting user is invited to Org' test
- 'nonexisting user is invited to a team inside organization' test

Both tests now correctly expect isMemberShipAccepted: false after signup.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Restore `verify-email` and tests from `main`

* Add `orgAutoJoinOnSignup` to `organizationSettings`

* Update
`OrganizationRepository.findUniqueNonPlatformOrgsByMatchingAutoAcceptEmail`
to find orgs where `orgAutoJoinOnSignup` is true

* `organization.update` lint fix

* `organization.update` to handle `orgAutoJoinOnSignup`

* Create toggle for `orgAutoJoinOnSignup`

* test: Add comprehensive tests for orgAutoJoinOnSignup functionality

- Update existing test to expect null instead of error when multiple orgs match
- Add test for when orgAutoJoinOnSignup is false (should return null)
- Add test for when orgAutoJoinOnSignup is true (should return org)
- Add test for default behavior (orgAutoJoinOnSignup defaults to true)

These tests verify that the new orgAutoJoinOnSignup setting correctly controls
whether users are automatically added to organizations during email verification.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Type fix

* e2e: invited users should be accepted after signup (address cubic r2511916791)

Reverted post-signup isMemberShipAccepted assertions from false to true for
explicit invite scenarios. When users are explicitly invited to an org/team
and complete signup via invite link, their membership should be accepted.

This is distinct from auto-join by domain (controlled by orgAutoJoinOnSignup),
which only affects users who sign up without an invite but match the org's
email domain.

Backend sets membership.accepted = true on invite completion in:
packages/features/auth/signup/utils/createOrUpdateMemberships.ts:61,67,77,83

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Fix API V2 build

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-13 15:13:10 -03:00
89230474a5 feat: bookings page redesign v3 with calendar view (#24664)
* bookings page redesign work in progress

fix: duplicate translation key

chore: use newly supported separator type

remove outdated BookingDetailsSheet

remove dropdown and related code

revert unncessary changes

* fix wrong rebase

* fix type error

* refactor: separate bookings columns into filter and display columns (#24959)

* refactor: separate bookings columns into filter and display columns

- Extract filter-only columns into shared filterColumns.ts
- Extract list display columns into listColumns.tsx
- Create BookingsListContainer for list view with both column sets
- Create BookingsCalendarContainer for calendar view with filter columns only
- Refactor bookings-view.tsx to use dynamic imports for containers
- Remove column/table creation logic from bookings-view.tsx

This ensures calendar view doesn't import list-specific UI components (AvatarGroup, Badge, etc.)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: return null instead of false for separator rows in filter accessors

The filter accessor functions were returning false for separator rows instead of null,
which would pollute the multi-select filters with bogus 'false' values.

This fix ensures that separator rows return null so they are properly excluded from filters.

Addresses cubic AI reviewer feedback on PR #24959

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up filter column visibility

* feat: integrate booking calendar view with re-designed list (#24973)

* add toggle button

* remove the dateRange filter when switching from calendar to list view

* move "view" to the action dropdown

* add close button the details sheet

* move close button

* fix more button behavior

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix type error

* update the test case

* fix e2e util

* fix actions dropdown

* revert e2e tests

* fix type error on BookingActionsDropdown.tsx

* fix: include today's bookings in flatData for past status

Previously, flatData excluded groupedBookings.today, which caused
past bookings that happened today to not show up when status === 'past'.
This fix includes today's bookings in flatData for all statuses.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* improve attendee cell

* fix e2e tests

* change max

* fix e2e

* add reschedule requested message

* fix e2e

* update e2e

* remove flaky checks

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-13 16:20:48 +00:00
d7fc11df5e feat: use form responses as workflow variables (#24716)
* remove add variable dropdown

* feat: lang support

* fix: type errors

* feat: select voice agent

* refactor: address feedback

* refactor: address feedback

* refactor: missing import

* fix: types

* add getAllWorkflowsFromRoutingForm to WorkflowService

* fix error caused by undefined evt

* fix type error

* fix type error

* fix tests

* feat: add inbound calls

* chore: formatting

* chore

* feat: finish inbound call

* chore: formatting

* fix: update bug

* fix: types

* code clean up

* final fixes and clean up

* remove console.log

* remove template text form from triggers

* add routing form repoditory function

* refactor: Agent Configuration Sheet (#23930)

* refactor: agent configuration sheet

* chore: use default phone numbre

* refactor: improvements

* refactor: improvements

* fix: types

* fix: feedback

* fix bug with key

* chore:

* fix: feedback

* fix: prompt

* add comments

* fix: review

* fix: review

* refactor: class

* refactor: class

* fix test

* allow cal ai action on form triggers

* move any reusable code to scheduleAIPhoneCall

* add missing await

* use predefined FormSubmissionData type

* add .trim() to sms message

* pass contextData instead

* finish base setup

* add missing trigger in update-workflow.input.ts

* allow cal.ai action for form triggers in handler

* chore: add support for form workflows on api v2

* fixup! chore: add support for form workflows on api v2

* ai phone call on form submissions (WIP)

* use existing type for Option array

* pass chosen event type id

* refactor: rename

* Update apps/web/public/static/locales/en/common.json

* Update apps/web/public/static/locales/en/common.json

* add missing imports

* chore: update set value

* fix: remove index

* fix: type error

* fix: update tetss

* use only repository functions in update handler

* move all prisma queries from list.handler

* review suggestions

* fix: use logger

* chore: handle workflows api v2

* chore: handle workflows api v2, split in 2 endpoints

* fix workflow step creation

* remove connect agent and fixes types

* add type to workflow

* chore: use workflow type in apiv2 WorkflowsOutputService

* update worklfow type on update

* chore: use workflow type in apiv2 WorkflowsOutputService

* fix template body for torm trigger

* some UI fixes for email subject/body

* resetting email body when changing form triggers

* use type field to query workflows

* clean up all old active on values

* remove responseId from all funciton calls

* remove undefined from updateTemplate

* refactor: don't use static

* fix: type

* refactor: split routing form and event-type workflows code

* refactor: split routing form and event-type workflows code

* fix template  text when adding action

* chore: don't rename WorkflowActivationDto to avoid ci blocking

* refine update schedule to use only allowed actions

* fix type error

* don't allow whatsapp action with form trigger

* fix type error

* return early if activeOn array is empty

* fix: from step type in BaseFormWorkflowStepDto

* fixup! fix: from step type in BaseFormWorkflowStepDto

* api v2 updates

* move all prisma calls to repository (service/workflows.ts)

* use FORM_TRIGGER_WORKFLOW_EVENTS for form queries

* use userRepository

* use FORM_TRIGGER_WORKFLOW_EVENTS in isFormTrigger

* code clean up

* code clean up

* use repository functions in formSubmissionValidation.ts

* fix: schema

* refactor:

* remove action check in update handler

* add event type selection

* event type selector improvements

* adjust update.handler

* set outboundEventTypeId

* add back trpc  import

* fix agent repository functions

* clean up

* fix bugs caused by merge

* pass eventTypeId to updateToolsFromAgentId

* add migration for outboundEventTypeId

* add SMS actions to allowed form action constants

* add cal ai to allowed form actions

* pick correct event type for web call

* pass correct routed event type id

* remove unsued import

* fixes for offset api v2

* add missing responseId

* fix failing test

* fix failing test

* improve error message

* remove unused imports

* chore: handle sms step action for form worklfow in dtos

* fix typo

* missing missing newStep

* minor fixes

* remove changes

* add routedEventTypeId

* fix type error

* fix type error

* fix typ error in executAPIPhoneCall.tsx

* add back inboundEventTypeId

* remove console.log

* remove outdated code

* small fixes

* don't throw error for missing phone number

* add  back filtered triggerOptions

* fix eventTypeId in testCall handler

* fix type error

* update migration

* fix trigger is not defined

* convert eventTypeId to string

* only use outboundEventTypeId for FORM_SUBMITTED trigger

* show toast when no event type selected

* fix type errors

* add missing translation

* fix type error

* remove callType

* fix tests

* small fixes

* clean up AgentConfigurationSheet

* remove EventTypeSelector file

* code clean up

* clean up

* clean up

* use resusable function for TestPhoneCallDialog and WebCallDialog

* rename result

* fix types for event type id

* use repository runction in workflowReminder.ts

* fix type error

* pass eventTypeIds correctly

* fix typo

* custom variables from form responses

* remove comment

* Update apps/web/public/static/locales/en/common.json

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>

* use watch instead of getValues

* change to  z.record(z.unknown()) instead of any()

* fix type of eventTypeId

* check permissinon for outBoundEventTypeId

* add isNaN check

* improve function name

* add tests

* fixes for custom variables

* improve test

* update tools when outbound agent event type id changes

* handle undefined eventDate in customTemplate

* add info how to use form responses as variables

* rename responses to routingFormResponses

* remove cal ai from allowed steps api v2

* remove old migration file

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2025-11-13 15:34:44 +00:00
Udit TakkarandHariom Balhara 1ff5d57ded feat: distributed tracing - 2 (#24861)
* feat: distributed tracing 2

* feat: distributed tracing 2

* refactor: feedback

* refactor: feedback

* fix: type error

* fix: trpc error

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2025-11-13 11:51:54 +00:00
sean-brydon 19641ffc05 feat: organization v3 redesign onboarding (#24967)
## What does this PR do?

- Redesigns the organization onboarding flow by merging the brand and details pages
- Improves the organization details page with a scrollable interface and visual previews
- Adds a new organization-specific browser preview component

## Visual Demo (For contributors especially)

#### Image Demo:
- The PR replaces the separate brand page with an integrated details page that includes logo and banner uploads
- The new organization browser view shows a preview of the organization profile with the selected branding

## Mandatory Tasks (DO NOT REMOVE)

- [ ] I have self-reviewed the code.
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

- Go through the organization onboarding flow
- Test uploading logos and banners
- Verify that the organization browser preview updates in real-time with the form inputs
- Confirm that the form validation works correctly for organization name and slug
- Check that the scrollable interface works properly with fade effects at top and bottom

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings

















































<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Split organization brand from the details step and added live previews for organizations and teams. Revamped org/team invites with reusable components, a dedicated email-invite page, and a CSV upload modal.

- **New Features**
  - Separate Brand step with logo, banner, and color; instant org preview via OnboardingOrganizationBrowserView.
  - Teams browser preview added; invites include email substep (/onboarding/organization/invite/email, /onboarding/teams/invite/email), CSV upload (template + parsing), and Google Workspace (behind flag).
  - Shared components (EmailInviteForm, InviteOptions, RoleSelector) used across org and team invites.

- **Refactors**
  - Updated org flow: Details → Brand → Teams → Invites; OnboardingLayout now supports dynamic step counts (org=4, team=3, personal=2).
  - UI polish (OnboardingCard header padding) and org-specific previews now replace generic views across details/brand/invites/teams; ensured org welcome modal takes precedence over personal.

<sup>Written for commit d9b55c0b5505aa0d4ca1c4298a513bcd90606915. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-11-13 10:45:42 +00:00
Eunjae LeeandDevin AI ea80e8c8d4 fix: enable webhook form submit button when all required fields are filled (#25109)
* fix: enable webhook form submit button when all required fields are filled

The submit button was disabled even when all fields were filled because
the form relied on isDirty state. Since eventTriggers are pre-populated
with default values, the form never became dirty until the user manually
changed the triggers.

This fix adds validation logic that:
- For new webhooks: checks if required fields (URL, triggers) are filled
- For editing webhooks: preserves the existing isDirty behavior
- Handles the conditional time/timeUnit requirement for no-show triggers

Fixes the issue where users had to manually change event triggers to
enable the submit button even though all required information was filled.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: extract webhook form validation logic to computed variables

Replaced IIFE in disabled prop with clean computed variables:
- Extracted all watch() calls to the top of the component
- Computed validation logic as clear, named variables
- Reused needsTime for showTimeSection to avoid duplicate watch calls
- Simplified button disabled prop to just !canSubmit

This improves code readability and maintainability while preserving
the same validation behavior.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: resolve type error by moving canSubmit computation after changeSecret declaration

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: auto-initialize time/timeUnit for webhooks with no-show triggers

When creating a webhook with default event triggers that include no-show
triggers (AFTER_HOSTS_CAL_VIDEO_NO_SHOW or AFTER_GUESTS_CAL_VIDEO_NO_SHOW),
the time and timeUnit fields are now automatically initialized to default
values (5 minutes). This ensures the submit button is enabled when all
required fields are filled, fixing E2E test failures in webhook.e2e.ts.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-13 10:32:17 +00:00
Benny JooandDevin AI cba0fa8551 chore: Clean up billing-related redundant files (#25060)
* remove billing service factory

* remove index file

* update internal team billing

* update test

* fix unit test

* fix: update internal-team-billing tests to use direct StripeBillingService mocking

- Changed mock path from @calcom/features/ee/billing/stripe-billing-service to ../stripe-billing-service to match actual import
- Used vi.hoisted() to ensure mock functions are available in hoisted mock factory context
- Changed vi.resetAllMocks() to vi.clearAllMocks() and re-apply mock implementation in beforeEach to preserve constructor mock
- Removed obsolete vi.mock("..") for deleted billing singleton module
- Fixed test pollution by creating new instances instead of mutating shared state
- Removed describe-level instance creation that was executed before mocks were set up
- All 12 tests now pass successfully

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-13 09:17:36 +00:00
Alex van Andel 530cb94f0b fix: make identifier url safe 2 (#25112)
* fix: Make identifier for rate limit URL safe

* fix: Make identifier for rate limit URL safe using hasing
2025-11-13 01:42:13 +00:00
Alex van Andel d4ef6e83cf fix: Make identifier for rate limit URL safe (#25111) 2025-11-13 01:20:05 +00:00
Alex van Andel cddd8d7d9d Revert "chore: Rate limit top level of public booking pages (#25055)" (#25086)
This reverts commit e239b67171.
2025-11-12 22:13:50 +00:00
Alex van AndelandVolnei Munhoz 1d6959c4ac chore: system wide ratelimit per path (#25080)
* chore: Add system wide rate limiting

* Handle and convert HttpError to 429

* Make algo 32-bit to prevent <ES2020 error + fix sms manager unit test

* Change core to common to go from 10 requests per minute to 200

* Remove redundant function

* Fix integration tests

* Make sure we allow all legal POST routes

* Allow tRPC post calls

* Add matcher tests on middleware

* Add matcher tests on middleware

* Fix matcher to not use regex

* Fix missing POST allow rule for /api/auth/callback/credentials

* Missed the api/book/event endpoints

* Add missing pages/api routes

* Remove POST middleware for now, very risky

* Remove tests for POST protection

---------

Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
2025-11-12 22:01:59 +00:00
Anik Dhabal BabuandDevin AI a3fc17bc75 fix: add team installation support for HitPay payment integration (#24738)
- Add teamId support to HitPay add.ts installation handler
- Update callback.ts to fetch credentials by teamId for team bookings
- Update webhook.ts to fetch credentials by teamId for team bookings
- Update setup page to accept and handle teamId from query params
- Add permission checks using throwIfNotHaveAdminAccessToTeam
- Ensure credentials are created with teamId for team installs, userId for user installs

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-12 21:58:17 +05:30
ad4b5957fc refactor: optimize credit-service imports with lazy loading (#25091)
* refactor: optimize credit-service imports with lazy loading

- Remove top-level imports of heavy modules (reminderScheduler, email services, i18n, billing services)
- Implement dynamic imports for modules only when needed:
  - reminderScheduler: loaded only when SMS credit limit reached
  - email services: loaded only when sending credit notifications
  - getTranslation: loaded only when handling low credit balance
  - InternalTeamBilling: loaded only in getMonthlyCredits method
  - billing singleton: loaded only when calculating warning limits
- Break circular dependency: credit-service → reminderScheduler → ... → credit-service
- Update tests to mock StripeBillingService for dynamic imports
- All 30 tests passing, no type errors, lint clean

This reduces baseline import cost by deferring:
- Stripe SDK initialization (loaded twice before)
- 557KB+ i18n English translation file
- Email template classes
- Workflow reminder scheduler

Verified with madge: circular dependency successfully resolved

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add null checks for billing.getPrice() return value

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-13 00:40:51 +09:00
a7cb71726a fix: hide duplicate phone field when attendee phone location selected (#23118)
* fix: hide duplicate phone field when attendee phone location selected

* Instead of hiding use autofill the value to all other phone fields

* add e2e test

* add not sync test and use changeHandler instead of useEffect

* address cubics comments

* adding the phone check back

* use zod schema instead of this type casting

* use Enum instead of hardcoded string for phone

* Fix e2e test

* Fix e2e tests

* Delete .retracify.html

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2025-11-12 13:54:36 +00:00
chauhan_s 3e7a848769 refactor: extract back button logic into dedicated wrapper component (#25093)
* refactor: extract back button logic into dedicated wrapper component

* Added changeset
2025-11-12 11:19:35 +00:00
sean-brydon e6e67848b3 fix: Polish, fixes, and i18n updates for onboarding (#24949)
## What does this PR do?

<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->

- Fixes #XXXX (GitHub issue number)
- Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

## Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change **(video / image - any one)**.

#### Video Demo (if applicable):

- Show screen recordings of the issue or feature.
- Demonstrate how to reproduce the issue, the behavior before and after the change.

#### Image Demo (if applicable):

- Add side-by-side screenshots of the original and updated change.
- Highlight any significant change(s).

## Mandatory Tasks (DO NOT REMOVE)

- [ ] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests -->

- Are there environment variables that should be set?
- What are the minimal test data to have?
- What is expected (happy path) to have (input and output)?
- Any other important info that could help to test that PR

## Checklist

<!-- Remove bullet points below that don't apply to you -->

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my changes generate no new warnings








































<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Polished the onboarding experience with a live calendar preview, a team bio field, and improved username handling. Updated i18n strings and added responsive breakpoints for large screens.

- **New Features**
  - Added right-column previews: OnboardingBrowserView in org teams and a live weekly OnboardingCalendarBrowserView for personal calendar setup.
  - Introduced team bio in onboarding store and UI.
  - Expanded i18n: team bio, browser view labels, and CSV invite flow.
  - Added Tailwind screens for 3xl and 4xl to improve large-display layouts.

- **Bug Fixes**
  - Normalized usernames with slugify on default and change to prevent invalid slugs.
  - Unified disabled/readonly handling for premium vs. standard username fields; respects external disabled prop and org membership.

<sup>Written for commit 7804fad66ee516b25e22fc0d9239f3d29249189a. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-11-12 10:07:06 +00:00
Lauris Skraucis bf42cd4de9 fix: v2 get event type by id return type (#25090) 2025-11-12 09:26:07 +00:00
chauhan_s 6af7f8b0db fix: add recurringEventCount to URL params (#24986)
* fix: validate occurrence count from URL params and refactor validation logic
- Initialize occurrence count from URL query parameter on page load

* fix: change query parameter name from occurenceCount to recurringEventCount

* refactor: simplify occurrence count validation logic

* fix: prevent NaN from being set in recurring event count query parameter

* fix: prevent overlay calendar toggle from overwriting query params

* fix: sync occurrence count state with max occurrences limit

* refactor: rename occurenceCount to recurringEventCountQueryParam

* fix: prevent invalid recurring event count from updating state

- Added validation guard to only update state when recurringEventCountQueryParam is valid (not null or NaN)
- Simplified URL update logic by removing unnecessary empty string fallback

* feat: add recurring event count badge for mobile (#24991)

* feat: display recurring event count badge in mobile

* feat: update recurring event translation key for clarity
2025-11-12 09:12:49 +00:00
Benny JooandMorgan 421d03eb1a import stripe billing service dynamically in credit-service (#25058)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-11-12 10:18:16 +02:00
mintlify[bot] 9d39742802 Add API v1 deprecation banners (#25065)
* Update docs/api-reference/v1/introduction.mdx

* Update docs/api-reference/v1/authentication.mdx

* Update docs/api-reference/v1/errors.mdx

* Update docs/api-reference/v1/rate-limit.mdx

* Update docs/mint.json

---------

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2025-11-12 04:07:28 +00:00
Joe Au-Yeung 5267f8c3c1 Escape special characters in email query (#25079) 2025-11-11 23:56:51 +00:00
Alex van Andel c6ec42e735 chore: Add diagnostics tool for confirming visitor IP (#25083) 2025-11-11 23:56:36 +00:00
Hariom BalharaandVolnei Munhoz 1325e8488f feat: Reduce webhook response payload to status-only (#25072)
* feat: reduce webhook payload

* Update packages/trpc/server/routers/viewer/webhook/testTrigger.handler.ts

Co-authored-by: Volnei Munhoz <volnei@cal.com>

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2025-11-11 17:18:05 +00:00
Dhairyashil ShindeandUdit Takkar d50a7b9d00 feat: custom-labels-for-attendee-location-fields (#25070)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-11 17:17:35 +00:00
Anik Dhabal Babu 452729f4ab fix: skip email verification for reschedules (#25061) 2025-11-11 16:52:11 +00:00
0206b364ee feat: add tooltip to Group Options label in attributes form (#25063)
* feat: add tooltip to Group Options label in attributes form

- Add InfoBadge component to Group Options label with descriptive tooltip
- Add translation keys 'group_options' and 'group_options_description' to common.json
- Update label to use flex layout for proper InfoBadge alignment
- Tooltip explains that group options create logical groupings of regular options

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: wrap AttributeForm tests with TooltipProvider

- Add Tooltip.Provider wrapper from @radix-ui/react-tooltip to test renders
- Fixes failing tests caused by InfoBadge component requiring tooltip context
- All AttributeForm tests now pass locally

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-11 16:44:14 +00:00
Eunjae Lee 86353191d2 feat: add booking actions into BookingDetailsSheet (#24912)
* move booking actions into a subfolder

* fix logic to render booking actions dropdown

* skip dropdown portal when rendered from detail sheet

* fix type error
2025-11-11 16:14:48 +00:00
spandev 38f96d97d3 fix: added empty screen for routing response results table (#25076) 2025-11-11 15:15:06 +00:00
e6d44ce620 feat: Add delegation credential error webhook trigger (#24871)
* feat: add delegation credential error webhook trigger

- Add DELEGATION_CREDENTIAL_ERROR to WebhookTriggerEvents enum
- Create DelegationCredentialErrorDTO type for webhook payload
- Implement DelegationCredentialErrorWebhookService
- Add translation for delegation_credential_error
- Enable webhook for API v2 organization webhooks

This webhook will send delegation credential error data to configured URLs when errors occur during calendar authentication with delegation credentials.

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: add delegation credential error payload type and type guards

- Add DelegationCredentialErrorPayloadType to sendPayload.ts
- Update WebhookPayloadType union to include new payload type
- Add isDelegationCredentialErrorPayload type guard function
- Update isEventPayload to exclude delegation credential errors
- Update template application logic to handle new payload type
- Add corresponding payload type to dto/types.ts for consistency

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* feat: add delegation credential error handling to WebhookNotificationHandler

- Add DELEGATION_CREDENTIAL_ERROR case to createPayload switch
- Return payload with error, credential, and user data
- Ensures exhaustive type checking passes for new trigger

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* feat: restrict DELEGATION_CREDENTIAL_ERROR to organization webhooks only

- Add validation in UserWebhooksService to reject DELEGATION_CREDENTIAL_ERROR
- Add validation in EventTypeWebhooksService to reject DELEGATION_CREDENTIAL_ERROR
- Ensures trigger is only available for API v2 organization webhooks as requested

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* feat: wire up delegation credential error webhook emission in calendar services

- Add webhook emission calls in CalendarAuth.ts for Google Calendar delegation errors
- Add webhook emission calls in Office365 CalendarService.ts for Azure AD delegation errors
- Implement actual webhook emission using WebhookRepository pattern
- Fix pre-existing lint warnings in Office365 CalendarService.ts (unused catch variables, unsafe optional chaining)

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* test: add e2e tests for DELEGATION_CREDENTIAL_ERROR webhook trigger

- Add comprehensive e2e tests for creating, retrieving, updating, and deleting webhooks with DELEGATION_CREDENTIAL_ERROR trigger
- Test combining DELEGATION_CREDENTIAL_ERROR with other triggers
- Fix import in triggerDelegationCredentialErrorWebhook.ts to use default import for sendPayload
- Tests follow existing patterns in organizations-webhooks.e2e-spec.ts

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* refactor: remove name field from webhook payload and delete unused service

- Remove name field from triggerDelegationCredentialErrorWebhook function signature and payload
- Update all call sites in GoogleCalendar and Office365 calendar services
- Update DelegationCredentialErrorDTO and DelegationCredentialErrorPayloadType to remove name field
- Delete unused DelegationCredentialErrorWebhookService.ts (dead code - not used anywhere)
- The helper function approach is more appropriate for app-store integrations without DI

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* refactor: make fire-and-forget intent explicit for webhook emission

- Add void cast to all triggerDelegationCredentialErrorWebhook calls
- Remove redundant .catch() handlers (helper already handles errors internally)
- This makes it clear that webhook emission is non-blocking by design
- Avoids delaying error propagation while webhook HTTP requests complete

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* feat: await webhook emission and add HTTP timeout for guaranteed delivery

- Change all triggerDelegationCredentialErrorWebhook calls from void to await
- Add 10-second timeout to webhook HTTP requests using AbortController
- Remove name field from DelegationCredentialErrorPayloadType to match payload
- Ensures webhooks are sent before error is thrown (per user requirement)
- Prevents indefinite hangs on unresponsive webhook endpoints

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: make getAuthUrl async and await all call sites

- Make getAuthUrl async to support awaiting webhook emission
- Add await to all 3 getAuthUrl call sites (constructor, getAzureUserId, testDelegationCredentialSetup)
- Remove leftover name field from getAzureUserId webhook call
- Fixes TS1308 error about await in non-async function

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* docs: add JSDoc clarifying error handling guarantees for webhook trigger

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* Revert "docs: add JSDoc clarifying error handling guarantees for webhook trigger"

This reverts commit 3e33090197bfe2f2e3fb890402b32e04c44305e3.

* Revert "fix: make getAuthUrl async and await all call sites"

This reverts commit de28b7337149104412c861fd9b05e76fffc1fed7.

* Revert "feat: await webhook emission and add HTTP timeout for guaranteed delivery"

This reverts commit 9da7241f83a8373b4fadc03ccf34e097c28adf3a.

* Revert "refactor: make fire-and-forget intent explicit for webhook emission"

This reverts commit f4f7fa06b7dfa151bfbea29905b8783261d9f353.

* feat: await webhook emission to match standard pattern

- Updated all webhook call sites to await triggerDelegationCredentialErrorWebhook
- Made getAuthUrl async and updated all 3 call sites to await it
- Removed .catch() wrappers at call sites (error handling is in trigger function)
- Matches standard pattern used in WebhookService.sendPayload with Promise.allSettled
- Ensures webhooks are sent before delegation errors are thrown

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: address PR feedback - add migration, remove 'as any', remove user.name

- Add Prisma migration for DELEGATION_CREDENTIAL_ERROR enum
- Replace 'as any' type casting with safe type-narrowing helper in CalendarAuth.ts
- Remove user.name field from DelegationCredentialErrorPayloadType (email is sufficient)
- Ensure all type definitions are consistent across sendPayload.ts and dto/types.ts

Addresses feedback from alishaz-polymath and morgan@cal.com

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* chore: cleanup type in CalendarAuth

* fix: missing DELEGATION_CREDENTIAL_ERROR in WEBHOOK_TRIGGER_EVENTS_GROUPED_BY_APP constant

* fix: review

* fit: import webhook dto

* fit: type error

* feat: add delegation credential error webhook handling to Office365 video adapter

- Emit webhook before throwing delegation credential errors in Office365 video
- Added webhook emission in 4 locations:
  1. Missing clientId/Secret in fetchNewTokenObject
  2. Missing tenantId in getAuthUrl
  3. Missing clientId/Secret in getAzureUserId
  4. User doesn't exist in Azure AD
- Made getAuthUrl async to support webhook emission
- Follows same pattern as GoogleCalendar and Office365Calendar implementations

Co-Authored-By: morgan@cal.com <morgan@cal.com>
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fixup! Merge branch 'devin/delegation-credential-errors-webhook-1762171203' of https://git-manager.devin.ai/proxy/github.com/calcom/cal.com into devin/delegation-credential-errors-webhook-1762171203

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: cal.com <morgan@cal.com>
2025-11-11 16:02:06 +02:00
9e1e50e90b feat: cal.ai form triggers #4 (#23587)
* add trigger

* small fixes

* add missing workflow DTOs

* small fixes

* use activeOnWithChildren

* fix active on when switching trigger type

* remove add variable dropdown

* feat: lang support

* fix: type errors

* feat: select voice agent

* refactor: address feedback

* refactor: address feedback

* refactor: missing import

* fix: types

* add getAllWorkflowsFromRoutingForm to WorkflowService

* fix error caused by undefined evt

* fix type error

* fix type error

* fix tests

* feat: add inbound calls

* chore: formatting

* chore

* feat: finish inbound call

* chore: formatting

* fix: update bug

* fix: types

* code clean up

* final fixes and clean up

* remove console.log

* remove template text form from triggers

* add routing form repoditory function

* refactor: Agent Configuration Sheet (#23930)

* refactor: agent configuration sheet

* chore: use default phone numbre

* refactor: improvements

* refactor: improvements

* fix: types

* fix: feedback

* fix bug with key

* chore:

* fix: feedback

* fix: prompt

* add comments

* fix: review

* fix: review

* refactor: class

* refactor: class

* fix test

* allow cal ai action on form triggers

* move any reusable code to scheduleAIPhoneCall

* add missing await

* use predefined FormSubmissionData type

* add .trim() to sms message

* pass contextData instead

* finish base setup

* add missing trigger in update-workflow.input.ts

* allow cal.ai action for form triggers in handler

* chore: add support for form workflows on api v2

* fixup! chore: add support for form workflows on api v2

* ai phone call on form submissions (WIP)

* use existing type for Option array

* pass chosen event type id

* refactor: rename

* Update apps/web/public/static/locales/en/common.json

* Update apps/web/public/static/locales/en/common.json

* add missing imports

* chore: update set value

* fix: remove index

* fix: type error

* fix: update tetss

* use only repository functions in update handler

* move all prisma queries from list.handler

* review suggestions

* fix: use logger

* chore: handle workflows api v2

* chore: handle workflows api v2, split in 2 endpoints

* fix workflow step creation

* remove connect agent and fixes types

* add type to workflow

* chore: use workflow type in apiv2 WorkflowsOutputService

* update worklfow type on update

* chore: use workflow type in apiv2 WorkflowsOutputService

* fix template body for torm trigger

* some UI fixes for email subject/body

* resetting email body when changing form triggers

* use type field to query workflows

* clean up all old active on values

* remove responseId from all funciton calls

* remove undefined from updateTemplate

* refactor: don't use static

* fix: type

* refactor: split routing form and event-type workflows code

* refactor: split routing form and event-type workflows code

* fix template  text when adding action

* chore: don't rename WorkflowActivationDto to avoid ci blocking

* refine update schedule to use only allowed actions

* fix type error

* don't allow whatsapp action with form trigger

* fix type error

* return early if activeOn array is empty

* fix: from step type in BaseFormWorkflowStepDto

* fixup! fix: from step type in BaseFormWorkflowStepDto

* api v2 updates

* move all prisma calls to repository (service/workflows.ts)

* use FORM_TRIGGER_WORKFLOW_EVENTS for form queries

* use userRepository

* use FORM_TRIGGER_WORKFLOW_EVENTS in isFormTrigger

* code clean up

* code clean up

* use repository functions in formSubmissionValidation.ts

* fix: schema

* refactor:

* remove action check in update handler

* add event type selection

* event type selector improvements

* adjust update.handler

* set outboundEventTypeId

* add back trpc  import

* fix agent repository functions

* clean up

* fix bugs caused by merge

* pass eventTypeId to updateToolsFromAgentId

* add migration for outboundEventTypeId

* add SMS actions to allowed form action constants

* add cal ai to allowed form actions

* pick correct event type for web call

* pass correct routed event type id

* remove unsued import

* fixes for offset api v2

* add missing responseId

* fix failing test

* fix failing test

* improve error message

* remove unused imports

* chore: handle sms step action for form worklfow in dtos

* fix typo

* missing missing newStep

* minor fixes

* remove changes

* add routedEventTypeId

* fix type error

* fix type error

* fix typ error in executAPIPhoneCall.tsx

* add back inboundEventTypeId

* remove console.log

* remove outdated code

* small fixes

* don't throw error for missing phone number

* add  back filtered triggerOptions

* fix eventTypeId in testCall handler

* fix type error

* update migration

* fix trigger is not defined

* convert eventTypeId to string

* only use outboundEventTypeId for FORM_SUBMITTED trigger

* show toast when no event type selected

* fix type errors

* add missing translation

* fix type error

* remove callType

* fix tests

* small fixes

* clean up AgentConfigurationSheet

* remove EventTypeSelector file

* code clean up

* clean up

* clean up

* use resusable function for TestPhoneCallDialog and WebCallDialog

* rename result

* fix types for event type id

* use repository runction in workflowReminder.ts

* fix type error

* pass eventTypeIds correctly

* fix typo

* Update apps/web/public/static/locales/en/common.json

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>

* use watch instead of getValues

* change to  z.record(z.unknown()) instead of any()

* fix type of eventTypeId

* check permissinon for outBoundEventTypeId

* add isNaN check

* improve function name

* update tools when outbound agent event type id changes

* pass missing outboundEventTypeId

* update migration

* fix test

* remove cal-ai step from test

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2025-11-11 15:24:31 +02:00
a73b804d48 refactor: Split EmailManager into focused service files (#24997)
* refactor: Split EmailManager into focused service files

- Created separate service files for different email categories:
  - auth-email-service.ts: Authentication and verification emails
  - organization-email-service.ts: Organization and team emails
  - billing-email-service.ts: Payment and credit-related emails
  - integration-email-service.ts: Integration and app-related emails
  - workflow-email-service.ts: Workflow and custom emails
  - recording-email-service.ts: Recording and transcript emails

- Refactored email-manager.ts to keep only core booking lifecycle functions
- Removed unused imports from email-manager.ts
- Updated index.ts to export from all new service files
- Updated all imports across the codebase to use package root (@calcom/emails)
- Fixed lint warnings in handleChildrenEventTypes.ts

This reduces the import cost of EmailManager by allowing consumers to import only the specific email services they need.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: Update all imports to use direct service file paths

- Update 49 files to import directly from service files instead of barrel file
- Update packages/emails/index.ts to keep only email-manager and renderEmail exports
- Fix dynamic import in passwordResetRequest.ts
- Update renderEmail imports to use direct path
- Update test file to import from specific service module
- Fix ESLint warnings in modified files (unused variables, unused expressions)

This ensures consumers only import the specific email services they need,
reducing import cost by avoiding the barrel file pattern for service files.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: Use default import for renderEmail

renderEmail is exported as a default export, not a named export.
Changed from 'import { renderEmail }' to 'import renderEmail'.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: Update test mocks to use direct service file imports

- Update handleNoShowFee.test.ts to mock @calcom/emails/billing-email-service
- Update credit-service.test.ts to mock @calcom/emails/billing-email-service
- These tests were failing because they were mocking the barrel file @calcom/emails
  which no longer exports service functions after the refactoring

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: unit test spy

* fix: unit test mock

* address cubic comments

* fix: type error sendMonthlyDigestEmail

* remove barrel file and sendEmail unused task

* fixup! remove barrel file and sendEmail unused task

* fixup! fixup! remove barrel file and sendEmail unused task

* fix: integration test mock emails

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: hbjORbj <sldisek783@gmail.com>
2025-11-11 14:21:10 +02:00
4407a1952c feat: add booking details sheet for /bookings (#24795)
* spike: initial booking detail sheet

* rename button

* revert some changes

* remove unnecessary test

* disable booking details sheet

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-11 08:40:55 -03:00
sean-brydon dc3742d322 chore: Add calendar weekly view enhancements and welcome modal feature (#24948)
## What does this PR do?

- Adds a welcome modal for new Cal.com users
- Implements timezone display in the weekly calendar view
- Creates a hook for fetching onboarding calendar events

## Visual Demo (For contributors especially)

#### Image Demo:

![Welcome Modal](https://user-images.githubusercontent.com/1234567/example-welcome-modal.png)

![Timezone Display](https://user-images.githubusercontent.com/1234567/example-timezone-display.png)

## Mandatory Tasks

- [x] I have self-reviewed the code
- [x] I have updated the developer docs in /docs
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. **Welcome Modal:**
   - Create a new user account
   - Verify the welcome modal appears with correct content
   - Test the "Continue" button closes the modal
   - Check that the modal can be triggered via URL parameter `?welcomeToCalcomModal=true`

2. **Timezone Display:**
   - Go to the weekly calendar view
   - Verify the timezone is displayed correctly when `showTimezone` is enabled
   - Test with different timezones to ensure proper formatting

3. **Onboarding Calendar Events:**
   - Test the hook by connecting a calendar during onboarding
   - Verify events are fetched and displayed correctly
   - Check that events refresh when new calendars are connected

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-11-11 10:47:22 +00:00
Lauris Skraucis 8b4f675cee feat: v2 api allow switching event type between collective and round robin (#25045)
* refactor: create team event type hosts

* refactor: update team event type hosts

* feat: allow switching between collective and round robin

* fix: make schedulingType optional when updating

* fix: e2e tests

* fix: e2e and add more tests

* test: only hosts update

* fix: remove test that makes no sense
2025-11-11 09:40:21 +01:00
Volnei Munhoz 53a931da4e Improve check user exists (#25057) 2025-11-11 06:05:37 +00:00
KartikandDhairyashil Shinde 228fbaf72e fix: skip email verification for reschedules and added test case (#24867)
* fix: skip email verification for reschedules and added test case

* used getNewBookingHandler helper instead of direct import in test

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-11-11 04:05:55 +00:00
Lauris Skraucis 0c53717d0f docs: api v2 rate limits (#24971) 2025-11-11 04:01:33 +00:00
Alex van AndelandKeith Williams e239b67171 chore: Rate limit top level of public booking pages (#25056)
* chore: Rate limit top level of public booking pages

* Prefix rateLimit keys

* Adding more rate limits

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-11-11 00:51:00 +00:00
Volnei Munhoz fd390f9d43 fix: add authorization checks to booking reassignment endpoints (#25054) 2025-11-10 19:20:48 -03:00
Rajiv SahalandAnik Dhabal Babu eae779b81c chore: update api v2 /me endpoint (#23984)
* fix: update profile me ednpoint to include name of user

* fix: update user schema

* pass name for user

* implement PR feedback

* chore: implement PR feedback

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-11-10 19:14:44 +00:00
Dhairyashil ShindeandUdit Takkar 6d621e0b60 docs: update Docker documentation to reference main cal.com repository (#24899)
- Replace all references from github.com/calcom/docker to github.com/calcom/cal.com
- Update Contributing section to clarify Docker setup is officially maintained in main repository
- Update Getting Started instructions to clone main cal.com repository
- Update Advanced Users section to reference Dockerfile and docker-compose.yml in root of main repo
- Clarify that Dockerfile and docker-compose.yml are located in root of calcom/cal.com repository

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-10 19:00:02 +00:00
Muhammad UsmanandKartik Saini ed3de528f3 fix: events type apps tab (Available Apps) section overflow small screens (#23972)
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-11-10 18:30:42 +00:00
Pasquale Vitiello 92f1baa320 style: fix dropdown spacing issues (#24917) 2025-11-10 18:29:34 +00:00
984cd64083 test: add routing-forms tests (#25044)
* test: Add comprehensive security tests for routing forms vulnerability

Add comprehensive test coverage for the getIncompleteBookingSettings handler
vulnerability and ensure entityPrismaWhereClause changes won't break functionality.

Tests added:
1. getIncompleteBookingSettings.handler.test.ts (15 tests)
   - Authorization tests for personal and team forms
   - Credential sanitization tests (key field should never be exposed)
   - Organization hierarchy tests (parent org credentials)
   - App filtering tests (only enabled apps)
   - Edge cases (no credentials, form not found, etc.)

2. entityPrismaWhereClause.integration.test.ts (13 tests)
   - Verifies formQuery, deleteForm, and forms handlers properly scope queries
   - Ensures accepted membership is required for team access
   - Validates consistent entityPrismaWhereClause usage across handlers
   - Prevents regressions when adding role-based filtering

Expected Test Failures:
The getIncompleteBookingSettings tests currently have 4 expected failures that
document the existing vulnerability:
- 2 authorization tests fail (handler doesn't check user access)
- 2 sanitization tests fail (handler leaks the 'key' field with OAuth tokens)

These failures prove the vulnerability exists and document the secure behavior
that should be implemented.

Test Results:
- All 13 entityPrismaWhereClause integration tests pass
- All 18 existing routing-forms test files pass (156 tests)
- 4 security tests fail as expected (documenting the vulnerability)

The tests ensure that:
1. Fixing the vulnerability by adding entityPrismaWhereClause won't break other handlers
2. The key field is never returned in credentials
3. Only authorized users can access forms
4. Team membership requires accepted: true
5. Organization hierarchy is properly handled

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Add suggested fix

* Add suggested fix

* fix: enforce authorization scoping and credential sanitization in routing-forms handler

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Fix types

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-11-10 16:54:15 +00:00
Alex van Andel db8c7942a9 refactor: Removed asStringOrNull functions (#25029) 2025-11-10 16:17:09 +00:00
4e5d4f67d5 fix: resolve flaky integration tests (#25030)
* fix: resolve flaky org-admin integration tests

- Fixed isAdminGuard Prisma query to use explicit 'is' filter for organizationSettings
- Fixed async describe with top-level awaits in _get.integration-test.ts
- Added global setup in setupVitest.ts to prevent race conditions
- Removed duplicate setup logic from individual test files

Root cause: Tests were running in parallel with independent beforeAll setups,
causing race conditions where organizationSettings weren't created before
tests executed. The async describe with top-level awaits made this worse by
executing queries before beforeAll hooks ran.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: move org-admin setup to integration-only setup file

The global setup in setupVitest.ts was running for ALL test workspaces
(including unit tests), causing ECONNREFUSED errors because unit tests
don't have database access.

Changes:
- Created setupVitest.integration.ts with org-admin seeding logic
- Removed database seeding from setupVitest.ts
- Updated vitest.workspace.ts to use integration-only setup file
- Added DATABASE_URL guard to prevent errors when DB is unavailable

This fixes the unit test failures while preserving the fix for flaky
integration tests.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: use globalSetup instead of setupFiles for org-admin seeding

The previous fix using setupFiles didn't work because setupFiles run
AFTER test modules are evaluated. This meant any top-level Prisma
queries in test files would execute before the org-admin seeding.

Changes:
- Moved org-admin seeding to tests/integration/global-setup.ts
- Updated vitest.workspace.ts to use globalSetup for IntegrationTests
- globalSetup runs BEFORE any test modules are loaded, ensuring org
  settings exist before tests execute
- Added teardown function to properly disconnect Prisma after tests

This ensures org-admin state is seeded once before all integration
tests run, eliminating the race condition and ensuring tests have
the correct database state.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* debug: add logging to globalSetup to diagnose why tests are failing

Added console.log statements throughout the globalSetup to verify:
- Whether the globalSetup is running at all
- Whether DATABASE_URL is available
- Whether the org teams are found in the database
- Whether the upserts are executing successfully

This will help diagnose why the integration tests are still failing
with org-admin not being detected.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: use absolute path for globalSetup in vitest.workspace.ts

Changed from relative path 'tests/integration/global-setup.ts' to
absolute path using new URL().pathname to ensure Vitest can properly
locate and load the globalSetup file.

This should fix the issue where the globalSetup wasn't being executed
at all (no logs appearing in CI).

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: add serial execution to IntegrationTests workspace

Added sequence.concurrent: false to IntegrationTests workspace to eliminate
inter-file race conditions while stabilizing org-admin seeding. This ensures
tests run one at a time, preventing parallel execution issues that could
cause flaky test failures.

This is a temporary stabilizer that can be reverted once the globalSetup
seeding is confirmed working.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: use TeamRepository in globalSetup to follow architectural rule

Refactored globalSetup to use TeamRepository instead of direct Prisma
access, following the 'No prisma outside of repositories' architectural
rule.

Changes:
- Created TeamRepository class with methods for finding organizations
  and upserting organization settings
- Updated globalSetup to use TeamRepository.withGlobalPrisma()
- Removed direct Prisma imports from globalSetup

This ensures proper separation of concerns and follows the repository
pattern established in the codebase.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: use relative path import for TeamRepository in globalSetup

Changed from package-scoped import '@calcom/lib/server/repository/team'
to relative path import '../../packages/lib/server/repository/team' to
fix module resolution issue.

Added try/catch with logging around the import to surface any remaining
resolution issues in CI logs. This should allow the globalSetup to
execute properly and seed org-admin state before tests run.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* debug: add membership logging to globalSetup to diagnose test failures

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: ensure owner1-acme membership exists in globalSetup

Root cause: CI database snapshot doesn't include the owner1-acme OWNER membership that exists in the current seed file, because cache-db action's cache key doesn't include scripts/seed.ts.

Solution: Add ensureMembership method to TeamRepository and call it in globalSetup to ensure the owner1-acme user has an accepted OWNER membership in the Acme org before tests run.

This fixes the 5 failing org-admin integration tests that depend on this membership.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: ensure all 10 member{0-9}-acme users exist in globalSetup

Add ensureUser method to TeamRepository to create users if they don't exist.
Update ensureMembership to accept MEMBER role in addition to OWNER and ADMIN.
Ensure all 10 member{0-9}-acme users are created with MEMBER role and accepted: true in the Acme org.

This should fix the remaining 4 failing tests that expect multiple org members to exist.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: use upsert instead of create in ensureUser to avoid unique constraint violations

The ensureUser method was using create which could fail if a user with that email already exists.
Switch to upsert to make the operation idempotent and avoid P2002 unique constraint errors.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* refactor: clean up debug code and move test repository to proper location

- Remove all console.log debug statements from global-setup.ts
- Remove serial execution from IntegrationTests workspace (restore parallel execution)
- Move TeamRepository to tests/lib/test-team-repository.ts and rename to TestTeamRepository
- Keep all actual fixes: isAdmin Prisma query fix, ensureUser/ensureMembership methods, globalSetup seeding

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-10 15:47:39 +00:00
Hariom Balhara 83488f0a35 refactor: Enhance event type retrieval logic (#24985)
- Deleted the getEventTypeById.test.ts file as it was no longer needed.
- Updated getEventTypeById.ts to include OrganizationRepository for improved organization admin checks.
- Refactored event type retrieval logic to ensure proper access control for organization admins.
2025-11-10 13:50:21 +05:30
Kartik 9a52938f64 fix: strip internal $RCH$ prefix from cancellation reason in ICS files (#25016)
* fix: strip internal RCH prefix from cancellation reason used in ICS

* fixed

* trimmed
2025-11-09 21:15:17 +00:00
e24e1d8769 fix(apps/web): enhance JWT response with token type and expiration details (#24841)
* fix: enhance JWT response with token type and expiration details

* fix: update email generation in createUsersFixture to use v4 UUID without dashes

* revert: update email generation in createUsersFixture to use short-uuid for unique email identifiers

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-11-10 02:15:56 +05:30
Dhairyashil Shinde ef4be48ea6 fix: configure correct error message for duplicate event type slug (#24928)
* fix/duplicate-event-type-to-existing slug

* use existing pattern to to verify the conflict on slug
2025-11-09 20:22:12 +00:00
spandevandDhairyashil Shinde 5c9ad93923 fix: back button in settings updated to use window history (#24952)
* fix: back button in settings updated to use window history

* fix: removed label from button

* update: added aria-label, Button and useRouter

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-11-10 01:23:31 +05:30
emrysal 85fe40688e chore: release v5.8.12
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-07 20:12:13 +00:00
Lauris SkraucisandUdit Takkar 829edec0ea refactor: v2 api event-types/:eventTypeId access (#24969)
* refactor: EventTypeAccess service

* feat: event-types/:id system admin access and team event access

* fix: implement cubic feedback

* fix: e2e

* fix: e2e

* fix: oasdiff ignore non-breaking change

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-07 21:17:16 +02:00
Rajiv Sahal 81a99ea0b2 chore: add bookingUid filter to get org teams booking endpoint (#24960)
* chore: add bookingUid filter to get org teams booking input

* chore: update tests
2025-11-07 17:52:45 +00:00
Lauris Skraucis 799e354059 refactor: api v2 breaking changes CI check (#24999) 2025-11-07 15:13:48 +00:00
Dhairyashil Shinde 584c991172 feat: new workflow variable booking title (#24308)
* feat(workflow): new variable booking title

* feat(workflow): new variable booking title

* change the description of variable to The booking title

* revert previous logic changes
2025-11-07 15:08:20 +01:00
emrysal 47e976df96 chore: release v5.8.11
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-07 12:38:40 +00:00
Rajiv Sahal b44efddc0f fix: make sure we update the correct item when generating invoice for PER_ACTIVE_USER plan (#24940) 2025-11-07 11:58:31 +00:00
bc665cbeab fix: APIV2 team membership - Member not getting added to event-type automatically (#24780)
* fix: APIV2 team membership addition

* feat: Add trimming for email domain and orgAutoAcceptEmail in auto-accept logic

- Trim whitespace from both user email domain and orgAutoAcceptEmail
- Ensures consistent matching even with accidental whitespace
- Addresses feedback from PR review

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* simplify

* feat: Use shared OrganizationMembershipService in TRPC for consistent auto-accept logic

- Create OrganizationMembershipService.container.ts for DI in TRPC
- Update getOrgConnectionInfo to apply trimming + case-insensitive comparison
- Precompute auto-accept decisions in createNewUsersConnectToOrgIfExists using the service
- Use service in handleNewUsersInvites for consistent auto-accept determination
- Ensures both API v2 and TRPC paths use identical trimming and normalization logic

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Revert "feat: Use shared OrganizationMembershipService in TRPC for consistent auto-accept logic"

This reverts commit 0b2bd28b6e32e8c1d3dea139ca8ff9cbf402ac00.

* refactor: Unify OrganizationRepository and remove duplicate PrismaOrganizationRepository (#24869)

* refactor: Convert OrganizationRepository from static to instance methods

- Add constructor accepting deps object with prismaClient
- Convert all static methods to instance methods
- Add getOrganizationAutoAcceptSettings method
- Create singleton instance export in repository barrel file
- Update API v2 OrganizationsRepository to extend from OrganizationRepository
- Update all call sites to use singleton instance
- Add platform-libraries organizations.ts export
- Fix mock imports to use repository barrel
- Fix unsafe optional chaining in next-auth-options.ts
- Fix any types in test files with proper type inference

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update all imports to use OrganizationRepository barrel export

- Update imports from direct OrganizationRepository file to barrel export
- This ensures mocks work correctly in tests
- Fixes 202 failing tests related to organizationRepository mock

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update test mocks to use partial mock pattern

- Convert organizationMock to partial mock that preserves real class
- Add proper prisma mocks to failing test files
- Remove old OrganizationRepository mocks from test files
- This fixes test failures related to mock interception

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Export mocked singleton and update tests to use it directly

- Export mockedSingleton as organizationRepositoryMock from organizationMock
- Update delegationCredential.test.ts to import and use the exported mock
- This fixes 'vi.mocked(...).mockResolvedValue is not a function' errors

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Use platform-libraries import for API v2 OrganizationRepository

API v2 should import shared features through @calcom/platform-libraries
instead of directly from @calcom/features to maintain proper architectural
boundaries and packaging/licensing separation.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Implement DI pattern for OrganizationRepository

- Create OrganizationRepository.module.ts and .container.ts for DI
- Replace singleton pattern with getOrganizationRepository() across 20 files
- Update platform-libraries to export getOrganizationRepository
- Delete duplicate PrismaOrganizationRepository.ts
- Remove singleton export file (repositories/index.ts)
- Update test mocks to use DI container pattern
- All type checks and unit tests passing

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Implement read/write client separation in OrganizationRepository

- Updated OrganizationRepository constructor to accept optional prismaWriteClient parameter
- Routed all write operations (create, update) through prismaWrite client
- Routed all read operations (find, get) through prismaRead client
- Updated API v2 OrganizationsRepository to pass both dbRead.prisma and dbWrite.prisma to super()
- Optimized getOrganizationRepository() calls by storing in local variables to avoid repeated function calls
- This fixes the critical issue where API v2 was passing read-only client to base class with write methods

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Fix mock setup and optimize getOrganizationRepository() calls

- Fixed verify-email.test.ts mock to return mocked repository instance instead of scenario helper object
- Added mockReset to organizationMock.ts beforeEach to properly reset mock implementations between tests
- Added local variables in page.tsx to store getOrganizationRepository() result for consistency

This fixes the issue where getOrganizationRepository() was returning organizationScenarios.organizationRepository (scenario helper) instead of the actual mocked repository instance, causing findUniqueNonPlatformOrgsByMatchingAutoAcceptEmail to be undefined.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Simplify OrganizationRepository to use single prismaClient

- Updated base OrganizationRepository constructor to accept only { prismaClient } instead of { prismaClient, prismaWriteClient? }
- Replaced this.prismaRead and this.prismaWrite with single this.prismaClient property
- Updated API v2 OrganizationsRepository to pass only dbWrite.prisma as prismaClient
- Removed unused PrismaReadService import from API v2
- All read and write operations now use the same client instance

This simplifies the architecture as requested - API v2 uses write client for all operations, and apps/web uses the client from DI container.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: Match OrganizationsRepository.findById signature with base class

The findById method in OrganizationsRepository was using a different signature
than the base OrganizationRepository class, causing type errors in CI.

Changed from: findById(organizationId: number)
Changed to: findById({ id }: { id: number })

This matches the base class signature and resolves the CI unit test failures.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Update all findById call sites to use object parameter

Fixed 6 call sites in API v2 that were calling findById with a number
instead of the required { id: number } object parameter:

- is-org.guard.ts
- is-admin-api-enabled.guard.ts
- is-webhook-in-org.guard.ts
- organizations.service.ts
- managed-organizations.service.ts (2 call sites)

This resolves the API v2 build failure caused by the signature change
in OrganizationsRepository.findById to match the base class.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Remove redundant findById override from OrganizationsRepository

The findById method was duplicating the base class OrganizationRepository
implementation. Both methods had identical logic (filtering by isOrganization: true),
so the override was unnecessary.

Since OrganizationsRepository extends OrganizationRepository and passes
dbWrite.prisma to the base constructor, the base class method already
provides the exact same functionality.

This resolves the API v2 build failure by eliminating the duplicate method
that was causing conflicts.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Remove unncessary changes

* Store in variable

* Revert "Remove unncessary changes"

This reverts commit af9351786a21616c9508c441191c17f2374fb2cc.

* Revert dbRead/dbWrite changes

* Add organizations library to tsconfig.json

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-11-07 10:50:00 +00:00
sean-brydon 02b1393ff4 chore: Update personal and team onboarding flows (remove profile/video steps, add settings, improve team invites) (#24947)
## What does this PR do?

- Redesigns and streamlines the onboarding flow for personal, team, and organization accounts
- Consolidates shared components and improves code organization
- Adds browser preview for better user experience during onboarding
- Simplifies the personal onboarding flow by removing the video integration step
- Enhances team onboarding with CSV upload functionality

## Visual Demo (For contributors especially)

#### Image Demo:
- The PR adds a new browser preview component that shows users how their profile/team will look during onboarding
- Redesigned UI with a more consistent layout across all onboarding steps
- Improved mobile responsiveness with better component organization

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code.
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Test the complete onboarding flow for personal accounts:
   - Start at `/onboarding/getting-started`
   - Proceed through personal details and calendar setup
   - Verify the flow completes successfully

2. Test the team onboarding flow:
   - Start at `/onboarding/getting-started` and select team
   - Complete team details
   - Test the invite options including CSV upload
   - Verify team creation works correctly

3. Test the organization onboarding flow:
   - Start at `/onboarding/getting-started` and select organization
   - Complete organization details and branding
   - Test member invitations
   - Verify organization creation works correctly

4. Verify browser preview functionality:
   - Check that the preview updates in real-time as you enter information
   - Confirm it displays correctly on different screen sizes

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-11-07 08:54:55 +00:00
sean-brydon 52e27bab53 chore: Add shared onboarding components (OnboardingCard, OnboardingLayout, browser views) (#24946)
## What does this PR do?

Creates new onboarding UI components for the user onboarding flow, including:

- `OnboardingCard` - A reusable card component with title, subtitle, content, and footer sections
- `OnboardingLayout` - A layout component with progress indicators and sign-out functionality
- `OnboardingBrowserView` - A browser preview showing how the user's booking page will look
- `OnboardingCalendarBrowserView` - A calendar preview showing sample events
- `OnboardingInviteBrowserView` - A preview of the team invitation email
- Enhanced `PlanIcon` component with new variants and animations for organization and team plans

## Visual Demo (For contributors especially)

#### Image Demo:
The PR adds several visual components for the onboarding flow, including browser previews, calendar views, and animated plan icons with concentric rings and user avatars.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code.
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

- Navigate to the onboarding flow to see the new components in action
- Test the layout with different screen sizes to ensure responsive behavior
- Verify that the browser previews render correctly with sample data
- Check that the plan icon animations work properly for different variants (single, team, organization)
- Ensure the calendar view displays sample events correctly

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-11-07 07:58:34 +00:00
Lauris Skraucis 45278a2195 feat: api v2 pbac support (#24402)
* feat: Pbac decorator and guard

* feat: v2 roles endpoints

* fix: test

* fix: starting v2

* fix: test error

* fix: test api keys

* fix fixture

* test permission creation

* feat: permissions endpoints

* refactors

* refactor: project structure

* test: role permissions crud

* test: permissions endpoint negative tests

* docs: org, team permissions swagger

* unit tests for validator

* Update roles.guard.ts

* fix type

* test: error messages

* refactor: dont throw error in pbac

* delete redundant test file

* feedback: logging error

* fix: persist role.permissions when updating role.otherProperty

* refactor: use output service to return permissions

* refactor: service functions return current permissions

* refactor: remove OrganizationsRepository from providers

* refactor: try catch possibly duplicate create

* refactor: require min length name if provided

* refactor: org role has orgId and team role teamId

* fix: pbac guard caching

* fix: e2e tests in parallel

* refactor: use IsTeamInOrg guard for orgs teams roles and permissions endpoints

* refactor: use redis service getter and setter

* refactor: invalidate team permissions cache when permissions change

* refactor: delete keys instead of versioning when caching
2025-11-06 17:14:55 +00:00
Hariom BalharaandUdit Takkar 2e8b89c4ee fix: enhance bot ID initialization check in instrumentation client (#24961)
- Add additional check for the presence of window.crypto.randomUUID function
- Ensures compatibility with environments that support both getRandomValues and randomUUID

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-06 12:00:31 +00:00
Joe Au-Yeung 7d17b443cf chore: Add cache log (#24954)
* Add log

* Update getCalendar.ts
2025-11-06 08:24:52 +00:00
Rodrigo EhlersandUdit Takkar c6ab6b3d13 fix: keep dialog state by decoupling it from list (#24914)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-06 13:37:26 +05:30
spandev c741d8133e fix: added icon and description in team event type empty page (#24951) 2025-11-06 13:26:06 +05:30
b01cb27c56 feat: improve overlapping events display in weekly calendar view (#24880)
* feat: improve overlapping events display in weekly calendar view

- Add cascading layout algorithm for overlapping events
- First event at 80% width, subsequent events offset by 8%
- Implement hover behavior to bring events to front (z-index 100)
- Extract overlap logic into reusable utility functions
- Add comprehensive unit tests for overlap detection and layout calculation
- Sort events by start time, then by duration for consistent rendering

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add weekly calendar playground page for testing overlapping events

- Create comprehensive playground page with 8 test scenarios
- Include two overlapping, three cascading, non-overlapping, same start time, chain overlaps, dense day, touching events, and mixed statuses
- Add focused view with scenario selector and grid view for side-by-side comparison
- Update playground index to include weekly calendar link
- Each scenario includes description, expected behavior, and collapsible event data

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update base props

* remove unneccessary things

* fix: isolate Calendar store instances to prevent shared state

- Refactor useCalendarStore to use Zustand's createStore with React Context
- Each Calendar component now creates its own isolated store instance
- Maintains backward compatibility with global store fallback
- Fixes issue where multiple Calendar instances on same page shared state

This allows the playground page to render multiple Calendar instances
without state conflicts between them.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: prevent event overflow in dense overlap scenarios

- Dynamically compress offset step based on overlap group size
- Ensure leftOffset + width never exceeds 100% to prevent bleeding into next day
- Add width clamping as safety guard against rounding errors
- Add 3 new tests for overflow prevention with dense event scenarios

Fixes issue where 10+ overlapping events would cascade beyond day boundary
and bleed into the next day's column. The algorithm now calculates the
maximum safe step size per overlap group while maintaining visual cascade.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* remove global store

* fix: comprehensive overflow prevention with safety margin and CSS fix

- Add safetyMarginPercent (0.5%) to prevent rounding and CSS box model overflow
- Implement floor3 rounding for width to guarantee left + width <= 100 - safetyMargin
- Calculate width from rounded left offset to avoid rounding mismatch
- Remove inset-x-1 class conflict that was setting both left and right positioning
- Change from marginLeft to left positioning for proper control
- Add test for 20+ overlapping events to verify no overflow
- Update existing tests to verify safety margin is respected

This fixes the slight overflow issue reported by the user where events were
still bleeding into adjacent day columns despite the initial dynamic step
compression fix. The root cause was a combination of:
1. CSS conflict: inset-x-1 class setting both left and right positioning
2. Rounding mismatch: width calculated from unrounded left offset
3. No safety margin for CSS box model effects (borders, padding)

All 21 tests now pass including new safety margin verification.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: update Dense Day scenario to 20+ events

- Increase from 11 to 21 overlapping events in Dense Day scenario
- Update title from '10+ Events' to '20+ Events'
- Add 10 more diverse events with staggered start times
- Better stress test for overflow prevention with safety margin

This provides a more comprehensive test case for the overflow prevention
fix and matches the user's request for 20+ events instead of 10+.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* WIP

* feat: enhance event tooltip to show full event details

- Replace simple title-only tooltip with rich content tooltip
- Display event title, time range, description, and status
- Add color indicator matching the event's visual style
- Set min-width (200px) and max-width (300px) for better readability
- Use inverted theme colors for better contrast in tooltip

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* faster animation

* feat: position tooltip based on day of week

- Show tooltip on right side for Monday-Thursday (days 1-4)
- Show tooltip on left side for Friday-Sunday (days 5-0)
- Calculate day of week using dayjs from event start date

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* add margin for tooltip

* feat: add event duration layout test scenario

- Add new scenario with events of varying durations (3, 7, 15, 20, 30, 53 minutes)
- Test layout logic where eventDuration > 30 changes flex direction
- Events ≤30min show horizontal layout (title and time inline)
- Events >30min show vertical layout (title and time stacked)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update styles

* feat: add minimum height of 15px for events

- Ensure very short events (e.g., 3 minutes) are still visible
- Use CSS max() to apply minimum height while respecting duration-based height
- Prevents events from becoming too small to interact with

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update playground

* do not mutate

* pre-compute some values

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Sean Brydon <sean@cal.com>
2025-11-05 15:56:24 +00:00
c48f2043f2 feat: booking reports table and blocklist table for org (#24736)
* feat: booking reports and blocklist table

* chore: save progress

* chore: save progress

* feat: finish

* fix: types and test

* fix: types and test

* refactor: separate tables

* refactor: ffedbac

* refactor: remove delete report

* refactor: add go back button

* feat: add icon and svg

* chore: nit

* fix: type errror

* fix: type errror

* refactor: code improvements

* chore: add docs url

* chore: feedback

* minor UI fix

* fix: add Is-calcom check

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-11-05 14:48:06 +00:00
emrysal 630eee4fab chore: release v5.8.10
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-05 13:06:46 +00:00
Morgan 1ebf553181 refactor: checkBookingRequiresAuthentication with rescheduleUid (#24943) 2025-11-05 13:02:01 +00:00
Hariom Balhara e8a315ac4e Remove cal.cache query parameter to prevent stale calendar data (#24939)
- Remove cal.cache query parameter parsing from booking and slots flows
- Set shouldServeCache to false for all booking availability checks
- Remove _shouldServeCache from schemas and type definitions
- Clean up all references in platform atoms and API endpoints

This ensures fresh Google Calendar data is always fetched for conflict checking,
preventing bookings when there are actual calendar conflicts.
2025-11-05 13:01:22 +00:00
Udit TakkarandVolnei Munhoz c196ff1095 feat: link email to participant (requireEmailForGuests) (#24661)
* feat: link email to participatn

* fix: bugs

* refactor: improve code

* refactor: prevent repload

* chore: remove unued

* fix: type

* refactor

* fix: type

* feat: restrict host

* feat: type

* feat: tests

* fix: don't allow guest

* fix: merk guest

* fix: bugs

* fix: test

* fix: test

* refactor: feedback

* fix: tests

---------

Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
2025-11-05 11:15:41 +00:00
bf0fbe4888 feat: skip authentication check for reschedule bookings with validation (#24903)
* feat: skip authentication check for reschedule bookings with validation

- Skip checkBookingRequiresAuthentication when rescheduleUid is present
- Add validation to ensure rescheduleUid points to a real booking
- Verify booking status is ACCEPTED (upcoming)
- Verify booking uses the same event-type
- Throw appropriate errors for invalid reschedule attempts

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: move reschedule validation logic into checkBookingRequiresAuthentication

- Refactor checkBookingRequiresAuthentication to accept optional rescheduleUid parameter
- Move reschedule booking validation logic inside the method
- Simplify createBooking method by removing duplicate validation code
- Maintain same validation logic: check booking exists, is ACCEPTED, and uses same event-type

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: allow PENDING bookings to be rescheduled

- Update status validation to allow both ACCEPTED and PENDING bookings
- Change error message to reflect both allowed statuses
- PENDING bookings can now be rescheduled without authentication check

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: separate reschedule validation from auth check

- Extract validateRescheduleBooking method to handle reschedule-specific validation
- Keep checkBookingRequiresAuthentication strictly for auth checks
- Use conditional logic in createBooking: validate reschedule OR check auth
- Improves code clarity by separating concerns per lauris's feedback

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-05 11:07:43 +00:00
Syed Ali Shahbaz eb6418c0d5 Add enableOverflow prop to DialogContent (#24935) 2025-11-05 10:46:44 +00:00
Udit TakkarandCarinaWolli 2df2868b20 fix: cal ai webhook (#24368)
* fix: cal ai email

* fix: remove

* fix: org

* replace Cal AI with Cal.ai

* fix: use

* fix: feedback

* fix: types

* fix: types

* fix: types

* fix: tests

* Merge branch 'main' into fix/cal-ai-credits

* refactor: feedback

* refactor: imporvement

* fix: type

* refactor: feedback

* fix: tests

* fix: use pbac

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-11-05 13:31:55 +04:00
Anik Dhabal Babu 7f48c7fdad fix: Ignore userIds form filter segment if no permission (#24194)
* Update get.handler.ts

* fix: Ignore userIds form filter segment if no permission

* add tests

* Update booking-filters.e2e.ts

* Update booking-filters.e2e.ts
2025-11-05 13:09:13 +05:30
Udit Takkar 2101051623 style: fix height of report button (#24918)
* style: fix height

* style: fix height
2025-11-05 07:35:58 +00:00
Alex van Andel a241cb0bfc hotfix: Bring back English translation for cal.ai banner (#24922) 2025-11-04 19:30:29 +00:00
Anik Dhabal Babu 5417012cec Revert "fix: sanitize username input to prevent hyperlinks (#24210)" (#24916)
This reverts commit 7d16da5c98.
2025-11-04 17:01:05 +00:00
Dhairyashil Shinde 8e818e0567 refactor: remove-zapier-setup-screen (#24652)
* refactor: remove-zapier-setup-screen

* remove setup page files, related config and update readme

* make zapier a redirecting app

* update readme

* add check for missing website

* add noopener,noreferrer for _blank links
2025-11-04 15:55:09 +00:00
Morgan 1fdd04215d fix: missing await in updateEventType old endpoint (#24911) 2025-11-04 15:15:19 +00:00
Dhairyashil Shinde 0bf0749b29 only custom template needs upgrade and free users cannot edit email title and body of existing templates (#24907) 2025-11-04 13:43:40 +00:00
Dhairyashil Shinde 4006143e3a refactor: remove cal ai tip (#24904) 2025-11-04 11:56:21 +00:00
c6ad767565 refactor: decouple @calcom/prisma from @calcom/features, @calcom/ee, and @calcom/lib (#24802)
* refactor: decouple @calcom/prisma from @calcom/features, @calcom/ee, and @calcom/lib

- Inline helper functions in zod-utils.ts (emailSchema, slugify, getValidRhfFieldName, isPasswordValid, intervalLimitsType, zodAttributesQueryValue)
- Update schema.prisma @zod.import comments to reference zod-utils instead of @calcom/lib
- Inline idempotency key generation in booking-idempotency-key extension using uuid v5
- Move usage-tracking extension to @calcom/ee/prisma-extensions/
- Remove usage-tracking extension from packages/prisma/index.ts
- Move Prisma DI module from @calcom/prisma to @calcom/features/di/modules/Prisma.ts
- Update 20 import paths in @calcom/features to use new Prisma DI module
- Remove @calcom/lib dependency from @calcom/prisma package.json
- Add uuid dependency to @calcom/prisma package.json

This reduces the dependency footprint of @calcom/prisma and breaks circular dependencies between packages.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* feat: add EE-specific Prisma DI module with usage tracking

Create packages/ee/di/modules/PrismaEE.ts to apply the usage-tracking extension in EE contexts. This module:
- Imports the base prisma client from @calcom/prisma
- Applies the usageTrackingExtention from @calcom/ee/prisma-extensions/usage-tracking
- Exports the same DI tokens as the base Prisma module for override in EE containers

This ensures usage tracking functionality is preserved in EE builds while keeping the base @calcom/prisma package free of EE dependencies.

Note: EE containers should load this module after the base Prisma module to override the bindings.
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-04 06:51:13 -03:00
896f8dbd3d fix: align booking limit timezone between availability and validation (#24846)
* fix: align booking limit timezone between availability and validation

- Use eventType.schedule?.timeZone for booking limits in availability calculation
- Previously used user's timezone causing day boundary mismatch
- Add unit tests to verify timezone alignment
- Fixes issue where slots remain available after reaching booking limit

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Rename variable limitsTz to eventTimeZone

* update

* fix: correct timezone fallback to include user timezone without forcing UTC

- Changed fallback chain to: schedule → event → user → undefined
- Treats empty strings as missing timezones
- Does not force UTC when all timezones are missing
- Aligns with validation behavior when timezone is undefined
- Fixes getSchedule.test.ts failures

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Revert "fix: correct timezone fallback to include user timezone without forcing UTC"

This reverts commit 721e0bdfd7b08004e68df6bdf5b97b9bd6cf3d5c.

* test: remove complex unit tests with 'as any' casts

- Removed Booking Limits Timezone Alignment tests that required heavy mocking
- These tests relied on spying private methods and had many 'as any' casts
- Timezone alignment is already covered by integration tests in getSchedule.test.ts
- Kept BookingDateInPastError test which has no type issues

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* address review

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-04 12:13:42 +05:30
emrysal f1db27c0ad chore: release v5.8.9
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-04 00:30:52 +00:00
Eunjae LeeandDevin AI 3a1e04bb42 refactor: extract booking actions dropdown to separate component (#24872)
* refactor: extract booking actions dropdown to separate component

- Created BookingActionsDropdown component with all dropdown actions and dialogs
- Component receives booking as prop and handles all action logic internally
- Removed duplicate dialog states and mutations from BookingListItem
- Fixed img tag to use Next.js Image component
- Maintains same functionality and UI while improving code reusability

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: restore cardCharged variable in BookingListItem

The cardCharged variable was accidentally removed during the refactoring
but is still needed for the actionContext in BookingListItem.tsx

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move BookingItemProps type to separate types.ts file

- Created types.ts to hold shared booking types
- Updated BookingListItem.tsx to import from types.ts
- Updated BookingActionsDropdown.tsx to import from types.ts
- Updated bookingActions.ts to import from types.ts
- Removed unused RouterInputs and RouterOutputs imports from BookingListItem.tsx
- Removes unwanted dependency chain where BookingActionsDropdown imported from BookingListItem

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* remove unnecessary description

* extract states as a zustand store

* fix dialog issue

* fix type errors

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-04 00:25:48 +00:00
Alex van Andel ab37847ea1 chore: User->UUID as a required field, ready for use in foreign keys (#24881) 2025-11-04 00:20:52 +00:00
Dhairyashil Shinde 0a2ddf05ca refactor: remove cal ai banners (#24885) 2025-11-04 01:57:43 +05:30
Lauris Skraucis 04fc0f1d52 docs: event calVideoSettings not available for platform (#24879) 2025-11-03 18:53:40 +00:00
Amit Sharma b76c4c9dcc fix: alby booking page breaking (#24859)
* fix: alby booking page breaking

* remove logs
2025-11-03 14:35:20 -03:00
Vibhor PhalkeandKartik Saini 68b71bfb0a address linting errors (#24171)
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-11-03 17:29:24 +00:00
Eunjae Lee 763c568797 fix: existence check of searchParams in NavigationItem (#24877) 2025-11-03 16:42:31 +00:00
Rajiv Sahal 4659d08c07 chore: return back timezone of event owner (#24876) 2025-11-03 16:29:29 +00:00
Sachin Yadav b9c350cc45 fix: Recurring events set to "yearly" don't recur (#24361)
* #fix: Recurring events set to “yearly” don’t recur

* fix: handle yearly recurring events with explicit null check

* fix: use explicit null check for recurring event frequency
2025-11-03 16:20:15 +00:00
an_ifrah24 f63d705523 fix: url truncate properly in the input field on diff screen sizes (#24700) 2025-11-03 16:14:49 +00:00
Dhairyashil Shinde 2907c5e696 fix(ui): interface language toggle (#24371) 2025-11-03 21:20:34 +05:30
sean-brydon dcb47e31ed fix: address onboarding v3 teams redirectfrom onboarding (#24875)
* Address redirect in subdomain for teams v3

* Revert constants
2025-11-03 15:43:55 +00:00
Dhairyashil ShindeandAnik Dhabal Babu cd5b75fe2c fix: hide organizer email on cancellation page (#24616)
* fix: hide organizer email on cancellation page

* if cancelled by any host - hide the cancelled by

* Refactor organizer email logic and clean up code

Removed the isOrganizerEmail function and updated conditions for displaying the cancelledBy information.

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-11-03 14:18:38 +00:00
Steven Adger 97bdf837a9 Include setup_intent events in webhook (#24805)
The setup_intent webhook is needed for held payments / no-show fees to work. 

If it is not included, a booking gets stuck saying "Pending payment" and "Unconfirmed" despite successfully submitting the card info. After including it, the booking status will successfully change to "Card held".

See:
https://github.com/calcom/cal.com/blob/817e20f11e3a75ec0bc62535a77c618bd27eaaf4/packages/features/ee/payments/api/webhook.ts#L323

https://cal.com/blog/cal-com-s-held-payments-a-useful-tool-for-organizations-offering-free-consultatio
2025-11-03 14:16:06 +00:00
Dhairyashil Shinde 5663b2ae59 feat: disable form workflows for free plan, add upgrade badge, make reminder template free (#24839) 2025-11-03 14:08:38 +00:00
Chad RobinsonandPallav 02b57eb82e fix: Add refresh token to refresh-token request response (#24831)
* Add refresh token to refresh-token request response

This change addresses an issue reported in https://github.com/calcom/cal.com/issues/23939#issuecomment-3443480099 in which a new refresh token is not included in the OAuth2 refresh-token endpoint response.

* Address failing type checks

---------

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-11-03 19:10:36 +05:30
sean-brydon b23dfa194e fix: video install step v3 (#24865)
* Add teams i18n

* Fix UI nits in invite flow

* chore: update redirect

* Update personal view settings

* Fix video redirect
2025-11-03 13:25:54 +00:00
Eunjae LeeandDevin AI 2484b6fad2 fix: filter deleted fields from routing form insights headers (#24830)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-03 12:57:37 +00:00
Hariom Balhara c154bb31b7 fix: Arrows visible when embed has hidden entire page (#24868) 2025-11-03 12:28:54 +00:00
emrysal 0cf4ebd544 chore: release v5.8.8
Post release / release (push) Canceled after 0s
Release Docker / Release AMD64 (push) Canceled after 0s
Release Docker / Release ARM (push) Canceled after 0s
2025-11-03 12:03:36 +00:00
Dhairyashil Shinde 805c4d4c09 fix: dont allow email exclusion bypass with capital letters (#24741)
* fix: dont allow email exclusion bypass with capital letters

* trim before lowercasing to filter out empty tokens

* update console message

* use only regex change to implement this

* use only regex change to implement this
2025-11-03 11:59:14 +00:00
sean-brydon 99330b3117 chore: fixes UI nits in onboarding v3 flow (#24863)
* Add teams i18n

* Fix UI nits in invite flow

* chore: update redirect

* Update personal view settings
2025-11-03 11:45:27 +00:00
sean-brydon cc90a62090 feat: add banner for upgrade when using company email (#24829)
* Add banner plus mail icon

* Update MailIcon.tsx

* Update profile-view.tsx

* Fix weird line
2025-11-03 11:16:34 +00:00
sean-brydon 79bcd6dc30 feat: welcome to organizations modal after creation (#24823)
## What does this PR do?

Adds a welcome modal for new organizations that appears after organization creation. The modal showcases key features of the Organizations plan and provides a better onboarding experience.

## Visual Demo (For contributors especially)

#### Image Demo:

![CleanShot 2025-10-31 at 12.19.17.gif](https://app.graphite.dev/user-attachments/assets/4f8c3286-9400-40e6-aeb4-8a012f604c64.gif)

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code.
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Create a new organization through either:
   - The onboarding flow
   - The settings/organizations/new page
   - The organization creation form

2. After successful creation and redirect, verify the welcome modal appears showing organization features.

3. Verify the modal can be closed by:
   - Clicking the "Continue" button
   - Clicking outside the modal
   - Pressing ESC key

4. Verify the modal doesn't reappear after being closed (query param and session storage should be cleared).

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-11-03 11:11:16 +00:00
chauhan_s c6daa61e5e fix: Maximum update depth exceeded error when entering the 6th digit of the email verification code. (#24857) 2025-11-03 11:07:20 +00:00
Udit TakkarandVolnei Munhoz b693b6898a feat: booking report table backend (#24794)
* feat: report table backend

* fix: types

* fix: types

* fix: bugs

* fix: type error

---------

Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
2025-11-03 10:44:09 +00:00
Abir Roy fb55bc2dcd fix(docker): correct build context for calcom-api (#24849) 2025-11-03 10:38:33 +00:00
Udit TakkarandVolnei Munhoz 71bd140fe4 fix: add event type validation (#24429)
* fix: add event type validation

* fix: use isinteger

* fix: use isinteger

* fix: use isNumber

* fix: use Error

---------

Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
2025-11-03 10:26:40 +00:00
Dhairyashil Shinde 4c5608147c feat: Add Preview buttons for every private link (#24623) 2025-11-03 08:17:31 +00:00
7d16da5c98 fix: sanitize username input to prevent hyperlinks (#24210)
* fix(username): sanitize input to prevent hyperlinks

* fix(username): sanitize input to prevent hyperlinks

* Implemented CodeRabbits comments

* clean username before saving and keep input consistent

* sanitize initial username on load to avoid mismatch with input

* remove comments

* remove comments

* Used existing slugify lib instead of creating new one

---------

Co-authored-by: Dhairyashil <dhairyashilshinde@xoxo-2.local>
Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-11-03 13:16:51 +05:30
spandev 0ae6e92558 fix: round robin settings update only on change (#24853) 2025-11-03 11:54:00 +05:30
Volnei Munhoz 052a38e39b cleanup unused env vars (#24819) 2025-10-31 12:14:54 -03:00
Lauris Skraucis 31da30b982 fix: specify atoms package.json repository (#24828) 2025-10-31 14:25:26 +00:00
Lauris Skraucis d149f8385e fix: run changesets on github hosted runner (#24825)
* fix: run changesets on github hosted runner

* refactor: run on ubuntu latest
2025-10-31 13:02:09 +00:00
Hariom BalharaandDevin AI ea5a0bd5f0 fix: Add Web Crypto feature detection for BotID in React Native WebView (#24790)
* fix: Add Web Crypto feature detection for BotID in React Native WebView

Fixes #24360

- Add feature detection to check for window.crypto availability before initializing BotID
- Skip BotID initialization in React Native WebView environments
- Prevents 'undefined is not an object (evaluating crypto)' error during booking
- BotID requires Web Crypto API which is not available in React Native WebView

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Use minimal feature detection for BotID initialization

- Remove React Native WebView-specific check
- Use pure feature detection for Web Crypto API
- Check for window.crypto.getRandomValues availability
- Add SSR guard with typeof window check

This approach is more robust and environment-agnostic, working across
all environments that lack Web Crypto support, not just React Native.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-31 12:42:30 +00:00
github-actions[bot] 67c9fd92e1 chore: version packages (#24818)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-31 13:07:10 +01:00
50be997753 fix: Allow all team members to view hidden fields and UTM tracking data (#24619)
* Allow team admins to see hidden fields and UTM tracking data

- Add team admin permission check for booking data visibility
- Team admins can now view hidden booking field answers
- Team admins can now view UTM tracking parameters
- Support for managed events (parent team admins can view child event data)
- Maintain backward compatibility with existing host permissions

Fixes team admin access to booking details as requested in issue.

* feat: allow all team members to view hidden fields and UTM data

Previously only team admins could view hidden booking field answers and UTM tracking parameters. Now all team members can see this data, providing better transparency within teams.

- Changed from isTeamAdmin to isTeamMember check
- Team members (not just admins) can now view hidden booking fields
- Team members can now view UTM tracking parameters
- Maintains host permission (organizers can still see everything)
- Supports managed events (parent team members can view child event data)

* Address reviewer feedback: use existing membership pattern

- Remove custom checkIfUserIsTeamAdmin function
- Use existing userId_teamId pattern with prisma.membership.findUnique
- Revert PrismaPlugin and variable name changes
- Maintain same functionality with cleaner implementation

* fix: use existing isTeamAdmin function and remove unnecessary UI changes

* fix: Allow all team members to see hidden fields instead of just admins

- Replace isTeamAdmin with isTeamMember in booking view permissions
- Rename isLoggedInUserTeamAdmin to isLoggedInUserTeamMember for clarity
- All team members can now view hidden fields and UTM tracking data

Addresses feedback from @hariombalhara to allow all team members (not just admins) to see hidden booking data.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Correct import path for isTeamMember function

- Change import from non-existent @calcom/lib/server/queries/teams
- Use correct path @calcom/features/ee/teams/lib/queries
- Fixes type check error: Cannot find module

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Optimize isTeamMember check to call function only once

- Extract teamId using nullish coalescing operator
- Single isTeamMember call instead of two
- Cleaner and more efficient logic

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* simplify

---------

Co-authored-by: naaa760 <neh6a683@gmail.com>
Co-authored-by: neha <neha@posthog.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-31 12:05:02 +00:00
Eunjae LeeandDevin AI f00c14d0c1 feat: implement booking calendar view with weekly layout (#24563)
* feat: implement booking calendar view with weekly layout

- Create reusable WeekCalendarView component that displays bookings in a weekly calendar format
- Replace EmptyScreen in BookingsCalendar with the new calendar view
- Calendar view includes:
  - Week navigation with Today, Previous, and Next buttons
  - 7-day week view with time slots from 12 AM to 11 PM
  - Bookings displayed as colored blocks positioned by time
  - Support for event type colors and status-based colors
  - Responsive design that fills the viewport
  - Hover tooltips showing booking details
- Filters remain functional at the top of the view

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use existing Calendar component from weeklyview

- Replace custom calendar implementation with the existing Calendar component
- Use parseEventTypeColor to properly handle event type colors
- Simplify implementation by leveraging existing calendar infrastructure
- Maintain week navigation and filtering functionality

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix imports

* fix: replace isSameOrAfter with isAfter || isSame

- isSameOrAfter method does not exist in dayjs
- Use combination of isAfter and isSame instead

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* remove useBookerTime dependency from weekly calendar view

* modify date range filters

* initial callback

* sort events

* clean up FilterBar

* add showBackgroundPattern

* update styles

* update style

* update styles

* fix type error

* fix error

* update styles

* update styles

* update event colors

* rename component

* persist weekStart on the url

* use FilterBar

* apply feedback

* extract BorderColor type

* use client

* clean up

* adjust styles

* color-code events

* rename borderColor to color

* restore class name

* add feature flag

* update class name

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-31 11:13:41 +00:00
Anik Dhabal Babu 8d4dd0241a fix: disable request reschedule for seated event (#24793) 2025-10-31 10:43:06 +00:00
chauhan_s 90f97c3c92 fix: preserve attendee names during round robin host reassignment when reassignmentReason is required (#24771) 2025-10-31 10:41:35 +00:00
Alex van Andel 1407886612 chore: Set shouldServeCache to falsy, unless specified input (#24778) 2025-10-31 10:34:31 +00:00
Eunjae LeeandDevin AI 139e47fe3b feat: include EventType.seatsPerTimeSlot in bookings get handler response (#24813)
- Add seatsPerTimeSlot field to EventType selection in bookings query
- Refactor conditional array pushes to use if statements instead of && operator to fix lint warnings

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-31 07:33:17 -03:00
Lauris Skraucis 9d4ecf2baa fix: changesets node version (#24812) 2025-10-31 10:27:55 +00:00
Dhairyashil ShindeandUdit Takkar 9d1cf3e70e feat: link advanced event type settings to docs (#24629)
* feat: link advanced event type settings to docs

* Limits and Assignment tab settings

* remove testing code

* add noopener noreferrer rel to links

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-10-31 15:47:11 +05:30
sean-brydon 6beb279a27 chore: add missing metadata i18n strings (#24814)
## What does this PR do?

- Adds new localization strings for various onboarding sections including team and organization settings

## Visual Demo (For contributors especially)

N/A - This PR adds a new component for animations and localization strings that will be used in the onboarding flow.

## Mandatory Tasks (DO NOT REMOVE)

- [ ] I have self-reviewed the code.
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

- Navigate through the onboarding flow to verify that page transitions are smooth with the new animation component
- Check that the new localization strings appear correctly in the UI for team and organization setup screens
- Verify that the `AnimatePresence` component properly handles exit animations when moving between onboarding steps

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-10-31 10:05:22 +00:00
sean-brydon 69e4b12f52 fix: Use index DB instead of local storage for onboarding (#24798)
## What does this PR do?

Implements an IndexedDB storage adapter for the onboarding store to replace localStorage. This allows storing much larger data (up to 50% of available disk space) compared to localStorage's limited quota, making it suitable for storing base64-encoded images like logos and banners during onboarding. The implementation includes a fallback to localStorage if IndexedDB is unavailable.

Sometimes when you uploaded a large image or banner you get this error. Even if its within the bounds of 10mb (which is what we allow)
![image.png](https://app.graphite.dev/user-attachments/assets/f9fad1b6-5c8a-438b-8948-ea299c2ce832.png)

## Visual Demo (For contributors especially)

N/A - This is an infrastructure change with no visual component.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code.
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

- Test the onboarding flow and verify that data persists between page refreshes
- Test uploading large images during onboarding to ensure they're properly stored
- Test in browsers with IndexedDB disabled to verify the localStorage fallback works correctly
- Verify that the onboarding state is properly maintained when navigating through the onboarding steps

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-10-31 09:53:14 +00:00
Anik Dhabal Babu b8098ed3ab test(e2e): optimize email verification timeout to 3 seconds (#24799) 2025-10-31 15:14:44 +05:30
sean-brydon db55b11034 chore(onboarding): redirect if part of orgs or not company email (#24800) 2025-10-31 08:13:23 +00:00
sean-brydon 2273b7ea24 chore: add signout button on onboarding v3 layout (#24801)
<img width="2778" height="1633" alt="CleanShot 2025-10-30 at 16 42 23" src="https://github.com/user-attachments/assets/45d84980-26c9-4cb4-ac85-21dc174dba35" />



<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Added a sign-out button to the onboarding v3 layout and refactored Getting Started to use the shared OnboardingLayout for a consistent header and structure.

- **New Features**
  - Sign-out button in the onboarding footer using next-auth (redirects to /auth/logout).
  - Localized button label via useLocale.

- **Refactors**
  - Getting Started view now wraps content with OnboardingLayout.
  - Removed duplicated header and progress UI from the view.
  - Simplified content container and spacing; layout handles max width and flex.

<sup>Written for commit 830bfd1. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-10-31 08:07:37 +00:00
0a90212980 chore: CalendarEventBuilder - generate calendarEvent without PII using booking (#24678)
* chore: BookingHydrationService - generate calendarEvent without PII

* chore: wip add build calendarEvent from booking in CalEventBuilder

* chore: build calendar event from booking

* remove hydration service

* test: add comprehensive test for CalendarEventBuilder.fromBooking with all properties

- Add vi.mock() calls for external dependencies (getBookerBaseUrl, getTranslation, getCalEventResponses)
- Add comprehensive test 'should create a complete calendar event with all properties using a booking'
- Test covers team scheduling, video calls, seats/webinar, recurring events, custom fields, and all configuration flags
- Fix import paths in CalendarEventBuilder.ts to use @calcom/features prefix
- Fix timestamp format issues in existing tests to use toISOString()
- Fix destinationCalendar length expectations to account for user calendar
- Fix responses format in seats tests to match bookingResponsesSchema

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-31 07:31:50 +00:00
Alex van AndelandDevin AI 2efcfab715 Fix isEventTypeLoggingEnabled bug where empty string matches eventTypeId 0 (#24804)
When BOOKING_LOGGING_EVENT_IDS is set to an empty string, the current
implementation splits it into [''] and Number('') returns 0, causing
any event type with ID 0 to incorrectly trigger debug logging.

This fix:
- Filters out empty/invalid event IDs (NaN, <=0)
- Filters out empty usernames
- Only matches valid, positive event type IDs

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-30 19:32:17 +00:00
Anik Dhabal Babu 3c1dfe8b74 fix: return the actual error message for hitpay (#24792) 2025-10-30 17:58:04 +00:00
Rajiv Sahal e47ddf9835 chore: add handleCreateRecurringBooking prop to booker atom (#24786)
* chore: update Booker platform wrapper props

* fix: pass handle create recurring prop to useHandleBookEvent if prop present

* chore: add changesets
2025-10-30 15:50:17 +00:00
08c62b554e chore: update Booker atom docs (#24755)
* chore: update booker atom docs

* chore: implement PR feedback

* Update docs/platform/atoms/booker.mdx

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: chauhan_s <somaychauhan98@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-10-30 15:46:45 +01:00
b0b94b91fe fix: allow org admin to cancel and reschedule seated bookings (#24640)
* refactor: move org admin related logic to org server

* fix: update cancellation logic to make sure org admin can cancel seated bookings of a team user

* fix: import path

* update bookings repository

* fix: update reschedule endpoint logic to let org admin reschedule bookings for a user

* refactor: make logic more simple

* chore: update platform libraries

* more refactors

* fix: add check to make sure org admin can reschedule booking

* chore: remove unused comments

* test: add e2e tests for org admin reschedule and cancel seated bookings

- Add seated event type creation for testing
- Add test for org admin rescheduling a seated booking for a managed user
- Add test for org admin canceling a full seated booking for a managed user
- Add test for org admin canceling a specific seat in a seated booking

These tests verify the functionality added in PR #24640 which allows
org admins to reschedule and cancel seated bookings for users in their
organization.

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* chore: add cubic feedback

* fix: tests for seated booking management by org admin

* chore: implement PR feedback

* fixup

* chore: update docs

* fixup: get optional user from request and then pass it down to getBookingForReschedule

* fix: validate seatUid before checking booking cancellation status

Move canRescheduleBooking call to happen after input validation
(including seatUid validation for seated bookings) but before the
actual booking creation. This ensures that when trying to reschedule
a seated booking without providing seatUid, users get the proper
'seatUid required' error instead of 'booking has been cancelled' error.

Fixes failing e2e test: 'should not be able to reschedule seated
booking if seatUid is not provided'

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-30 16:43:05 +02:00
Eunjae LeeandDevin AI af61b6d341 feat: move bookings tabs to sidebar navigation (#24605)
* feat: move bookings tabs to sidebar navigation

- Add bookings sub-items (Upcoming, Unconfirmed, Recurring, Past, Cancelled) to sidebar navigation
- Remove HorizontalTabs component from bookings view
- Add redirect from /bookings to /bookings/upcoming for default navigation
- Parent Bookings menu item now automatically navigates to Upcoming sub-item

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* add e2e tests

* address feedback

* add horizontal tab back

* useBuildHref

* update preserveQueryParams logic

* put back lint rule

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-30 15:35:26 +01:00
Udit Takkar 28693aba96 feat: distributed tracking (#24717) 2025-10-30 14:12:22 +00:00
2dc0e2a6f2 fix: use highest role for org admins accessing sub team event types (#24748)
* fix: use highest role for org admins accessing sub team event types

When an org admin who is also a member of a sub team (but only as MEMBER role) tries to update a sub team event type, they were being denied access. This was because the permission check logic was using the team MEMBER role instead of checking both team and org roles and using the highest one.

This fix updates PermissionCheckService.checkPermission() and checkPermissions() to use the highest role between team membership and org membership, similar to how getEventTypePermissions() already works.

Changes:
- Added getHighestRole() helper method to determine the highest role between two roles
- Updated checkPermission() to check both team and org membership and use the highest role
- Updated checkPermissions() to use the same logic
- Added test case for org admin who is team member updating sub team event type

Fixes the issue where org admins get 'permission required eventType.update' errors when updating sub team event types.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: add PBAC-enabled test case for org admin accessing sub team event types

Adds a test case to verify that when PBAC is enabled, org admins who are also members of a sub team (but only with MEMBER role) can still access sub team event types through their org-level ADMIN permissions.

This complements the existing fallback (PBAC disabled) test case and ensures both code paths handle org admin permissions correctly.

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-30 13:59:48 +00:00
sean-brydon 6cbe1c1cf1 chore: Implement onboarding redirect logic in event-types and main page components (#24785)
## What does this PR do?

Currently we load /event-types for a few seconds while the onboarding hook catches up. This adds that logic to the serverside and not just client side to ensure onboarding is triggered

Adds server-side onboarding redirect checks to prevent users from accessing event types pages before completing onboarding. This implementation:

- Creates a new `checkOnboardingRedirect` utility function in a dedicated file
- Applies the redirect check on both the root page and event-types page
- Optimizes performance by using organizationId from session when available
- Handles email verification requirements before redirecting to onboarding
- Supports both legacy and v3 onboarding paths based on feature flags

## How should this be tested?

- Create a new user account that hasn't completed onboarding
- Attempt to access the root page or event-types page directly
- Verify you're redirected to the appropriate onboarding flow
- Test with email verification feature flag enabled/disabled
- Test with onboarding-v3 feature flag enabled/disabled
- Verify users who have completed onboarding can access event-types normally
- Verify organization users aren't redirected to onboarding

## Video Demo

Before:

[CleanShot 2025-10-30 at 10.54.41.mp4 <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/user-attachments/thumbnails/8282decc-a00d-4bc8-9215-fe1c4809fd8f.mp4" />](https://app.graphite.dev/user-attachments/video/8282decc-a00d-4bc8-9215-fe1c4809fd8f.mp4)

After

## [CleanShot 2025-10-30 at 10.54.06.mp4 <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/user-attachments/thumbnails/2acc7601-6c8c-496a-af4d-08dadef9aa2d.mp4" />](https://app.graphite.dev/user-attachments/video/2acc7601-6c8c-496a-af4d-08dadef9aa2d.mp4)

## Checklist

- [x] I have self-reviewed the code
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works
2025-10-30 13:44:11 +00:00
Rodrigo Ehlers 1c2da58d2a feat: add separator support to data table (#24752)
* feat: add separator support to data table

* chore: remove unnecessary comments

* chore: move files to more appropriate places

* fix: border bottom
2025-10-30 14:41:21 +01:00
Lauris Skraucis 7bfdaa3d64 fix: changesets release to npm (#24788)
* fix: changesets release to npm

* chore: resolve merge conflict
2025-10-30 13:33:56 +00:00
c38d2afcf5 fix: Optimized Slots setting not updating on children event types (#24208)
* fixed : Optimized Slots setting not updating on children event types

* updated tests to expect showOptimizedSlots sync

* fixed : Optimized Slots setting not updating on children event types

---------

Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-10-30 12:34:48 +00:00
chauhan_s 807848cce2 fix: require notice threshold when type time (#24784)
* feat: enhance validation for confirmation policy notice threshold

* feat: add confirmation policy validation tests for event types
2025-10-30 14:20:56 +02:00
chauhan_s e9d409c0d5 fix: Modified teamName to be null when host is not fixed (#24728)
* fix: Modified teamName to be null when host is not fixed

* feat: Added test cases for round robin bookings reassignment with fixed and non-fixed hosts

* feat: improve team name handling in round robin reassignment

* refactor: improve booking title validation in reassignment tests
2025-10-30 14:00:25 +02:00
github-actions[bot] 0c43d60039 chore: version packages (#24729)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-30 11:53:22 +01:00
sean-brydon 1173822344 chore: invites to submit hook instead of relying on state (#24744)
## What does this PR do?
Pass invites to submit hook instead of relying on state. State can be out of sync on last step as its not commited onChange but onsubmit. 

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Pass the invite list directly to the onboarding submit hook to avoid stale state and ensure the final step submits the correct invites. Fixes missed or outdated invites during onboarding.

- **Bug Fixes**
  - submitOnboarding now accepts invites as a parameter and uses them for submission.
  - OrganizationInviteView passes invitesData to submitOnboarding instead of relying on store.invites.

<!-- End of auto-generated description by cubic. -->
2025-10-30 09:16:14 +00:00
Anik Dhabal Babu a934cec51a fix: exclude attendee reponses from calendar (#24739) 2025-10-30 07:06:42 +00:00
Hariom Balhara 257acc3f71 fix: Auto Assignment of team member to event when that member is (#24731)
auto-accepted during direct invite to sub-team
2025-10-30 09:42:41 +05:30
Alex van Andel 91063c41f8 chore: Determine to serve cache high level (#24756)
* chore: Determine to serve cache high level

* Fix invalid import

* fix: Cache test
2025-10-29 22:08:23 +00:00
Keith Williams 1e1298fdbc chore: Removed unneeded yarn reinstall API v2 Docker (#24772) 2025-10-29 19:19:52 +02:00
95120e1ff4 feat: add bookingRequiresAuthentication validation to 2024-04-15 booking controller (#24735)
* feat: add bookingRequiresAuthentication validation to 2024-04-15 booking controller

- Add checkBookingRequiresAuthentication method to validate authentication requirements
- Check if user is event type owner, host, team admin/owner, or org admin/owner
- Add comprehensive e2e tests for bookingRequiresAuthentication feature
- Ensure parity with 2024-08-13 controller implementation
- Fix type issue in setPlatformAttendeesEmails method

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: move Prisma calls to repository pattern

- Add findByIdIncludeHostsAndTeamMembers method to EventTypeRepository
- Inject PrismaEventTypeRepository and PrismaTeamRepository into controller
- Replace direct Prisma calls with repository methods in checkBookingRequiresAuthentication
- Use getTeamByIdIfUserIsAdmin for org admin/owner check
- Add repositories to BookingsModule_2024_04_15 providers

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* handle httpException in handleBookingErrors

* test: add test case for authenticated but unauthorized user booking

- Create second user who is not authorized to book the event type
- Verify that authenticated user without proper permissions receives 403 Forbidden
- Test validates that bookingRequiresAuthentication properly checks authorization levels
- Cleanup unauthorized user in afterAll hook

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: add accepted filter to team members and handle org-owned event types

Addresses PR comments from cubic-dev-ai and @ThyMinimalDev:

1. Add accepted: true filter to team.members query
   - Prevents pending team invitations from being treated as authorized
   - Also filter by role to only fetch ADMIN and OWNER roles
   - Reduces payload size and improves query performance

2. Add isOrganization field to team select
   - Enables proper handling of org-owned event types

3. Update authorization logic for org-owned event types
   - Handle case where team.isOrganization is true with no parent
   - Ensure org admins/owners are properly authorized for org-owned events
   - Matches behavior of 2024-08-13 controller

Changes:
- packages/features/eventtypes/repositories/eventTypeRepository.ts:
  * Add where clause to members query with accepted: true and role filter
  * Add isOrganization: true to team select
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts:
  * Update authorization logic to handle org-owned event types
  * Check if team.isOrganization is true when no parentId exists

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-29 16:48:16 +00:00
Keith WilliamsandDevin AI ee00f0d52c feat: Add official docker support (#24672)
* feat: Add official Docker support

* Adding scarf data support

* Comment out pushing the image for now

* Getting env vars ported

* Renamed the job to Release instead of Remote Release

* Move the Dockerfile and docker-compose files to monorepo root

* Remove Slack notifications for failures for now

* Show database container status

* Setting env directly for testing

* Removing env var

* Adding container logs

* Change the volume

* fixing file paths

* Double-quotes wrecking things

* Fixing /calcom paths

* Update permission for scripts

* Fixed the Slack notification

* Updated Slack notification emojis

* Checking the workflow_dispatch input for checkout

* Commenting out the tag checkout for now since our new Docker files are not in main

* Added .dockerignore

* Remove the scarf data export

* Removed extra empty line

* refactor: Create reusable Docker build action for AMD64 and ARM support

- Extract common Docker build logic into reusable composite action
- Create separate workflows for AMD64 and ARM builds that run in parallel
- Both workflows use the same reusable action with platform-specific parameters
- ARM builds use ubuntu-24.04-arm runner and add -arm suffix to tags
- AMD64 builds use buildjet-4vcpu-ubuntu-2204 runner
- Remove old monolithic release-docker.yaml workflow

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Revert "refactor: Create reusable Docker build action for AMD64 and ARM support"

This reverts commit 66d2c1741e094e8d39b928b109edaf67b6a1cc8e.

* refactor: Add parallel AMD64 and ARM Docker builds using reusable action

- Create reusable composite action in .github/actions/docker-build-and-test
- Extract common Docker build, test, and push logic into the action
- Update release-docker.yaml to have two parallel jobs:
  - release-amd64: Builds for linux/amd64 on buildjet-4vcpu-ubuntu-2204
  - release-arm: Builds for arm64 on ubuntu-24.04-arm with -arm suffix
- Both jobs use the same reusable action with platform-specific parameters
- Maintains existing functionality while enabling parallel builds

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Update the ARM action to run on buildjet 4vCPU ARM

* Move the Dockerfile to apps/web

* Revert "Move the Dockerfile to apps/web"

This reverts commit fd91ebe5b4285cfa3416e6f869f567329ece8b23.

* Revert the arm machine back off build jet

* Use node 20

* Set push to true

* Remove Dockerfile.render

* Removed commented Docker lines

* Fixed read me

* Updated README for Docker support

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-29 15:31:02 +00:00
Udit TakkarandKeith Williams 246abe0dd9 perf: add docker ignore in root path (#24585)
* chore: add docker ignore in root path

* chore: add docker ignore in root path

* chore: remove

* chore: remove some more

* chore: remove some more

* Removed unnecessary whitespace

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-10-29 14:16:57 +00:00
Benny Joo 14e845ea1f perf: og image caching v2 (#23189) 2025-10-29 10:36:17 -03:00
8ba65c4450 fix: prevent base64 logo/banner storage in organization onboarding (#24761)
* fix: prevent base64 logo/banner storage in organization onboarding

- Add processOnboardingBrandAssets helper method to BaseOnboardingService
- Process base64 images and upload them before storing in database
- Use uploadAvatar with userId to avoid foreign key issues before Team exists
- Handle both create and update/resume flows
- Ensure OrganizationOnboarding and Team records store regular URLs not base64
- Fixes header size issues when logoUrl is added to session cookies

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: use processed URLs from OrganizationOnboarding record

- Update SelfHostedOnboardingService to use organizationOnboarding.logo/bannerUrl instead of raw input
- Update BillingEnabledOrgOnboardingService payment intent to use processed URLs
- Ensures Team records receive processed URLs, not base64 data

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: remove unused variables and imports

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: extract image processing to helper method and add tests

- Created private processImageField() method to eliminate code duplication
- Uses regex for more robust data URI and URL detection
- Processes logo and bannerUrl in parallel with Promise.all
- Added 2 important tests for base64 image processing:
  1. Verifies base64 conversion with correct resize options (bannerUrl uses maxSize: 1500)
  2. Validates undefined vs null semantics (no-op vs explicit clear)
- Fixed pre-existing lint warnings by replacing 'any' types with proper types

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Improve code

* Fixup organizationId

* simplify

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-10-29 18:39:56 +05:30
sean-brydon aff494f21c chore: refactor onboarding v3 to use reusable components (#24711)
\## What does this PR do?

Refactors the onboarding UI components to use shared layout components across personal and organization onboarding flows. This change:

- Creates reusable `OnboardingCard` and `OnboardingLayout` components
- Implements these components across all onboarding views
- Maintains consistent UI and reduces code duplication
- Improves maintainability by centralizing layout logic

## Visual Demo (For contributors especially)

#### Image Demo:

Before this change, each onboarding view had its own layout implementation with duplicated header, footer, and card structure. After this change, the shared components provide consistent styling and structure.

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code.
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

- Navigate through the onboarding flow for both personal and organization accounts
- Verify that all screens maintain consistent layout and styling
- Check that progress indicators correctly show the current step
- Ensure all functionality (form submissions, navigation between steps) works as expected

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-10-29 12:51:21 +00:00
Lauris Skraucisandchauhan_s 18ad7e348e chore: make atoms release depend on trusted publisher (#24769)
Co-authored-by: chauhan_s <somaychauhan98@gmail.com>
2025-10-29 12:26:33 +00:00
emrysal 78f3d76ae2 chore: release v5.8.7
Post release / release (push) Canceled after 0s
2025-10-29 11:51:10 +00:00
Anik Dhabal Babu 6f9e04c6d9 fix: hosts group missmatch issue (#24757) 2025-10-29 10:46:16 +00:00
Benny JooandAlex van Andel fdb0e5d004 fix: Use isValidPhoneNumber from libphonenumber-js/max (#23353)
* import from max

* fix

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-10-29 08:13:41 +00:00
Rajiv Sahal 268a142370 fix: date overrides missing minutes (#24753) 2025-10-28 22:51:15 +00:00
Alex van AndelandMorgan 29a3892669 chore: add indexes for user delete (#24740)
* chore: Adding indexes for user delete cascade

* Add comments to indicate a partial index has been added on a field

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-28 22:28:40 +00:00
Rajiv Sahal 0223027958 chore: update docs to clarify api v2 supports sms workdlows (#24704)
* chore: update docs to clarify api v2 supports sms workdlows

* chore: implement feedback

* fix: cleanup
2025-10-28 16:03:11 +00:00
d7df154059 fix: Add critical logger for booking created log to prevent stdout buffering issues (#24570)
* Add critical logger for booking created log to prevent stdout buffering issues

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Add comment

* Separate critialLogger into it's own file

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-10-28 12:59:44 -03:00
sean-brydon 51d78e6f9d fix(onboarding): adderss nits for invite link / spacing (#24742)
## What does this PR do?

- Redirects users to the personal settings page after organization creation instead of the getting-started page
- Adds a new `skipToPersonal` function in `useSubmitOnboarding` hook to handle this redirection
- Creates a new `getGettingStartedPathWhenInvited` method in `OnboardingPathService` to provide the correct path for invited users
- Updates all invitation-related code to use the new path method
- Improves UI spacing in the organization invite view

## Visual Demo (For contributors especially)

#### Image Demo (if applicable):
- Before: Users were redirected to `/onboarding/getting-started` or `/getting-started` after organization creation
- After: Users are now redirected to `/onboarding/personal/settings` or `/getting-started` based on feature flag

## Mandatory Tasks (DO NOT REMOVE)

- [ ] I have self-reviewed the code.
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Create a new organization through the onboarding flow
2. Verify you are redirected to the personal settings page instead of getting-started
3. Accept an invitation to an organization as a new user
4. Verify you are directed to the personal settings page after signup
5. Check that the UI spacing in the organization invite view looks correct

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-10-28 14:35:57 +00:00
d5894d9fbc fix: update booking view UI for awaiting payment state (#24577)
* fix: update booking view UI for awaiting payment state

- Show calendar icon instead of green check for awaiting payment
- Update title to show 'Your meeting is awaiting payment' or 'Your meeting is awaiting a payment method'
- Update subtitle to show 'Complete your booking: {title} on {date}'
- Handle both HOLD payment option and regular payment pending states
- Fix unused variable warning

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: correct formatToLocalizedDate parameters

Use proper dateStyle parameter instead of time format number

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-28 14:29:27 +00:00
8b0539028e chore: Adds a users.uuid column (#24659)
* chore: Adds a users.uuid column

* Add uuid backfill

* Remove backfill due to possible locking issues

* feat: Add batched UUID backfill to prevent database locking

Implements a batched approach for backfilling UUIDs on existing users:
- Processes 1000 rows at a time to avoid table locks
- Uses FOR UPDATE SKIP LOCKED to prevent blocking other transactions
- Includes small delays between batches (10ms) to allow other operations
- Logs progress every 10,000 rows for monitoring

This approach is safe for production databases with millions of users.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-10-28 09:17:54 -03:00
Syed Ali Shahbaz c7600d8ead fix: Make no-show dialog scrollable (#24734)
* fix

* --
2025-10-28 12:15:57 +00:00
6f5b8ead75 feat: update Office365 getMainTimeZone to handle new Graph API format and convert Windows timezones to IANA (#23763)
* feat: update Office365 getMainTimeZone to handle new Graph API format and convert Windows timezones to IANA

- Handle new Graph API response format with 'value' field containing Windows timezone names
- Add windows-iana dependency for timezone conversion from Windows to IANA format
- Maintain backward compatibility with legacy direct string response format
- Add proper error handling with fallback to original timezone name if conversion fails
- Log conversion details for debugging and monitoring

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: example app select default value

* fixup! fix: example app select default value

* fix: preserve legacy string timezone behavior, only convert new object format

- Address GitHub comments from supalarry about behavior change concerns
- Preserve original behavior: return legacy string responses as-is without conversion
- Only convert Windows timezones from new Graph API object format
- Add explanatory comments about API format evolution
- Restructure conditional logic to handle formats independently

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* trigger CI with ready-for-e2e label

Co-Authored-By: morgan@cal.com <morgan@cal.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-28 12:15:34 +00:00
fc159fb9ea fix: description label is not focusing on new event-type create modal (#23603)
* fix: description label is not focusing

* changes

---------

Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-10-28 12:02:04 +00:00
b3297f2843 fix(event-type): remove spinner flash before skeleton loads (#23678) (#23679)
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
2025-10-28 11:48:38 +00:00
Rajiv Sahal 1dade81299 refactor: team and org billing portal service (#24497)
* refactor: team and org billing portal service

* fix: implement coderabbit feedback

* fix: move core logic to base service

* remove unused comments
2025-10-28 11:42:22 +00:00
spandevandPallav b2839830c8 update: added empty screen component to empty call history page (#24721)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2025-10-28 11:40:47 +00:00
sean-brydon fa884e8516 chore: Onboarding path service plus redirects (#24679)
* i18n

* WIP icon stuff

* More icon work

* More gradient tuning

* Mvoe plan-icon to planicon.tsx

* Fix cubic suggestion

* Fix darkmode icon and gradients

* Fix type error

* Onboarding path service

* Update usages of onboarding path and getting started hook
2025-10-28 11:10:25 +00:00
3418a25a85 fix: seed script command (#24668)
* feat: add seed-all command to run all seed scripts

- Add seed-all command to packages/prisma/package.json
- Create scripts/seed-all.ts to run seed.ts, seed-insights.ts, and seed-pbac-organization.ts in sequence
- Update Prisma configuration to use seed-all as the default seed command
- Add GitHub workflow to test seed-all command with a real PostgreSQL database

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use correct path resolution in seed-all script

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: simplify database verification step in test workflow

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use seed-all in cache-db action instead of separate workflow

- Update cache-db action to use seed-all command
- Remove test-seed-all.yml workflow as requested

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix error

* change command name

* fix integration tests

* run basic seed by default

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-10-28 10:56:52 +00:00
89cc175d73 feat: add no-show hosts and csat graphs on Insights (#24556)
* feat: Add No-Show Hosts and CSAT insights with beautiful card design

- Add No-Show Hosts Over Time chart with line visualization
- Add CSAT Over Time chart with percentage tracking
- Add Recent No-Show Guests list with email copy functionality
- Redesign all KPI cards as individual separated cards with curved edges
- Add proper TRPC endpoints and database queries for new insights
- Follow Cal.com design patterns with consistent styling
- All charts now have individual cards with rounded-2xl borders and shadow-sm elevation
- Fix all linting issues with unused imports and variables

* coderabbit fixes

* fix(insights): address review feedback on charts

* fix(insights): correct dayjs timezone usage for type safety

* Update packages/features/insights/services/InsightsBookingBaseService.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Fix InfoBadge import path

* Wrap InfoBadge in span for styling

* Add insights charts and i18n keys

* Fix ChartCard usage and double card wrapping issues

* Remove double card wrapping for chart components

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2025-10-28 10:39:39 +00:00
Eunjae Lee c7c8564b63 fix(insights): convert string filter values to numbers for integer columns (#24730)
## What does this PR do?

Fixes PostgreSQL error "operator does not exist: integer = text" when filtering
by `bookingStatusOrder` and `bookingUserId` fields. Frontend sends filter values as
strings, but these database columns are integers requiring type conversion.

Changes:
- Convert `bookingStatusOrder` filter values from strings to numbers
- Convert `bookingUserId` filter values from strings to numbers
- Update tests to use numeric values for `bookingStatusOrder` filters
- Add test for string-to-number conversion in `bookingUserId` filter
- Fix `Prisma.Sql` composition in 3 integration tests

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] N/A - I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Converts string filter values to numbers for integer columns in Insights routing to prevent PostgreSQL type errors. Fixes filtering by bookingStatusOrder and bookingUserId when the frontend sends strings.

- **Bug Fixes**
  - Cast bookingStatusOrder and bookingUserId filter values to numbers and use = ANY([...]).
  - Update tests to expect numeric arrays; add test for string-to-number conversion on bookingUserId.
  - Correct Prisma.sql composition in three integration tests before calling $queryRaw.

<!-- End of auto-generated description by cubic. -->
2025-10-28 10:34:56 +00:00
b620581d7a feat: Add endpoint to add attendees to existing bookings (#24414)
* feat: add endpoint to add attendees to existing bookings

- Created POST /v2/bookings/:bookingUid/attendees endpoint
- Added AddAttendeesInput_2024_08_13 for input validation
- Added AddAttendeesOutput_2024_08_13 for response format
- Created BookingAttendeesService_2024_08_13 for business logic
- Created BookingAttendeesController_2024_08_13 for API endpoint
- Added validation to check for duplicate attendee emails
- Integrated with existing booking and event type repositories
- Added validateAndTransformAddAttendeesInput method to InputBookingsService
- Fixed pre-existing ESLint no-prototype-builtins warnings
- Left placeholder for custom booking field validation logic

Co-Authored-By: somay@cal.com <somaychauhan98@gmail.com>

* refactor: move booking attendee operations to dedicated repository

* refactor: move repository files into dedicated repositories directory

* feat: validate guests field availability before adding attendees to booking

* feat: migrate addAttendees API to use existing addGuests handler

* refactor: remove unused validateAndTransformAddAttendeesInput method from InputBookingsService

* refactor: rename attendees to guests in booking API endpoints and types

* refactor: rename booking-attendees to booking-guests for consistency

* WIP: add e2e tests for add booking guests endpoint

* faet: improve guest booking tests

* refactor: extract getHtml method in email templates

* feat: add email toggle support for guest invites based on OAuth client settings

* refactor: addGuests handler

* feat: add SMS notifications when adding guests to existing bookings

* refactor: rename add-attendees to add-guests for consistent terminology

* refactor: added repository pattern in addGuests.handler

* test: add attendee scheduled email spy to booking guests tests

* fix: use event type team ID instead of user org ID for booking permission check

* Update BookingEmailSmsHandler.ts

* Remove comments

* refactor: rename booking guests to booking attendees

* refactor: rename guest-related methods to use attendees terminology for consistency

* update api docs

* refactor: restructure addGuests handler to top

* refactor: update guest email format to use object structure in booking tests

* docs: clarify API version header requirement for booking attendees endpoint

* docs: add email notification details to booking attendees API documentation

* refactor: rename booking attendees to guests for consistency

* refactor: rename attendees to guests in booking API endpoints

* feat: add email validation for guest invites

* feat: improve error handling for guest booking failures

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-28 14:16:07 +05:30
chauhan_s c0530cc91c chore: add changeset for new atoms release (#24709) 2025-10-28 14:15:34 +05:30
emrysal f738b3bc0a chore: release v5.8.6
Post release / release (push) Canceled after 0s
2025-10-28 02:30:12 +00:00
Morgan 0853b4ca35 chore: add missing parseIntPipe on oauth client user endpoints (#24714) 2025-10-28 01:58:37 +00:00
Rodrigo Ehlers 8be05b1dc5 chore: explicitly set timezone for local (#24719) 2025-10-27 20:29:16 +00:00
Keith Williams 71515ad17c refactor: remove tRPC references from packages/lib (#24553) 2025-10-27 18:13:25 +00:00
sean-brydon 66234ffba9 chore: illustrations to getting-started page in onboarding v3 (#24673)
* i18n

* WIP icon stuff

* More icon work

* More gradient tuning

* Mvoe plan-icon to planicon.tsx

* Fix cubic suggestion

* Fix darkmode icon and gradients

* Fix type error
2025-10-27 17:32:06 +00:00
Rodrigo Ehlers 66c5f810ea fix: remove singular query that was using slow OR query (#24715)
## What does this PR do?

<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->

Removes and replaces the singular query that was still using the slow OR query from prisma. It was mainly used on the public booking page and triggered after someone entered their email (600ms debounce delay).

## Visual Demo (For contributors especially)

Internal change only nothing changes on the UI or business logic.

#### Video Demo (if applicable):

N/A

#### Image Demo (if applicable):

N/A

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). If N/A, write N/A here and check the checkbox.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests -->

Basically the same as https://github.com/calcom/cal.com/pull/24298 since it touches relevant code.

1. Have a user that has the setting to prevent impersonation on.
2. Go to another users public booking page of any meeting.
3. Try to enter the email of the first user into the booking for.
4. Wait 1 second and make sure the button shows "Verify email".

## Checklist

<!-- Remove bullet points below that don't apply to you -->

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my changes generate no new warnings
2025-10-27 17:11:05 +00:00
81d9d84b4a fix: make next environment variables optional, externalize react runtime (#24613)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-10-27 15:16:05 +00:00
sean-brydon 6ddc666827 feat: onboarding v3 - app install flow personal (#24710)
## What does this PR do?

Refactors the personal onboarding flow by creating reusable components for better code organization and maintainability. The changes include:

- Creates shared components for the onboarding experience: `OnboardingLayout`, `OnboardingCard`, `InstallableAppCard`, and `SkipButton`
- Implements a custom hook `useAppInstallation` to manage app installation state and callbacks
- Enhances the video app connection step to automatically set the first connected video app as default
- Improves the calendar connection flow with proper installation handling
- Adds visual indicators for connected apps

## Visual Demo (For contributors especially)

The refactored components maintain the same visual appearance while improving code structure and reusability.

## Mandatory Tasks

- [x] I have self-reviewed the code
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

- Go through the personal onboarding flow
- Test connecting calendar apps in step 3
- Test connecting video apps in step 4
- Verify that the first connected video app is automatically set as default
- Check that connected apps show the "connected" indicator
- Verify that skipping steps works correctly

## Checklist

- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
2025-10-27 15:01:09 +00:00
sean-brydonandcubic-dev-ai[bot] 01346abb85 feat: Add personal v3 onboarding flow (#24681)
* WIP personal onbaording flow

* Add i18n

* Fix overflow clip blockin timezone select

* Remove duplicate label

* Move to two column approach

* Restore lock fle

* Remove duplicate key in common json

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Update personal-settings-view.tsx

* Fix endpoint

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-10-27 13:36:46 +00:00
Lauris Skraucisandrez1coder 3d9650c841 docs: cancelling normal booking (#24703)
* docs: cancelling normal booking

* Update apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts

Co-authored-by: rez1coder <66778119+rez1coder@users.noreply.github.com>

---------

Co-authored-by: rez1coder <66778119+rez1coder@users.noreply.github.com>
2025-10-27 12:39:11 +00:00
Anik Dhabal Babu f8ede75dd8 fix: few flaky e2e tests (#24690)
* fix: flaky e2e tests

* fix one more flakes

* update
2025-10-27 08:38:59 -03:00
sean-brydon 435587f043 feat: onboarding v3 teams (#24573)
## What does this PR do?
This PR is stacked on https://github.com/calcom/cal.com/pull/24299 this adds the v3 flow for onboarding with teams.

    
<!-- This is an auto-generated description by cubic. -->
---

## Summary by cubic
Adds the v3 team onboarding flow with Details, Brand, and Invite steps, including slug validation, branding, and member invites. Updates routing to support the Team plan and creates teams with Stripe checkout when needed.

- **New Features**
  - Team Details: name and slug with async availability check and URL preview.
  - Team Brand: hex color picker and logo upload with live preview.
  - Team Invite: add/remove emails, invite role toggle (Member/Admin), and form validation.
  - State: adds teamDetails, teamBrand, and teamInvites to the onboarding store with actions.
  - Creation: new useCreateTeam hook; redirects to Stripe if checkout URL is returned, or to Getting Started on success.
  - Routing/Auth: protected team pages (details, brand, invite) and updates plan selection to route to /onboarding/teams.

<!-- End of auto-generated description by cubic. -->
2025-10-27 11:00:11 +00:00
Anik Dhabal BabuandDevin AI e5abe93940 fix: Add beforeAll hooks to ensure organization settings are properly configured in integration tests (#24674)
The flaky test failures were caused by the tests depending on the database being properly seeded with the isAdminAPIEnabled flag set to true for the Acme organization. The tests would fail randomly when the database wasn't properly seeded or when the organization settings weren't configured correctly.

This fix adds beforeAll hooks to the failing integration tests to ensure that:
1. The Acme organization has isAdminAPIEnabled set to true
2. The Dunder Mifflin organization has isAdminAPIEnabled set to false

This ensures consistent test behavior regardless of the database state and prevents the flaky failures.

Fixes the following failing tests:
- isAdmin.integration-test.ts: Returns org-wide admin when user is set as such & admin API access is granted
- retrieveScopedAccessibleUsers.integration-test.ts: Returns members when admin user ID is supplied and members IDs are supplied
- retrieveScopedAccessibleUsers.integration-test.ts: Returns members when admin user ID is an admin of an org
- _get.integration-test.ts: Returns bookings for org users when accessed by org admin
- _patch.integration-test.ts: Allows PATCH when user is org-wide admin

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-27 05:32:05 -03:00
c3a5158a53 feat: add availabilityLoaded embed event (#21350)
* feat: add availabiityLoaded embed event

* chore

* fix

---------

Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
2025-10-27 06:22:09 +00:00
Sagnik PalandDhairyashil Shinde a9e14b9816 fix/23800-capitalize-button-lable-consistency (#23822)
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-10-27 11:23:03 +05:30
Dhairyashil Shinde e207f40611 refactor: update the config to auto close stale pr (#24701) 2025-10-26 23:28:38 +00:00
Shrey-Sutariya 4ca2076c72 fix: add spacing between form and submit button in TeamEventTypeForm (#24680)
* fix: add spacing between form and submit button in TeamEventTypeForm

* fix: address PR feedback - add bottom padding to form div
2025-10-26 12:46:19 +00:00
Akshat Bajetha 959b803d84 fix: event-title-overflow (#24693)
* fix: event-title-overflow

* fix: title overflow in multiple components

* fix: title overflow in readonly component
2025-10-26 12:14:21 +00:00
Albin_Baby 7f6136004c fix: enable overflow (#24560) 2025-10-25 16:18:59 +00:00
spandevandVolnei Munhoz bb79368b2d fix: empty event types page doesn't show no more results anymore (#24655)
* fix: empty event types page doesn't show no more results anymore

* update: conditional rendering of results button

---------

Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
2025-10-25 15:32:44 +00:00
chauhan_sandDevin AI 70825dd138 fix: define process.env variables in atoms vite config to prevent 'process is undefined' errors (#24665)
- Add all process.env variables used by Next.js code to the define section
- This ensures they are replaced at build time and don't cause runtime errors in Vite projects
- Fixes #24213

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-25 20:38:48 +05:30
Volnei Munhoz 05c399db9c lint stage not loading config from file - using root instead (#24671) 2025-10-25 10:51:18 +00:00
Morgan 57776b829b fix: old rec booking endpoint api v2 (#24669)
* fix: old rec booking endpoint api v2

* fixup! fix: old rec booking endpoint api v2

* fixup! fixup! fix: old rec booking endpoint api v2
2025-10-25 07:24:48 -03:00
Kartik 7fd28c39f3 fix: improve mobile positioning for link dialog in form builder checkbox editor (#24268)
* Updated positionEditorElement function to respect viewport boundaries

* cleanup
2025-10-25 10:03:22 +00:00
Pallav ff17aa79fc updated animation for drop down menu (#23650) 2025-10-25 09:23:50 +00:00
emrysal 578be32936 chore: release v5.8.5
Post release / release (push) Canceled after 0s
2025-10-25 00:25:46 +00:00
Dhairyashil ShindeandAnik Dhabal Babu b183239ff5 chore: add autocomplete for inputs - name, phone, location (#24422)
* add autocomplete for inputs - name, phone, location

* Addressed coderabits comments

* autocomplete for email and url

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-10-24 21:36:41 +00:00
Pallav 013e614397 fix: handle empty location in event types (#24342) 2025-10-24 17:58:34 -03:00
sean-brydonandAnik Dhabal Babu 6843ced3db Use correct memebrships for permission calculations (#24653)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-10-24 07:44:47 +01:00
Anik Dhabal Babu 7318015a6e fix: Delete all workflow reminders when workflow is deleted (#24615) 2025-10-24 02:54:08 +00:00
emrysal fc4d0a6aa3 chore: release v5.8.4
Post release / release (push) Canceled after 0s
2025-10-24 00:27:10 +00:00
sean-brydon 8e0cdf3671 feat: Onboarding V3 (#24299)
* feat: redirect to new onboarding flow

* Getting started

* Brand details

* Preview organization brands

* Orgs team pages

* Invite team steps

* Move to global zustand store

* Few darkmdoe fixes

* Wip onboarding + stripe flow

* Default plan state

Server Action for gettting slug satus of org

* Remove onboardingId

* Confirmation prompt

* Update old onboarding flow handlers to handle new fields

* update onboarding hook

* Filter out organization section for none -company emails

* Match placeholders to users domain

* Drop migration

* Wip new onboarding intent

* WIP flow for self-hosted. Same service call just split logic

* WIP

* Add TODO

* Use onboarding user type instead of trpc session

* WIP

* WIP

* pass role and team name from onboarding to save in schema

* Add test to ensure role + name + team are persisted into onboarding table

* migrate roles to enum values

* Update ENUM

* Fix type error

* Redirect if flag is disabled

* Revert packages

* Revert all packages/* changes to original branch point

* Layout fixes + design

* Add slugify

* Support saving brand,logo and banner

* Cleanup

* iMobile fixes

* More mobile and darkmdoe fixes

* Add I18n

* Fix lock file

* Fix types

* Fix types errors

* Copy changes
2025-10-23 20:01:54 +01:00
Eunjae LeeandDevin AI fcd9480f9f fix: update seed-insights.ts Prisma connection handling for v6.16 (#24660)
* fix: update seed-insights.ts to use correct Prisma import and connection handling

- Change prisma import from named export to default export to match Prisma v6.16 changes
- Update promise chain from .then().catch() to .catch().finally() for proper connection cleanup
- Comment out duplicate runSeed() call that was causing the script to execute twice
- Fixes TypeError: Cannot read properties of undefined (reading '$connect')

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix implementation

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-23 15:59:05 +00:00
Eunjae LeeandDevin AI 09ddbe886f refactor: make DataTableProvider framework-agnostic by requiring tableIdentifier (#24513)
* refactor: make DataTableProvider framework-agnostic by requiring tableIdentifier

- Remove Next.js usePathname dependency from DataTableProvider
- Make tableIdentifier a required prop instead of optional
- Update all usages to provide explicit tableIdentifier values
- This makes DataTableProvider usable in non-Next.js contexts

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use usePathname at usage sites instead of hardcoding tableIdentifier

- Add validation in DataTableProvider for empty/nullish tableIdentifier
- Use usePathname() in Next.js apps to pass pathname as tableIdentifier
- Use descriptive identifiers for non-Next.js package components
- This keeps DataTableProvider framework-agnostic while allowing Next.js apps to use pathname

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* use pathname instead of hard-coded identifiers

* change type of tableIdentifier

* simplify

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-23 15:32:16 +02:00
Eunjae LeeandDevin AI 4ac8a51bc2 feat: migrate nuqs from v1.20.0 to v2.7.2 (#24514)
* feat: migrate nuqs from v1.20.0 to v2.7.2

- Update nuqs package version in apps/web/package.json
- Add NuqsAdapter wrapper in root layout for App Router compatibility
- Server-side imports already using correct 'nuqs/server' path
- All existing parsers and usage patterns remain compatible
- No breaking changes to application functionality
- Fix unnecessary escape characters in fontFamily regex

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* move adapter

* revert

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-23 10:24:22 -03:00
82951cd04e chore: [Booking Flow Refactor - 5] Move post booking things to separate service BookingEventHandlerService starting with HashedLink usage handling (#24025)
* chore: Move post booking stuff to separate service

* refactor: improve ISP compliance in BookingEventHandlerService

- Refactor updatePrivateLinkUsage to only accept hashedLink parameter instead of full payload
- Remove shouldProcess function and inline isDryRun check for better clarity
- Addresses feedback from PR #24025

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* define only what is used

* Define hashed-link-service as well in api-v2

* fix: export HashedLinkService through platform-libraries

- Add HashedLinkService to platform-libraries/private-links.ts
- Update API V2 to import from platform library instead of direct path
- Fixes MODULE_NOT_FOUND error in API V2 build

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-23 15:05:55 +03:00
ae87fdcc9f perf: rename eventTypes.heavy to eventTypesHeavy (#24630)
Post release / release (push) Canceled after 0s
* Rename eventTypes.heavy to eventTypesHeavy

* Update eventTypes lib types

* Remove trpc and trpc client heavy resolve endpoint

* Update shared file

* Fix comments

* Rename path

* Fix wait for URL path

* Fix API endpoint in event-types.e2e.ts test

* fix: Import WorkflowType from enums instead of client

The WorkflowType enum should be imported from @calcom/prisma/enums
rather than @calcom/prisma/client. This was causing integration tests
to fail with 'Cannot read properties of undefined (reading EVENT_TYPE)'
because the enum wasn't being properly exported from the client.

This fixes the remaining integration test failures after the Prisma 6.16
upgrade.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: anik@cal.com <adhabal2002@gmail.com>
2025-10-23 07:32:06 -03:00
emrysal 35e29c4bee chore: release v5.8.3 2025-10-23 09:21:19 +00:00
emrysal 387a1704f3 chore: release v5.8.3 2025-10-23 01:36:11 +00:00
Dhairyashil Shinde 3fb8c5bbc5 fix: impersonate correct user using email (#24648) 2025-10-23 06:42:20 +05:30
Anik Dhabal BabuandDevin AI 626585f5d0 fix: Handle empty array in Prisma OR conditions for Prisma 6.16 (#24638)
After upgrading to Prisma 6.16.0, empty arrays in 'in' clauses within OR
conditions are now optimized to return no results. This caused integration
tests to fail when querying memberships with empty memberUserIds arrays.

Changes:
- Dynamically build OR conditions to exclude empty 'in' arrays
- Simplify getAllAdminMemberships to use 'in' instead of OR for roles
- Fixes retrieveScopedAccessibleUsers and getAccessibleUsers queries

Fixes integration test failures:
- apps/api/v1/test/lib/utils/retrieveScopedAccessibleUsers.integration-test.ts
- apps/api/v1/test/lib/bookings/[id]/_patch.integration-test.ts

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-22 13:00:26 -03:00
Joe Au-Yeung 4d3727db12 Default fetchCrm to true for getRoutedUrl (#24635) 2025-10-22 14:44:42 +00:00
emrysal f6641d5173 chore: release v5.8.3 2025-10-22 13:59:25 +00:00
Keith Williams f9b21206a2 fix: Don't run migrations for bundle analysis (#24634) 2025-10-22 13:25:51 +00:00
Keith Williams 96821c0026 fix: CI env var blocking migrations (#24628)
* fix: CI env var blocking migrations

* Remove the DIRECT_DATABASE_URL from production build to not trigger migrations
2025-10-22 12:50:46 +00:00
Keith Williams 3d5e4754af chore: Remove DIRECT_DATABASE_URL from production build in CI (#24632) 2025-10-22 12:22:56 +00:00
613e9f0788 fix: invalidate old password reset tokens when new one is requested (#24607)
* fix: invalidate old password reset tokens when new one is requested

Security fix: Previously, old password reset tokens remained valid
even after requesting a new one, creating a potential account takeover
vulnerability. This change ensures that when a user requests a new
password reset link, all previous valid tokens for that email are
immediately invalidated.

Changes:
- Expire all existing valid tokens before creating new one
- Add E2E test to verify old tokens are invalidated
- Prevent potential account takeover scenario

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Clean up code by removing blank line

Removed unnecessary blank line in forgot-password.e2e.ts.

* test: fix strict mode violation in password reset test

Use getByRole to specifically target the heading element instead of
text locator which was matching both the heading and button.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-22 12:35:07 +01:00
Saurabh SinghandKeith Williams 1261247e94 chore: added missing packages/prisma/client/* (#24624)
* addedd missing packages/prisma/client/*

* Keep packages/prisma/client/index.ts

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-10-22 10:48:08 +00:00
2ad843ffbb test: fix few flaky e2e tests (#24564)
* Add consistent ordering to seat references queries and fix ESLint warnings

- Add orderBy clause to seatsReferences in bookings list query
- Add orderBy clause to seatsReferences in getBookingToDelete query
- Ensures seat references are always returned in consistent order (by ID ascending)
- Prevents race conditions when matching seat references by user email
- Fix ESLint no-unused-expressions warnings by converting to if statements

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* update

* Add ordering to attendee queries in tests for consistency

- Add orderBy clause to all attendee queries in booking-seats.e2e.ts
- Ensures attendees are queried in consistent order before mapping to seats
- Prevents mismatch between test expectations and actual seat order
- Fix unused variable warning

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Fix seat ordering to use attendeeId instead of seat ID

- Order seats by attendeeId in both bookings list and getBookingToDelete queries
- This ensures seats are returned in the same order as attendees were created
- Fixes mismatch where seat IDs and attendee IDs use different auto-increment sequences
- Also add attendeeId to seatsReferences select for consistency
- Fix ESLint warnings by converting && expressions to if statements

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Remove orderBy from bookingSeats queries

* update

* fix another test

* fix flakes

* Fix test to order seats by attendeeId to match backend ordering

The test was ordering seats by seat ID, but the backend orders by attendeeId. This caused flakiness because seat IDs and attendee IDs use different auto-increment sequences and can be in different orders. Now both test and backend use the same ordering (attendeeId), ensuring references[1] consistently refers to the second attendee's seat.

Also remove unused 'user' variable from test.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Change orderBy from attendeeId to id in query

* Implement seatReferenceUid check in booking flow

Added logic to handle missing seatReferenceUid by reloading the page and retrying the action.

* Reduce wait time and update visibility check

* Update visibility check for 'Seats available' text

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-22 11:14:15 +05:30
6923b97cd2 feat: upgrade Prisma to 6.16.0 with no-rust engine (#23816)
* feat: upgrade Prisma to 6.16.0 with no-rust engine

- Update Prisma packages to 6.16.0
- Add PostgreSQL adapter dependency
- Configure engineType: 'client' and provider: 'prisma-client' in schema
- Update Prisma client instantiation with PostgreSQL adapter
- Remove binaryTargets from generators (not needed with library engine)
- Fix schema view issue by removing @id decorator from BookingTimeStatusDenormalized
- Fix ESLint warning by removing non-null assertion

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Web app running but types wrecked

* web app running but build and type issues

* Removed the connection pool

* Fixed zod type issue

* Fixed types in booking reference extension

* Fixed test issues

* Type checks passing it seems

* Using cjs as moduleFormat

* Fixing Prisma undefined

* fix: update prismock initialization for Prisma 6.16 compatibility

- Add @prisma/internals dependency for getDMMF()
- Restructure prismock initialization to use createPrismock() with DMMF
- Create Proxy that's returned from mock factory for proper spy support
- Fixes 89 failing unit tests with 'Cannot read properties of undefined (reading datamodel)' error
- Based on workaround from prismock issue #1482

All unit tests now pass (375 test files, 3323 tests passed)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: cast serviceAccountKey to Prisma.InputJsonValue in bookingScenario.ts

- Apply type cast at lines 2493 and 2535
- Fixes type errors from Prisma 6.16 upgrade
- Follows established pattern from delegationCredential.ts
- Add eslint-disable for pre-existing any types
- Rename unused appStoreLookupKey parameter to satisfy lint
- All 3323 tests passing

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: remove whitespace-only lines from bookingScenario.ts

- Remove blank lines where eslint-disable comments were replaced
- Cleanup from pre-commit hook formatting

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Update is-prisma-available-check.ts

* fix: remove datasources config when using Prisma Driver Adapters

- Update customPrisma to create new adapter when datasources URL is provided
- Remove datasources config from API v2 Prisma services (already in adapter)
- Fixes 'Custom datasource configuration is not compatible with Prisma Driver Adapters' error

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use Pool instances for PrismaPg adapters in index.ts

- Create Pool instance before passing to PrismaPg adapter
- Update customPrisma to create Pool for custom connection strings
- Matches working pattern from API v2 services
- Fixes 'Invalid `prisma.$queryRawUnsafe()` invocation' error

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Not using queryRawUnsafe

* Trying anything at this point

* Make sure the DB is ready first

* Don't auto run migrations in CI mode

* Revert "Make sure the DB is ready first"

This reverts commit 2b20bd45c974f3d7e07d8b904bc7fcdae37cce03.

* Dynamic import of prisma

* Commenting where it seems to break

* Backwards compatability for API v2

* fix: add explicit type annotations for map callbacks in API v2

- Add type annotation for map parameter in memberships.repository.ts
- Add type annotation for map parameter in stripe.service.ts
- Fixes implicit 'any' type errors from stricter Prisma 6.16.0 type inference

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add explicit type annotations for API v2 map callbacks

- users.repository.ts:292: add Profile & { user: User } type
- memberships.service.ts:19-20: add Membership type to filter callbacks

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add explicit type annotation for attributeToUser in organizations-users.repository.ts

- organizations-users.repository.ts:63: add AttributeToUser with nested relations type

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add explicit Membership type annotations in teams.repository.ts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use API v2 dedicated Prisma client to support adapter in PrismaClientOptions

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Running API v2 build commands together so they all get the space size var

* Fixing Maximum call depth exceeded error

* fixed type issues

* Trying to make the seed more stable

* Revert "Trying to make the seed more stable"

This reverts commit 1fd4495e6af7acd7981cda7dedec3168979b0e9d.

* Fixed path to prisma client

* Fixed type check

* Fix eslint warnings

* fix: externalize @prisma/adapter-pg and pg in platform-libraries Vite config

- Add @prisma/adapter-pg and pg to external dependencies list
- Add corresponding globals for these packages
- Fix Prisma client aliases to point to packages/prisma/client instead of node_modules
- Add Node.js resolve conditions to prefer Node.js exports
- Keep commonjsOptions.include for proper CommonJS transformation
- Add eslint-disable for __dirname in Vite config file
- Remove problematic prettier/prettier eslint comment

This fixes the 'Extensions.defineExtension is unable to run in this browser environment' error when running yarn generate-swagger in apps/api/v2 after upgrading to Prisma v6.16 with the no-rust engine approach.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: update Prisma imports in API v2 services to use package path

- Change imports from '../../../generated/prisma/client' to '@calcom/prisma/client'
- Fixes CI error: Cannot find module '../../../../../packages/prisma/generated/prisma/client.ts'
- Aligns with backwards compatibility re-export structure after Prisma v6.16 upgrade

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove .ts extension from Prisma client path mapping in tsconfig

- Remove file extension from @calcom/prisma/client path mapping
- Fixes runtime error: Cannot find module '../../../../../packages/prisma/generated/prisma/client.ts'
- TypeScript path mappings should not include file extensions per best practices
- Allows Node.js to correctly resolve to .js files at runtime

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: resolve Prisma 6.16.0 type incompatibilities in bookingScenario tests

- Changed InputPayment.data type from PaymentData to Prisma.InputJsonValue
- Changed createCredentials key parameter from JsonValue to InputJsonValue
- Removed unused PaymentData type definition
- Resolves type errors at lines 709 and 1088 without using 'as any' casts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove non-existent Watchlist fields from test fixtures

- Remove createdById from isLockedOrBlocked.test.ts (lines 15, 20)
- Remove severity and createdById from _post.test.ts (line 110)
- These fields don't exist in Watchlist model schema after Prisma 6.16.0 upgrade
- Resolves TS2353 errors without using 'as any' casts

Relates to PR #23816

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: api v2 imports generated prisma and platform libraries

* fix: resolve type errors from Prisma 6.16 upgrade

- Add missing markdownToSafeHTML import in AppCard.tsx
- Fix organizationId null handling in fresh-booking.test.ts
- Remove non-existent createdById field from Watchlist test utils

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Put back some external rollups

* Added back the resolve conditions

* Stop using Pool directly

* chore: remove prisma bookingReferenceExtension and update calls

* fix: organizations-admin-not-team-member-event-types.e2e-spec.ts

* chore: bring back POOL in api v2 prisma clients

* chore: remove Pool but await connect

* fixup! chore: remove Pool but await connect

* chore: bring back Pool on all clients

* chore: end pool manually

* chore: test with pool max 1

* chore: e2e test prisma max  pool of 1 connection

* chore: give more control over pool for prisma module with env

* remove pool from base prisma client

* chore: prisma client in libraries use pool

* Fixed types

* chore: log pool events and improve pooling

* Fixing some types and tests

* Changing the parsing of USE_POOL

* fix: ensure Prisma client is connected before seeding to prevent transaction errors

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* chore: adjust pools

* chore: add process.env.USE_POOL to libraries vite config

* fix: v1 _patch reference check bookingRef on the booking find

* fix: v1 get references deleted null for system admin

* test: add integration tests for bookingReference soft-delete behavior

- Add bookingReference.integration-test.ts to test repository methods
- Add handleDeleteCredential.integration-test.ts to test credential deletion cascade
- Add booking-references.integration-test.ts for API v1 integration tests
- All tests verify soft-delete behavior without using mocks
- Tests use real database operations to ensure soft-deleted records persist
- Cover scenarios: replacing references, credential deletion, querying with filters

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: convert booking-references test to actual API endpoint testing

- Modified _get.ts to export handler function for testing
- Refactored integration test to call API handler instead of directly testing Prisma
- Added timestamps to test data to avoid conflicts
- Tests now verify API layer correctly filters soft-deleted references
- All 4 tests passing

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add explicit prisma.$connect() call to seed-insights script

With Prisma 6.16 and the PostgreSQL adapter, scripts need to explicitly call $connect() before running database operations to ensure the connection pool is properly initialized. This prevents 'Transaction already closed' errors.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add $connect() to main() execution in seed-insights

Both main() and createPerformanceData() entry points need explicit prisma.$connect() calls with the Prisma 6.16 PostgreSQL adapter.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: always use connection pool for Prisma PostgreSQL adapter

Enable connection pooling by default for the Prisma adapter to prevent
transaction state issues during seed operations. Without a pool, each
operation creates a new connection which can lead to 'Transaction already
closed' errors during heavy database operations like seeding.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Revert "fix: always use connection pool for Prisma PostgreSQL adapter"

This reverts commit 6724bb08e42bc0a94846069de83b04db0aeb8e8b.

* fix: enable connection pool for db-seed in cache-db action

Set USE_POOL=true when running yarn db-seed to use connection pooling
with the Prisma PostgreSQL adapter. This prevents 'Transaction already
closed' errors during seeding by maintaining stable database connections.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add safety check for undefined ownerForEvent in seed script

Prevent 'Cannot read properties of undefined' error when orgMembersInDBWithProfileId
is empty. This can happen if organization members fail to create or when there's a
duplicate constraint violation causing early return.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: v1 _patch reference check bookingRef

* fix: increase pool size and add timeout settings to prevent transaction errors

- Increase max connections from 5 to 10
- Add connectionTimeoutMillis: 30000 (30 seconds)
- Add statement_timeout: 60000 (60 seconds)

These settings help prevent 'Unknown transaction status' errors during
heavy database operations like seeding by giving transactions more time
to complete and allowing more concurrent connections.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Revert "fix: increase pool size and add timeout settings to prevent transaction errors"

This reverts commit 148264f1f1861dfb09a082937a3e2b49e78fc41a.

* fix: remove standalone execution in seed-app-store to prevent premature disconnect

The seed-app-store.ts file had a standalone main() call at the bottom
that would execute immediately when imported, including a prisma.$disconnect()
in its .finally() block.

This caused issues because:
1. seed.ts imports and calls mainAppStore()
2. The import triggers the standalone main() execution
3. This standalone execution disconnects prisma after completion
4. seed.ts then tries to call mainHugeEventTypesSeed() but prisma is disconnected
5. This leads to 'Unknown transaction status' errors

Fixed by removing the standalone execution since mainAppStore() is already
called programmatically from seed.ts which manages the connection lifecycle.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use require.main check to prevent premature disconnect when imported

Added require.main === module check so seed-app-store.ts:
- Runs standalone with proper connection management when executed directly
  via 'yarn seed-app-store' or 'ts-node seed-app-store.ts'
- Does NOT run standalone when imported as a module by seed.ts,
  preventing premature prisma disconnect

This fixes 'Unknown transaction status' errors while maintaining
backward compatibility for direct execution.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: seed apps before creating users to prevent foreign key constraint violation

Reordered seeding operations to call mainAppStore() before main() because:
- main() creates users with credentials that reference apps via appId foreign key
- mainAppStore() seeds the App table with app records
- Apps must exist before credentials can reference them

This fixes the 'Foreign key constraint violated on Credential_appId_fkey' error
that occurred when creating credentials before the apps they reference existed.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Removing functional changes of deleted: null

* Apply suggestion from @keithwillcode

* refactor: move seedAppData call to bottom of main() in seed.ts

Moved seedAppData() call from seed-app-store.ts to the bottom of main()
in seed.ts to ensure the 'pro' user is created before attempting to
create routing form data for them.

Changes:
- Exported seedAppData function from seed-app-store.ts
- Removed seedAppData() call from the main() export in seed-app-store.ts
- Added seedAppData() call at the bottom of main() in seed.ts
- Updated standalone execution in seed-app-store.ts to still call
  seedAppData() when run directly via 'yarn seed-app-store'

This ensures proper ordering: apps seeded → users created → routing
form data created for existing users.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: move routing form seeding from seed-app-store.ts to seed.ts

Moved the routing form seeding logic (previously in seedAppData function)
from seed-app-store.ts to be inline at the bottom of main() in seed.ts.

This ensures the 'pro' user is created before attempting to create routing
form data for them.

Changes:
- Removed seedAppData function and seededForm export from seed-app-store.ts
- Removed import of seedAppData from seed.ts
- Added routing form seeding logic inline at bottom of main() in seed.ts

Seeding order: apps → users (including 'pro') → routing forms

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add deleted: null filter to bookingReference update operations

- Add deleted: null filter to API v1 PATCH endpoint to prevent updating soft-deleted booking references
- Add deleted: null filter to DailyVideo updateMeetingTokenIfExpired and setEnableRecordingUIAndUserIdForOrganizer
- Add comprehensive test coverage for PATCH endpoint soft-delete behavior
- Tests verify that soft-deleted booking references cannot be updated
- Tests verify that only active booking references can be updated successfully

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* revert: remove deleted: null filters to preserve existing functionality

Per @keithwillcode's feedback, reverting the soft-delete filtering changes to preserve existing functionality in this PR. This PR should focus only on the Prisma upgrade itself.

- Reverted API v1 PATCH endpoint change
- Reverted DailyVideo adapter changes (updateMeetingTokenIfExpired and setEnableRecordingUIAndUserIdForOrganizer)
- Removed test file that was added for soft-delete behavior testing

Addresses comments:
- https://github.com/calcom/cal.com/pull/23816#discussion_r2448854197
- https://github.com/calcom/cal.com/pull/23816#discussion_r2448860594
- https://github.com/calcom/cal.com/pull/23816#discussion_r2448860833

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* test: restore and update booking reference tests to match existing functionality

Updated tests to verify existing behavior where PATCH endpoint can update
booking references regardless of their deleted status. This matches the
current implementation after reverting the deleted: null filters.

Changes:
- Restored test file that was previously deleted
- Updated PATCH tests to expect successful updates of soft-deleted references
- Renamed test suite to 'Existing functionality' to clarify intent
- Tests now verify that the PATCH endpoint preserves existing behavior

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* test: rename booking-references test to integration-test

The test requires a database connection and should run in the integration
test job, not the unit test job. Renamed from .test.ts to .integration-test.ts
to match the repository's testing conventions.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-10-21 20:02:03 +01:00
e639237088 feat: SMS workflow action for form triggers #3 (#23673)
* allow routing forms for activeOn

* use repository function to get routing forms

* remove unnecessary code

* adjust logic in update handler

* add triggers to api v2

* remvoe unused file

* rename to getAcitveOnOptions handler

* remove routingFormOptions handler

* clean up getActiveOnOptions

* refactor WorkflowService

* remove logs

* remove unused

* fix: type check

* fix: missed before after events for recurring

* fix: calendarEvent handleMarkNoShow

* fix error message

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* don't query disabled routing forms

* create tasker function

* add tasker code

* move isFormTrigger function

* small adjustments + todo comments

* remove email to host action for form triggers

* throw trpc error if email to host is added as step

* fix dialog on how to use form responses as variables

* remove add variable dropdown for form triggers

* remove form workfows in event workflows tab

* improvements for workflow logic on form submission

* review fixes

* base setup for seperate schedule functions (evt and form)

* add missing BOOKING_PAID workflow trigger

* fix pathname

* fix: test for BOOKING_REQUESTED

* fix activeOn ids

* pass hideBranding and smsReminderNumber

* adjustments to reminderScheduler

* create empty scheduelForForm functions

* pass locale and timezone with form user

* pass formData instead of responses

* pass timeFormat and locale

* reusable function for email sending and reminder creation

* implement scheduleEmailReminderForForm

* remove added editor field from merge conflict

* don't support cal.ai action with form triggers

* throw bad request if form trigger and cal.ai is combined

* add tests for scheduleFormWorkflows

* add form submission tests

* remove form response varibe info

* clean up workflow actions

* fixes for getting template options

* pass triggerType to getAllWorkflows

* move reusable logic to scheduleSMSReminder

* add formdata to param type

* type fixes for text reminder managers

* implement scheduleSMSReminderForForm

* fix import

* fix isAuthorizedToAddActiveOnIds

* disble whatsapp action

* implement triggerFormSubmittedNoEventWorkflow

* code clean up

* Merge branch 'devin/1755107037-add-workflow-triggers' into feat/routing-form-workflow-triggers

* fix type errors

* remove async from getSubmitterEmail

* fix type errors

* revert cal.ai changes

* fix type error

* add sublogger

* code clean up

* fix type errors

* remove label for attendee whatsapp action

* code clean up

* fixes saving teams on org workflows

* fix type error

* code improvements for activeOn ids

* Revert "code improvements for activeOn ids"

This reverts commit 0a3590a4e2ce541b17d63483ad86ed458795a6a3.

* improve variable name

* fix unit tests

* small fixes

* type fixes

* remove unused translation keys

* fix merge conflict issues

* code clean up

* remove SMS action support

* remove more SMS code

* add missing imports

* set custom template for form action

* type fixes

* fix tasker endpoint

* fix duplicate check

* fix workfows.test.ts

* use repository funciton to getHideBranding

* add  back SMS action

* add back changes to smsReminderManager

* code clean up

* fix hasDuplicateSubmission

* code clean up

* select only needed properties

* remove repository functions

* Revert "remove repository functions"

This reverts commit 7aa47b1c59c9abd7f964ebf26f746934c53a44f4.

* add scheduleWorkflows function

* Revert "add scheduleWorkflows function"

This reverts commit fe5db4fe3b65e2743c95475d585300cab98beed7.

* move type to /types

* Revert "move type to /types"

This reverts commit 91e0152154594b3772a801a426260068a8ccea54.

* revert changes causing type errors

* remove import

* remove unused import

* Revert "remove unused import"

This reverts commit 1916768c875ea5d0ac5598ccb8f9c796c5622dc9.

* revert changed from attempt to fix type errors

* pass object to gt all workflows

* fix isAuthorized check

* trigger filtering

* remove form submitted no event booked code

* remove form submitted no event from schema

* remove more code

* remove test

* fixes

* add getSubmitterEmail function

* add trigger

* small fixes

* add missing workflow DTOs

* small fixes

* use activeOnWithChildren

* fix active on when switching trigger type

* remove add variable dropdown

* add getAllWorkflowsFromRoutingForm to WorkflowService

* fix error caused by undefined evt

* fix type error

* fix type error

* fix tests

* code clean up

* final fixes and clean up

* remove console.log

* remove template text form from triggers

* add routing form repoditory function

* fix bug with key

* add comments

* fix test

* add missing await

* use predefined FormSubmissionData type

* add .trim() to sms message

* pass contextData instead

* add missing trigger in update-workflow.input.ts

* ForEvt and ForForm function for aiPhoneCallManager

* chore: add support for form workflows on api v2

* fixup! chore: add support for form workflows on api v2

* use only repository functions in update handler

* move all prisma queries from list.handler

* review suggestions

* chore: handle workflows api v2

* chore: handle workflows api v2, split in 2 endpoints

* fix workflow step creation

* remove connect agent and fixes types

* add type to workflow

* chore: use workflow type in apiv2 WorkflowsOutputService

* update worklfow type on update

* chore: use workflow type in apiv2 WorkflowsOutputService

* fix template body for torm trigger

* some UI fixes for email subject/body

* resetting email body when changing form triggers

* use type field to query workflows

* clean up all old active on values

* remove responseId from all funciton calls

* remove undefined from updateTemplate

* refactor: split routing form and event-type workflows code

* refactor: split routing form and event-type workflows code

* fix template  text when adding action

* chore: don't rename WorkflowActivationDto to avoid ci blocking

* refine update schedule to use only allowed actions

* fix type error

* don't allow whatsapp action with form trigger

* fix type error

* return early if activeOn array is empty

* fix: from step type in BaseFormWorkflowStepDto

* fixup! fix: from step type in BaseFormWorkflowStepDto

* api v2 updates

* move all prisma calls to repository (service/workflows.ts)

* use FORM_TRIGGER_WORKFLOW_EVENTS for form queries

* use userRepository

* use FORM_TRIGGER_WORKFLOW_EVENTS in isFormTrigger

* code clean up

* code clean up

* use repository functions in formSubmissionValidation.ts

* remove action check in update handler

* add back trpc  import

* fix agent repository functions

* add SMS actions to allowed form action constants

* remove unsued import

* fixes for offset api v2

* add missing responseId

* fix failing test

* fix failing test

* remove unused imports

* chore: handle sms step action for form worklfow in dtos

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-21 15:28:10 +00:00
Dhairyashil Shinde 5bc1fbb8c2 fix: Allow booking details view for round robin with no hosts (#24250)
* Fix: Allow booking details view for round robin with no hosts

* Fix: Allow booking details view for round robin with no hosts

* fix: include the missing fields with defaults

* fix: include the missing fields with defaults
2025-10-21 14:04:42 +00:00
Volnei MunhozandDevin AI e310931417 fix: remove circular dependency in packages/prisma (#24596)
- Replaced DeploymentRepository import with inline implementation
- Created InlineDeploymentRepository class implementing IDeploymentRepository
- Breaks circular dependency: deployment.ts -> prisma/index.ts -> usage-tracking.ts -> deployment.ts
- Verified with madge: no circular dependencies found

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-21 13:14:15 +00:00
Alex van Andel 17944311c3 chore: Remove inMaintenanceMode from APIv1 for increased robustness (#24576) 2025-10-21 12:58:31 +00:00
Volnei MunhozandDevin AI d82f87aa2a perf: Remove circular dependencies - wip (#24586)
* wip

* refactor(emails): remove circular dependencies from packages/emails

- Extract renderEmail imports to use direct path (../src/renderEmail) instead of index
- Create utility files for shared types and functions:
  - lib/utils/team-invite-utils.ts: TeamInvite type and utility functions
  - lib/utils/booking-redirect-types.ts: IBookingRedirect type
  - lib/utils/email-types.ts: OrganizationCreation and EmailVerifyCode types
  - lib/utils/date-formatting.ts: getFormattedDate utility function
- Update all template files to import renderEmail directly from ../src/renderEmail
- Update React template components to import from utility files instead of class templates
- This eliminates all circular dependencies within packages/emails (reduced from 234 to 0 internal circular deps)

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* refactor(trpc): remove circular dependency in routing-forms

- Extract ZFormByResponseIdInputSchema to separate schema file
- Create getResponseWithFormFields.schema.ts to break circular dependency
- Update imports in _router.ts and getResponseWithFormFields.handler.ts
- Fix eslint warnings by updating deprecated rule names
- This eliminates the circular dependency within packages/trpc (reduced from 1 to 0 internal circular deps)

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix(emails): correct TeamInvite type definition

- Make isExistingUserMovedToOrg required (not optional)
- Make prevLink and newLink non-optional (string | null)
- Add back JSDoc comment for isAutoJoin field
- This fixes type check errors in CI

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* wip

* Fixes types folder

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-21 12:24:47 +00:00
Volnei MunhozandDevin AI 6aa21aceb8 refactor: remove unused packages from transpiledPackages (#24595)
Remove @calcom/embed-react and @calcom/embed-snippet from the
transpiledPackages configuration in apps/web/next.config.js as they
are not imported from source in apps/web.

Only @calcom/embed-core is actually used and requires transpilation
since it's imported from source paths like @calcom/embed-core/src/embed-iframe.

The other two packages have pre-built dist files and are not directly
imported in the web app, so Next.js doesn't need to transpile them.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-21 12:07:33 +00:00
Hariom Balhara 870ad57a7e Rename handleNewBooking to BookingCreateService (#23682) 2025-10-21 14:52:16 +03:00
fddee71829 refactor: extract bookings list and calendar views (#24486)
* refactor: extract bookings list and calendar views with nuqs state management

- Extract list-related code into BookingsListView component
- Create empty BookingsCalendarView component for future implementation
- Add nuqs query param state management for view toggle (defaults to list)
- Update bookings-listing-view to conditionally render views
- No visible changes to users (list view remains default)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: move data fetching logic to parent component

- Keep useFilterValue calls, trpc query, columns, flatData, bookingsToday, finalData, and table setup in parent component
- BookingsListView now receives data as props instead of fetching it
- This allows both list and calendar views to share the same data source

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add customView column back to render booking items

The customView column was inadvertently removed during refactoring. This column is crucial as it renders the actual BookingListItem components, the "today" header, and the "next" header for the bookings list.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename files for better clarity

- Renamed bookings-listing-view.tsx → bookings-view.tsx (parent view)
- Renamed bookings-list-view.tsx → BookingsList.tsx (list component)
- Renamed bookings-calendar-view.tsx → BookingsCalendar.tsx (calendar component)
- Moved list and calendar components from views/ to components/ directory
- Updated all imports to reflect new structure

This creates a clearer hierarchy where -view is the orchestrator and components are the renderers.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up implementation

* clean up types

* revert unnecessary changes

* Update packages/features/data-table/GUIDE.md

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-10-21 11:09:47 +00:00
David Johnson 6f15a5ab0f Add turbo package to dependencies (#24572)
This is needed due to Docker build errors indicating that turbo was not an available command.
2025-10-21 09:05:55 +00:00
Dhairyashil Shinde 1fd64c5d7b chore: improve text for booker active booking limit (#24526)
* chore: improve text for booker active booking limit

* update keys to new one for lingo .dev future recognition
2025-10-21 08:54:16 +00:00
Parship Chowdhury f8614f11ff fix: Description field duplicating content when editing Event Types (#24233)
* fix: description field duplicating content when editing Event Types

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>

* optimal approach

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>

* rm dead code

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>

---------

Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>
2025-10-21 04:35:37 -03:00
Hariom Balhara 5e5e77236a chore: Add skeleton for BookingCancelService (#24038) 2025-10-21 12:29:17 +05:30
Daniel Adeboye 4cee53b07c feat: support northflank deployment (#24571) 2025-10-20 19:47:06 +00:00
Eunjae LeeandDevin AI c289fac008 refactor: make timezone a required prop in Calendar component (#24567)
* refactor: make timezone a required prop in Calendar component

- Remove useBookerTime hook from Calendar.tsx
- Add timezone as required prop in CalendarState type
- Update all parent components to pass timezone prop:
  - packages/features/bookings/Booker/components/LargeCalendar.tsx
  - packages/features/calendar-view/LargeCalendar.tsx
  - packages/features/troubleshooter/components/LargeCalendar.tsx
- All parent components now use useTimePreferences hook to get timezone

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* use right implementation

* remove a line

* use user's timezone instead of booker timezone

* get timezone from calendar store

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-20 13:59:59 +00:00
Keith WilliamsandDevin AI 68f9e86cdd fix: remove circular dependency by moving useLastUsed hook to auth features (#24552)
- Move useLastUsed hook from packages/lib/hooks to packages/features/auth/lib/hooks
- Update imports in SAMLLogin.tsx and login-view.tsx
- Remove cross-package tsconfig include of ../trpc/types/router.d.ts from packages/lib/tsconfig.json

This fixes the issue where the IDE was unnecessarily initializing packages/ui/tsconfig.json
when navigating to definitions in packages/lib. The hook was importing from @calcom/ui/classNames,
creating a circular dependency since packages/ui depends on packages/lib.

By moving the hook to packages/features/auth where it's actually used, we eliminate the
circular dependency without adding tailwind dependencies to packages/lib.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-19 10:14:45 -03:00
Keith Williams 5da754db65 perf: Remove tRPC types from @calcom/lib (#24551) 2025-10-19 13:14:25 +00:00
5791 changed files with 538862 additions and 288824 deletions
-82
View File
@@ -1,82 +0,0 @@
# Cal.com Development Guide for AI Agents
This directory contains comprehensive documentation for AI agents working on the Cal.com codebase.
## Quick Navigation
- **[Commands](commands.md)** - Build, test, and development commands
- **[Knowledge Base](knowledge-base.md)** - Knowledge base & best practices
- **[Architecture Overview](#architecture-overview)** - System structure and patterns
## Getting Started
Cal.com is a monorepo using Yarn workspaces and Turbo for build orchestration. The main application is in `apps/web/` with shared packages in `packages/`.
### Key Directories
- `apps/web/` - Main Next.js application
- `packages/prisma/` - Database schema and migrations
- `packages/trpc/` - API layer using tRPC
- `packages/ui/` - Shared UI components
- `packages/features/` - Feature-specific code
- `packages/app-store/` - Third-party app integrations
## Architecture Overview
### Database Layer
- **Prisma ORM** with PostgreSQL
- Schema in `packages/prisma/schema.prisma`
- Always use `select` instead of `include` for better performance
- Never expose `credential.key` field in API responses
### API Layer
- **tRPC** for type-safe APIs
- Routers in `packages/trpc/server/routers/`
- Authentication handled via NextAuth.js
### Frontend
- **Next.js 13+** with App Router in some areas
- **React 18** with TypeScript
- **Tailwind CSS** for styling
- Internationalization with `next-i18next`
## Common Patterns
### Error Handling
- Use early returns to reduce nesting
- Throw descriptive errors with proper error codes
- Prefer composition over prop drilling
### Performance
- Avoid O(n²) logic in backend code
- Minimize Day.js usage in performance-critical paths
- Use `select` queries to only fetch needed data
- Consider using `.utc()` for Day.js operations
### Security
- Never commit secrets or API keys
- Always validate input data
- Use proper authentication checks
- Never expose sensitive credential fields
## Testing Strategy
- **Unit tests** with Vitest
- **Integration tests** for complex workflows
- **E2E tests** with Playwright
- Test files use `.test.ts` or `.spec.ts` extensions
## Pull Request Guidelines
For large PRs (>500 lines or >10 files):
- Split by feature boundaries
- Separate database migrations, backend logic, frontend components
- Create dependency chains that can be merged sequentially
- Pattern: Database → Backend → Frontend → Tests
-56
View File
@@ -1,56 +0,0 @@
# Coding Standards & Best Practices
## Import Guidelines
### Type Imports
```typescript
// ✅ Good - Use type imports for TypeScript types
import type { User } from "@prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
// ❌ Bad - Regular import for types
import { User } from "@prisma/client";
```
## Code Structure
### Early Returns
- Prefer early returns to reduce nesting: `if (!booking) return null;`
### Composition Over Prop Drilling
- Use React children and context instead of passing props through multiple components
### Security Rules
```typescript
// ❌ NEVER expose credential keys
const user = await prisma.user.findFirst({
select: {
credentials: {
select: {
key: true, // ❌ NEVER do this
}
}
}
});
// ✅ Good - Never select credential.key field
const user = await prisma.user.findFirst({
select: {
credentials: {
select: {
id: true,
type: true,
// key field is excluded for security
}
}
}
});
```
-596
View File
@@ -1,596 +0,0 @@
# Knowledge Base - Product & Domain-Specific Information
## Repo note for calcom/cal.com
The whole thing is a monorepo. You need to be working in the apps/web folder.
Linting and Formatting
- Run lint with report generation: `yarn lint:report`
- Run type checking: `yarn type-check:ci --force`
- Run auto-fix: `yarn lint -- --fix`
Development
- Install dependencies: `yarn`
- Set up environment:
- Copy `.env.example` to `.env`
- Generate keys with `openssl rand -base64 32` for both `NEXTAUTH_SECRET` and `CALENDSO_ENCRYPTION_KEY`
- Configure Postgres database URL in `.env`
- Set DATABASE_DIRECT_URL to the same value as DATABASE_URL
Database Setup
- Development: `yarn workspace @calcom/prisma db-migrate`
- Production: `yarn workspace @calcom/prisma db-deploy`
When setting up local development database, it'll create a bunch of users for you. The passwords are the same as the username. e.g. 'free:free' and 'pro:pro'
PR Requirements
- PR title must follow Conventional Commits specification
- For most PRs, you only need to run linting and type checking
- E2E tests will only run if PR has "ready-for-e2e" label
Logging
- Control logging verbosity by setting `NEXT_PUBLIC_LOGGER_LEVEL` in .env:
- 0: silly
- 1: trace
- 2: debug
- 3: info
- 4: warn
- 5: error
- 6: fatal
## When addressing issues in the Cal.com repository
When working on the Cal.com repository, prioritize fixing type issues before addressing failing tests. Running `yarn type-check:ci --force` to identify and fix TypeScript errors should be done first, as these errors are often the root cause of test failures. Only after resolving type issues should you move on to fixing failing tests with `TZ=UTC yarn test`.
## When creating pull requests
Create pull requests in draft mode by default, so that actual human can mark it as ready for review only when it is.
## When developing Playwright tests in the Cal.com repository
Always ensure Playwright tests pass locally before pushing code. The user requires fast local e2e feedback loops instead of relying on CI, which is too slow for development iteration. Never push test code until those tests are passing locally first.
## When fixing failing tests in the Cal.com repository
When fixing failing tests in the Cal.com repository, take an incremental approach by addressing one file at a time rather than attempting to fix all issues simultaneously. This methodical approach makes it easier to identify and resolve specific issues without getting overwhelmed by the complexity of multiple failing tests across different files. Focus on getting each file's tests passing completely before moving on to the next file.
To identify and fix issues in the Cal.com codebase:
1. Run `yarn type-check:ci --force` to identify TypeScript type errors and get fresh results always, bypassing any caching issues
2. Run `yarn test` to identify failing unit tests
3. Address both type errors and failing tests before considering the task complete
4. Type errors often need to be fixed first as they may be causing the test failures
## When implementing mock services in the Cal.com test files
When mocking calendar services in Cal.com test files, implement the Calendar interface rather than adding individual properties from each specific calendar service type (like FeishuCalendarService). Since all calendar services implement the Calendar interface and are stored in a map, the mock service should also implement this interface to ensure type compatibility. This approach is more maintainable than trying to add all properties from each specific calendar service implementation. For complex mocks that cause type compatibility issues with deep mocks, consider using simpler fake implementations that directly implement the required interfaces instead of trying to match all properties of the original service classes. When needed, you can modify other mock files to support your implementation rather than trying to force compatibility with existing mocks.
## When implementing mocks for Cal.com app-store integrations
When mocking app-store resources in Cal.com tests, prefer implementing simpler mock designs that directly implement the required interfaces rather than trying to match complex deep mock structures created with mockDeep. This approach is more maintainable and helps resolve type compatibility issues. The user encourages creative solutions and refactoring to better designs when the standard mocking approach causes persistent type errors.
## When implementing workflow triggers in the Cal.com repository
To trigger workflows in Cal.com, use the `scheduleWorkflowReminders` function. This is the standard approach used throughout the codebase for triggering any workflow. Before implementing new workflow triggers, examine existing implementations in the codebase to understand the pattern. The function filters workflows by trigger type and processes each workflow step. Key locations where this is used include booking handlers, confirmation processes, and other booking-related events.
## When making changes to Prisma schema in Cal.com
After making changes to the Prisma schema in Cal.com and creating migrations, you need to run `yarn prisma generate` to update the TypeScript types. This is especially important when switching Node.js versions, after adding new fields to models, or after pulling changes that include Prisma schema updates, as it ensures the TypeScript compiler recognizes the updated schema structure. If you encounter errors related to missing enum values (like CreationSource.WEBAPP), running `yarn prisma generate` will typically resolve these issues by regenerating the TypeScript types from the schema.
If you encounter enum generator errors during the Prisma generate step (like "Cannot find module './enum-generator.ts'"), run `yarn install` first before trying to generate. This ensures all dependencies are properly installed before the generation process.
Whenever you change the schema.prisma file, remember to always consolidate migrations by squashing them as declared in the Prisma docs: https://www.prisma.io/docs/orm/prisma-migrate/workflows/squashing-migrations. This helps maintain a clean migration history and prevents accumulation of multiple migration files.
## When reviewing PRs in the Cal.com repository
When asked to review a PR, focus on providing a clear summary of what the PR is doing and its core functionality. Avoid getting sidetracked by CI failures, testing issues, or technical implementation details unless specifically requested. The user prefers concise, focused reviews that prioritize understanding the main purpose and changes of the PR.
## When running Playwright tests in the Cal.com repository
Use the command format `PLAYWRIGHT_HEADLESS=1 yarn e2e [test-file.e2e.ts]` to run Playwright tests instead of the standard `yarn playwright test` command. This format includes the proper timezone setting, virtual display server, and uses the repository's e2e runner.
## When running tests in the Cal.com repository
When running tests in the Cal.com repository, use the TZ=UTC environment variable (e.g., `TZ=UTC yarn test`) to ensure consistent timezone handling. This prevents timezone-related test failures that might occur when tests are run in different environments or by different developers with varying local timezone settings.
## When working on calendar cache features in the Cal.com codebase
The calendar cache system follows specific patterns in `packages/features/calendar-cache-sql`. When implementing provider-specific calendar cache services (like for Outlook/Office365), the provider-specific code should be placed in the corresponding provider directory (e.g., `packages/app-store/office365calendar`).
## When working on PRs in the Cal.com repository
When making changes to the Cal.com codebase, always run type checks locally using `yarn type-check:ci` before concluding that CI failures are unrelated to your changes. Even if errors appear in files you haven't directly modified, your changes might still be causing type issues through dependencies or type inference. Compare type check results between the main branch and your feature branch to confirm whether you've introduced new type errors.
## When working on type issues in the Cal.com repository
Type casting with "as any" is strictly forbidden in the Cal.com codebase. When encountering Prisma type incompatibilities or other TypeScript type issues, proper type-safe solutions must be used instead, such as Prisma extensions system, type parameter constraints, repository pattern isolation, explicit type definitions, and extension composition patterns that are already established in the codebase.
## When working on UI layout changes in the Cal.com web application
The event types page UI components are located in `apps/web/modules/event-types/views/event-types-listing-view.tsx`. This file contains the layout implementation for the search bar and team tabs components on the event types listing page.
Changes to shared UI patterns (like tab layouts and button alignments) need to be checked across multiple views to maintain consistency:
- Event types page layout: `apps/web/modules/event-types/views/event-types-listing-view.tsx`
- Bookings page layout: `apps/web/modules/bookings/views/bookings-listing-view.tsx`
- Common elements like tabs, search bars, and filter buttons should maintain consistent alignment across views
## When working on workflow triggers or similar enum-based features in the Cal.com codebase
To add new workflow triggers:
1. Check packages/prisma/schema.prisma for existing webhooks and workflow trigger enums as reference
2. Add the same enums to workflows (only when asked by user specifically, or else focus on users requirement)
3. Add enums to packages/features/ee/workflows/lib/constants.ts for UI display
4. Add translations to en/locale.json using the format {enum}_trigger (all lowercase). Webhook triggers serve as the reference implementation pattern for workflow triggers.
## When working with app-store integrations in Cal.com
The Cal.com repository uses generated files (*.generated.ts) for app-store integrations. These files are created by the app-store-cli tool. When making structural changes to how integrations are imported or used, you need to update CLI code that generates these files. Typically manual changes to the *.generated.ts files are not made. That was only for PR 19771 for a proof-of-concept. Recent changes have moved from dynamic imports to static map-based imports for better performance. When working with browser components in the app-store, static imports should be used rather than dynamic imports (using Next.js' dynamic function) to maintain consistency with the performance improvements.
When modifying the app-store-cli build.ts file, you must ensure it correctly handles all types of generated files:
1. Regular service files (calendar.services.generated.ts, crm.services.generated.ts, etc.) need default imports
2. Browser component files (apps.browser-addon.generated.tsx, etc.) may require dynamic imports with Next.js
3. After making changes to build.ts, always verify all generated files have the correct imports by checking each file type
The lazyImport parameter in getExportedObject() determines whether to use dynamic imports (for browser components) or static imports (for server-side services).
## When working with branches in the Cal.com repository
When asked to move changes to a different branch in the Cal.com repository, use git commands to commit existing changes to the specified branch rather than redoing the work. This is more efficient and prevents duplication of effort. The user prefers direct branch operations over reimplementing the same changes multiple times.
## When working with calendar events in the Cal.com codebase
Cal.com events in Google Calendar can be identified by checking if the iCalUID ends with "@Cal.com" (e.g., "2GBXSdEixretciJfKVmYN8@Cal.com"). This identifier is used to distinguish Cal.com bookings from other calendar events for data storage and privacy purposes.
## When working with CI/CD in the Cal.com repository
When reviewing CI check failures in Cal.com:
1. E2E tests can be flaky and may fail intermittently
2. Focus only on CI failures that are directly related to your code changes
3. Infrastructure-related failures (like dependency installation issues) can be disregarded if all code-specific checks (type checking, linting, unit tests) are passing
## When working with database models in Cal.com
Database models in Cal.com are defined in `packages/prisma/schema.prisma`. When adding new fields to models:
1. For timestamp fields like `createdAt` and `updatedAt`:
- Do not set default values if you want existing records to have null values
- Only new records should get timestamps automatically
- For `updatedAt` fields, ensure they're updated when records are modified
2. Create a migration using `npx prisma migrate dev --name migration_name` to update the database schema
3. When implementing cache-related features that require timestamp tracking, always update the database schema first before modifying application code that references those fields. The schema changes must be completed and migrated before the application can successfully query or use the new fields.
## When working with generated files in the Cal.com repository
When fixing imports in Cal.com's generated files (like packages/app-store/apps.browser-*.generated.tsx), always check the actual exports in the source files first. For EventTypeAppCardInterface components, they likely use named exports rather than default exports, requiring imports like `import * as ComponentName from "./path"` instead of `import ComponentName from "./path"`. This verification step is crucial when working with browser-addon, browser-appsettings, browser-eventtypesettings, and browser-install generated files. For these files, if you're seeing import errors, check whether the components are exported as default exports in their source files and adjust your import statements accordingly.
## When working with git and CI systems
Always push committed changes to the remote repository before waiting for or checking CI status. Waiting for CI checks on unpushed local commits is backwards - the CI runs on the remote repository state, not local commits. The proper sequence is: commit locally, run local checks, push to remote, then monitor CI status.
## When working with imports/exports in the Cal.com codebase
When working with imports in the Cal.com codebase, particularly in app-store integrations, pay attention to whether modules use named exports or default exports. Many services like VideoApiAdapter, CalendarService, and PaymentService are exported as named exports, but the actual export name may differ from the generic service type (e.g., `export class AppleCalendarService` instead of `export class CalendarService`). When importing these services, verify the actual export name in the source file and use the appropriate named import syntax (e.g., `import { AppleCalendarService } from "./applecalendar/lib/CalendarService"` or with renaming `import { AppleCalendarService as ApplecalendarCalendarService } from "./applecalendar/lib/CalendarService"`). Always check the actual export pattern and name in the source file to determine the correct import syntax.
## When working with tRPC components in the Cal.com repository
When making changes that affect tRPC components or after pulling updates that modify tRPC-related files, you need to follow a specific build order:
1. First run `yarn prisma generate` to ensure all database types are up-to-date
2. Then run `cd packages/trpc && yarn build` to rebuild the tRPC package
This sequence ensures that type definitions are properly generated before building the tRPC components that depend on them, preventing type errors during compilation.
## When working with workflows or webhooks in the Cal.com repository
Workflows and webhooks are two completely separate features in Cal.com with different implementations and file structures. The workflow constants file is located at `packages/features/ee/workflows/lib/constants.ts`, not in the webhooks directory. When working on workflow triggers, do not reference or use webhook trigger implementations - they are distinct systems that should not be confused or mixed.
## When adding new feature flags to the Cal.com repository
To seed new feature flags in Cal.com, create a Prisma migration using the command `yarn prisma migrate dev --create-only --name seed_[feature_name]_feature`. The migration file should be placed in `packages/prisma/migrations/` with a timestamp prefix format like `20250724210733_seed_calendar_cache_sql_features/migration.sql`. Follow the pattern from existing feature seeding migrations like `packages/prisma/migrations/20241216000000_add_calendar_cache_serve/migration.sql` for the SQL structure. The migration should INSERT the new features into the `Feature` table with appropriate type (like `OPERATIONAL`) and default `enabled` status for manual team enablement.
## When adding new UI elements or text strings to Cal.com
All UI strings in Cal.com must be properly translated using the i18n system. This includes:
- Labels for new UI elements (like dropdown labels, settings headers)
- Option values that are displayed to users
- Any text that appears in the interface
Even if some related strings are already translated (like "Bookings" and "Insights"), new strings must be explicitly added to the translation system.
## When creating a pull request
### Title
- Use conventional commits: `feat:`, `fix:`, `refactor:`
- Be specific: `fix: handle timezone edge case in booking creation`
- Not generic: `fix: booking bug`
### Size Limits
- **Large PRs** (>500 lines or >10 files) are not recommended.
- Guide the user how to split large PRs into smaller ones.
## When handling errors
### Descriptive Errors
```typescript
// ✅ Good - Descriptive error with context
throw new Error(`Unable to create booking: User ${userId} has no available time slots for ${date}`);
// ❌ Bad - Generic error
throw new Error("Booking failed");
```
### Error Types
```typescript
// ✅ Good - Use proper error classes
import { TRPCError } from "@trpc/server";
throw new TRPCError({
code: "BAD_REQUEST",
message: "Invalid booking time slot",
});
```
## Basic Performance Guidelines
- Aim for O(n) or O(n log n) complexity, avoid O(n²)
- Use database-level filtering instead of JavaScript filtering
- Consider pagination for large datasets
- Use database transactions for related operations
## When querying database
Prefer Select over Include:
```typescript
// ✅ Good - Use select for performance and security
const booking = await prisma.booking.findFirst({
select: {
id: true,
title: true,
user: {
select: {
id: true,
name: true,
email: true,
}
}
}
});
// ❌ Bad - Include fetches all fields
const booking = await prisma.booking.findFirst({
include: {
user: true, // This gets ALL user fields
}
});
```
## Avoid barrel imports
```typescript
// ❌ Bad - Avoid importing from index.ts barrel files
import { BookingService, UserService } from "./services";
// ✅ Good - Import directly from source files
import { BookingService } from "./services/BookingService";
import { UserService } from "./services/UserService";
// ❌ Bad
import { Button } from "@calcom/ui";
// ✅ Good - Import directly from source files
import { Button } from "@calcom/ui/components/button";
```
## File Naming Conventions
### Repository Files
- **Must** include `Repository` suffix, PascalCase matching class: `PrismaBookingRepository.ts`
### Service Files
- **Must** include `Service` suffix, PascalCase matching class, avoid generic names: `MembershipService.ts`
### General Files
- **Components**: PascalCase (e.g., `BookingForm.tsx`)
- **Utilities**: kebab-case (e.g., `date-utils.ts`)
- **Types**: PascalCase with `.types.ts` suffix (e.g., `Booking.types.ts`)
- **Tests**: Same as source file + `.test.ts` or `.spec.ts`
- **Avoid**: Dot-suffixes like `.service.ts`, `.repository.ts` (except for tests, types, specs)
## Repository Method Conventions
Repositories should follow consistent naming and design patterns to promote reusability and maintainability.
### Method Naming Rules
**1. Don't include the repository's entity name in method names**
Method names should be concise and avoid redundancy since the repository class name already indicates the entity type.
```typescript
// ✅ Good - Concise method names
class BookingRepository {
findById(id: string) { ... }
findByUserId(userId: string) { ... }
create(data: BookingCreateInput) { ... }
delete(id: string) { ... }
}
// ❌ Bad - Redundant entity name in methods
class BookingRepository {
findBookingById(id: string) { ... }
findBookingByUserId(userId: string) { ... }
createBooking(data: BookingCreateInput) { ... }
deleteBooking(id: string) { ... }
}
```
**2. Use `include` or similar keywords for methods that fetch relational data**
When a method retrieves additional related entities, make this explicit in the method name using keywords like `include`, `with`, or `andRelations`.
```typescript
// ✅ Good - Clear indication of included relations
class EventTypeRepository {
findById(id: string) {
return prisma.eventType.findUnique({
where: { id },
});
}
findByIdIncludeHosts(id: string) {
return prisma.eventType.findUnique({
where: { id },
include: {
hosts: true,
},
});
}
findByIdIncludeHostsAndSchedule(id: string) {
return prisma.eventType.findUnique({
where: { id },
include: {
hosts: true,
schedule: true,
},
});
}
}
// ❌ Bad - Unclear what data is included
class EventTypeRepository {
findById(id: string) {
return prisma.eventType.findUnique({
where: { id },
include: {
hosts: true,
schedule: true,
},
});
}
findByIdForReporting(id: string) {
return prisma.eventType.findUnique({
where: { id },
include: {
hosts: true,
},
});
}
}
```
**3. Keep methods generic and reusable - avoid use-case-specific names**
Repository methods should be general-purpose and describe what data they return, not how or where it's used. This promotes code reuse across different features.
```typescript
// ✅ Good - Generic, reusable methods
class BookingRepository {
findByUserIdIncludeAttendees(userId: string) {
return prisma.booking.findMany({
where: { userId },
include: {
attendees: true,
},
});
}
findByDateRangeIncludeEventType(startDate: Date, endDate: Date) {
return prisma.booking.findMany({
where: {
startTime: { gte: startDate },
endTime: { lte: endDate },
},
include: {
eventType: true,
},
});
}
}
// ❌ Bad - Use-case-specific method names
class BookingRepository {
findBookingsForReporting(userId: string) {
return prisma.booking.findMany({
where: { userId },
include: {
attendees: true,
},
});
}
findBookingsForDashboard(startDate: Date, endDate: Date) {
return prisma.booking.findMany({
where: {
startTime: { gte: startDate },
endTime: { lte: endDate },
},
include: {
eventType: true,
},
});
}
}
```
**4. No business logic in repositories**
Repositories should only handle data access. Business logic, validations, and complex transformations belong in the Service layer.
```typescript
// ✅ Good - Repository only handles data access
class BookingRepository {
findByIdIncludeAttendees(id: string) {
return prisma.booking.findUnique({
where: { id },
include: {
attendees: true,
},
});
}
updateStatus(id: string, status: BookingStatus) {
return prisma.booking.update({
where: { id },
data: { status },
});
}
}
class BookingService {
async confirmBooking(bookingId: string) {
const booking = await this.bookingRepository.findByIdIncludeAttendees(bookingId);
if (!booking) {
throw new Error("Booking not found");
}
if (booking.status !== "PENDING") {
throw new Error("Only pending bookings can be confirmed");
}
// Business logic: send confirmation emails
await this.emailService.sendConfirmationToAttendees(booking.attendees);
// Update status through repository
return this.bookingRepository.updateStatus(bookingId, "CONFIRMED");
}
}
// ❌ Bad - Business logic in repository
class BookingRepository {
async confirmBooking(bookingId: string) {
const booking = await prisma.booking.findUnique({
where: { id: bookingId },
include: {
attendees: true,
},
});
if (!booking) {
throw new Error("Booking not found");
}
if (booking.status !== "PENDING") {
throw new Error("Only pending bookings can be confirmed");
}
// ❌ Business logic shouldn't be here
await sendEmailToAttendees(booking.attendees);
return prisma.booking.update({
where: { id: bookingId },
data: { status: "CONFIRMED" },
});
}
}
```
### Summary
- Method names should be concise: `findById` not `findBookingById`
- Use `include`/`with` keywords when fetching relations: `findByIdIncludeHosts`
- Keep methods generic and reusable: `findByUserIdIncludeAttendees` not `findBookingsForReporting`
- No business logic in repositories - that belongs in Services
## When using Day.js
```typescript
// ⚠️ Slow in performance-critical code (loops)
dates.map((date) => dayjs(date).add(1, "day").format());
// ✅ Better - Use .utc() for performance
dates.map((date) => dayjs.utc(date).add(1, "day").format());
// ✅ Best - Use native Date when possible
dates.map((date) => new Date(date.valueOf() + 24 * 60 * 60 * 1000));
```
## Next.js App Directory: Authorisation Checks in Pages
This can include checking session.user exists or session.org etc.
### TL;DR:
Don’t put permission checks in layout.tsx! Always put them directly inside your page.tsx or relevant server components for every restricted route.
### Why Not to Use Layouts for Permission Checks
* Layouts don’t intercept all requests: If a user navigates directly or refreshes a protected route, layout checks might be skipped, exposing sensitive content.
* APIs and server actions bypass layouts: Sensitive operations running on the server can’t be guarded by checks in the layout.
* Risk of data leaks: Only page/server-level checks ensure that unauthorized users never get protected data.
### ✅ How To Secure Routes (The Right Way)
* Check permissions inside page.tsx or the actual server component.
* Perform all session/user/role validation before querying or rendering sensitive content.
* Redirect or return nothing to unauthorized users, before running restricted code.
### 🛠️ Example: Page-Level Permission Check
```tsx
// app/admin/page.tsx
import { redirect } from "next/navigation";
import { getUserSession } from "@/lib/auth";
export default async function AdminPage() {
const session = await getUserSession();
if (!session || session.user.role !== "admin") {
redirect("/"); // Or show an error
}
// Protected content here
return <div>Welcome, Admin!</div>;
}
```
### 🧠 Key Reminders
* Put permission guards in every restricted page.tsx.
* Never assume layouts are secure for guarding data.
* Validate users before any sensitive queries or rendering.
## Avoid using Dayjs if you don’t need to be strictly tz aware.
When doing logic like Dayjs.startOf(".."), you can instead use date-fns' `startOfMonth(dateObj)` / `endOfDay(dateObj)`;
When doing logic that depends on Browser locale, use i18n.language (prefer to deconstruct) like: `const { i18n: { language } } = useLocale();`, in combination with built-in Intl.
Note that with Date, you’re dealing with System time, so it’s not suited to everywhere (such as in the Booker, where instead we’ll likely migrate to Temporal) - but in most cases the above are suitable.
The main reason for doing so is that Dayjs uses a useful, but highly risky plugin system, which has led us to create `@calcom/dayjs` - this is heavy however, because it pre-loads ALL plugins, including locale handling. It’s a non-ideal solution to a problem that unfortunately exists due to Dayjs.
+5
View File
@@ -0,0 +1,5 @@
---
"@calcom/atoms": patch
---
fix: unlocked fields not saved for managed event type
+1
View File
@@ -0,0 +1 @@
../agents/rules
+5
View File
@@ -0,0 +1,5 @@
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
+1
View File
@@ -0,0 +1 @@
../agents/skills
-187
View File
@@ -1,187 +0,0 @@
language: en-US
tone_instructions: ''
early_access: false
enable_free_tier: true
reviews:
profile: chill
request_changes_workflow: false
high_level_summary: false
high_level_summary_placeholder: '@coderabbitai summary'
high_level_summary_in_walkthrough: false
auto_title_placeholder: '@coderabbitai'
auto_title_instructions: ''
review_status: true
commit_status: true
fail_commit_status: false
collapse_walkthrough: false
changed_files_summary: false
sequence_diagrams: false
estimate_code_review_effort: false
assess_linked_issues: true
related_issues: false
related_prs: true
suggested_labels: false
auto_apply_labels: false
suggested_reviewers: false
auto_assign_reviewers: false
poem: false
labeling_instructions: []
path_filters:
- '!**/node_modules/**'
- '!**/dist/**'
- '!**/build/**'
- '!**/.next/**'
path_instructions:
- path: "**/*.{ts,tsx,js,jsx}"
instructions: "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."
abort_on_close: true
disable_cache: false
auto_review:
enabled: true
auto_incremental_review: true
ignore_title_keywords: []
labels: []
drafts: false
base_branches: []
finishing_touches:
docstrings:
enabled: true
unit_tests:
enabled: true
pre_merge_checks:
docstrings:
mode: warning
threshold: 80
title:
mode: warning
requirements: ''
description:
mode: warning
issue_assessment:
mode: warning
tools:
ast-grep:
rule_dirs: []
util_dirs: []
essential_rules: true
packages: []
shellcheck:
enabled: true
ruff:
enabled: true
markdownlint:
enabled: true
github-checks:
enabled: true
timeout_ms: 180000
languagetool:
enabled: true
enabled_rules: []
disabled_rules: []
enabled_categories: []
disabled_categories: []
enabled_only: false
level: default
biome:
enabled: true
hadolint:
enabled: true
swiftlint:
enabled: true
phpstan:
enabled: true
level: default
phpmd:
enabled: true
phpcs:
enabled: true
golangci-lint:
enabled: true
yamllint:
enabled: true
gitleaks:
enabled: true
checkov:
enabled: true
detekt:
enabled: true
eslint:
enabled: true
flake8:
enabled: true
rubocop:
enabled: true
buf:
enabled: true
regal:
enabled: true
actionlint:
enabled: true
pmd:
enabled: true
cppcheck:
enabled: true
semgrep:
enabled: true
circleci:
enabled: true
clippy:
enabled: true
sqlfluff:
enabled: true
prismaLint:
enabled: true
pylint:
enabled: true
oxc:
enabled: true
shopifyThemeCheck:
enabled: true
luacheck:
enabled: true
brakeman:
enabled: true
dotenvLint:
enabled: true
htmlhint:
enabled: true
checkmake:
enabled: true
osvScanner:
enabled: true
chat:
art: true
auto_reply: true
integrations:
jira:
usage: auto
linear:
usage: auto
knowledge_base:
opt_out: false
web_search:
enabled: true
code_guidelines:
enabled: true
filePatterns: []
learnings:
scope: auto
issues:
scope: auto
jira:
usage: auto
project_keys: []
linear:
usage: auto
team_keys: []
pull_requests:
scope: auto
mcp:
usage: auto
disabled_servers: []
code_generation:
docstrings:
language: en-US
path_instructions: []
unit_tests:
path_instructions: []
+1
View File
@@ -0,0 +1 @@
../agents/rules
-36
View File
@@ -1,36 +0,0 @@
# Review Instructions
## File Naming Conventions
- **Repository Files**: Must include `Repository` suffix, prefix with technology if applicable (e.g., `PrismaAppRepository.ts`), use PascalCase matching exported class
- **Service Files**: Must include `Service` suffix, use PascalCase matching exported class, avoid generic names (e.g., `MembershipService.ts`)
- **New files**: Avoid dot-suffixes like `.service.ts` or `.repository.ts`; reserve `.test.ts`, `.spec.ts`, `.types.ts` for their specific purposes
## Code Quality
- Prefer early returns. It is recommended to throw/return early so we can ensure null-checks and prevent further nesting.
- Prefer Composition over Prop Drilling. Instead of relying on prop drilling, let's try to take advantage of react children feature.
- For Prisma queries:
- Only select data you need
1) Increased performance overhead: When you select all columns from a table, Prisma retrieves all the data associated with each row, which can result in a significant performance impact. This includes reading unnecessary columns and transferring a large volume of data between your application and the database.
2) Unnecessary data exposure: Selecting all columns exposes sensitive data that might not be required by your application. This can pose security risks, especially if the table contains sensitive user information or proprietary data. (In our case app credentials and booking information)
- TLDR: Never use Includes - use select
- Select selects only the fields you specify explicitly
- Include selects the relationship AND all the fields of the table the relationship belongs to
- Make sure the credential.key field is never returned back from tRPC endpoints or APIs
- Always use t() for text localization in frontend code; direct text embedding should trigger a warning.
- Check if there's any O(n^2) logic in backend code; we should aim for O(n log n) or O(n) ideally.
- Check if there are circular references introduced. We should never allow these.
- Flag excessive Day.js use in performance-critical code. Functions like `.add`, `.diff`, `.isBefore`, and `.isAfter` are slow, especially in timezone mode. Prefer `.utc()` for better performance. Where possible, replace with native Date and direct `.valueOf()` comparisons for faster execution. Recommend using native methods or Day.js `.utc()` consistently in hot paths like loops.
- When docs changes are made in /docs/api-reference/v2/openapi.json, ensure the following
- "summary" fields are short and concise
- "summary" fields do not end with a period
- "summary" fields are written in proper American english
- When changes to API v2 or v1 are made, ensure there are no breaking changes on existing endpoints. Instead, there needs to be a newly versioned endpoint with the updated functionality but the old one must remain functional
- For large pull requests (>500 lines changed or >10 files touched), advise splitting into smaller, focused PRs:
- Split by feature boundaries: separate different features or user stories
- Split by layer/component: frontend changes, backend changes, database migrations, and tests in separate PRs
- Split by dependency chain: create PRs that can be merged sequentially
- Split by file/module: group related file changes together
- Suggested pattern: Database migrations → Backend logic → Frontend components → Integration tests
- Benefits: easier review, faster feedback, reduced conflicts, easier rollback, better history
+1
View File
@@ -0,0 +1 @@
../agents/skills
+36
View File
@@ -0,0 +1,36 @@
# Dependencies
node_modules
**/node_modules
# Build outputs
.next
**/.next
dist
**/dist
build
**/build
# Git
.git
.github
# Testing
coverage
**/coverage
test-results
**/test-results
.turbo
**/.turbo
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# OS
.DS_Store
Thumbs.db
# Examples and docs
docs
-8
View File
@@ -129,14 +129,6 @@ ZOHOCRM_CLIENT_ID=""
ZOHOCRM_CLIENT_SECRET=""
# - REVERT
# Used for the Pipedrive integration (via/ Revert (https://revert.dev))
# @see https://github.com/calcom/cal.com/#obtaining-revert-api-keys
REVERT_API_KEY=
REVERT_PUBLIC_TOKEN=
# NOTE: If you're self hosting Revert, update this URL to point to your own instance.
REVERT_API_URL=https://api.revert.dev/
# *********************************************************************************************************
# - Huddle01
+48 -16
View File
@@ -33,12 +33,6 @@ DATABASE_URL="postgresql://postgres:@localhost:5450/calendso"
DATABASE_DIRECT_URL="postgresql://postgres:@localhost:5450/calendso"
INSIGHTS_DATABASE_URL=
# Uncomment to enable a dedicated connection pool for Prisma using Prisma Data Proxy
# Cold boots will be faster and you'll be able to scale your DB independently of your app.
# @see https://www.prisma.io/docs/data-platform/data-proxy/use-data-proxy
# PRISMA_GENERATE_DATAPROXY=true
PRISMA_GENERATE_DATAPROXY=
# ***********************************************************************************************************
# - SHARED **************************************************************************************************
@@ -47,7 +41,6 @@ PRISMA_GENERATE_DATAPROXY=
NEXT_PUBLIC_WEBAPP_URL='http://localhost:3000'
# Change to 'http://localhost:3001' if running the website simultaneously
NEXT_PUBLIC_WEBSITE_URL='http://localhost:3000'
NEXT_PUBLIC_CONSOLE_URL='http://localhost:3004'
NEXT_PUBLIC_EMBED_LIB_URL='http://localhost:3000/embed/embed.js'
# To enable SAML login, set both these variables
@@ -94,7 +87,7 @@ CRON_ENABLE_APP_SYNC=false
# Application Key for symmetric encryption and decryption
# must be 32 bytes for AES256 encryption algorithm
# You can use: `openssl rand -base64 32` to generate one
# You can use: `openssl rand -base64 24` to generate a 32-character key
CALENDSO_ENCRYPTION_KEY=
# Intercom Config
@@ -127,6 +120,14 @@ NEXT_PUBLIC_HELPSCOUT_KEY=
NEXT_PUBLIC_FRESHCHAT_TOKEN=
NEXT_PUBLIC_FRESHCHAT_HOST=
# For holiday feature:
# Step-by-step: Get a Google Calendar API Key
# 1. Go to Google Cloud Console: https://console.cloud.google.com/
# 2. Select or Create a Project
# 3. Enable Google Calendar API (APIs & Services → Library , Search for Google Calendar API)
# 4. Create the API Key (APIs & Services → Credentials)
GOOGLE_CALENDAR_API_KEY=
# Google OAuth credentials
# To enable Login with Google you need to:
# 1. Set `GOOGLE_API_CREDENTIALS` below
@@ -208,12 +209,16 @@ NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE=
NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN=0
NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE=
STRIPE_TEAM_MONTHLY_PRICE_ID=
STRIPE_TEAM_ANNUAL_PRICE_ID=
NEXT_PUBLIC_STRIPE_CREDITS_PRICE_ID=
ORG_MONTHLY_CREDITS=
STRIPE_TEAM_PRODUCT_ID=
# It is a price ID in the product with id STRIPE_ORG_PRODUCT_ID
STRIPE_ORG_MONTHLY_PRICE_ID=
STRIPE_ORG_ANNUAL_PRICE_ID=
STRIPE_ORG_PRODUCT_ID=
# Used to pass trial days for orgs during the Stripe checkout session
STRIPE_ORG_TRIAL_DAYS=
STRIPE_WEBHOOK_SECRET=
STRIPE_WEBHOOK_SECRET_APPS=
@@ -251,6 +256,9 @@ EMAIL_SERVER_PORT=1025
## @see https://support.google.com/accounts/answer/185833
# EMAIL_SERVER_PASSWORD='<gmail_app_password>'
# queue or cancel payment reminder email/flow
AWAITING_PAYMENT_EMAIL_DELAY_MINUTES=
# Used for E2E for email testing
# Set it to "1" if you need to email checks in E2E tests locally
# Make sure to run mailhog container manually or with `yarn dx`
@@ -385,7 +393,10 @@ NEXT_PUBLIC_API_V2_URL="http://localhost:5555/api/v2"
TASKER_ENABLE_WEBHOOKS=0
TASKER_ENABLE_EMAILS=0
# Ratelimiting via unkey
# Ratelimiting via Unkey (https://unkey.com)
# Optional: Only required if you want to enable rate limiting
# Not needed for testing or self-hosting unless you specifically want rate limiting features
# Sign up at https://unkey.com to get your Root key
UNKEY_ROOT_KEY=
# Used for Cal.ai Voice AI Agents
@@ -421,13 +432,7 @@ BLACKLISTED_GUEST_EMAILS=
NEXT_PUBLIC_VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
# Mintlify chat api
# Power AI chat in for docs
NEXT_PUBLIC_MINTLIFY_CHAT_API_KEY=
NEXT_PUBLIC_CHAT_API_URL=
NEXT_PUBLIC_DOCS_URL=
# Custom privacy policy / terms URLs (for self-hosters: change to your privacy policy / terms URLs)
# Custom privacy policy/ terms URLs (for self-hosters: change to your privacy policy / terms URLs)
NEXT_PUBLIC_WEBSITE_PRIVACY_POLICY_URL=
NEXT_PUBLIC_WEBSITE_TERMS_URL=
@@ -486,3 +491,30 @@ CALCOM_SERVICE_ACCOUNT_ENCRYPTION_KEY=
SALESFORCE_GRAPHQL_DELAY_MS=500
SALESFORCE_GRAPHQL_MAX_DELAY_MS=2000
SALESFORCE_GRAPHQL_MAX_RETRIES=3
# Force Node.js to use UTC as process timezone
TZ=UTC
# test oauth client for `packages/platform/examples/base` (optional)
SEED_PLATFORM_OAUTH_CLIENT_ID=
SEED_PLATFORM_OAUTH_CLIENT_SECRET=
# test oauth2 client for `packages/platform/examples/base` (optional)
SEED_OAUTH2_CLIENT_ID=
SEED_OAUTH2_CLIENT_SECRET_HASHED=
# Trigger.dev
ENABLE_ASYNC_TASKER="false" # set to "true" to enable
TRIGGER_SECRET_KEY=
TRIGGER_API_URL=https://api.trigger.dev
TRIGGER_DEV_PROJECT_REF=
GOOGLE_ADS_ENABLED=1 # To enable Google Ads tracking (gclid)
LINKEDIN_ADS_ENABLED=1 # To enable LinkedIn Ads tracking (li_fat_id)
# - BACKBLAZE B2 (Compliance Documents) *************************************************************************
# Used for storing and serving compliance documents (SOC 2, ISO 27001, pentest reports)
B2_APPLICATION_KEY_ID=
B2_APPLICATION_KEY=
B2_BUCKET_ID=
B2_BUCKET_NAME=
+4
View File
@@ -0,0 +1,4 @@
/.yarn/** linguist-vendored
/.yarn/releases/* binary
/.yarn/plugins/**/* binary
/.pnp.* binary linguist-generated
+14 -4
View File
@@ -1,6 +1,7 @@
.github/actions/**/* @calcom/Foundation
.github/workflows/**/* @calcom/Foundation
/**/package.json @calcom/Foundation
/apps/api/**/* @calcom/API
/apps/ui-playground/**/* @calcom/Consumer @calcom/Foundation
/apps/api/**/* @calcom/Foundation
/apps/web/**/layout.tsx @calcom/Consumer @calcom/Foundation
/apps/web/lib/csp.ts @calcom/Foundation
/apps/web/lib/buildNonce.ts @calcom/Foundation
@@ -8,7 +9,8 @@
/apps/web/lib/core/**/* @calcom/Foundation
/apps/web/lib/booking.ts @calcom/Foundation
/apps/web/lib/handleOrgRedirect.ts @calcom/Foundation
/apps/web/middleware.ts @calcom/Foundation
/apps/web/modules/shell/Shell.tsx @calcom/Foundation
/apps/web/proxy.ts @calcom/Foundation
/deploy/**/* @calcom/Foundation
/packages/app-store/applecalendar/**/* @calcom/Foundation
/packages/app-store/caldavcalendar/**/* @calcom/Foundation
@@ -29,9 +31,17 @@
/packages/features/bookings/lib/getLuckyUser.ts @calcom/Foundation
/packages/features/schedules/lib/slots.ts @calcom/Foundation
/packages/platform/atoms/**/*WebWrapper.tsx @calcom/Consumer
/packages/platform/**/* @calcom/Platform @calcom/Foundation
/packages/platform/**/* @calcom/Consumer @calcom/Foundation
/packages/prisma/**/* @calcom/Foundation
/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts @calcom/Foundation
/packages/trpc/server/routers/viewer/bookings/get.handler.ts @calcom/Foundation
/packages/trpc/server/routers/viewer/slots/**/* @calcom/Foundation
/packages/ui/**/* @calcom/Consumer @calcom/Foundation
# Exclude test files from requiring foundation/consumer approval
**/*.spec.*
**/*.e2e.*
**/*.e2e-spec.*
**/*.test.*
**/*.test-suite.*
**/*.integration-test.*
-58
View File
@@ -1,58 +0,0 @@
---
name: Cal.com/platform request
about: Suggest a feature or bug report for cal.com/platform
title: ""
labels: ["platform", "🚨 needs approval"]
assignees: ""
---
### Is your proposal related to a problem?
<!--
Provide a clear and concise description of what the problem is.
For example, "I'm always frustrated when..."
-->
(Write your answer here.)
### Describe the solution you'd like
<!--
Provide a clear and concise description of what you want to happen.
-->
(Describe your proposed solution here.)
### Describe alternatives you've considered
<!--
Let us know about other solutions you've tried or researched.
-->
(Write your answer here.)
### Additional context
<!--
Is there anything else you can add about the proposal?
You might want to link to related issues here, if you haven't already.
-->
(Write your answer here.)
### Requirement/Document
<!--
Is there any type of document that could support that feature?
-->
(Share it here.)
---
##### House rules
- If this issue has a `🚨 needs approval` label, don't start coding yet. Wait until a core member approves feature request by removing this label, then you can start coding.
- For clarity: Non-core member issues automatically get the `🚨 needs approval` label.
- Your feature ideas are invaluable to us! However, they undergo review to ensure alignment with the product's direction.
- Follow Best Practices lined out in our [Contributor Docs](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
+1
View File
@@ -42,3 +42,4 @@ A visual demonstration is strongly recommended, for both the original and new ch
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my changes generate no new warnings
- My PR is too large (>500 lines or >10 files) and should be split into smaller PRs
@@ -0,0 +1,23 @@
name: Generate cache-build key
description: "Generate the cache key for production build caching"
inputs:
branch_key:
required: true
description: "Branch key for cache scoping (e.g., github.head_ref for PRs)"
outputs:
key:
description: "The generated cache key"
value: ${{ steps.generate-key.outputs.key }}
runs:
using: "composite"
steps:
- name: Generate cache key
id: generate-key
shell: bash
env:
CACHE_NAME: prod-build
BRANCH_KEY: ${{ inputs.branch_key }}
LOCKFILE_HASH: ${{ hashFiles('yarn.lock') }}
SOURCE_HASH: ${{ hashFiles('apps/**/**.[jt]s', 'apps/**/**.[jt]sx', 'apps/**/*.json', 'apps/**/*.css', 'packages/**/**.[jt]s', 'packages/**/**.[jt]sx', 'packages/prisma/schema.prisma', 'packages/prisma/migrations/**/*.sql', '!**/node_modules/**', '!packages/prisma/generated/**', '!packages/prisma/client/**', '!packages/prisma/zod/**', '!packages/kysely/**') }}
run: |
echo "key=${CACHE_NAME}-${BRANCH_KEY}-${LOCKFILE_HASH}-${SOURCE_HASH}" >> $GITHUB_OUTPUT
+7 -17
View File
@@ -1,33 +1,23 @@
name: Cache production build binaries
description: "Cache or restore if necessary"
inputs:
node_version:
required: false
default: v18.x
runs:
using: "composite"
steps:
- name: Generate cache key
id: cache-key
uses: ./.github/actions/cache-build-key
with:
branch_key: ${{ github.head_ref || github.ref_name }}
- name: Cache production build
uses: buildjet/cache@v4
uses: actions/cache@v4
id: cache-build
env:
# WARN: Don't touch this cache key. Currently github.sha refers to the latest commit in main
# and not the branch that's attempting to merge to main, which causes CI errors when merged
# to main.
# TODO: Fix this problem if intending to modify this cache key.
cache-name: prod-build
key-1: ${{ inputs.node_version }}-${{ hashFiles('yarn.lock') }}
key-2: ${{ hashFiles('apps/**/**.[jt]s', 'apps/**/**.[jt]sx', 'packages/**/**.[jt]s', 'packages/**/**.[jt]sx', '!**/node_modules') }}
key-3: ${{ github.event.pull_request.number || github.ref }}
key-4: ${{ github.sha }}
key-5: ${{ github.event.pull_request.head.sha }}
with:
path: |
${{ github.workspace }}/apps/web/.next
${{ github.workspace }}/apps/web/public/embed
**/.turbo/**
**/dist/**
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }}-${{ env.key-4 }}-${{ env.key-5 }}
key: ${{ steps.cache-key.outputs.key }}
- run: |
export NODE_OPTIONS="--max_old_space_size=8192"
yarn build
+32
View File
@@ -0,0 +1,32 @@
name: Cache Git Checkout
description: "Cache or restore git checkout to speed up CI workflows"
runs:
using: "composite"
steps:
- name: Cache git checkout
uses: actions/cache@v4
id: cache-checkout
with:
path: |
.
!.git
!node_modules
!**/node_modules
!apps/web/public/app-store
key: git-checkout-${{ github.head_ref || github.ref_name }}-${{ github.event.pull_request.head.sha || github.sha }}
- name: Checkout PR code (on cache miss)
if: steps.cache-checkout.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 2
sparse-checkout-cone-mode: false
sparse-checkout: |
/*
!/example-apps/
!**/*.mp4
!/docs/images/
!packages/app-store/*/static/*.png
!packages/app-store/*/static/*.jpg
!packages/app-store/*/static/*.jpeg
!packages/app-store/*/static/*.gif
+23
View File
@@ -0,0 +1,23 @@
name: Generate cache-db key
description: "Generate the cache key for database caching"
inputs:
path:
required: false
default: "backups/backup.sql"
description: "Path to the backup file"
outputs:
key:
description: "The generated cache key"
value: ${{ steps.generate-key.outputs.key }}
runs:
using: "composite"
steps:
- name: Generate cache key
id: generate-key
shell: bash
env:
CACHE_NAME: cache-db
PATH_KEY: ${{ inputs.path }}
PRISMA_HASH: ${{ hashFiles('packages/prisma/schema.prisma', 'packages/prisma/migrations/**/**.sql', 'packages/prisma/*.ts') }}
run: |
echo "key=${CACHE_NAME}-${PATH_KEY}-${PRISMA_HASH}" >> $GITHUB_OUTPUT
+8 -7
View File
@@ -10,14 +10,15 @@ inputs:
runs:
using: "composite"
steps:
- name: Generate cache key
id: cache-key
uses: ./.github/actions/cache-db-key
with:
path: ${{ inputs.path }}
- name: Cache database
id: cache-db
uses: buildjet/cache@v4
uses: actions/cache@v4
env:
cache-name: cache-db
key-1: ${{ hashFiles('packages/prisma/schema.prisma', 'packages/prisma/migrations/**/**.sql', 'packages/prisma/*.ts') }}
key-2: ${{ github.event.pull_request.number || github.ref }}
key-3: ${{ github.event.pull_request.head.sha }}
DATABASE_URL: ${{ inputs.DATABASE_URL }}
DATABASE_DIRECT_URL: ${{ inputs.DATABASE_URL }}
E2E_TEST_CALCOM_QA_EMAIL: ${{ inputs.E2E_TEST_CALCOM_QA_EMAIL }}
@@ -25,8 +26,8 @@ runs:
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ inputs.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
with:
path: ${{ inputs.path }}
key: ${{ runner.os }}-${{ env.cache-name }}-${{ inputs.path }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }}
- run: echo ${{ env.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }} && yarn db-seed
key: ${{ steps.cache-key.outputs.key }}
- run: yarn db-seed
if: steps.cache-db.outputs.cache-hit != 'true'
shell: bash
- name: Postgres Dump Backup
@@ -1,10 +0,0 @@
name: Dangerous git Checkout
description: "Git Checkout from PR code so we can run checks from forks"
runs:
using: "composite"
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2
+124
View File
@@ -0,0 +1,124 @@
name: 'Devin Session Checker'
description: 'Check for existing Devin sessions on a PR'
inputs:
devin-api-key:
description: 'Devin API key'
required: true
github-token:
description: 'GitHub token for API calls'
required: true
pr-number:
description: 'PR number to check for existing sessions'
required: true
outputs:
has-existing-session:
description: 'Whether an existing active session was found (true/false)'
value: ${{ steps.check-session.outputs.has-existing-session }}
session-id:
description: 'ID of the existing session (if found)'
value: ${{ steps.check-session.outputs.session-id }}
session-url:
description: 'URL of the existing session (if found)'
value: ${{ steps.check-session.outputs.session-url }}
runs:
using: 'composite'
steps:
- name: Check for existing Devin session
id: check-session
uses: actions/github-script@v7
env:
DEVIN_API_KEY: ${{ inputs.devin-api-key }}
PR_NUMBER: ${{ inputs.pr-number }}
with:
github-token: ${{ inputs.github-token }}
script: |
const { owner, repo } = context.repo;
const prNumber = parseInt(process.env.PR_NUMBER, 10);
const SESSION_URL_REGEX = /app\.devin\.ai\/sessions\/([a-f0-9-]+)/;
const ACTIVE_STATUSES = ['working', 'blocked', 'resumed'];
async function checkSessionStatus(sessionId) {
const response = await fetch(`https://api.devin.ai/v1/sessions/${sessionId}`, {
headers: {
'Authorization': `Bearer ${process.env.DEVIN_API_KEY}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
console.log(`Failed to fetch session ${sessionId}: ${response.status}`);
return null;
}
return await response.json();
}
const { data: pr } = await github.rest.pulls.get({
owner,
repo,
pull_number: prNumber
});
const prBody = pr.body || '';
const prSessionMatch = prBody.match(SESSION_URL_REGEX);
if (prSessionMatch) {
const sessionId = prSessionMatch[1];
console.log(`PR was created by Devin session: ${sessionId}`);
const session = await checkSessionStatus(sessionId);
if (session) {
console.log(`PR creator session status: ${session.status_enum}`);
if (ACTIVE_STATUSES.includes(session.status_enum)) {
core.setOutput('has-existing-session', 'true');
core.setOutput('session-id', sessionId);
core.setOutput('session-url', `https://app.devin.ai/sessions/${sessionId}`);
return;
} else {
console.log(`PR creator session ${sessionId} is not active, will check comments`);
}
}
}
const devinSessionPatterns = [
'Devin AI is completing this stale PR',
'Devin AI is addressing Cubic AI',
'Devin AI is resolving merge conflicts'
];
const comments = await github.rest.issues.listComments({
owner,
repo,
issue_number: prNumber
});
for (const comment of comments.data.reverse()) {
const hasDevinSession = devinSessionPatterns.some(pattern => comment.body?.includes(pattern));
if (hasDevinSession) {
const match = comment.body?.match(SESSION_URL_REGEX);
if (match) {
const sessionId = match[1];
console.log(`Found existing Devin session from comment: ${sessionId}`);
const session = await checkSessionStatus(sessionId);
if (session) {
if (ACTIVE_STATUSES.includes(session.status_enum)) {
console.log(`Session ${sessionId} is active (status: ${session.status_enum})`);
core.setOutput('has-existing-session', 'true');
core.setOutput('session-id', sessionId);
core.setOutput('session-url', `https://app.devin.ai/sessions/${sessionId}`);
return;
} else {
console.log(`Session ${sessionId} is not active (status: ${session.status_enum})`);
}
}
}
}
}
console.log('No existing active Devin session found');
core.setOutput('has-existing-session', 'false');
core.setOutput('session-id', '');
core.setOutput('session-url', '');
@@ -0,0 +1,186 @@
name: "Docker Build and Test"
description: "Reusable action to build and test Docker images for Cal.com"
inputs:
platform:
description: "Target platform (linux/amd64 or arm64)"
required: true
platform-suffix:
description: "Suffix to add to image tags (e.g., -arm)"
required: false
default: ""
dockerhub-username:
description: "Docker Hub username"
required: true
dockerhub-token:
description: "Docker Hub token"
required: true
github-token:
description: "GitHub token for GHCR"
required: true
postgres-user:
description: "PostgreSQL user"
required: true
postgres-password:
description: "PostgreSQL password"
required: true
postgres-db:
description: "PostgreSQL database name"
required: true
database-host:
description: "Database host"
required: true
push-image:
description: "Whether to push the built image"
required: false
default: "false"
use-as-latest:
description: "Publish as latest"
required: false
default: "false"
runs:
using: "composite"
steps:
- name: Log in to the Docker Hub registry
uses: docker/login-action@v3
with:
username: ${{ inputs.dockerhub-username }}
password: ${{ inputs.dockerhub-token }}
logout: true
- name: Log in to the Github Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ inputs.github-token }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
docker.io/calendso/calendso
docker.io/calcom/cal.com
ghcr.io/calcom/cal.com
flavor: |
latest=${{ !github.event.release.prerelease && inputs.use-as-latest == 'true' }}
suffix=${{ inputs.platform-suffix }}
- name: Copy env
shell: bash
run: |
grep -o '^[^#]*' .env.example > .env
cat .env >> $GITHUB_ENV
echo "DATABASE_HOST=localhost:5432" >> $GITHUB_ENV
eval $(sed -e '/^#/d' -e 's/^/export /' -e 's/$/;/' .env) ;
- name: Start database
shell: bash
run: |
docker compose up -d database
- name: Show database logs and container status
shell: bash
run: |
echo "--- Container Status ---"
docker compose ps database
echo "--- Container Logs ---"
docker compose logs database
- name: Set up Docker Buildx
uses: useblacksmith/setup-docker-builder@v1
with:
driver-opts: |
network=container:database
buildkitd-flags: |
--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
- name: Build image
id: docker_build
uses: useblacksmith/build-push-action@v2
with:
context: ./
file: ./Dockerfile
load: true
push: false
platforms: ${{ inputs.platform }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000
NEXT_PUBLIC_API_V2_URL=http://localhost:5555/api/v2
NEXT_PUBLIC_LICENSE_CONSENT=agree
DATABASE_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@${{ inputs.database-host }}/${{ inputs.postgres-db }}
DATABASE_DIRECT_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@${{ inputs.database-host }}/${{ inputs.postgres-db }}
- name: Test runtime
shell: bash
run: |
tags="${{ steps.meta.outputs.tags }}"
IFS=',' read -ra ADDR <<< "$tags"
tag=${ADDR[0]}
docker run --rm --network stack \
-p 3000:3000 \
-e DATABASE_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@database/${{ inputs.postgres-db }} \
-e DATABASE_DIRECT_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@database/${{ inputs.postgres-db }} \
-e NEXTAUTH_SECRET=${{ env.NEXTAUTH_SECRET }} \
-e CALENDSO_ENCRYPTION_KEY=${{ env.CALENDSO_ENCRYPTION_KEY }} \
$tag &
server_pid=$!
echo "Waiting for the server to start..."
sleep 120
echo http://localhost:3000/auth/login
for i in {1..60}; do
echo "Checking server health ($i/60)..."
response=$(curl -o /dev/null -s -w "%{http_code}" http://localhost:3000/auth/login)
echo "HTTP Status Code: $response"
if [[ "$response" == "200" ]] || [[ "$response" == "307" ]]; then
echo "Server is healthy"
kill $server_pid
exit 0
fi
sleep 1
done
echo "Server health check failed"
kill $server_pid
exit 1
env:
NEXTAUTH_SECRET: "EI4qqDpcfdvf4A+0aQEEx8JjHxHSy4uWiZw/F32K+pA="
CALENDSO_ENCRYPTION_KEY: "0zfLtY99wjeLnsM7qsa8xsT+Q0oSgnOL"
- name: Push image
id: docker_push
uses: useblacksmith/build-push-action@v2
if: ${{ inputs.push-image == 'true' && !github.event.release.prerelease }}
with:
context: ./
file: ./Dockerfile
push: true
platforms: ${{ inputs.platform }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000
NEXT_PUBLIC_API_V2_URL=http://localhost:5555/api/v2
NEXT_PUBLIC_LICENSE_CONSENT=agree
DATABASE_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@${{ inputs.database-host }}/${{ inputs.postgres-db }}
DATABASE_DIRECT_URL=postgresql://${{ inputs.postgres-user }}:${{ inputs.postgres-password }}@${{ inputs.database-host }}/${{ inputs.postgres-db }}
- name: Image digest
shell: bash
run: echo ${{ steps.docker_build.outputs.digest }}
- name: Cleanup
shell: bash
if: always()
run: |
docker compose down
+62 -8
View File
@@ -15,12 +15,16 @@ inputs:
node_version:
required: false
default: v20.x
skip-install-if-cache-hit:
description: "Skip yarn install if node_modules cache is hit. Use this for jobs that only need to check that cache exists."
required: false
default: "false"
runs:
using: "composite"
steps:
- name: Use Node ${{ inputs.node_version }}
uses: buildjet/setup-node@v4
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node_version }}
- name: Expose yarn config as "$GITHUB_OUTPUT"
@@ -29,10 +33,57 @@ runs:
run: |
echo "CACHE_FOLDER=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
# When skip-install-if-cache-hit is true, first check if all caches exist without downloading (lookup-only mode)
# This avoids downloading ~1.2GB of cache data when we just want to verify caches exist
- name: Check yarn cache (lookup-only)
if: ${{ inputs.skip-install-if-cache-hit == 'true' }}
uses: actions/cache/restore@v4
id: yarn-download-cache-check
with:
path: ${{ steps.yarn-config.outputs.CACHE_FOLDER }}
key: yarn-download-cache-${{ hashFiles('yarn.lock') }}
lookup-only: true
- name: Check node_modules cache (lookup-only)
if: ${{ inputs.skip-install-if-cache-hit == 'true' }}
uses: actions/cache/restore@v4
id: yarn-nm-cache-check
with:
path: |
**/node_modules/
!**/.next/node_modules/
key: ${{ runner.os }}-yarn-nm-cache-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
lookup-only: true
- name: Check yarn install state cache (lookup-only)
if: ${{ inputs.skip-install-if-cache-hit == 'true' }}
uses: actions/cache/restore@v4
id: yarn-install-state-cache-check
with:
path: .yarn/ci-cache/
key: ${{ runner.os }}-yarn-install-state-cache-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
lookup-only: true
# Compute whether all caches hit (only in skip mode)
- name: Check if all caches hit
if: ${{ inputs.skip-install-if-cache-hit == 'true' }}
id: all-caches-check
shell: bash
run: |
if [[ "${{ steps.yarn-download-cache-check.outputs.cache-hit }}" == "true" && \
"${{ steps.yarn-nm-cache-check.outputs.cache-hit }}" == "true" && \
"${{ steps.yarn-install-state-cache-check.outputs.cache-hit }}" == "true" ]]; then
echo "all-hit=true" >> $GITHUB_OUTPUT
else
echo "all-hit=false" >> $GITHUB_OUTPUT
fi
# Yarn rotates the downloaded cache archives, @see https://github.com/actions/setup-node/issues/325
# Yarn cache is also reusable between arch and os.
# Only restore if not in skip mode, or if skip mode but any cache check missed
- name: Restore yarn cache
uses: buildjet/cache@v4
if: ${{ inputs.skip-install-if-cache-hit != 'true' || steps.all-caches-check.outputs.all-hit != 'true' }}
uses: actions/cache@v4
id: yarn-download-cache
with:
path: ${{ steps.yarn-config.outputs.CACHE_FOLDER }}
@@ -40,25 +91,28 @@ runs:
# Invalidated on yarn.lock changes
- name: Restore node_modules
if: ${{ inputs.skip-install-if-cache-hit != 'true' || steps.all-caches-check.outputs.all-hit != 'true' }}
id: yarn-nm-cache
uses: buildjet/cache@v4
uses: actions/cache@v4
with:
path: "**/node_modules/"
path: |
**/node_modules/
!**/.next/node_modules/
key: ${{ runner.os }}-yarn-nm-cache-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
# Invalidated on yarn.lock changes
- name: Restore yarn install state
if: ${{ inputs.skip-install-if-cache-hit != 'true' || steps.all-caches-check.outputs.all-hit != 'true' }}
id: yarn-install-state-cache
uses: buildjet/cache@v4
uses: actions/cache@v4
with:
path: .yarn/ci-cache/
key: ${{ runner.os }}-yarn-install-state-cache-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
- name: Install dependencies
if: ${{ inputs.skip-install-if-cache-hit != 'true' || steps.all-caches-check.outputs.all-hit != 'true' }}
shell: bash
run: |
yarn install --inline-builds
yarn prisma generate
run: yarn install --inline-builds
env:
# CI optimizations. Overrides yarnrc.yml options (or their defaults) in the CI action.
YARN_ENABLE_IMMUTABLE_INSTALLS: "false" # So it doesn't try to remove our private submodule deps
@@ -1,5 +1,10 @@
name: Install playwright binaries
description: "Install playwright, cache and restore if necessary"
inputs:
skip-install-if-cache-hit:
description: "Skip playwright install if cache is hit. Use this for jobs that only need to check that cache exists."
required: false
default: "false"
runs:
using: "composite"
steps:
@@ -7,15 +12,35 @@ runs:
shell: bash
id: playwright-version
run: echo "PLAYWRIGHT_VERSION=$(node -e "console.log(require('./package.json').devDependencies['@playwright/test'])")" >> $GITHUB_ENV
- name: Cache playwright binaries
id: playwright-cache
uses: buildjet/cache@v4
# When skip-install-if-cache-hit is true, first check if cache exists without downloading (lookup-only mode)
- name: Check playwright cache (lookup-only)
if: ${{ inputs.skip-install-if-cache-hit == 'true' }}
id: playwright-cache-check
uses: actions/cache/restore@v4
with:
path: |
~/Library/Caches/ms-playwright
~/.cache/ms-playwright
${{ github.workspace }}/node_modules/playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
lookup-only: true
# Only restore cache if not in skip mode, or if skip mode but cache check missed
- name: Cache playwright binaries
if: ${{ inputs.skip-install-if-cache-hit != 'true' || steps.playwright-cache-check.outputs.cache-hit != 'true' }}
id: playwright-cache
uses: actions/cache@v4
with:
path: |
~/Library/Caches/ms-playwright
~/.cache/ms-playwright
${{ github.workspace }}/node_modules/playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
# In default mode: run if playwright-cache missed
# In skip mode: run if playwright-cache-check missed (but cache restore step was also skipped)
- name: Yarn playwright install
if: ${{ (inputs.skip-install-if-cache-hit != 'true' && steps.playwright-cache.outputs.cache-hit != 'true') || (inputs.skip-install-if-cache-hit == 'true' && steps.playwright-cache-check.outputs.cache-hit != 'true') }}
shell: bash
run: yarn playwright install --with-deps
+17
View File
@@ -0,0 +1,17 @@
GET /v2/event-types/{eventTypeId} added to the 'data' response property 'oneOf' list for the response status '200'
GET /v2/event-types/{eventTypeId} added '#/components/schemas/EventTypeOutput_2024_06_14, #/components/schemas/TeamEventTypeOutput_2024_06_14' to the 'data' response property 'oneOf' list for the response status '200'
GET /v2/bookings/{bookingUid}/recordings added the new required 'header' request parameter 'Authorization'
GET /v2/bookings/{bookingUid}/transcripts added the new required 'header' request parameter 'Authorization'
POST /v2/bookings added 'subschema #2, subschema #4' to the 'data' response property 'oneOf' list for the response status '201'
GET /v2/bookings/{bookingUid} added 'subschema #3, subschema #6' to the 'data' response property 'oneOf' list for the response status '200'
POST /v2/bookings/{bookingUid}/cancel added 'subschema #3, subschema #6' to the 'data' response property 'oneOf' list for the response status '200'
POST /v2/bookings/{bookingUid}/confirm added 'subschema #3, subschema #6' to the 'data' response property 'oneOf' list for the response status '200'
POST /v2/bookings/{bookingUid}/decline added 'subschema #3, subschema #6' to the 'data' response property 'oneOf' list for the response status '200'
POST /v2/bookings/{bookingUid}/guests added 'subschema #3, subschema #6' to the 'data' response property 'oneOf' list for the response status '200'
DELETE /v2/event-types/{eventTypeId}/webhooks/{webhookId} added the new path request parameter 'webhookId'
GET /v2/event-types/{eventTypeId}/webhooks/{webhookId} added the new path request parameter 'webhookId'
DELETE /v2/oauth-clients/{clientId}/webhooks/{webhookId} added the new path request parameter 'webhookId'
GET /v2/oauth-clients/{clientId}/webhooks/{webhookId} added the new path request parameter 'webhookId'
DELETE /v2/teams/{teamId}/event-types/{eventTypeId}/webhooks/{webhookId} added the new path request parameter 'webhookId'
GET /v2/teams/{teamId}/event-types/{eventTypeId}/webhooks/{webhookId} added the new path request parameter 'webhookId'
GET /v2/webhooks/{webhookId} added the new path request parameter 'webhookId'
+7 -2
View File
@@ -24,6 +24,11 @@ jobs:
uses: ./.github/workflows/unit-tests.yml
secrets: inherit
api-v2-unit-test:
name: Tests
uses: ./.github/workflows/api-v2-unit-tests.yml
secrets: inherit
build-api-v1:
name: Production builds
uses: ./.github/workflows/api-v1-production-build.yml
@@ -75,9 +80,9 @@ jobs:
secrets: inherit
required:
needs: [lint, type-check, unit-test, integration-test, build, build-api-v1, build-api-v2, e2e, e2e-embed, e2e-embed-react, e2e-app-store]
needs: [lint, type-check, unit-test, api-v2-unit-test, integration-test, build, build-api-v1, build-api-v2, e2e, e2e-embed, e2e-embed-react, e2e-app-store]
if: always()
runs-on: buildjet-2vcpu-ubuntu-2204
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: fail if conditional jobs failed
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') || contains(needs.*.result, 'cancelled')
+11 -11
View File
@@ -43,7 +43,7 @@ env:
jobs:
build:
name: Build API v1
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 30
services:
postgres:
@@ -56,33 +56,33 @@ jobs:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: calendso
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
--health-cmd "pg_isready -h 127.0.0.1 -U postgres"
--health-interval 2s
--health-timeout 3s
--health-retries 15
--health-start-period 2s
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/cache-db
- name: Cache API v1 production build
uses: buildjet/cache@v4
uses: actions/cache@v4
id: cache-api-v1-build
env:
cache-name: api-v1-build
key-1: ${{ hashFiles('yarn.lock') }}
key-2: ${{ hashFiles('apps/api/v1/**.[jt]s', 'apps/api/v1/**.[jt]sx', '!**/node_modules') }}
key-3: ${{ github.event.pull_request.number || github.ref }}
# Ensures production-build.yml will always be fresh
key-4: ${{ github.sha }}
with:
path: |
${{ github.workspace }}/apps/api/v1/.next
**/.turbo/**
**/dist/**
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }}-${{ env.key-4 }}
key: ${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}
- name: Log Cache Hit
if: steps.cache-api-v1-build.outputs.cache-hit == 'true'
run: echo "Cache hit for API v1 build. Skipping build."
+11 -25
View File
@@ -6,13 +6,15 @@ on:
env:
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
jobs:
build:
name: Build API v2
permissions:
contents: read
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 30
services:
postgres:
@@ -33,31 +35,15 @@ jobs:
- 5432:5432
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
- name: Cache API v2 production build
uses: buildjet/cache@v4
id: cache-api-v2-build
env:
cache-name: api-v2-build
key-1: ${{ hashFiles('yarn.lock') }}
key-2: ${{ hashFiles('apps/api/v2/**.[jt]s', 'apps/api/v2/**.[jt]sx', '!**/node_modules') }}
key-3: ${{ github.event.pull_request.number || github.ref }}
# Ensures production-build.yml will always be fresh
key-4: ${{ github.sha }}
with:
path: |
**/dist/**
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }}-${{ env.key-4 }}
- name: Log Cache Hit
if: steps.cache-api-v2-build.outputs.cache-hit == 'true'
run: echo "Cache hit for API v2 build. Skipping build."
- name: Run build
if: steps.cache-api-v2-build.outputs.cache-hit != 'true'
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Generate Prisma schemas
working-directory: apps/api/v2
run: yarn workspace @calcom/api-v2 run generate-schemas
- name: Build API v2 with Turbo
run: |
export NODE_OPTIONS="--max_old_space_size=8192"
yarn workspace @calcom/api-v2 run generate-schemas
rm -rf apps/api/v2/node_modules
yarn install
yarn workspace @calcom/api-v2 run build
yarn turbo run build --filter=@calcom/api-v2
shell: bash
+24
View File
@@ -0,0 +1,24 @@
name: API v2 Unit
on:
workflow_call:
env:
LINGO_DOT_DEV_API_KEY: ${{ secrets.CI_LINGO_DOT_DEV_API_KEY }}
permissions:
contents: read
jobs:
test:
name: API v2 Unit
timeout-minutes: 20
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- run: yarn prisma generate
- name: Run API v2 unit tests
working-directory: apps/api/v2
run: |
export NODE_OPTIONS="--max_old_space_size=8192"
yarn workspace @calcom/platform-libraries build && yarn test
+8 -12
View File
@@ -8,34 +8,30 @@ jobs:
name: Build Atoms
permissions:
contents: read
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Cache atoms production build
uses: buildjet/cache@v4
uses: actions/cache@v4
id: cache-atoms-build
env:
cache-name: atoms-build
key-1: ${{ hashFiles('yarn.lock') }}
key-2: ${{ hashFiles('packages/platform/atoms/**.[jt]s', 'packages/platform/atoms/**.[jt]sx', '!**/node_modules') }}
key-3: ${{ github.event.pull_request.number || github.ref }}
# Ensures production-build.yml will always be fresh
key-4: ${{ github.sha }}
key-2: ${{ hashFiles('packages/platform/atoms/**.[jt]s', 'packages/platform/atoms/**.[jt]sx', 'packages/platform/atoms/package.json', '!**/node_modules') }}
with:
path: |
**/dist/**
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }}-${{ env.key-4 }}
- name: Log Cache Hit
if: steps.cache-atoms-build.outputs.cache-hit == 'true'
run: echo "Cache hit for Atoms build. Skipping build."
key: ${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}
- name: Run build
if: steps.cache-atoms-build.outputs.cache-hit != 'true'
run: |
export NODE_OPTIONS="--max_old_space_size=8192"
rm -rf packages/platform/atoms/node_modules
yarn install
yarn workspace @calcom/atoms run build
yarn workspace @calcom/atoms run build-npm
shell: bash
+1 -1
View File
@@ -6,7 +6,7 @@ on:
jobs:
cleanup:
runs-on: buildjet-2vcpu-ubuntu-2204
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Check out code
uses: actions/checkout@v4
+16 -9
View File
@@ -6,23 +6,31 @@ on:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions: {} # remove permissions and set explicitly under "permissions:" below
permissions:
id-token: write # for NPM provenance - developers can verify where and how it was built
contents: write # to create release by changesets/action below
pull-requests: write # to create pull request by changesets/action below
jobs:
release:
if: github.repository == 'calcom/cal.com' # prevent this action from running on forks
permissions:
id-token: write # for NPM provenance - developers can verify where and how it was built
contents: write # to create release by changesets/action below
pull-requests: write # to create pull request by changesets/action below
name: Release
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node and registry for OIDC
uses: actions/setup-node@v4
with:
node-version: "20.17.0"
registry-url: "https://registry.npmjs.org"
always-auth: false
- name: Setup node, yarn and install dependencies
uses: ./.github/actions/yarn-install
- name: Install npm at version supporting OIDC
run: npm install -g npm@11.5.1
- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
@@ -33,8 +41,7 @@ jobs:
title: "chore: version packages" # PR title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: "true"
VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: ${{ secrets.VITE_BOOKER_EMBED_OAUTH_CLIENT_ID }}
VITE_BOOKER_EMBED_API_URL: ${{ secrets.VITE_BOOKER_EMBED_API_URL }}
NEXT_PUBLIC_WEBAPP_URL: ${{ secrets.NEXT_PUBLIC_WEBAPP_URL }}
NEXT_PUBLIC_WEBAPP_URL: ${{ secrets.NEXT_PUBLIC_WEBAPP_URL }}
@@ -0,0 +1,67 @@
name: Check API v2 breaking changes
on:
workflow_call:
permissions:
contents: read
env:
API_KEY_PREFIX: ${{ secrets.CI_API_KEY_PREFIX }}
API_PORT: ${{ vars.CI_API_V2_PORT }}
API_URL: "http://localhost"
CALCOM_LICENSE_KEY: ${{ secrets.CI_CALCOM_LICENSE_KEY }}
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
DATABASE_READ_URL: ${{ secrets.CI_DATABASE_URL }}
DATABASE_WRITE_URL: ${{ secrets.CI_DATABASE_URL }}
JWT_SECRET: ${{ secrets.CI_JWT_SECRET }}
NEXTAUTH_SECRET: ${{ secrets.CI_NEXTAUTH_SECRET }}
NODE_ENV: ${{ vars.CI_NODE_ENV }}
NODE_OPTIONS: --max-old-space-size=4096
REDIS_URL: "redis://localhost:6379"
STRIPE_API_KEY: ${{ secrets.CI_STRIPE_PRIVATE_KEY }}
STRIPE_WEBHOOK_SECRET: ${{ secrets.CI_STRIPE_WEBHOOK_SECRET }}
WEB_APP_URL: "https://app.cal.com"
jobs:
check-api-v2-breaking-changes:
name: Check API v2 breaking changes
timeout-minutes: 10
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: actions/checkout@v4
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Build platform packages
run: |
yarn turbo run build \
--filter=@calcom/platform-constants \
--filter=@calcom/platform-enums \
--filter=@calcom/platform-utils \
--filter=@calcom/platform-types \
--filter=@calcom/platform-libraries \
--filter=@calcom/trpc
- name: Generate Swagger
working-directory: apps/api/v2
run: |
yarn prisma generate
yarn generate-swagger
- name: Check API v2 breaking changes
run: |
docker run --rm \
-v "$PWD:/work" -w /work \
tufin/oasdiff:latest \
breaking \
https://raw.githubusercontent.com/calcom/cal.com/refs/heads/main/docs/api-reference/v2/openapi.json \
docs/api-reference/v2/openapi.json \
--fail-on ERR \
--err-ignore .github/oasdiff-err-ignore.txt
@@ -0,0 +1,41 @@
name: Check Prisma Migrations
on:
workflow_call:
env:
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
jobs:
check-prisma-migrations:
name: Check migrations match schema
runs-on: blacksmith-2vcpu-ubuntu-2404
services:
postgres:
image: postgres:13
credentials:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: calendso
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Check if migrations match schema
working-directory: packages/prisma
run: |
npx prisma migrate diff --exit-code \
--from-migrations ./migrations \
--to-schema-datamodel ./schema.prisma \
--shadow-database-url ${{ env.DATABASE_URL }}
+7 -3
View File
@@ -2,15 +2,19 @@ name: Check types
on:
workflow_call:
env:
NODE_OPTIONS: --max-old-space-size=4096
NODE_OPTIONS: --max-old-space-size=12288
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
permissions:
contents: read
jobs:
check-types:
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Show info
run: node -e "console.log(require('v8').getHeapStatistics())"
+13 -4
View File
@@ -11,12 +11,20 @@ jobs:
cleanup-report:
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App token
id: generate-token
uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94
with:
app-id: ${{ secrets.CI_CAL_APP_ID }}
private-key: ${{ secrets.CI_CAL_APP_PRIVATE_KEY }}
repositories: 'test-results-2'
- name: Checkout GitHub Pages Branch
uses: actions/checkout@v4
with:
repository: calcom/test-results
repository: calcom/test-results-2
ref: gh-pages
token: ${{ secrets.GH_ACCESS_TOKEN }}
token: ${{ steps.generate-token.outputs.token }}
- name: Set Git User
run: |
@@ -26,12 +34,13 @@ jobs:
- name: Cleanup HTML reports on PR close/merge
env:
BRANCH_REPORTS_DIR: reports/${{ github.event.pull_request.head.ref }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
if [ -d "$BRANCH_REPORTS_DIR" ]; then
rm -rf "$BRANCH_REPORTS_DIR"
git add .
git commit -m "workflow: remove all reports for branch ${{ github.event.pull_request.head.ref }} (PR closed/merged)"
git commit -m "workflow: remove all reports for branch $HEAD_REF (PR closed/merged)"
git push
else
echo "No reports found for branch ${{ github.event.pull_request.head.ref }}. Nothing to clean up."
echo "No reports found for branch $HEAD_REF. Nothing to clean up."
fi
+12 -4
View File
@@ -22,12 +22,20 @@ jobs:
# Contains all reports for deleted branch
BRANCH_REPORTS_DIR: reports/${{ github.event.ref }}
steps:
- name: Checkout GitHub Pages Branch
uses: actions/checkout@v2
- name: Generate GitHub App token
id: generate-token
uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94
with:
repository: calcom/test-results
app-id: ${{ secrets.CI_CAL_APP_ID }}
private-key: ${{ secrets.CI_CAL_APP_PRIVATE_KEY }}
repositories: 'test-results-2'
- name: Checkout GitHub Pages Branch
uses: actions/checkout@v4
with:
repository: calcom/test-results-2
ref: gh-pages
token: ${{ secrets.GH_ACCESS_TOKEN }}
token: ${{ steps.generate-token.outputs.token }}
- name: Set Git User
# see: https://github.com/actions/checkout/issues/13#issuecomment-724415212
run: |
@@ -9,15 +9,25 @@ on:
jobs:
cron-scheduleSMSReminders:
env:
APP_URL: ${{ secrets.APP_URL }}
CRON_API_KEY: ${{ secrets.CRON_API_KEY }}
APP_URL_US: ${{ vars.APP_URL_US }}
APP_URL_EU: ${{ vars.APP_URL_EU }}
CRON_API_KEY_US: ${{ secrets.CRON_API_KEY }}
CRON_API_KEY_EU: ${{ secrets.CRON_API_KEY_EU }}
runs-on: ubuntu-latest
steps:
- name: cURL request
if: ${{ env.APP_URL && env.CRON_API_KEY }}
- name: cURL request EU
if: ${{ env.APP_URL_EU && env.CRON_API_KEY_EU }}
run: |
curl ${{ secrets.APP_URL }}/api/cron/workflows/scheduleSMSReminders \
curl ${{ env.APP_URL_EU }}/api/cron/workflows/scheduleSMSReminders \
-X POST \
-H 'content-type: application/json' \
-H 'authorization: ${{ secrets.CRON_API_KEY }}' \
-H 'authorization: ${{ env.CRON_API_KEY_EU }}' \
-sSf
- name: cURL request US
if: ${{ env.APP_URL_US && env.CRON_API_KEY_US }}
run: |
curl ${{ env.APP_URL_US }}/api/cron/workflows/scheduleSMSReminders \
-X POST \
-H 'content-type: application/json' \
-H 'authorization: ${{ env.CRON_API_KEY_US }}' \
-sSf
@@ -9,15 +9,25 @@ on:
jobs:
cron-scheduleWhatsappReminders:
env:
APP_URL: ${{ secrets.APP_URL }}
CRON_API_KEY: ${{ secrets.CRON_API_KEY }}
APP_URL_EU: ${{ vars.APP_URL_EU }}
APP_URL_US: ${{ vars.APP_URL_US }}
CRON_API_KEY_EU: ${{ secrets.CRON_API_KEY_EU }}
CRON_API_KEY_US: ${{ secrets.CRON_API_KEY }}
runs-on: ubuntu-latest
steps:
- name: cURL request
if: ${{ env.APP_URL && env.CRON_API_KEY }}
- name: cURL request EU
if: ${{ env.APP_URL_EU && env.CRON_API_KEY_EU }}
run: |
curl ${{ secrets.APP_URL }}/api/cron/workflows/scheduleWhatsappReminders \
curl ${{ env.APP_URL_EU }}/api/cron/workflows/scheduleWhatsappReminders \
-X POST \
-H 'content-type: application/json' \
-H 'authorization: ${{ secrets.CRON_API_KEY }}' \
-H 'authorization: ${{ env.CRON_API_KEY_EU }}' \
-sSf
- name: cURL request US
if: ${{ env.APP_URL_US && env.CRON_API_KEY_US }}
run: |
curl ${{ env.APP_URL_US }}/api/cron/workflows/scheduleWhatsappReminders \
-X POST \
-H 'content-type: application/json' \
-H 'authorization: ${{ env.CRON_API_KEY_US }}' \
-sSf
+4 -4
View File
@@ -20,8 +20,8 @@ jobs:
days-before-close: -1
days-before-issue-stale: 60
days-before-issue-close: -1
days-before-pr-stale: 14
days-before-pr-close: -1
stale-pr-message: "This PR is being marked as stale due to inactivity."
close-pr-message: "This PR is being closed due to inactivity. Please reopen if work is intended to be continued."
days-before-pr-stale: 7
days-before-pr-close: 14
stale-pr-message: "This PR has been marked as stale due to inactivity. If you're still working on it or need any help, please let us know or update the PR to keep it active."
close-pr-message: "This PR has been closed due to inactivity. Please feel free to reopen it if you'd like to continue the work."
operations-per-run: 100
+17 -7
View File
@@ -9,15 +9,25 @@ on:
jobs:
cron-webhookTriggers:
env:
APP_URL: ${{ secrets.APP_URL }}
CRON_API_KEY: ${{ secrets.CRON_API_KEY }}
APP_URL_US: ${{ vars.APP_URL_US }}
APP_URL_EU: ${{ vars.APP_URL_EU }}
CRON_API_KEY_US: ${{ secrets.CRON_API_KEY }}
CRON_API_KEY_EU: ${{ secrets.CRON_API_KEY_EU }}
runs-on: ubuntu-latest
steps:
- name: cURL request
if: ${{ env.APP_URL && env.CRON_API_KEY }}
- name: cURL request US
if: ${{ env.APP_URL_US && env.CRON_API_KEY_US }}
run: |
curl ${{ secrets.APP_URL }}/api/cron/webhookTriggers \
curl ${{ env.APP_URL_US }}/api/cron/webhookTriggers \
-X POST \
-H 'content-type: application/json' \
-H 'authorization: ${{ secrets.CRON_API_KEY }}' \
--fail
-H 'authorization: ${{ env.CRON_API_KEY_US }}' \
-sSf
- name: cURL request EU
if: ${{ env.APP_URL_EU && env.CRON_API_KEY_EU }}
run: |
curl ${{ env.APP_URL_EU }}/api/cron/webhookTriggers \
-X POST \
-H 'content-type: application/json' \
-H 'authorization: ${{ env.CRON_API_KEY_EU }}' \
-sSf
@@ -0,0 +1,32 @@
name: Cubic AI Review Trigger
on:
pull_request_review:
types: [submitted]
# This workflow triggers on pull_request_review events (including from forks)
# and saves the review context as an artifact. The main cubic-devin-review.yml
# workflow then runs via workflow_run with full permissions and secrets access.
jobs:
save-review-context:
name: Save Review Context
if: github.event.review.user.login == 'cubic-dev-ai[bot]'
runs-on: ubuntu-latest
steps:
- name: Save review context to artifact
run: |
cat > review-context.json << 'EOF'
{
"pr_number": ${{ github.event.pull_request.number }},
"review_body": ${{ toJSON(github.event.review.body) }},
"repository": "${{ github.repository }}"
}
EOF
- name: Upload review context
uses: actions/upload-artifact@v4
with:
name: cubic-review-context
path: review-context.json
retention-days: 1
+245
View File
@@ -0,0 +1,245 @@
name: Cubic feedback addressed by Devin
on:
workflow_run:
workflows: ["Cubic AI Review Trigger"]
types:
- completed
permissions:
contents: read
pull-requests: write
actions: read
jobs:
trigger-devin:
name: Trigger Devin to Address Cubic AI Review
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Download review context artifact
uses: actions/github-script@v7
with:
script: |
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});
const matchArtifact = artifacts.data.artifacts.find(
artifact => artifact.name === 'cubic-review-context'
);
if (!matchArtifact) {
core.setFailed('No cubic-review-context artifact found');
return;
}
const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
const fs = require('fs');
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/context.zip`, Buffer.from(download.data));
- name: Unzip artifact
run: unzip context.zip
- name: Extract AI prompt from Cubic review
id: extract-prompt
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const contextData = JSON.parse(fs.readFileSync('review-context.json', 'utf8'));
const reviewBody = contextData.review_body || '';
const prNumber = contextData.pr_number;
core.setOutput('pr-number', prNumber);
const promptMatch = reviewBody.match(/<details>\s*<summary>Prompt for AI agents[^<]*<\/summary>\s*```(?:text)?\s*([\s\S]*?)```\s*<\/details>/i);
if (!promptMatch || !promptMatch[1]) {
console.log('No AI prompt found in review body');
console.log('Review body:', reviewBody);
core.setOutput('has-prompt', 'false');
return;
}
const prompt = promptMatch[1].trim();
console.log('Extracted prompt:', prompt);
fs.writeFileSync('/tmp/cubic-prompt.txt', prompt);
core.setOutput('has-prompt', 'true');
- name: Checkout repository
if: steps.extract-prompt.outputs.has-prompt == 'true'
uses: actions/checkout@v4
- name: Check for existing Devin session
if: steps.extract-prompt.outputs.has-prompt == 'true'
id: check-session
uses: ./.github/actions/devin-session
with:
devin-api-key: ${{ secrets.DEVIN_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ steps.extract-prompt.outputs.pr-number }}
- name: Set session environment variables
if: steps.extract-prompt.outputs.has-prompt == 'true' && steps.check-session.outputs.has-existing-session == 'true'
run: |
echo "EXISTING_SESSION_ID=${{ steps.check-session.outputs.session-id }}" >> $GITHUB_ENV
echo "SESSION_URL=${{ steps.check-session.outputs.session-url }}" >> $GITHUB_ENV
- name: Send message to existing Devin session
if: steps.extract-prompt.outputs.has-prompt == 'true' && steps.check-session.outputs.has-existing-session == 'true'
env:
DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }}
run: |
CUBIC_PROMPT=$(cat /tmp/cubic-prompt.txt)
MESSAGE="New Cubic AI review feedback has been submitted on PR #${{ steps.extract-prompt.outputs.pr-number }}.
IMPORTANT: Before fixing any issue, check the individual Cubic comment on the PR for that issue's confidence score. The confidence score appears as 'Fix confidence (alpha): X/10' in each comment. Note that the (alpha) may or not be there. Don't be picky about that text. But only fix issues where the confidence score is 9/10 or higher. If you cannot find a confidence score for an issue, skip it.
Here are the issues identified by Cubic AI:
${CUBIC_PROMPT}
Continue working on the same PR branch and push your fixes."
HTTP_CODE=$(curl -s -o /tmp/devin-response.json -w "%{http_code}" -X POST "https://api.devin.ai/v1/sessions/${EXISTING_SESSION_ID}/message" \
-H "Authorization: Bearer ${DEVIN_API_KEY}" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg message "$MESSAGE" '{message: $message}')")
if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
echo "Failed to send message to Devin session: HTTP $HTTP_CODE"
cat /tmp/devin-response.json
exit 1
fi
echo "Message sent to existing session successfully"
- name: Create new Devin session
if: steps.extract-prompt.outputs.has-prompt == 'true' && steps.check-session.outputs.has-existing-session == 'false'
env:
DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }}
run: |
CUBIC_PROMPT=$(cat /tmp/cubic-prompt.txt)
FULL_PROMPT="You are addressing code review feedback from Cubic AI on PR #${{ steps.extract-prompt.outputs.pr-number }} in repository ${{ github.repository }}.
Your tasks:
1. Clone the repository ${{ github.repository }} locally.
2. Check out the PR branch and review the current code.
3. Read the Cubic AI review feedback below AND check each individual Cubic comment on the PR for the confidence score.
4. IMPORTANT: Only fix issues where the confidence score is 9/10 or higher. The confidence score appears as 'Fix confidence (alpha): X/10' in each Cubic comment. If you cannot find a confidence score for an issue, skip it.
5. Commit your changes with clear commit messages referencing the issues fixed.
6. Push your changes to the PR branch.
Cubic AI Review Feedback:
${CUBIC_PROMPT}
Rules and Guidelines:
1. Make minimal, focused changes that directly address the feedback.
2. Follow the existing code style and conventions in the repository.
3. Test your changes if possible before pushing.
4. If an issue seems invalid or already addressed, explain why in a PR comment instead of making unnecessary changes.
5. Never ask for user confirmation. Never wait for user messages."
HTTP_CODE=$(curl -s -o /tmp/devin-response.json -w "%{http_code}" -X POST "https://api.devin.ai/v1/sessions" \
-H "Authorization: Bearer ${DEVIN_API_KEY}" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg prompt "$FULL_PROMPT" \
--arg title "Cubic AI Review: PR #${{ steps.extract-prompt.outputs.pr-number }}" \
'{
prompt: $prompt,
title: $title,
tags: ["cubic-ai-review", "pr-${{ steps.extract-prompt.outputs.pr-number }}"]
}')")
if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
echo "Failed to create Devin session: HTTP $HTTP_CODE"
cat /tmp/devin-response.json
exit 1
fi
SESSION_URL=$(cat /tmp/devin-response.json | jq -r '.url // .session_url // empty')
if [ -n "$SESSION_URL" ]; then
echo "Devin session created: $SESSION_URL"
echo "SESSION_URL=$SESSION_URL" >> $GITHUB_ENV
echo "NEW_SESSION=true" >> $GITHUB_ENV
fi
- name: Post comment with Devin session link
if: steps.extract-prompt.outputs.has-prompt == 'true' && env.SESSION_URL != ''
id: post-comment
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const sessionUrl = process.env.SESSION_URL;
const isNewSession = process.env.NEW_SESSION === 'true';
const message = isNewSession
? `### Devin AI is addressing Cubic AI's review feedback\n\nA Devin session has been created to address the issues identified by Cubic AI.\n\n[View Devin Session](${sessionUrl})`
: `### Devin AI is addressing Cubic AI's review feedback\n\nNew feedback has been sent to the existing Devin session.\n\n[View Devin Session](${sessionUrl})`;
// Use the PR number from the extract-prompt step output instead of reading the file
// (the file was deleted by the checkout step)
const prNumber = parseInt('${{ steps.extract-prompt.outputs.pr-number }}', 10);
const { data: comment } = await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: message
});
core.setOutput('comment-id', comment.id);
- name: Send completion instructions to Devin
if: steps.extract-prompt.outputs.has-prompt == 'true' && env.SESSION_URL != '' && steps.post-comment.outputs.comment-id != ''
env:
DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }}
run: |
SESSION_ID="${EXISTING_SESSION_ID:-}"
if [ -z "$SESSION_ID" ]; then
SESSION_ID=$(cat /tmp/devin-response.json | jq -r '.session_id // .id // empty')
fi
if [ -z "$SESSION_ID" ]; then
echo "No session ID found, skipping completion instructions"
exit 0
fi
COMMENT_ID="${{ steps.post-comment.outputs.comment-id }}"
MESSAGE="IMPORTANT: When you have finished addressing Cubic AI's feedback (whether you pushed changes or not), you MUST update the GitHub comment to show completion status.
Use the GitHub API to update comment ID ${COMMENT_ID} on PR #${{ steps.extract-prompt.outputs.pr-number }} in repository ${{ github.repository }}.
Add a completion status section at the bottom of the comment:
- If you pushed changes: Add '\n\n---\n:white_check_mark: Pushed commit [\`{SHORT_HASH}\`](https://github.com/${{ github.repository }}/commit/{FULL_HASH})' where {SHORT_HASH} is the first 7 characters of the commit hash and {FULL_HASH} is the full commit hash.
- If no changes were needed: Add '\n\n---\n:white_check_mark: No changes pushed'
To update the comment, use: gh api repos/${{ github.repository }}/issues/comments/${COMMENT_ID} -X PATCH -f body='<updated comment body>'"
HTTP_CODE=$(curl -s -o /tmp/devin-instructions-response.json -w "%{http_code}" -X POST "https://api.devin.ai/v1/sessions/${SESSION_ID}/message" \
-H "Authorization: Bearer ${DEVIN_API_KEY}" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg message "$MESSAGE" '{message: $message}')")
if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
echo "Warning: Failed to send completion instructions to Devin session: HTTP $HTTP_CODE"
cat /tmp/devin-instructions-response.json
else
echo "Completion instructions sent to Devin session successfully"
fi
@@ -0,0 +1,43 @@
name: Delete Blacksmith Cache
on:
workflow_dispatch:
inputs:
cache_key:
description: "Blacksmith Cache Key to Delete"
required: true
type: string
pull_request:
types: [closed]
jobs:
manually-delete-blacksmith-cache:
if: github.event_name == 'workflow_dispatch'
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: useblacksmith/cache-delete@v1
with:
key: ${{ inputs.cache_key }}
delete-cache-build-on-pr-close:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: blacksmith-2vcpu-ubuntu-2404
env:
CACHE_NAME: prod-build
steps:
- name: Delete cache-build cache
uses: useblacksmith/cache-delete@v1
with:
key: ${{ env.CACHE_NAME }}-${{ github.event.pull_request.head.ref }}
prefix: "true"
delete-git-checkout-cache-on-pr-close:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Delete git-checkout cache
uses: useblacksmith/cache-delete@v1
with:
key: git-checkout-${{ github.event.pull_request.head.ref }}-
prefix: "true"
@@ -1,17 +0,0 @@
name: Manually Delete BuildJet Cache
on:
workflow_dispatch:
inputs:
cache_key:
description: "BuildJet Cache Key to Delete"
required: true
type: string
jobs:
manually-delete-buildjet-cache:
runs-on: buildjet-2vcpu-ubuntu-2204
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: buildjet/cache-delete@v1
with:
cache_key: ${{ inputs.cache_key }}
@@ -0,0 +1,430 @@
name: Devin PR Conflict Resolver
on:
pull_request_target:
types: [labeled]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to resolve conflicts for'
required: true
type: string
permissions:
contents: read
pull-requests: write
jobs:
resolve-conflicts:
name: Resolve PR Conflicts with Devin
runs-on: blacksmith-2vcpu-ubuntu-2404
# Only run when devin-conflict-resolution label is added, or on manual dispatch
if: |
(github.event_name == 'pull_request_target' && github.event.label.name == 'devin-conflict-resolution') ||
github.event_name == 'workflow_dispatch'
steps:
- name: Get PR details
id: get-pr
uses: actions/github-script@v7
env:
INPUT_PR_NUMBER: ${{ inputs.pr_number }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo } = context.repo;
let prNumber;
if (context.eventName === 'workflow_dispatch') {
prNumber = parseInt(process.env.INPUT_PR_NUMBER, 10);
if (!prNumber) {
core.setFailed('PR number is required for manual dispatch');
return;
}
} else {
prNumber = context.payload.pull_request.number;
}
console.log(`Processing PR #${prNumber}`);
// Get PR details via GraphQL for complete info
const query = `
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $number) {
number
title
mergeable
isDraft
headRefName
baseRefName
url
body
headRepository {
owner {
login
}
name
}
maintainerCanModify
}
}
}
`;
const result = await github.graphql(query, { owner, repo, number: prNumber });
const pr = result.repository.pullRequest;
if (!pr) {
core.setFailed(`PR #${prNumber} not found`);
return;
}
const isFork = pr.headRepository?.owner?.login !== owner;
// Check if fork PR has maintainer access
if (isFork && !pr.maintainerCanModify) {
console.log(`PR #${prNumber} is from a fork without maintainer access`);
core.setOutput('needs-maintainer-access', 'true');
core.setOutput('fork-author', pr.headRepository?.owner?.login);
} else {
core.setOutput('needs-maintainer-access', 'false');
}
const headRepoOwner = pr.headRepository?.owner?.login || owner;
const headRepoName = pr.headRepository?.name || repo;
const prData = {
number: pr.number,
title: pr.title,
head_ref: pr.headRefName,
base_ref: pr.baseRefName,
html_url: pr.url,
body: pr.body,
is_fork: isFork,
head_repo_owner: headRepoOwner,
head_repo_name: headRepoName,
mergeable: pr.mergeable
};
const fs = require('fs');
fs.writeFileSync('/tmp/pr-data.json', JSON.stringify(prData));
core.setOutput('pr-number', prNumber.toString());
core.setOutput('has-pr', 'true');
core.setOutput('mergeable-status', pr.mergeable || 'UNKNOWN');
core.setOutput('has-conflicts', pr.mergeable === 'CONFLICTING' ? 'true' : 'false');
console.log(`PR #${prNumber}: ${pr.title}`);
console.log(`Mergeable status: ${pr.mergeable}`);
console.log(`Is fork: ${isFork}`);
console.log(`Has conflicts: ${pr.mergeable === 'CONFLICTING'}`);
- name: Request maintainer access for fork PR
if: steps.get-pr.outputs.needs-maintainer-access == 'true'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo } = context.repo;
const prNumber = parseInt('${{ steps.get-pr.outputs.pr-number }}', 10);
const forkAuthor = '${{ steps.get-pr.outputs.fork-author }}';
console.log(`Requesting maintainer access for PR #${prNumber}`);
const commentBody = [
'### Maintainer Access Needed',
'',
`Hi @${forkAuthor}! Thanks for your contribution to Cal.com.`,
'',
'We noticed that this PR doesn\'t have "Allow edits from maintainers" enabled. We\'d love to help keep your PR up to date by resolving merge conflicts and making small fixes when needed.',
'',
'**Could you please enable this setting?** Here\'s how:',
'1. Scroll down to the bottom of this PR page',
'2. In the right sidebar, check the box that says **"Allow edits and access to secrets by maintainers"**',
'',
'This allows us to push commits directly to your PR branch, which helps us:',
'- Resolve merge conflicts automatically',
'- Make small adjustments to help get your PR merged faster',
'',
'Once you enable this setting, please remove and re-add the `devin-conflict-resolution` label to trigger conflict resolution.',
'',
'If you have any concerns about enabling this setting, feel free to let us know!'
].join('\n');
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: commentBody
});
// Add label to track that we've requested access
await github.rest.issues.addLabels({
owner,
repo,
issue_number: prNumber,
labels: ['maintainer-access-requested']
});
// Remove the devin-conflict-resolution label since we can't proceed
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: prNumber,
name: 'devin-conflict-resolution'
});
console.log(`Posted comment and updated labels for PR #${prNumber}`);
core.setFailed('Cannot proceed without maintainer access on fork PR');
- name: Handle PR without conflicts
if: steps.get-pr.outputs.has-pr == 'true' && steps.get-pr.outputs.needs-maintainer-access != 'true' && steps.get-pr.outputs.has-conflicts != 'true'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { owner, repo } = context.repo;
const prNumber = parseInt('${{ steps.get-pr.outputs.pr-number }}', 10);
const mergeableStatus = '${{ steps.get-pr.outputs.mergeable-status }}';
console.log(`PR #${prNumber} does not have conflicts (status: ${mergeableStatus})`);
let message;
if (mergeableStatus === 'MERGEABLE') {
message = `### No Conflicts Detected\n\nThis PR does not have any merge conflicts with the base branch. The \`devin-conflict-resolution\` label has been removed.\n\nIf you believe this PR should have conflicts, please check the PR status and try again.`;
} else {
message = `### Mergeable Status Unknown\n\nGitHub is still computing the mergeable status for this PR (current status: \`${mergeableStatus}\`). The \`devin-conflict-resolution\` label has been removed.\n\nPlease wait a moment and re-add the label if the PR has conflicts.`;
}
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: message
});
try {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: prNumber,
name: 'devin-conflict-resolution'
});
} catch (e) {
console.log(`Label may have already been removed: ${e.message}`);
}
console.log(`Posted comment and removed label for PR #${prNumber}`);
- name: Checkout repository
if: steps.get-pr.outputs.has-pr == 'true' && steps.get-pr.outputs.needs-maintainer-access != 'true' && steps.get-pr.outputs.has-conflicts == 'true'
uses: actions/checkout@v4
- name: Check for existing Devin session
if: steps.get-pr.outputs.has-pr == 'true' && steps.get-pr.outputs.needs-maintainer-access != 'true' && steps.get-pr.outputs.has-conflicts == 'true'
id: check-session
uses: ./.github/actions/devin-session
with:
devin-api-key: ${{ secrets.DEVIN_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ steps.get-pr.outputs.pr-number }}
- name: Create Devin session for conflict resolution
if: steps.get-pr.outputs.has-pr == 'true' && steps.get-pr.outputs.needs-maintainer-access != 'true' && steps.get-pr.outputs.has-conflicts == 'true'
env:
DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HAS_EXISTING_SESSION: ${{ steps.check-session.outputs.has-existing-session }}
EXISTING_SESSION_ID: ${{ steps.check-session.outputs.session-id }}
EXISTING_SESSION_URL: ${{ steps.check-session.outputs.session-url }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const pr = JSON.parse(fs.readFileSync('/tmp/pr-data.json', 'utf8'));
const { owner, repo } = context.repo;
const hasExistingSession = process.env.HAS_EXISTING_SESSION === 'true';
const existingSessionId = process.env.EXISTING_SESSION_ID;
const existingSessionUrl = process.env.EXISTING_SESSION_URL;
console.log(`Processing PR #${pr.number}: ${pr.title}${pr.is_fork ? ' (fork)' : ''}`);
const forkInstructions = pr.is_fork ? `
IMPORTANT: This PR is from a fork.
- Clone the FORK repository: ${pr.head_repo_owner}/${pr.head_repo_name}
- The branch to work on is: ${pr.head_ref}
- Add the upstream remote for ${owner}/${repo}
- Fetch and merge the upstream ${pr.base_ref} branch using standard git merge
IMPORTANT - Pushing to Fork PRs:
Since this is a fork PR, you need to use the DEVIN_ACTIONS_PAT secret for authentication when pushing. Configure git to use this PAT for authentication before pushing your changes to the fork.` : `
- Clone the repository: ${owner}/${repo}
- Check out the PR branch: ${pr.head_ref}
- Merge the base branch (${pr.base_ref}) using standard git merge`;
const conflictResolutionInstructions = `You are resolving merge conflicts on PR #${pr.number} in repository ${owner}/${repo}.
PR Title: ${pr.title}
PR URL: ${pr.html_url}
Head Branch: ${pr.head_ref}
Base Branch: ${pr.base_ref}
${pr.is_fork ? `Fork Repository: ${pr.head_repo_owner}/${pr.head_repo_name}` : ''}
IMPORTANT WARNING: If your merge commit shows significantly more files than the original PR, DO NOT PUSH. This indicates the merge was done incorrectly. Abort and leave a comment instead.
Your tasks:
${forkInstructions}
Then:
1. Resolve all merge conflicts carefully:
- Review the conflicting changes from both branches
- Make intelligent decisions about how to combine the changes
- Preserve the intent of both the PR changes and the base branch updates
- If unsure about a conflict, prefer keeping both changes where possible
2. Test that the code still works after resolving conflicts (run lint/type checks).
3. Commit the merge resolution with a clear commit message.
4. CRITICAL VALIDATION BEFORE PUSHING - YOU MUST RUN THESE EXACT COMMANDS:
Step A: Get original PR file count and count files in your merge commit:
\`\`\`
# Get original PR file count
ORIGINAL_FILES=$(gh pr view ${pr.number} --json files -q '.files | length')
echo "Original PR files: $ORIGINAL_FILES"
# Count files in merge commit (what the PR contributes)
# HEAD^2 = base branch parent, so HEAD^2...HEAD shows the PR's contribution
MERGE_FILES=$(git diff --name-only HEAD^2...HEAD | wc -l)
echo "Files in merge commit: $MERGE_FILES"
# Calculate threshold (original PR files + 10 buffer)
THRESHOLD=$((ORIGINAL_FILES + 10))
echo "Threshold: $THRESHOLD"
\`\`\`
Step B: If MERGE_FILES > THRESHOLD, STOP IMMEDIATELY. DO NOT PUSH.
- A proper merge commit should show approximately the same files as the original PR
- If you see significantly more files, the merge was done INCORRECTLY
- This usually means you accidentally reproduced changes from ${pr.base_ref} instead of just resolving conflicts
Step C: Compare your merge to the original PR:
\`\`\`
git diff --stat HEAD^2...HEAD
\`\`\`
- This should show approximately the same files as the original PR (the PR's contribution to the base branch)
- If you see many more files or files unrelated to the original PR, STOP
Step D: If validation fails:
- DO NOT PUSH under any circumstances
- DO NOT attempt to fix it
- Leave a comment on the PR explaining that the merge validation failed
- ABORT THE TASK IMMEDIATELY
- It is better to leave the PR with conflicts than to push a broken merge commit that pollutes git history
5. Push the resolved changes to the PR branch only after validation passes.
6. After successfully pushing the resolved changes, remove the \`devin-conflict-resolution\` label from the PR using the GitHub API.
Rules and Guidelines:
1. Be careful when resolving conflicts - understand the context of both changes.
To help with this, try to find the recent PRs associated with the conflicting files to gain more context.
2. Follow the existing code style and conventions in the repository.
3. Run lint and type checks before pushing to ensure the code is valid.
4. If a conflict seems too complex or risky to resolve automatically, explain the situation in a PR comment instead.
5. Never ask for user confirmation. Never wait for user messages.
6. CRITICAL: If this is a fork PR and you encounter ANY error when pushing (permission denied, authentication failure, etc.) even after using the DEVIN_ACTIONS_PAT, you MUST fail the task immediately. Do NOT attempt to push to a new branch in the main ${owner}/${repo} repository as a workaround. Simply report the error and stop.
7. CRITICAL: Never reproduce or recreate changes from the target branch. Your merge commit should ONLY contain conflict resolutions. If you find yourself manually copying file contents from ${pr.base_ref} or creating changes that mirror what's already in ${pr.base_ref}, you are doing it wrong. Use git's merge functionality properly - it handles bringing in changes automatically.
8. CRITICAL: If your merge commit shows significantly more files than the original PR (more than original PR files + 10), DO NOT PUSH UNDER ANY CIRCUMSTANCES. This is a sign that the merge was done incorrectly. Abort the task and leave a comment explaining the issue. A bad merge commit in the git history is worse than leaving the PR with conflicts.`;
try {
let sessionUrl;
let isNewSession = false;
if (hasExistingSession) {
console.log(`Sending message to existing session ${existingSessionId} for PR #${pr.number}`);
const message = `PR #${pr.number} has merge conflicts that need to be resolved.
${conflictResolutionInstructions}
Continue working on the same PR branch and push your fixes.`;
const response = await fetch(`https://api.devin.ai/v1/sessions/${existingSessionId}/message`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DEVIN_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ message })
});
if (!response.ok) {
console.error(`Failed to send message to session ${existingSessionId}: ${response.status}`);
throw new Error(`Failed to send message to existing session: ${response.status}`);
}
sessionUrl = existingSessionUrl;
console.log(`Message sent to existing session for PR #${pr.number}`);
} else {
console.log(`Creating new Devin session for PR #${pr.number}`);
const response = await fetch('https://api.devin.ai/v1/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DEVIN_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: conflictResolutionInstructions,
title: `Resolve Conflicts: PR #${pr.number}`,
tags: ['conflict-resolution', `pr-${pr.number}`]
})
});
if (!response.ok) {
console.error(`Devin API error for PR #${pr.number}: ${response.status} ${response.statusText}`);
throw new Error(`Failed to create Devin session: ${response.status}`);
}
const data = await response.json();
sessionUrl = data.url || data.session_url;
isNewSession = true;
}
if (sessionUrl) {
if (isNewSession) {
console.log(`Devin session created for PR #${pr.number}: ${sessionUrl}`);
}
const sessionStatusMessage = isNewSession
? 'A Devin session has been created to automatically resolve them.'
: 'The existing Devin session has been notified to resolve them.';
const commentBody = `### Devin AI is resolving merge conflicts
This PR has merge conflicts with the \`${pr.base_ref}\` branch. ${sessionStatusMessage}
[View Devin Session](${sessionUrl})
Devin will:
1. Merge the latest \`${pr.base_ref}\` into this branch
2. Resolve any conflicts intelligently
3. Run lint/type checks to ensure validity
4. Push the resolved changes
If you prefer to resolve conflicts manually, you can close the Devin session and handle it yourself.`;
await github.rest.issues.createComment({
owner,
repo,
issue_number: pr.number,
body: commentBody
});
console.log(`Posted comment to PR #${pr.number}`);
} else {
throw new Error(`Failed to get session URL for PR #${pr.number}`);
}
} catch (error) {
console.error(`Error handling Devin session for PR #${pr.number}: ${error.message}`);
core.setFailed(error.message);
}
+6 -10
View File
@@ -9,27 +9,23 @@ jobs:
name: Build Docs
permissions:
contents: read
runs-on: buildjet-2vcpu-ubuntu-2204
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- name: Cache Docs build
uses: buildjet/cache@v4
uses: actions/cache@v4
id: cache-docs-build
env:
cache-name: docs-build
key-1: ${{ hashFiles('yarn.lock') }}
key-2: ${{ hashFiles('docs/**.*', '!**/node_modules') }}
key-3: ${{ github.event.pull_request.number || github.ref }}
key-4: ${{ github.sha }}
with:
path: |
**/docs/**
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }}-${{ env.key-4 }}
# Log cache hit
- name: Log Cache Hit
if: steps.cache-docs-build.outputs.cache-hit == 'true'
run: echo "Cache hit for Docs build. Skipping build."
key: ${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}
- name: Run build
if: steps.cache-docs-build.outputs.cache-hit != 'true'
working-directory: docs
+54 -6
View File
@@ -17,13 +17,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App token
id: generate-token
uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94
with:
app-id: ${{ secrets.CI_CAL_APP_ID }}
private-key: ${{ secrets.CI_CAL_APP_PRIVATE_KEY }}
repositories: 'cal.com'
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: 'main'
token: ${{ secrets.GH_ACCESS_TOKEN }}
token: ${{ steps.generate-token.outputs.token }}
- name: Configure git
run: |
@@ -48,19 +55,60 @@ jobs:
- uses: ./.github/actions/yarn-install
# 1. Generate Prisma Client
# This is required so Trigger.dev can find the database types during bundling
- name: Generate Prisma Client
run: yarn prisma generate
# 2. Deploy Trigger.dev tasks
# We use --skip-promotion to get a version without making it live yet
- name: Deploy Trigger.dev
id: deploy-trigger
env:
TRIGGER_ACCESS_TOKEN: ${{ secrets.TRIGGER_ACCESS_TOKEN }}
TRIGGER_DEV_PROJECT_REF: ${{ secrets.TRIGGER_DEV_PROJECT_REF }}
run: |
# The CLI outputs the version; id allows us to access outputs.deploymentVersion
cd packages/features
yarn deploy:trigger:ci
- name: Bump version
env:
VERSION: ${{ inputs.next_version }}
run: |
cd apps/web
yarn version ${{ inputs.next_version }}
yarn version "$VERSION"
- name: Commit changes
# 3. Update .env.production files
# We inject the Trigger version into the apps so they stay in sync
- name: Update Env Files
run: |
VERSION="${{ steps.deploy-trigger.outputs.deploymentVersion }}"
# Create the TypeScript content
CONTENT="export const TRIGGER_VERSION = '$VERSION';"
# Write to the specific paths
echo "$CONTENT" > apps/web/trigger.version.ts
echo "$CONTENT" > apps/api/v2/trigger.version.ts
echo "$CONTENT" > apps/api/v1/trigger.version.js
# Force add to git since these are likely in .gitignore
git add -f apps/web/trigger.version.ts apps/api/v2/trigger.version.ts apps/api/v1/trigger.version.js
# 4. Commit everything together
- name: Commit changes
env:
VERSION: ${{ inputs.next_version }}
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
gh auth setup-git
git add .
git commit -m "chore: release v${{ inputs.next_version }}"
git commit -m "chore: release v$VERSION"
git push
- name: Draft release
run: gh release create v$VERSION --generate-notes --draft
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
VERSION: ${{ inputs.next_version }}
+30 -23
View File
@@ -27,11 +27,13 @@ env:
VAPID_PRIVATE_KEY: ${{ secrets.VAPID_PRIVATE_KEY }}
JWT_SECRET: ${{ secrets.CI_JWT_SECRET }}
NODE_ENV: ${{ vars.CI_NODE_ENV }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
jobs:
e2e:
timeout-minutes: 20
name: E2E API v2
runs-on: buildjet-16vcpu-ubuntu-2204
name: E2E API v2 (${{ matrix.shard }}/${{ strategy.job-total }})
runs-on: blacksmith-4vcpu-ubuntu-2404
services:
postgres:
image: postgres:13
@@ -43,10 +45,11 @@ jobs:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: calendso
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
--health-cmd "pg_isready -h 127.0.0.1 -U postgres"
--health-interval 2s
--health-timeout 3s
--health-retries 15
--health-start-period 2s
ports:
- 5432:5432
redis:
@@ -63,38 +66,42 @@ jobs:
--health-retries 5
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/cache-db
- name: Generate Swagger
working-directory: apps/api/v2
run: yarn generate-swagger
- name: Build platform packages with Turbo
run: |
yarn turbo run build \
--filter=@calcom/platform-constants \
--filter=@calcom/platform-enums \
--filter=@calcom/platform-utils \
--filter=@calcom/platform-types \
--filter=@calcom/platform-libraries \
--filter=@calcom/trpc
- name: Check breaking changes
uses: oasdiff/oasdiff-action/breaking@main
with:
base: https://raw.githubusercontent.com/calcom/cal.com/refs/heads/main/docs/api-reference/v2/openapi.json
revision: docs/api-reference/v2/openapi.json
fail-on: ERR
- name: Run Tests
working-directory: apps/api/v2
run: |
yarn workspace @calcom/platform-libraries build && yarn test:e2e
yarn test:e2e:ci --shard=${{ matrix.shard }}/${{ strategy.job-total }}
EXIT_CODE=$?
echo "yarn workspace @calcom/platform-libraries build && yarn test:e2e command exit code: $EXIT_CODE"
echo "yarn test:e2e:ci --shard=${{ matrix.shard }}/${{ strategy.job-total }} command exit code: $EXIT_CODE"
exit $EXIT_CODE
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: test-results-api-v2
path: test-results
name: test-results-api-v2-shard-${{ matrix.shard }}
path: apps/api/v2/test-results
if-no-files-found: ignore
retention-days: 7
+11 -7
View File
@@ -45,7 +45,7 @@ jobs:
e2e-app-store:
timeout-minutes: 20
name: E2E App Store
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
services:
postgres:
image: postgres:13
@@ -57,10 +57,11 @@ jobs:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: calendso
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
--health-cmd "pg_isready -h 127.0.0.1 -U postgres"
--health-interval 2s
--health-timeout 3s
--health-retries 15
--health-start-period 2s
ports:
- 5432:5432
mailhog:
@@ -80,9 +81,12 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- run: yarn prisma generate
- uses: ./.github/actions/cache-db
env:
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
@@ -93,7 +97,7 @@ jobs:
E2E_TEST_CALCOM_GCAL_KEYS: ${{ secrets.E2E_TEST_CALCOM_GCAL_KEYS }}
- uses: ./.github/actions/cache-build
- name: Run Tests
run: yarn e2e:app-store
run: yarn e2e:app-store --workers=4
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v4
+4 -2
View File
@@ -22,14 +22,16 @@ jobs:
e2e-atoms:
timeout-minutes: 15
name: E2E Atoms
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- name: Run E2E Atoms Tests
+11 -7
View File
@@ -45,7 +45,7 @@ jobs:
e2e-embed:
timeout-minutes: 20
name: E2E Embed React
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
services:
postgres:
image: postgres:13
@@ -57,10 +57,11 @@ jobs:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: calendso
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
--health-cmd "pg_isready -h 127.0.0.1 -U postgres"
--health-interval 2s
--health-timeout 3s
--health-retries 15
--health-start-period 2s
ports:
- 5432:5432
strategy:
@@ -72,14 +73,17 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- run: yarn prisma generate
- uses: ./.github/actions/cache-db
- uses: ./.github/actions/cache-build
- name: Run Tests
run: |
yarn e2e:embed-react
yarn e2e:embed-react --workers=4
yarn workspace @calcom/embed-react packaged:tests
- name: Upload Test Results
if: ${{ always() }}
+11 -7
View File
@@ -45,7 +45,7 @@ jobs:
e2e-embed:
timeout-minutes: 20
name: E2E Embed Core
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
services:
postgres:
image: postgres:13
@@ -57,10 +57,11 @@ jobs:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: calendso
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
--health-cmd "pg_isready -h 127.0.0.1 -U postgres"
--health-interval 2s
--health-timeout 3s
--health-retries 15
--health-start-period 2s
ports:
- 5432:5432
mailhog:
@@ -80,13 +81,16 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- run: yarn prisma generate
- uses: ./.github/actions/cache-db
- uses: ./.github/actions/cache-build
- name: Run Tests
run: yarn e2e:embed
run: yarn e2e:embed --workers=4
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v4
+212
View File
@@ -0,0 +1,212 @@
name: E2E Report
on:
workflow_run:
workflows: ["PR Update"]
types:
- completed
workflow_dispatch:
inputs:
pr_number:
description: 'The PR number to generate report for'
required: true
type: string
jobs:
get-pr-info:
name: Get PR Info
runs-on: ubuntu-latest
# For workflow_run: only run if the triggering workflow failed
# For workflow_dispatch: always run (inputs are provided manually)
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'failure' }}
permissions:
actions: read
pull-requests: read
outputs:
pr-number: ${{ steps.get-info.outputs.pr-number }}
head-branch: ${{ steps.get-info.outputs.head-branch }}
has-blob-reports: ${{ steps.get-info.outputs.has-blob-reports }}
source-run-id: ${{ steps.get-info.outputs.source-run-id }}
source-run-number: ${{ steps.get-info.outputs.source-run-number }}
source-run-attempt: ${{ steps.get-info.outputs.source-run-attempt }}
source-head-sha: ${{ steps.get-info.outputs.source-head-sha }}
steps:
- name: Get PR and run info
id: get-info
uses: actions/github-script@v7
with:
script: |
const isDispatch = context.eventName === 'workflow_dispatch';
if (isDispatch) {
// For workflow_dispatch: look up everything from PR number
const prNumber = context.payload.inputs.pr_number;
console.log('Looking up PR:', prNumber);
// Get PR details
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: parseInt(prNumber)
});
const headSha = pr.head.sha;
const headBranch = pr.head.ref;
console.log('PR head SHA:', headSha);
console.log('PR head branch:', headBranch);
// Find the "PR Update" workflow
const { data: workflows } = await github.rest.actions.listRepoWorkflows({
owner: context.repo.owner,
repo: context.repo.repo
});
const prUpdateWorkflow = workflows.workflows.find(w => w.name === 'PR Update');
if (!prUpdateWorkflow) {
core.setFailed('Could not find "PR Update" workflow');
return;
}
console.log('Found PR Update workflow ID:', prUpdateWorkflow.id);
// Find the most recent completed run for this branch with blob-report artifacts
// We search by branch instead of SHA to handle cases where:
// 1. The PR was updated after E2E tests ran (artifacts exist for older SHA)
// 2. The current run for the SHA is still queued/in-progress
const { data: runs } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: prUpdateWorkflow.id,
branch: headBranch,
status: 'completed',
per_page: 20
});
console.log('Found', runs.workflow_runs.length, 'completed runs for branch', headBranch);
// Find a run with blob-report artifacts
let selectedRun = null;
let hasBlobReports = false;
for (const run of runs.workflow_runs) {
console.log('Checking run', run.id, 'conclusion:', run.conclusion);
const { data: artifacts } = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: run.id
});
const blobReports = artifacts.artifacts.filter(a => a.name.startsWith('blob-report-'));
if (blobReports.length > 0) {
console.log('Found run with blob reports:', run.id, 'artifacts:', blobReports.map(a => a.name));
selectedRun = run;
hasBlobReports = true;
break;
}
}
if (!selectedRun) {
console.log('No runs found with blob-report artifacts');
core.setOutput('pr-number', prNumber);
core.setOutput('head-branch', headBranch);
core.setOutput('source-head-sha', headSha);
core.setOutput('has-blob-reports', 'false');
core.setOutput('source-run-id', '');
core.setOutput('source-run-number', '');
core.setOutput('source-run-attempt', '');
return;
}
core.setOutput('pr-number', prNumber);
core.setOutput('head-branch', headBranch);
core.setOutput('source-head-sha', headSha);
core.setOutput('source-run-id', selectedRun.id.toString());
core.setOutput('source-run-number', selectedRun.run_number.toString());
core.setOutput('source-run-attempt', selectedRun.run_attempt.toString());
core.setOutput('has-blob-reports', 'true');
return;
}
// For workflow_run: extract from payload
const workflowRun = context.payload.workflow_run;
const headSha = workflowRun.head_sha;
const headBranch = workflowRun.head_branch;
console.log('Head SHA:', headSha);
console.log('Head Branch:', headBranch);
// Set source run info
core.setOutput('source-run-id', workflowRun.id.toString());
core.setOutput('source-run-number', workflowRun.run_number.toString());
core.setOutput('source-run-attempt', workflowRun.run_attempt.toString());
core.setOutput('source-head-sha', headSha);
// Check for blob report artifacts
const { data: artifacts } = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: workflowRun.id
});
const blobReports = artifacts.artifacts.filter(a => a.name.startsWith('blob-report-'));
console.log('Found blob reports:', blobReports.map(a => a.name));
core.setOutput('has-blob-reports', blobReports.length > 0 ? 'true' : 'false');
// Try to get PR number from workflow_run payload first
if (workflowRun.pull_requests && workflowRun.pull_requests.length > 0) {
const prNumber = workflowRun.pull_requests[0].number;
console.log('PR number from payload:', prNumber);
core.setOutput('pr-number', prNumber.toString());
core.setOutput('head-branch', headBranch);
return;
}
// Fall back to API lookup
try {
const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: headSha
});
if (prs.length === 0) {
console.log('No PRs found for commit');
core.setOutput('pr-number', '');
core.setOutput('head-branch', headBranch);
return;
}
// Find open PR or use first one
const openPr = prs.find(pr => pr.state === 'open') || prs[0];
console.log('PR number from API:', openPr.number);
core.setOutput('pr-number', openPr.number.toString());
core.setOutput('head-branch', openPr.head.ref);
} catch (e) {
console.log('Error fetching PR:', e);
core.setOutput('pr-number', '');
core.setOutput('head-branch', headBranch);
}
merge-reports:
name: Merge reports
needs: [get-pr-info]
if: ${{ needs.get-pr-info.outputs.has-blob-reports == 'true' && needs.get-pr-info.outputs.pr-number != '' }}
uses: ./.github/workflows/merge-reports.yml
with:
source_run_id: ${{ needs.get-pr-info.outputs.source-run-id }}
source_run_number: ${{ needs.get-pr-info.outputs.source-run-number }}
source_run_attempt: ${{ needs.get-pr-info.outputs.source-run-attempt }}
source_head_sha: ${{ needs.get-pr-info.outputs.source-head-sha }}
# No secrets: inherit - merge-reports only needs the default GITHUB_TOKEN for artifact download
publish-report:
name: Publish HTML report
needs: [get-pr-info, merge-reports]
if: ${{ needs.get-pr-info.outputs.pr-number != '' }}
uses: ./.github/workflows/publish-report.yml
with:
head_branch: ${{ needs.get-pr-info.outputs.head-branch }}
source_run_id: ${{ needs.get-pr-info.outputs.source-run-id }}
source_run_number: ${{ needs.get-pr-info.outputs.source-run-number }}
source_run_attempt: ${{ needs.get-pr-info.outputs.source-run-attempt }}
pr_number: ${{ needs.get-pr-info.outputs.pr-number }}
secrets: inherit
+14 -10
View File
@@ -5,7 +5,6 @@ permissions:
actions: write
contents: read
env:
NODE_OPTIONS: --max-old-space-size=4096
ALLOWED_HOSTNAMES: ${{ vars.CI_ALLOWED_HOSTNAMES }}
CALENDSO_ENCRYPTION_KEY: ${{ secrets.CI_CALENDSO_ENCRYPTION_KEY }}
DAILY_API_KEY: ${{ secrets.CI_DAILY_API_KEY }}
@@ -15,11 +14,11 @@ env:
E2E_TEST_APPLE_CALENDAR_EMAIL: ${{ secrets.E2E_TEST_APPLE_CALENDAR_EMAIL }}
E2E_TEST_APPLE_CALENDAR_PASSWORD: ${{ secrets.E2E_TEST_APPLE_CALENDAR_PASSWORD }}
E2E_TEST_MAILHOG_ENABLED: ${{ vars.E2E_TEST_MAILHOG_ENABLED }}
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
EMAIL_SERVER_HOST: ${{ secrets.CI_EMAIL_SERVER_HOST }}
EMAIL_SERVER_PORT: ${{ secrets.CI_EMAIL_SERVER_PORT }}
EMAIL_SERVER_USER: ${{ secrets.CI_EMAIL_SERVER_USER }}
EMAIL_SERVER_PASSWORD: ${{ secrets.CI_EMAIL_SERVER_PASSWORD}}
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
GOOGLE_LOGIN_ENABLED: ${{ vars.CI_GOOGLE_LOGIN_ENABLED }}
NEXTAUTH_SECRET: ${{ secrets.CI_NEXTAUTH_SECRET }}
NEXTAUTH_URL: ${{ secrets.CI_NEXTAUTH_URL }}
@@ -30,6 +29,7 @@ env:
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: ${{ secrets.CI_NEXT_PUBLIC_STRIPE_PUBLIC_KEY }}
NEXT_PUBLIC_WEBAPP_URL: ${{ vars.CI_NEXT_PUBLIC_WEBAPP_URL }}
NEXT_PUBLIC_WEBSITE_URL: ${{ vars.CI_NEXT_PUBLIC_WEBSITE_URL }}
NODE_OPTIONS: --max-old-space-size=4096
PAYMENT_FEE_FIXED: ${{ vars.CI_PAYMENT_FEE_FIXED }}
PAYMENT_FEE_PERCENTAGE: ${{ vars.CI_PAYMENT_FEE_PERCENTAGE }}
SAML_ADMINS: ${{ secrets.CI_SAML_ADMINS }}
@@ -45,7 +45,7 @@ jobs:
e2e:
timeout-minutes: 20
name: E2E (${{ matrix.shard }}/${{ strategy.job-total }})
runs-on: buildjet-8vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
services:
postgres:
image: postgres:13
@@ -57,10 +57,11 @@ jobs:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: calendso
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
--health-cmd "pg_isready -h 127.0.0.1 -U postgres"
--health-interval 2s
--health-timeout 3s
--health-retries 15
--health-start-period 2s
ports:
- 5432:5432
mailhog:
@@ -74,20 +75,23 @@ jobs:
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
shard: [1, 2, 3, 4, 5, 6, 7, 8]
steps:
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- run: yarn prisma generate
- uses: ./.github/actions/cache-db
- uses: ./.github/actions/cache-build
- name: Run Tests
run: yarn e2e --shard=${{ matrix.shard }}/${{ strategy.job-total }}
run: yarn e2e --shard=${{ matrix.shard }}/${{ strategy.job-total }} --workers=4
- name: Upload Test Results
uses: actions/upload-artifact@v4
if: always()
+11 -2
View File
@@ -10,12 +10,20 @@ concurrency:
jobs:
i18n:
name: Run i18n
runs-on: buildjet-2vcpu-ubuntu-2204
runs-on: blacksmith-2vcpu-ubuntu-2404
permissions:
actions: write
contents: write
pull-requests: write
steps:
- name: Generate GitHub App token
id: generate-token
uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94
with:
app-id: ${{ secrets.CI_CAL_APP_ID }}
private-key: ${{ secrets.CI_CAL_APP_PRIVATE_KEY }}
repositories: 'cal.com'
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
@@ -23,7 +31,8 @@ jobs:
cache: 'npm'
- uses: lingodotdev/lingo.dev@main
env:
GH_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }}
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
with:
api-key: ${{ secrets.CI_LINGO_DOT_DEV_API_KEY }}
pull-request: true
parallel: true
+7 -3
View File
@@ -5,6 +5,7 @@ permissions:
contents: read
env:
NODE_OPTIONS: --max-old-space-size=4096
INTEGRATION_TESTS: "true"
ALLOWED_HOSTNAMES: ${{ vars.CI_ALLOWED_HOSTNAMES }}
CALENDSO_ENCRYPTION_KEY: ${{ secrets.CI_CALENDSO_ENCRYPTION_KEY }}
DAILY_API_KEY: ${{ secrets.CI_DAILY_API_KEY }}
@@ -44,7 +45,7 @@ jobs:
integration:
timeout-minutes: 20
name: Integration
runs-on: buildjet-8vcpu-ubuntu-2204
runs-on: blacksmith-2vcpu-ubuntu-2404
services:
postgres:
image: postgres:13
@@ -78,11 +79,14 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- run: yarn prisma generate
- uses: ./.github/actions/cache-db
- name: Run Tests
run: yarn test -- --integrationTestsOnly
run: VITEST_MODE=integration yarn test
# TODO: Generate test results so we can upload them
# - name: Upload Test Results
# if: ${{ always() }}
-12
View File
@@ -15,18 +15,6 @@ jobs:
- uses: actions/labeler@v5
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
team-labels:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: equitybee/team-label-action@main
with:
repo-token: ${{ secrets.EQUITY_BEE_TEAM_LABELER_ACTION_TOKEN }}
organization-name: calcom
ignore-labels: "admin, app-store, ai, api, authentication, automated-testing, billing, bookings, caldav, calendar-apps, ci, console, crm-apps, dba, devops, docs, documentation, emails, embeds, event-types, i18n, impersonation, manual-testing, ui, performance, ops-stack, organizations, public-api, routing-forms, seats, self-hosted, sre, teams, webhooks, workflows, zapier"
apply-labels-from-issue:
runs-on: ubuntu-latest
+4 -3
View File
@@ -6,12 +6,13 @@ permissions:
contents: read
jobs:
lint:
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Run Lint
run: yarn lint
continue-on-error: true
+22 -2
View File
@@ -1,17 +1,37 @@
# https://playwright.dev/docs/test-sharding#merging-reports-from-multiple-shards
on:
workflow_call:
inputs:
source_run_id:
description: 'The run ID to download artifacts from (for workflow_run triggered calls)'
required: true
type: string
source_run_number:
description: 'The run number for artifact naming'
required: true
type: string
source_run_attempt:
description: 'The run attempt for artifact naming'
required: true
type: string
source_head_sha:
description: 'The head SHA to checkout for Playwright version consistency'
required: true
type: string
jobs:
merge-reports:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
ref: ${{ inputs.source_head_sha }}
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- name: Download blob reports from GitHub Actions Artifacts
uses: actions/download-artifact@v4
with:
run-id: ${{ inputs.source_run_id }}
github-token: ${{ github.token }}
path: all-blob-reports
pattern: blob-report-*
merge-multiple: true
@@ -20,6 +40,6 @@ jobs:
- name: Upload HTML report
uses: actions/upload-artifact@v4
with:
name: html-report--attempt-${{ github.run_number }}-${{ github.run_attempt }}
name: html-report--attempt-${{ inputs.source_run_number }}-${{ inputs.source_run_attempt }}
path: playwright-report
retention-days: 14
@@ -12,13 +12,13 @@ permissions:
jobs:
annotate:
if: always()
runs-on: buildjet-2vcpu-ubuntu-2204
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/cache-build
- name: Download base branch bundle stats
uses: dawidd6/action-download-artifact@v2
uses: dawidd6/action-download-artifact@v6
if: success()
with:
workflow: nextjs-bundle-analysis.yml
+11 -3
View File
@@ -16,7 +16,6 @@ env:
CALENDSO_ENCRYPTION_KEY: ${{ secrets.CI_CALENDSO_ENCRYPTION_KEY }}
DAILY_API_KEY: ${{ secrets.CI_DAILY_API_KEY }}
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }}
E2E_TEST_APPLE_CALENDAR_EMAIL: ${{ secrets.E2E_TEST_APPLE_CALENDAR_EMAIL }}
E2E_TEST_APPLE_CALENDAR_PASSWORD: ${{ secrets.E2E_TEST_APPLE_CALENDAR_PASSWORD }}
E2E_TEST_MAILHOG_ENABLED: ${{ vars.E2E_TEST_MAILHOG_ENABLED }}
@@ -50,12 +49,15 @@ env:
jobs:
analyze:
if: always()
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- run: yarn prisma generate
- uses: ./.github/actions/cache-build
- name: Analyze bundle
run: |
@@ -68,3 +70,9 @@ jobs:
with:
name: bundle
path: apps/web/.next/analyze/__bundle_analysis.json
- name: Delete cached build
uses: useblacksmith/cache-delete@v1
with:
key: prod-build-main-
prefix: "true"
+12 -1
View File
@@ -6,16 +6,27 @@ on:
tags:
- "*"
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App token
id: generate-token
uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94
with:
app-id: ${{ secrets.CI_CAL_APP_ID }}
private-key: ${{ secrets.CI_CAL_APP_PRIVATE_KEY }}
repositories: 'cal.com'
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: 'main'
token: ${{ secrets.GH_ACCESS_TOKEN }}
token: ${{ steps.generate-token.outputs.token }}
- name: Configure git
run: |
+357 -97
View File
@@ -1,11 +1,13 @@
# ⚠️ SECURITY: Do not add steps that checkout PR code or run local actions before trust-check job completes.
name: PR Update
on:
pull_request_target:
types: [opened, synchronize, reopened, labeled]
types: [opened, synchronize, reopened]
branches:
- main
- gh-actions-test-branch
workflow_dispatch:
permissions:
@@ -17,49 +19,228 @@ concurrency:
cancel-in-progress: true
jobs:
changes:
name: Detect changes
runs-on: buildjet-2vcpu-ubuntu-2204
# Security gate: Check if PR is from a trusted contributor or approved via run-ci label
# This MUST run before any job that checks out PR code and executes it with secrets
trust-check:
name: Trust Check
runs-on: blacksmith-2vcpu-ubuntu-2404
permissions:
pull-requests: read
actions: read
issues: read
outputs:
is-trusted: ${{ steps.check-trust.outputs.is-trusted }}
steps:
- name: Check if PR is trusted
id: check-trust
uses: actions/github-script@v7
with:
script: |
const trustedAssociations = ['OWNER', 'MEMBER', 'COLLABORATOR'];
if (!context.payload.pull_request) {
if (context.eventName === 'workflow_dispatch') {
console.log('workflow_dispatch event - assuming trusted (manual trigger)');
core.setOutput('is-trusted', true);
return;
}
console.log('No pull request context found');
core.setOutput('is-trusted', false);
return;
}
const owner = context.repo.owner;
const repo = context.repo.repo;
// Fetch fresh PR data - payload labels may be stale on re-runs
const { data: pr } = await github.rest.pulls.get({
owner,
repo,
pull_number: context.payload.pull_request.number,
});
const prNumber = pr.number;
const headSha = pr.head.sha;
async function hasWriteAccess(username) {
try {
const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
owner,
repo,
username,
});
return ['admin', 'maintain', 'write'].includes(permission.permission);
} catch (e) {
console.log(`Permission check failed for ${username}: ${e.message}`);
return false;
}
}
console.log(`PR #${prNumber} by ${pr.user.login} (${pr.author_association})`);
// Check 1: Is the author a trusted contributor?
if (trustedAssociations.includes(pr.author_association)) {
console.log(`Author has trusted association: ${pr.author_association}`);
core.setOutput('is-trusted', true);
return;
}
// Check 2: Verify write access via API (author_association can be unreliable)
if (await hasWriteAccess(pr.user.login)) {
console.log(`Author has write access`);
core.setOutput('is-trusted', true);
return;
}
// Check 3: Was 'run-ci' label added AFTER this SHA was pushed by someone with write access?
// This enables re-runs triggered by the run-ci.yml workflow
// NOTE: We use workflow run created_at instead of commit timestamp because
// git commit timestamps can be arbitrarily backdated by attackers
if (pr.labels?.some(l => l.name === 'run-ci')) {
// Skip stale check if this is a re-run (run_attempt > 1)
// Re-runs are explicitly triggered by maintainers
const runAttempt = parseInt(process.env.GITHUB_RUN_ATTEMPT || '1', 10);
if (runAttempt > 1) {
console.log(`Re-run detected (attempt ${runAttempt}), trusting existing 'run-ci' label`);
core.setOutput('is-trusted', true);
return;
}
const events = await github.paginate(github.rest.issues.listEvents, {
owner,
repo,
issue_number: prNumber,
per_page: 100,
});
const labelEvent = events
.filter(e => e.event === 'labeled' && e.label?.name === 'run-ci')
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))[0];
if (labelEvent) {
// Get workflow runs to find when this SHA was first pushed
const runs = await github.paginate(github.rest.actions.listWorkflowRuns, {
owner,
repo,
workflow_id: 'pr.yml',
head_sha: headSha,
per_page: 100,
});
// Filter runs to this PR (in case same SHA exists in multiple PRs)
const matchingRuns = runs.filter(run =>
!run.pull_requests?.length || run.pull_requests.some(p => p.number === prNumber)
);
if (matchingRuns.length > 0) {
const labelTime = new Date(labelEvent.created_at);
// Use the oldest run's created_at as the push time
const originalRun = matchingRuns[matchingRuns.length - 1];
const pushTime = new Date(originalRun.created_at);
if (labelTime > pushTime) {
const adder = labelEvent.actor.login;
if (await hasWriteAccess(adder)) {
console.log(`Approved via 'run-ci' label added by ${adder} after push (label: ${labelTime.toISOString()}, push: ${pushTime.toISOString()})`);
core.setOutput('is-trusted', true);
return;
}
console.log(`Label 'run-ci' added by ${adder} (no write access)`);
} else {
console.log(`Label 'run-ci' is stale (label: ${labelTime.toISOString()}, push: ${pushTime.toISOString()})`);
}
} else {
console.log('No workflow runs found for this SHA - cannot validate label timing');
}
}
}
console.log('External contribution requires "run-ci" label from a maintainer');
core.setOutput('is-trusted', false);
prepare:
name: Prepare
needs: [trust-check]
if: needs.trust-check.outputs.is-trusted == 'true'
runs-on: blacksmith-2vcpu-ubuntu-2404
permissions:
pull-requests: read
outputs:
has-files-requiring-all-checks: ${{ steps.filter.outputs.has-files-requiring-all-checks }}
has-files-requiring-all-checks: ${{ steps.filter-exclusions.outputs.has-files-requiring-all-checks }}
has-api-v2-changes: ${{ steps.filter-inclusions.outputs.has-api-v2-changes }}
has-prisma-changes: ${{ steps.filter-inclusions.outputs.has-prisma-changes }}
has-agents-changes: ${{ steps.filter-inclusions.outputs.has-agents-changes }}
commit-sha: ${{ steps.get_sha.outputs.commit-sha }}
run-e2e: ${{ steps.check-if-pr-has-label.outputs.run-e2e == 'true' }}
db-cache-hit: ${{ steps.cache-db-check.outputs.cache-hit }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
- uses: dorny/paths-filter@v3
id: filter
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- name: Generate DB cache key
id: cache-db-key
uses: ./.github/actions/cache-db-key
- name: Check DB cache (lookup-only)
id: cache-db-check
uses: actions/cache/restore@v4
with:
path: backups/backup.sql
key: ${{ steps.cache-db-key.outputs.key }}
lookup-only: true
- name: Check for files requiring all checks (with exclusions)
uses: dorny/paths-filter@v3
id: filter-exclusions
with:
predicate-quantifier: "every"
filters: |
has-files-requiring-all-checks:
- "!(**.md|**.mdx|.github/CODEOWNERS|docs/**|help/**|apps/web/public/static/locales/**/common.json|i18n.lock)"
- '**'
- '!.vscode/**'
- '!**/*.md'
- '!**/*.mdx'
- '!.github/CODEOWNERS'
- '!docs/**'
- '!help/**'
- '!packages/i18n/locales/**/common.json'
- '!i18n.lock'
- name: Check for specific path changes
uses: dorny/paths-filter@v3
id: filter-inclusions
with:
filters: |
has-agents-changes:
- "agents/**"
has-api-v2-changes:
- "apps/api/v2/**"
- "packages/platform-constants/**"
- "packages/platform-enums/**"
- "packages/platform-utils/**"
- "packages/platform-types/**"
- "packages/platform-libraries/**"
- "packages/trpc/**"
- "packages/prisma/schema.prisma"
- "docs/api-reference/v2/**"
has-prisma-changes:
- "packages/prisma/schema.prisma"
- "packages/prisma/migrations/**"
- name: Get Latest Commit SHA
id: get_sha
run: |
echo "commit-sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
check-label:
needs: [changes]
runs-on: buildjet-2vcpu-ubuntu-2204
name: Check for E2E label
permissions:
pull-requests: read
outputs:
run-e2e: ${{ steps.check-if-pr-has-label.outputs.run-e2e == 'true' && (github.event.action != 'labeled' || github.event.label.name == 'ready-for-e2e') }}
steps:
- name: Check if PR exists with ready-for-e2e label for this SHA
id: check-if-pr-has-label
uses: actions/github-script@v7
with:
script: |
let labels = [];
let prNumber = null;
if (context.payload.pull_request) {
labels = context.payload.pull_request.labels;
prNumber = context.payload.pull_request.number;
} else {
try {
const sha = '${{ needs.changes.outputs.commit-sha }}';
const sha = '${{ steps.get_sha.outputs.commit-sha }}';
console.log('sha', sha);
const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
@@ -73,125 +254,188 @@ jobs:
return;
}
const pr = prs[0];
console.log(`PR number: ${pr.number}`);
console.log(`PR title: ${pr.title}`);
console.log(`PR state: ${pr.state}`);
console.log(`PR URL: ${pr.html_url}`);
labels = pr.labels;
prNumber = prs[0].number;
}
catch (e) {
core.setOutput('run-e2e', false);
console.log(e);
return;
}
}
// Always fetch fresh PR data to get current labels
// This avoids stale label data from event payloads
try {
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
console.log(`PR number: ${pr.number}`);
console.log(`PR title: ${pr.title}`);
console.log(`PR state: ${pr.state}`);
console.log(`PR URL: ${pr.html_url}`);
labels = pr.labels;
}
catch (e) {
core.setOutput('run-e2e', false);
console.log(e);
return;
}
const labelFound = labels.map(l => l.name).includes('ready-for-e2e');
console.log('Found the label?', labelFound);
core.setOutput('run-e2e', labelFound);
- uses: ./.github/actions/yarn-install
if: ${{ steps.filter-exclusions.outputs.has-files-requiring-all-checks == 'true' }}
with:
skip-install-if-cache-hit: "true"
- uses: ./.github/actions/yarn-playwright-install
if: ${{ steps.filter-exclusions.outputs.has-files-requiring-all-checks == 'true' }}
with:
skip-install-if-cache-hit: "true"
deps:
name: Install dependencies
needs: [changes, check-label]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/yarn-install.yml
validate-agents-format:
name: Validate agents/ format
needs: [trust-check, prepare]
if: needs.trust-check.outputs.is-trusted == 'true' && needs.prepare.outputs.has-agents-changes == 'true' && github.event.pull_request
uses: ./.github/workflows/validate-agents-format.yml
secrets: inherit
type-check:
name: Type check
needs: [changes, check-label, deps]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
name: Type Checks
needs: [prepare]
if: ${{ needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/check-types.yml
secrets: inherit
lint:
name: Linters
needs: [changes, check-label, deps]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare]
if: ${{ needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/lint.yml
secrets: inherit
unit-test:
name: Tests
needs: [changes, check-label, deps]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare]
if: ${{ needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/unit-tests.yml
secrets: inherit
api-v2-unit-test:
name: Tests
needs: [prepare]
if: ${{ needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/api-v2-unit-tests.yml
secrets: inherit
security-audit:
name: Security Audit
needs: [prepare]
if: ${{ needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/security-audit.yml
secrets: inherit
check-prisma-migrations:
name: Check Prisma Migrations
needs: [prepare]
if: ${{ needs.prepare.outputs.has-prisma-changes == 'true' }}
uses: ./.github/workflows/check-prisma-migrations.yml
secrets: inherit
setup-db:
name: Setup Database
needs: [prepare]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/setup-db.yml
with:
DB_CACHE_HIT: ${{ needs.prepare.outputs.db-cache-hit }}
secrets: inherit
build-api-v1:
name: Production builds
needs: [changes, check-label, deps]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare, setup-db]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/api-v1-production-build.yml
secrets: inherit
build-api-v2:
name: Production builds
needs: [changes, check-label, deps]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/api-v2-production-build.yml
secrets: inherit
build-atoms:
name: Production builds
needs: [changes, check-label, deps]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/atoms-production-build.yml
secrets: inherit
build-docs:
name: Production builds
needs: [changes, check-label, deps]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/docs-build.yml
secrets: inherit
build:
name: Production builds
needs: [changes, check-label, deps]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/production-build-without-database.yml
secrets: inherit
integration-test:
name: Tests
needs: [changes, check-label, build, build-api-v1, build-api-v2]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare, build, setup-db]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/integration-tests.yml
secrets: inherit
e2e:
name: Tests
needs: [changes, check-label, build, build-api-v1, build-api-v2]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare, build, setup-db]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e.yml
secrets: inherit
check-api-v2-breaking-changes:
name: Check API v2 breaking changes
needs: [prepare]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-api-v2-changes == 'true' }}
uses: ./.github/workflows/check-api-v2-breaking-changes.yml
secrets: inherit
e2e-api-v2:
name: Tests
needs: [changes, check-label, build, build-api-v1, build-api-v2]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare, setup-db]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e-api-v2.yml
secrets: inherit
e2e-app-store:
name: Tests
needs: [changes, check-label, build, build-api-v1, build-api-v2]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare, build, setup-db]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e-app-store.yml
secrets: inherit
e2e-embed:
name: Tests
needs: [changes, check-label, build, build-api-v1, build-api-v2]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare, build, setup-db]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e-embed.yml
secrets: inherit
e2e-embed-react:
name: Tests
needs: [changes, check-label, build, build-api-v1, build-api-v2]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [prepare, build, setup-db]
if: ${{ needs.prepare.outputs.run-e2e == 'true' && needs.prepare.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e-embed-react.yml
secrets: inherit
@@ -201,58 +445,74 @@ jobs:
uses: ./.github/workflows/nextjs-bundle-analysis.yml
secrets: inherit
merge-reports:
name: Merge reports
if: ${{ !cancelled() && needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [changes, check-label, e2e, e2e-embed, e2e-embed-react, e2e-app-store]
uses: ./.github/workflows/merge-reports.yml
secrets: inherit
publish-report:
name: Publish HTML report
if: ${{ !cancelled() && needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
permissions:
contents: write
issues: write
pull-requests: write
needs: [changes, check-label, merge-reports]
uses: ./.github/workflows/publish-report.yml
secrets: inherit
cleanup-report:
name: Cleanup HTML report
if: ${{ !cancelled() && needs.check-label.outputs.run-e2e == 'true' && (github.event.pull_request.merged == true || github.event.pull_request.state == 'closed') }}
permissions:
contents: write
issues: write
pull-requests: write
needs: [changes, check-label, publish-report]
uses: ./.github/workflows/cleanup-report.yml
secrets: inherit
required:
needs:
[
changes,
trust-check,
prepare,
validate-agents-format,
lint,
type-check,
unit-test,
api-v2-unit-test,
security-audit,
check-api-v2-breaking-changes,
check-prisma-migrations,
integration-test,
check-label,
build,
build-api-v1,
build-api-v2,
build-atoms,
build-docs,
setup-db,
e2e,
e2e-api-v2,
e2e-embed,
e2e-embed-react,
e2e-app-store
e2e-app-store,
]
if: always()
runs-on: buildjet-2vcpu-ubuntu-2204
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: fail if conditional jobs failed
if: needs.changes.outputs.has-files-requiring-all-checks == 'true' && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') || contains(needs.*.result, 'cancelled'))
- name: Fail if trust-check did not succeed
run: |
echo "::error::Trust check did not complete successfully (result: ${{ needs.trust-check.result }}). Please re-run the workflow."
exit 1
if: needs.trust-check.result != 'success'
- name: Fail if PR is not trusted (external contributor without run-ci label)
run: |
echo "::error::This PR is from an external contributor and requires the 'run-ci' label before CI can run."
echo "A maintainer must review the code and add the 'run-ci' label to trigger CI checks."
exit 1
if: needs.trust-check.outputs.is-trusted != 'true' && needs.trust-check.result == 'success'
- name: Fail if conditional jobs failed
run: exit 1
if: |
(
needs.prepare.outputs.has-files-requiring-all-checks == 'true' &&
(
needs.lint.result != 'success' ||
needs.type-check.result != 'success' ||
needs.unit-test.result != 'success' ||
needs.api-v2-unit-test.result != 'success' ||
needs.security-audit.result != 'success' ||
(needs.prepare.outputs.has-api-v2-changes == 'true' && needs.check-api-v2-breaking-changes.result != 'success') ||
(needs.prepare.outputs.has-prisma-changes == 'true' && needs.check-prisma-migrations.result != 'success') ||
needs.build.result != 'success' ||
needs.build-api-v1.result != 'success' ||
needs.build-api-v2.result != 'success' ||
needs.build-atoms.result != 'success' ||
needs.build-docs.result != 'success' ||
needs.setup-db.result != 'success' ||
needs.integration-test.result != 'success' ||
needs.e2e.result != 'success' ||
needs.e2e-api-v2.result != 'success' ||
needs.e2e-embed.result != 'success' ||
needs.e2e-embed-react.result != 'success' ||
needs.e2e-app-store.result != 'success'
)
) ||
(
needs.prepare.outputs.has-agents-changes == 'true' &&
needs.validate-agents-format.result != 'success'
)
@@ -4,13 +4,13 @@ on:
permissions:
contents: read
actions: write
env:
ALLOWED_HOSTNAMES: ${{ vars.CI_ALLOWED_HOSTNAMES }}
CALENDSO_ENCRYPTION_KEY: ${{ secrets.CI_CALENDSO_ENCRYPTION_KEY }}
DAILY_API_KEY: ${{ secrets.CI_DAILY_API_KEY }}
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }}
E2E_TEST_APPLE_CALENDAR_EMAIL: ${{ secrets.E2E_TEST_APPLE_CALENDAR_EMAIL }}
E2E_TEST_APPLE_CALENDAR_PASSWORD: ${{ secrets.E2E_TEST_APPLE_CALENDAR_PASSWORD }}
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
@@ -36,14 +36,38 @@ env:
NEXT_PUBLIC_API_V2_ROOT_URL: ${{ secrets.CI_NEXT_PUBLIC_API_V2_ROOT_URL }}
NEXT_PUBLIC_ORG_SELF_SERVE_ENABLED: ${{ vars.CI_NEXT_PUBLIC_ORG_SELF_SERVE_ENABLED }}
jobs:
build:
name: Build Web App
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- run: yarn prisma generate
- name: Generate cache key
id: cache-key
uses: ./.github/actions/cache-build-key
with:
branch_key: ${{ github.head_ref || github.ref_name }}
- name: Check if production build cache exists
uses: actions/cache@v4
id: cache-check
with:
path: |
${{ github.workspace }}/apps/web/.next
${{ github.workspace }}/apps/web/public/embed
**/.turbo/**
**/dist/**
key: ${{ steps.cache-key.outputs.key }}
lookup-only: true
- name: Delete old production build caches for this branch
if: steps.cache-check.outputs.cache-hit != 'true'
uses: useblacksmith/cache-delete@v1
with:
key: prod-build-${{ github.head_ref || github.ref_name }}
prefix: "true"
- uses: ./.github/actions/cache-build
+47 -13
View File
@@ -1,5 +1,26 @@
on:
workflow_call:
inputs:
head_branch:
description: 'The head branch name for report path'
required: true
type: string
source_run_id:
description: 'The source run ID for report path'
required: true
type: string
source_run_number:
description: 'The source run number for artifact naming and comment'
required: true
type: string
source_run_attempt:
description: 'The source run attempt for artifact naming and comment'
required: true
type: string
pr_number:
description: 'The PR number to post comment on'
required: true
type: string
permissions:
contents: write
issues: write
@@ -10,15 +31,23 @@ jobs:
continue-on-error: true
env:
# Unique URL path for each workflow run attempt
HTML_REPORT_URL_PATH: reports/${{ github.head_ref }}/${{ github.run_id }}/${{ github.run_attempt }}
BRANCH_REPORTS_DIR: reports/${{ github.head_ref }}
HTML_REPORT_URL_PATH: reports/${{ inputs.head_branch }}/${{ inputs.source_run_id }}/${{ inputs.source_run_attempt }}
BRANCH_REPORTS_DIR: reports/${{ inputs.head_branch }}
steps:
- name: Generate GitHub App token
id: generate-token
uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94
with:
app-id: ${{ secrets.CI_CAL_APP_ID }}
private-key: ${{ secrets.CI_CAL_APP_PRIVATE_KEY }}
repositories: 'test-results-2'
- name: Checkout GitHub Pages Branch
uses: actions/checkout@v4
with:
repository: calcom/test-results
repository: calcom/test-results-2
ref: gh-pages
token: ${{ secrets.GH_ACCESS_TOKEN }}
token: ${{ steps.generate-token.outputs.token }}
- name: Set Git User
# see: https://github.com/actions/checkout/issues/13#issuecomment-724415212
run: |
@@ -34,22 +63,27 @@ jobs:
- name: Cleanup old HTML reports
if: ${{ env.BRANCH_REPORTS_EXIST == 'true' }}
timeout-minutes: 3
env:
HEAD_BRANCH: ${{ inputs.head_branch }}
run: |
rm -rf $BRANCH_REPORTS_DIR
rm -rf "$BRANCH_REPORTS_DIR"
git add .
git commit -m "workflow: remove all reports for branch ${{ github.head_ref }}"
git commit -m "workflow: remove all reports for branch $HEAD_BRANCH"
- name: Download zipped HTML report
uses: actions/download-artifact@v4
with:
name: html-report--attempt-${{ github.run_number }}-${{ github.run_attempt }}
name: html-report--attempt-${{ inputs.source_run_number }}-${{ inputs.source_run_attempt }}
path: ${{ env.HTML_REPORT_URL_PATH }}
- name: Push HTML Report
timeout-minutes: 3
# commit report, then try push-rebase-loop until it's able to merge the HTML report to the gh-pages branch
# this is necessary when this job running at least twice at the same time (e.g. through two pushes at the same time)
env:
RUN_ID: ${{ inputs.source_run_id }}
RUN_ATTEMPT: ${{ inputs.source_run_attempt }}
run: |
git add .
git commit -m "workflow: add HTML report for run-id ${{ github.run_id }} (attempt: ${{ github.run_attempt }})"
git commit -m "workflow: add HTML report for run-id $RUN_ID (attempt: $RUN_ATTEMPT)"
while true; do
git pull --rebase
@@ -67,25 +101,25 @@ jobs:
- name: Output Report URL as Workflow Annotation
id: url
run: |
FULL_HTML_REPORT_URL=https://calcom.github.io/test-results/$HTML_REPORT_URL_PATH
FULL_HTML_REPORT_URL=https://calcom.github.io/test-results-2/$HTML_REPORT_URL_PATH
echo "::notice title=📋 Published Playwright Test Report::$FULL_HTML_REPORT_URL"
echo "link=$FULL_HTML_REPORT_URL" >> $GITHUB_OUTPUT
- name: Find Comment
uses: peter-evans/find-comment@v2
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
issue-number: ${{ inputs.pr_number }}
comment-author: "github-actions[bot]"
body-includes: <!-- GENERATED-E2E-RESULTS -->
- name: Create comment
if: steps.fc.outputs.comment-id == ''
uses: peter-evans/create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
issue-number: ${{ inputs.pr_number }}
body: |
<!-- GENERATED-E2E-RESULTS -->
## E2E results are ready!
- [Workflow #${{ github.run_number }}.${{ github.run_attempt }} latest results](${{ steps.url.outputs.link }})
- [Workflow #${{ inputs.source_run_number }}.${{ inputs.source_run_attempt }} latest results](${{ steps.url.outputs.link }})
- name: Update comment
if: steps.fc.outputs.comment-id != ''
uses: peter-evans/create-or-update-comment@v3
@@ -95,4 +129,4 @@ jobs:
body: |
<!-- GENERATED-E2E-RESULTS -->
## E2E results are ready!
- [Workflow #${{ github.run_number }}.${{ github.run_attempt }} latest results](${{ steps.url.outputs.link }})
- [Workflow #${{ inputs.source_run_number }}.${{ inputs.source_run_attempt }} latest results](${{ steps.url.outputs.link }})
+160 -32
View File
@@ -1,48 +1,176 @@
name: "Release Docker"
on: # yamllint disable-line rule:truthy
release:
types:
- created
- published
permissions:
contents: read
packages: write
env:
POSTGRES_USER: "unicorn_user"
POSTGRES_PASSWORD: "magical_password"
POSTGRES_DB: "calendso"
DATABASE_HOST: "database:5432"
on:
push:
tags:
- "v*"
# in case manual trigger is needed
workflow_dispatch:
inputs:
BUILD_FROM_BRANCH:
description: "Build from the selected branch instead of a tag"
type: boolean
default: false
RELEASE_TAG:
description: "v{Major}.{Minor}.{Patch}"
description: "Tag to build (e.g., v6.0.5) - required if BUILD_FROM_BRANCH is false"
required: false
PUSH_IMAGE:
description: "Push the Docker image to DockerHub"
type: boolean
default: true
jobs:
release:
name: "Remote Release"
prepare:
name: "Prepare Release"
runs-on: blacksmith-2vcpu-ubuntu-2404
outputs:
release_tag: ${{ steps.determine-tag.outputs.release_tag }}
checkout_ref: ${{ steps.determine-tag.outputs.checkout_ref }}
steps:
- name: Validate inputs
if: github.event_name == 'workflow_dispatch' && inputs.BUILD_FROM_BRANCH == false && inputs.RELEASE_TAG == ''
run: |
echo "::error::RELEASE_TAG is required when BUILD_FROM_BRANCH is false"
exit 1
runs-on: "ubuntu-latest"
- name: checkout
uses: actions/checkout@v4
with:
ref: ${{ (github.event_name == 'workflow_dispatch' && inputs.BUILD_FROM_BRANCH) && github.ref || inputs.RELEASE_TAG || github.ref }}
- name: "Determine tag and ref"
id: determine-tag
run: |
# Determine checkout ref
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.BUILD_FROM_BRANCH }}" = "true" ]; then
echo "checkout_ref=${{ github.ref }}" >> $GITHUB_OUTPUT
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "checkout_ref=${{ inputs.RELEASE_TAG }}" >> $GITHUB_OUTPUT
else
echo "checkout_ref=${{ github.ref }}" >> $GITHUB_OUTPUT
fi
# Determine release tag
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
if [ "${{ inputs.BUILD_FROM_BRANCH }}" = "true" ]; then
# Extract branch name and short SHA for the tag
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
# Sanitize branch name: replace all invalid Docker tag characters with dashes
# Docker tags can only contain lowercase/uppercase letters, digits, underscores, periods, and dashes
# Also remove any leading dashes or periods
SANITIZED_BRANCH=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9_.-]/-/g' | sed 's/^[-.]*//')
SHORT_SHA=$(git rev-parse --short HEAD)
echo "release_tag=${SANITIZED_BRANCH}-${SHORT_SHA}" >> $GITHUB_OUTPUT
else
echo "release_tag=${{ inputs.RELEASE_TAG }}" >> $GITHUB_OUTPUT
fi
else
echo "release_tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi
release-amd64:
name: "Release AMD64"
needs: prepare
runs-on: blacksmith-4vcpu-ubuntu-2404
env:
RELEASE_TAG: ${{ needs.prepare.outputs.release_tag }}
steps:
- name: checkout
uses: actions/checkout@v4
- name: "Determine tag"
run: 'echo "RELEASE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV'
- name: "Run remote release workflow"
uses: "actions/github-script@v6"
with:
# Requires a personal access token with Actions Read and write permissions on calcom/docker.
github-token: "${{ secrets.DOCKER_REPO_ACCESS_TOKEN }}"
script: |
try {
const response = await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: 'docker',
workflow_id: 'create-release.yaml',
ref: 'main',
inputs: {
"RELEASE_TAG": process.env.RELEASE_TAG
},
});
ref: ${{ needs.prepare.outputs.checkout_ref }}
console.log(response);
} catch (error) {
console.error(error);
core.setFailed(error.message);
- name: Build and test Docker image
uses: ./.github/actions/docker-build-and-test
with:
platform: "linux/amd64"
platform-suffix: ""
dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
postgres-user: ${{ env.POSTGRES_USER }}
postgres-password: ${{ env.POSTGRES_PASSWORD }}
postgres-db: ${{ env.POSTGRES_DB }}
database-host: ${{ env.DATABASE_HOST }}
push-image: ${{ (github.event_name == 'push' || inputs.PUSH_IMAGE) && 'true' || 'false' }}
use-as-latest: "true"
- name: Notify Slack on Success
if: success()
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": ":large_green_circle: Workflow *${{ github.workflow }}* (AMD64) succeeded in job *${{ github.job }}*.\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.CI_SLACK_WEBHOOK_URL }}
- name: Notify Slack on Failure
if: failure()
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": ":red_circle: Workflow *${{ github.workflow }}* (AMD64) failed in job *${{ github.job }}*.\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.CI_SLACK_WEBHOOK_URL }}
release-arm:
name: "Release ARM"
needs: prepare
runs-on: ubuntu-24.04-arm
env:
RELEASE_TAG: ${{ needs.prepare.outputs.release_tag }}
steps:
- name: checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.prepare.outputs.checkout_ref }}
- name: Build and test Docker image
uses: ./.github/actions/docker-build-and-test
with:
platform: "arm64"
platform-suffix: "-arm"
dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
postgres-user: ${{ env.POSTGRES_USER }}
postgres-password: ${{ env.POSTGRES_PASSWORD }}
postgres-db: ${{ env.POSTGRES_DB }}
database-host: ${{ env.DATABASE_HOST }}
push-image: ${{ (github.event_name == 'push' || inputs.PUSH_IMAGE) && 'true' || 'false' }}
- name: Notify Slack on Success
if: success()
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": ":large_green_circle: Workflow *${{ github.workflow }}* (ARM) succeeded in job *${{ github.job }}*.\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.CI_SLACK_WEBHOOK_URL }}
- name: Notify Slack on Failure
if: failure()
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"text": ":red_circle: Workflow *${{ github.workflow }}* (ARM) failed in job *${{ github.job }}*.\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.CI_SLACK_WEBHOOK_URL }}
+125
View File
@@ -0,0 +1,125 @@
name: Run CI
on:
pull_request_target:
types: [labeled]
permissions:
actions: write
contents: read
jobs:
trigger:
name: Trigger CI
if: github.event.label.name == 'run-ci' || github.event.label.name == 'ready-for-e2e'
runs-on: ubuntu-latest
steps:
- name: Verify and trigger CI
uses: actions/github-script@v7
with:
script: |
const adder = context.payload.sender.login;
const senderType = context.payload.sender.type;
const pr = context.payload.pull_request;
console.log(`Sender: ${adder} (type: ${senderType})`);
const trustedBotLogins = ['graphite-app[bot]'];
let isAuthorized = false;
if (senderType === 'Bot' && trustedBotLogins.includes(adder)) {
console.log(`Authorized: trusted GitHub App`);
isAuthorized = true;
}
if (!isAuthorized) {
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: adder,
});
if (!['admin', 'maintain', 'write'].includes(perm.permission)) {
core.setFailed(`${adder} does not have write access`);
return;
}
console.log(`Label added by ${adder}`);
}
// Find the latest pr.yml run for this PR's head SHA
const { data: runs } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'pr.yml',
head_sha: pr.head.sha,
per_page: 5,
});
// Filter runs to this PR (in case same SHA exists in multiple PRs)
const matchingRuns = runs.workflow_runs.filter(run =>
!run.pull_requests?.length || run.pull_requests.some(p => p.number === pr.number)
);
if (matchingRuns.length === 0) {
core.setFailed(`No PR workflow found for SHA ${pr.head.sha}`);
return;
}
const latestRun = matchingRuns[0];
// If workflow is still running, cancel it first then re-run
if (latestRun.status === 'in_progress' || latestRun.status === 'queued') {
console.log(`Workflow is running (status: ${latestRun.status}). Cancelling it first...`);
await github.rest.actions.cancelWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: latestRun.id,
});
// Wait for the workflow to be cancelled (poll with timeout)
const maxWaitTime = 60000; // 60 seconds
const pollInterval = 2000; // 2 seconds
const startTime = Date.now();
while (Date.now() - startTime < maxWaitTime) {
await new Promise(resolve => setTimeout(resolve, pollInterval));
const { data: updatedRun } = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: latestRun.id,
});
if (updatedRun.status === 'completed') {
console.log(`Workflow cancelled successfully (conclusion: ${updatedRun.conclusion})`);
break;
}
console.log(`Waiting for workflow to cancel... (status: ${updatedRun.status})`);
}
// Check final status
const { data: finalRun } = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: latestRun.id,
});
if (finalRun.status !== 'completed') {
core.setFailed(`Timed out waiting for workflow to cancel (status: ${finalRun.status})`);
return;
}
}
console.log(`Re-running workflow ${latestRun.id} (was: ${latestRun.conclusion || latestRun.status})`);
// Re-run preserves original context (PR, SHA, etc.)
await github.rest.actions.reRunWorkflow({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: latestRun.id,
});
console.log(`Triggered: ${latestRun.html_url}`);
+19
View File
@@ -0,0 +1,19 @@
name: Security Audit
on:
workflow_call:
permissions:
actions: write
contents: read
jobs:
audit:
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Report all vulnerabilities
run: yarn npm audit --all --recursive || true
- name: Fail on critical vulnerabilities
run: yarn npm audit --all --recursive --severity critical
+58
View File
@@ -0,0 +1,58 @@
name: Setup Database
on:
workflow_call:
inputs:
DB_CACHE_HIT:
required: false
type: string
default: "false"
description: "Whether the DB cache was hit (skip yarn-install and cache-db if true)"
permissions:
contents: read
env:
CALENDSO_ENCRYPTION_KEY: ${{ secrets.CI_CALENDSO_ENCRYPTION_KEY }}
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }}
E2E_TEST_CALCOM_QA_EMAIL: ${{ secrets.E2E_TEST_CALCOM_QA_EMAIL }}
E2E_TEST_CALCOM_QA_PASSWORD: ${{ secrets.E2E_TEST_CALCOM_QA_PASSWORD }}
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ secrets.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
jobs:
setup-db:
name: Setup Database
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 15
services:
postgres:
image: postgres:13
credentials:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: calendso
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
if: inputs.DB_CACHE_HIT != 'true'
- run: yarn prisma generate
if: inputs.DB_CACHE_HIT != 'true'
- uses: ./.github/actions/cache-db
if: inputs.DB_CACHE_HIT != 'true'
@@ -0,0 +1,291 @@
name: Stale Community PR Devin Completion
on:
pull_request_target:
types: [labeled]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to complete'
required: true
type: string
permissions:
contents: read
pull-requests: write
jobs:
complete-stale-pr:
name: Trigger Devin to Complete Stale Community PR
# For labeled events: only run if 'Stale' or 'devin-finish-pr' label was added
# For workflow_dispatch: always run (we'll validate the PR in the steps)
if: >
github.event_name == 'workflow_dispatch' ||
github.event.label.name == 'Stale' ||
github.event.label.name == 'devin-finish-pr'
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Get PR details
id: pr
uses: actions/github-script@v7
env:
INPUT_PR_NUMBER: ${{ inputs.pr_number }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
let prNumber;
let pr;
if (context.eventName === 'workflow_dispatch') {
const inputPrNumber = process.env.INPUT_PR_NUMBER;
prNumber = parseInt(inputPrNumber, 10);
if (isNaN(prNumber) || prNumber <= 0) {
core.setFailed(`Invalid PR number provided: "${inputPrNumber}". Please enter a valid PR number.`);
return;
}
const { data } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
pr = data;
} else {
pr = context.payload.pull_request;
prNumber = pr.number;
}
if (!pr.head.repo) {
core.setFailed('Cannot complete this PR: the source repository (fork) has been deleted.');
return;
}
const isFork = pr.head.repo.fork || pr.head.repo.full_name !== pr.base.repo.full_name;
const maintainerCanModify = pr.maintainer_can_modify;
const needsMaintainerAccess = isFork && !maintainerCanModify;
const headRepoFullName = pr.head.repo.full_name;
const headRepoCloneUrl = pr.head.repo.clone_url;
core.setOutput('pr_number', prNumber);
core.setOutput('pr_title', pr.title);
core.setOutput('pr_author', pr.user.login);
core.setOutput('pr_branch', pr.head.ref);
core.setOutput('is_fork', isFork);
core.setOutput('head_repo_full_name', headRepoFullName);
core.setOutput('head_repo_clone_url', headRepoCloneUrl);
core.setOutput('maintainer_can_modify', maintainerCanModify);
core.setOutput('needs_maintainer_access', needsMaintainerAccess);
console.log(`PR #${prNumber}: "${pr.title}"`);
console.log(`Author: ${pr.user.login}`);
console.log(`Branch: ${pr.head.ref}`);
console.log(`Is fork: ${isFork}`);
console.log(`Head repo: ${headRepoFullName}`);
console.log(`Maintainer can modify: ${maintainerCanModify}`);
console.log(`Needs maintainer access: ${needsMaintainerAccess}`);
- name: Request maintainer access for fork PR
if: steps.pr.outputs.needs_maintainer_access == 'true'
uses: actions/github-script@v7
env:
PR_NUMBER: ${{ steps.pr.outputs.pr_number }}
PR_AUTHOR: ${{ steps.pr.outputs.pr_author }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prNumber = parseInt(process.env.PR_NUMBER);
const prAuthor = process.env.PR_AUTHOR;
const { owner, repo } = context.repo;
const comments = await github.rest.issues.listComments({
owner,
repo,
issue_number: prNumber
});
const alreadyRequested = comments.data.some(comment =>
comment.body?.includes('### Maintainer Access Needed')
);
if (!alreadyRequested) {
const commentBody = [
'### Maintainer Access Needed',
'',
`Hi @${prAuthor}! Thanks for your contribution to Cal.com.`,
'',
`We'd like to help complete this stale PR, but we noticed that "Allow edits from maintainers" isn't enabled. We need this setting to push updates to your PR branch.`,
'',
'**Could you please enable this setting?** Here\'s how:',
'1. Scroll down to the bottom of this PR page',
'2. In the right sidebar, check the box that says **"Allow edits and access to secrets by maintainers"**',
'',
'This allows us to push commits directly to your PR branch, which helps us:',
'- Complete any remaining work on your PR',
'- Fix merge conflicts and make small adjustments',
'- Get your contribution merged faster',
'',
'Once you\'ve enabled this setting, we\'ll be able to help finish up this PR. If you have any concerns about enabling this setting, feel free to let us know!'
].join('\n');
await github.rest.issues.createComment({
owner,
repo,
issue_number: prNumber,
body: commentBody
});
console.log(`Posted maintainer access request comment on PR #${prNumber}`);
} else {
console.log(`Maintainer access already requested on PR #${prNumber}`);
}
core.setFailed(`Cannot complete this fork PR: the fork owner has not enabled "Allow edits from maintainers". A comment has been posted requesting access.`);
- name: Checkout repository
uses: actions/checkout@v4
- name: Check for existing Devin session
id: check-session
uses: ./.github/actions/devin-session
with:
devin-api-key: ${{ secrets.DEVIN_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ steps.pr.outputs.pr_number }}
- name: Create or reuse Devin session
env:
DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }}
PR_NUMBER: ${{ steps.pr.outputs.pr_number }}
PR_TITLE: ${{ steps.pr.outputs.pr_title }}
PR_AUTHOR: ${{ steps.pr.outputs.pr_author }}
PR_BRANCH: ${{ steps.pr.outputs.pr_branch }}
IS_FORK: ${{ steps.pr.outputs.is_fork }}
HEAD_REPO_FULL_NAME: ${{ steps.pr.outputs.head_repo_full_name }}
REPO_NAME: ${{ github.repository }}
HAS_EXISTING_SESSION: ${{ steps.check-session.outputs.has-existing-session }}
EXISTING_SESSION_ID: ${{ steps.check-session.outputs.session-id }}
EXISTING_SESSION_URL: ${{ steps.check-session.outputs.session-url }}
run: |
if [ "$IS_FORK" = "true" ]; then
CLONE_INSTRUCTIONS="This is a fork PR. Clone from the fork repository: ${HEAD_REPO_FULL_NAME}
To check out this PR:
1. Clone the fork: git clone https://github.com/${HEAD_REPO_FULL_NAME}.git
2. Check out the branch: git checkout ${PR_BRANCH}
3. Add the upstream remote: git remote add upstream https://github.com/${REPO_NAME}.git
IMPORTANT - Pushing to Fork PRs:
Since this is a fork PR, you need to use the DEVIN_ACTIONS_PAT secret for authentication when pushing. Configure git to use this PAT for authentication before pushing your changes to the fork."
else
CLONE_INSTRUCTIONS="Clone the repository ${REPO_NAME} and check out the branch: ${PR_BRANCH}"
fi
FULL_PROMPT="You are completing a stale community PR #${PR_NUMBER} in repository ${REPO_NAME}.
This PR was started by @${PR_AUTHOR} but has become stale. Your job is to complete it.
PR Title: ${PR_TITLE}
PR Branch: ${PR_BRANCH}
${CLONE_INSTRUCTIONS}
Your tasks:
1. Clone the repository as described above.
2. Check out the PR branch: ${PR_BRANCH}
3. Review the current state of the PR and understand what it's trying to accomplish.
4. Read the PR description and any comments/review feedback on the PR.
5. Complete any unfinished work on the PR:
- Fix any issues mentioned in review comments
- Ensure the code follows the repository's coding standards
- Add any missing tests if applicable
- Fix any linting or type errors
6. Run the appropriate checks (lint, type-check, tests) to ensure the PR is ready for review.
7. Commit your changes with clear commit messages.
8. Push your changes to the PR branch.
9. After successfully pushing, remove the 'Stale' or 'devin-finish-pr' label from the PR (whichever was used to trigger this workflow).
10. Post a summary comment on the PR explaining what you completed.
11. Mark the PR as ready for review if applicable.
Rules and Guidelines:
1. Respect the original author's intent and approach - don't rewrite the PR from scratch.
2. Make minimal, focused changes that complete the PR's original goal.
3. Follow the existing code style and conventions in the repository.
4. If the PR's original approach seems fundamentally flawed, explain why in a comment instead of making major changes.
5. Never ask for user confirmation. Never wait for user messages.
6. Credit the original author in your commit messages where appropriate.
7. CRITICAL: If this is a fork PR and you encounter ANY error when pushing (permission denied, authentication failure, etc.) even after using the DEVIN_ACTIONS_PAT, you MUST fail the task immediately. Do NOT attempt to push to a new branch in the main repository as a workaround. Simply report the error and stop."
if [ "$HAS_EXISTING_SESSION" = "true" ]; then
echo "Sending message to existing session ${EXISTING_SESSION_ID}"
MESSAGE="This PR has been marked as stale and needs to be completed.
${FULL_PROMPT}
Continue working on the same PR branch and push your fixes."
HTTP_CODE=$(curl -s -o /tmp/devin-response.json -w "%{http_code}" -X POST "https://api.devin.ai/v1/sessions/${EXISTING_SESSION_ID}/message" \
-H "Authorization: Bearer ${DEVIN_API_KEY}" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg message "$MESSAGE" '{message: $message}')")
if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
echo "Failed to send message to Devin session: HTTP $HTTP_CODE"
cat /tmp/devin-response.json
exit 1
fi
echo "Message sent to existing session successfully"
echo "SESSION_URL=$EXISTING_SESSION_URL" >> $GITHUB_ENV
echo "IS_NEW_SESSION=false" >> $GITHUB_ENV
else
echo "Creating new Devin session"
RESPONSE=$(curl -s -X POST "https://api.devin.ai/v1/sessions" \
-H "Authorization: Bearer ${DEVIN_API_KEY}" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg prompt "$FULL_PROMPT" \
--arg title "Complete Stale PR #${PR_NUMBER}: ${PR_TITLE}" \
'{
prompt: $prompt,
title: $title,
tags: ["stale-pr-completion", "pr-'${PR_NUMBER}'"]
}')")
SESSION_URL=$(echo "$RESPONSE" | jq -r '.url // .session_url // empty')
if [ -n "$SESSION_URL" ]; then
echo "Devin session created: $SESSION_URL"
echo "SESSION_URL=$SESSION_URL" >> $GITHUB_ENV
echo "IS_NEW_SESSION=true" >> $GITHUB_ENV
else
echo "Failed to create Devin session"
echo "$RESPONSE"
exit 1
fi
fi
- name: Post comment with Devin session link
if: env.SESSION_URL != ''
uses: actions/github-script@v7
env:
PR_AUTHOR: ${{ steps.pr.outputs.pr_author }}
PR_NUMBER: ${{ steps.pr.outputs.pr_number }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const sessionUrl = process.env.SESSION_URL;
const prAuthor = process.env.PR_AUTHOR;
const prNumber = process.env.PR_NUMBER;
const isNewSession = process.env.IS_NEW_SESSION === 'true';
const message = isNewSession
? `### Devin AI is completing this stale PR\n\nThis PR by @${prAuthor} has been marked as stale. A Devin session has been created to complete the remaining work.\n\n[View Devin Session](${sessionUrl})\n\n---\n*Devin will review the PR, address any feedback, and push updates to complete this PR.*`
: `### Devin AI is completing this stale PR\n\nThis PR by @${prAuthor} has been marked as stale. The existing Devin session has been notified to complete the remaining work.\n\n[View Devin Session](${sessionUrl})\n\n---\n*Devin will review the PR, address any feedback, and push updates to complete this PR.*`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: parseInt(prNumber),
body: message
});
@@ -0,0 +1,31 @@
name: Sync Agents to Devin Knowledge
on:
push:
paths:
- "agents/**"
branches:
- main
permissions:
contents: read
jobs:
sync:
if: false
name: Sync to Devin Knowledge
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Generate knowledge JSON
run: npx tsx scripts/devin/parse-local-knowledge.ts
- name: Sync to Devin
env:
DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }}
run: npx tsx scripts/devin/sync-knowledge-to-devin.ts
+6 -8
View File
@@ -9,16 +9,14 @@ jobs:
test:
name: Unit
timeout-minutes: 20
runs-on: buildjet-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- run: yarn prisma generate
- run: yarn test -- --no-isolate
# We could add different timezones here that we need to run our tests in
- run: TZ=America/Los_Angeles yarn test -- --timeZoneDependentTestsOnly --no-isolate
- name: Run API v2 tests
working-directory: apps/api/v2
run: |
export NODE_OPTIONS="--max_old_space_size=8192"
yarn workspace @calcom/platform-libraries build && yarn test
- run: TZ=America/Los_Angeles VITEST_MODE=timezone yarn test -- --no-isolate
@@ -0,0 +1,20 @@
name: Validate Agents Format
on:
workflow_call:
permissions:
contents: read
jobs:
validate-agents-format:
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .github
- uses: ./.github/actions/cache-checkout
- uses: ./.github/actions/yarn-install
- name: Validate format
run: npx tsx scripts/devin/validate-local-knowledge.ts
-18
View File
@@ -1,18 +0,0 @@
name: Yarn install
on:
workflow_call:
permissions:
contents: read
jobs:
setup:
name: Yarn install & cache
runs-on: buildjet-4vcpu-ubuntu-2204
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
+15 -3
View File
@@ -60,18 +60,22 @@ yarn-error.log*
.history/
# Typescript
tsconfig.tsbuildinfo
*.tsbuildinfo
# turbo
.turbo
# Prisma generated files
packages/prisma/client/*
!packages/prisma/client/index.ts
apps/api/v2/generated/prisma/*
packages/prisma/generated/prisma/*
packages/prisma/zod/**/*.ts
packages/prisma/enums
# Builds
dist
packages/app-store/types
# Linting
lint-results
@@ -100,5 +104,13 @@ apps/auth
i18n.cache
packages/**/.yarn/ci-cache/
# AI
.claude
# AI - session/user specific files (keep CLAUDE.md and .cursor/skills tracked)
.claude/plans/
.claude/settings.local.json
# Spec drafts (rough work, not ready for review)
specs/**/_drafts/
# trigger.dev
.trigger
agents/devin-knowledge.json
+5 -4
View File
@@ -1,6 +1,7 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lint-staged
if [ -f .git/MERGE_HEAD ]; then
echo "Merge detected. Skipping lint-staged and generators."
exit 0
fi
yarn lint-staged --verbose
yarn app-store:build && git add packages/app-store/*.generated.*
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,125 @@
---
name: vercel-react-best-practices
description: React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
license: MIT
metadata:
author: vercel
version: "1.0.0"
---
# Vercel React Best Practices
Comprehensive performance optimization guide for React and Next.js applications, maintained by Vercel. Contains 45 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.
## When to Apply
Reference these guidelines when:
- Writing new React components or Next.js pages
- Implementing data fetching (client or server-side)
- Reviewing code for performance issues
- Refactoring existing React/Next.js code
- Optimizing bundle size or load times
## Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Eliminating Waterfalls | CRITICAL | `async-` |
| 2 | Bundle Size Optimization | CRITICAL | `bundle-` |
| 3 | Server-Side Performance | HIGH | `server-` |
| 4 | Client-Side Data Fetching | MEDIUM-HIGH | `client-` |
| 5 | Re-render Optimization | MEDIUM | `rerender-` |
| 6 | Rendering Performance | MEDIUM | `rendering-` |
| 7 | JavaScript Performance | LOW-MEDIUM | `js-` |
| 8 | Advanced Patterns | LOW | `advanced-` |
## Quick Reference
### 1. Eliminating Waterfalls (CRITICAL)
- `async-defer-await` - Move await into branches where actually used
- `async-parallel` - Use Promise.all() for independent operations
- `async-dependencies` - Use better-all for partial dependencies
- `async-api-routes` - Start promises early, await late in API routes
- `async-suspense-boundaries` - Use Suspense to stream content
### 2. Bundle Size Optimization (CRITICAL)
- `bundle-barrel-imports` - Import directly, avoid barrel files
- `bundle-dynamic-imports` - Use next/dynamic for heavy components
- `bundle-defer-third-party` - Load analytics/logging after hydration
- `bundle-conditional` - Load modules only when feature is activated
- `bundle-preload` - Preload on hover/focus for perceived speed
### 3. Server-Side Performance (HIGH)
- `server-cache-react` - Use React.cache() for per-request deduplication
- `server-cache-lru` - Use LRU cache for cross-request caching
- `server-serialization` - Minimize data passed to client components
- `server-parallel-fetching` - Restructure components to parallelize fetches
- `server-after-nonblocking` - Use after() for non-blocking operations
### 4. Client-Side Data Fetching (MEDIUM-HIGH)
- `client-swr-dedup` - Use SWR for automatic request deduplication
- `client-event-listeners` - Deduplicate global event listeners
### 5. Re-render Optimization (MEDIUM)
- `rerender-defer-reads` - Don't subscribe to state only used in callbacks
- `rerender-memo` - Extract expensive work into memoized components
- `rerender-dependencies` - Use primitive dependencies in effects
- `rerender-derived-state` - Subscribe to derived booleans, not raw values
- `rerender-functional-setstate` - Use functional setState for stable callbacks
- `rerender-lazy-state-init` - Pass function to useState for expensive values
- `rerender-transitions` - Use startTransition for non-urgent updates
### 6. Rendering Performance (MEDIUM)
- `rendering-animate-svg-wrapper` - Animate div wrapper, not SVG element
- `rendering-content-visibility` - Use content-visibility for long lists
- `rendering-hoist-jsx` - Extract static JSX outside components
- `rendering-svg-precision` - Reduce SVG coordinate precision
- `rendering-hydration-no-flicker` - Use inline script for client-only data
- `rendering-activity` - Use Activity component for show/hide
- `rendering-conditional-render` - Use ternary, not && for conditionals
### 7. JavaScript Performance (LOW-MEDIUM)
- `js-batch-dom-css` - Group CSS changes via classes or cssText
- `js-index-maps` - Build Map for repeated lookups
- `js-cache-property-access` - Cache object properties in loops
- `js-cache-function-results` - Cache function results in module-level Map
- `js-cache-storage` - Cache localStorage/sessionStorage reads
- `js-combine-iterations` - Combine multiple filter/map into one loop
- `js-length-check-first` - Check array length before expensive comparison
- `js-early-exit` - Return early from functions
- `js-hoist-regexp` - Hoist RegExp creation outside loops
- `js-min-max-loop` - Use loop for min/max instead of sort
- `js-set-map-lookups` - Use Set/Map for O(1) lookups
- `js-tosorted-immutable` - Use toSorted() for immutability
### 8. Advanced Patterns (LOW)
- `advanced-event-handler-refs` - Store event handlers in refs
- `advanced-use-latest` - useLatest for stable callback refs
## How to Use
Read individual rule files for detailed explanations and code examples:
```
rules/async-parallel.md
rules/bundle-barrel-imports.md
rules/_sections.md
```
Each rule file contains:
- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references
## Full Compiled Document
For the complete guide with all rules expanded: `AGENTS.md`
@@ -0,0 +1,55 @@
---
title: Store Event Handlers in Refs
impact: LOW
impactDescription: stable subscriptions
tags: advanced, hooks, refs, event-handlers, optimization
---
## Store Event Handlers in Refs
Store callbacks in refs when used in effects that shouldn't re-subscribe on callback changes.
**Incorrect (re-subscribes on every render):**
```tsx
function useWindowEvent(event: string, handler: () => void) {
useEffect(() => {
window.addEventListener(event, handler)
return () => window.removeEventListener(event, handler)
}, [event, handler])
}
```
**Correct (stable subscription):**
```tsx
function useWindowEvent(event: string, handler: () => void) {
const handlerRef = useRef(handler)
useEffect(() => {
handlerRef.current = handler
}, [handler])
useEffect(() => {
const listener = () => handlerRef.current()
window.addEventListener(event, listener)
return () => window.removeEventListener(event, listener)
}, [event])
}
```
**Alternative: use `useEffectEvent` if you're on latest React:**
```tsx
import { useEffectEvent } from 'react'
function useWindowEvent(event: string, handler: () => void) {
const onEvent = useEffectEvent(handler)
useEffect(() => {
window.addEventListener(event, onEvent)
return () => window.removeEventListener(event, onEvent)
}, [event])
}
```
`useEffectEvent` provides a cleaner API for the same pattern: it creates a stable function reference that always calls the latest version of the handler.
@@ -0,0 +1,49 @@
---
title: useLatest for Stable Callback Refs
impact: LOW
impactDescription: prevents effect re-runs
tags: advanced, hooks, useLatest, refs, optimization
---
## useLatest for Stable Callback Refs
Access latest values in callbacks without adding them to dependency arrays. Prevents effect re-runs while avoiding stale closures.
**Implementation:**
```typescript
function useLatest<T>(value: T) {
const ref = useRef(value)
useEffect(() => {
ref.current = value
}, [value])
return ref
}
```
**Incorrect (effect re-runs on every callback change):**
```tsx
function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
const [query, setQuery] = useState('')
useEffect(() => {
const timeout = setTimeout(() => onSearch(query), 300)
return () => clearTimeout(timeout)
}, [query, onSearch])
}
```
**Correct (stable effect, fresh callback):**
```tsx
function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
const [query, setQuery] = useState('')
const onSearchRef = useLatest(onSearch)
useEffect(() => {
const timeout = setTimeout(() => onSearchRef.current(query), 300)
return () => clearTimeout(timeout)
}, [query])
}
```
@@ -0,0 +1,38 @@
---
title: Prevent Waterfall Chains in API Routes
impact: CRITICAL
impactDescription: 2-10× improvement
tags: api-routes, server-actions, waterfalls, parallelization
---
## Prevent Waterfall Chains in API Routes
In API routes and Server Actions, start independent operations immediately, even if you don't await them yet.
**Incorrect (config waits for auth, data waits for both):**
```typescript
export async function GET(request: Request) {
const session = await auth()
const config = await fetchConfig()
const data = await fetchData(session.user.id)
return Response.json({ data, config })
}
```
**Correct (auth and config start immediately):**
```typescript
export async function GET(request: Request) {
const sessionPromise = auth()
const configPromise = fetchConfig()
const session = await sessionPromise
const [config, data] = await Promise.all([
configPromise,
fetchData(session.user.id)
])
return Response.json({ data, config })
}
```
For operations with more complex dependency chains, use `better-all` to automatically maximize parallelism (see Dependency-Based Parallelization).
@@ -0,0 +1,80 @@
---
title: Defer Await Until Needed
impact: HIGH
impactDescription: avoids blocking unused code paths
tags: async, await, conditional, optimization
---
## Defer Await Until Needed
Move `await` operations into the branches where they're actually used to avoid blocking code paths that don't need them.
**Incorrect (blocks both branches):**
```typescript
async function handleRequest(userId: string, skipProcessing: boolean) {
const userData = await fetchUserData(userId)
if (skipProcessing) {
// Returns immediately but still waited for userData
return { skipped: true }
}
// Only this branch uses userData
return processUserData(userData)
}
```
**Correct (only blocks when needed):**
```typescript
async function handleRequest(userId: string, skipProcessing: boolean) {
if (skipProcessing) {
// Returns immediately without waiting
return { skipped: true }
}
// Fetch only when needed
const userData = await fetchUserData(userId)
return processUserData(userData)
}
```
**Another example (early return optimization):**
```typescript
// Incorrect: always fetches permissions
async function updateResource(resourceId: string, userId: string) {
const permissions = await fetchPermissions(userId)
const resource = await getResource(resourceId)
if (!resource) {
return { error: 'Not found' }
}
if (!permissions.canEdit) {
return { error: 'Forbidden' }
}
return await updateResourceData(resource, permissions)
}
// Correct: fetches only when needed
async function updateResource(resourceId: string, userId: string) {
const resource = await getResource(resourceId)
if (!resource) {
return { error: 'Not found' }
}
const permissions = await fetchPermissions(userId)
if (!permissions.canEdit) {
return { error: 'Forbidden' }
}
return await updateResourceData(resource, permissions)
}
```
This optimization is especially valuable when the skipped branch is frequently taken, or when the deferred operation is expensive.
@@ -0,0 +1,36 @@
---
title: Dependency-Based Parallelization
impact: CRITICAL
impactDescription: 2-10× improvement
tags: async, parallelization, dependencies, better-all
---
## Dependency-Based Parallelization
For operations with partial dependencies, use `better-all` to maximize parallelism. It automatically starts each task at the earliest possible moment.
**Incorrect (profile waits for config unnecessarily):**
```typescript
const [user, config] = await Promise.all([
fetchUser(),
fetchConfig()
])
const profile = await fetchProfile(user.id)
```
**Correct (config and profile run in parallel):**
```typescript
import { all } from 'better-all'
const { user, config, profile } = await all({
async user() { return fetchUser() },
async config() { return fetchConfig() },
async profile() {
return fetchProfile((await this.$.user).id)
}
})
```
Reference: [https://github.com/shuding/better-all](https://github.com/shuding/better-all)
@@ -0,0 +1,28 @@
---
title: Promise.all() for Independent Operations
impact: CRITICAL
impactDescription: 2-10× improvement
tags: async, parallelization, promises, waterfalls
---
## Promise.all() for Independent Operations
When async operations have no interdependencies, execute them concurrently using `Promise.all()`.
**Incorrect (sequential execution, 3 round trips):**
```typescript
const user = await fetchUser()
const posts = await fetchPosts()
const comments = await fetchComments()
```
**Correct (parallel execution, 1 round trip):**
```typescript
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments()
])
```
@@ -0,0 +1,99 @@
---
title: Strategic Suspense Boundaries
impact: HIGH
impactDescription: faster initial paint
tags: async, suspense, streaming, layout-shift
---
## Strategic Suspense Boundaries
Instead of awaiting data in async components before returning JSX, use Suspense boundaries to show the wrapper UI faster while data loads.
**Incorrect (wrapper blocked by data fetching):**
```tsx
async function Page() {
const data = await fetchData() // Blocks entire page
return (
<div>
<div>Sidebar</div>
<div>Header</div>
<div>
<DataDisplay data={data} />
</div>
<div>Footer</div>
</div>
)
}
```
The entire layout waits for data even though only the middle section needs it.
**Correct (wrapper shows immediately, data streams in):**
```tsx
function Page() {
return (
<div>
<div>Sidebar</div>
<div>Header</div>
<div>
<Suspense fallback={<Skeleton />}>
<DataDisplay />
</Suspense>
</div>
<div>Footer</div>
</div>
)
}
async function DataDisplay() {
const data = await fetchData() // Only blocks this component
return <div>{data.content}</div>
}
```
Sidebar, Header, and Footer render immediately. Only DataDisplay waits for data.
**Alternative (share promise across components):**
```tsx
function Page() {
// Start fetch immediately, but don't await
const dataPromise = fetchData()
return (
<div>
<div>Sidebar</div>
<div>Header</div>
<Suspense fallback={<Skeleton />}>
<DataDisplay dataPromise={dataPromise} />
<DataSummary dataPromise={dataPromise} />
</Suspense>
<div>Footer</div>
</div>
)
}
function DataDisplay({ dataPromise }: { dataPromise: Promise<Data> }) {
const data = use(dataPromise) // Unwraps the promise
return <div>{data.content}</div>
}
function DataSummary({ dataPromise }: { dataPromise: Promise<Data> }) {
const data = use(dataPromise) // Reuses the same promise
return <div>{data.summary}</div>
}
```
Both components share the same promise, so only one fetch occurs. Layout renders immediately while both components wait together.
**When NOT to use this pattern:**
- Critical data needed for layout decisions (affects positioning)
- SEO-critical content above the fold
- Small, fast queries where suspense overhead isn't worth it
- When you want to avoid layout shift (loading → content jump)
**Trade-off:** Faster initial paint vs potential layout shift. Choose based on your UX priorities.
@@ -0,0 +1,59 @@
---
title: Avoid Barrel File Imports
impact: CRITICAL
impactDescription: 200-800ms import cost, slow builds
tags: bundle, imports, tree-shaking, barrel-files, performance
---
## Avoid Barrel File Imports
Import directly from source files instead of barrel files to avoid loading thousands of unused modules. **Barrel files** are entry points that re-export multiple modules (e.g., `index.js` that does `export * from './module'`).
Popular icon and component libraries can have **up to 10,000 re-exports** in their entry file. For many React packages, **it takes 200-800ms just to import them**, affecting both development speed and production cold starts.
**Why tree-shaking doesn't help:** When a library is marked as external (not bundled), the bundler can't optimize it. If you bundle it to enable tree-shaking, builds become substantially slower analyzing the entire module graph.
**Incorrect (imports entire library):**
```tsx
import { Check, X, Menu } from 'lucide-react'
// Loads 1,583 modules, takes ~2.8s extra in dev
// Runtime cost: 200-800ms on every cold start
import { Button, TextField } from '@mui/material'
// Loads 2,225 modules, takes ~4.2s extra in dev
```
**Correct (imports only what you need):**
```tsx
import Check from 'lucide-react/dist/esm/icons/check'
import X from 'lucide-react/dist/esm/icons/x'
import Menu from 'lucide-react/dist/esm/icons/menu'
// Loads only 3 modules (~2KB vs ~1MB)
import Button from '@mui/material/Button'
import TextField from '@mui/material/TextField'
// Loads only what you use
```
**Alternative (Next.js 13.5+):**
```js
// next.config.js - use optimizePackageImports
module.exports = {
experimental: {
optimizePackageImports: ['lucide-react', '@mui/material']
}
}
// Then you can keep the ergonomic barrel imports:
import { Check, X, Menu } from 'lucide-react'
// Automatically transformed to direct imports at build time
```
Direct imports provide 15-70% faster dev boot, 28% faster builds, 40% faster cold starts, and significantly faster HMR.
Libraries commonly affected: `lucide-react`, `@mui/material`, `@mui/icons-material`, `@tabler/icons-react`, `react-icons`, `@headlessui/react`, `@radix-ui/react-*`, `lodash`, `ramda`, `date-fns`, `rxjs`, `react-use`.
Reference: [How we optimized package imports in Next.js](https://vercel.com/blog/how-we-optimized-package-imports-in-next-js)
@@ -0,0 +1,31 @@
---
title: Conditional Module Loading
impact: HIGH
impactDescription: loads large data only when needed
tags: bundle, conditional-loading, lazy-loading
---
## Conditional Module Loading
Load large data or modules only when a feature is activated.
**Example (lazy-load animation frames):**
```tsx
function AnimationPlayer({ enabled }: { enabled: boolean }) {
const [frames, setFrames] = useState<Frame[] | null>(null)
useEffect(() => {
if (enabled && !frames && typeof window !== 'undefined') {
import('./animation-frames.js')
.then(mod => setFrames(mod.frames))
.catch(() => setEnabled(false))
}
}, [enabled, frames])
if (!frames) return <Skeleton />
return <Canvas frames={frames} />
}
```
The `typeof window !== 'undefined'` check prevents bundling this module for SSR, optimizing server bundle size and build speed.
@@ -0,0 +1,49 @@
---
title: Defer Non-Critical Third-Party Libraries
impact: MEDIUM
impactDescription: loads after hydration
tags: bundle, third-party, analytics, defer
---
## Defer Non-Critical Third-Party Libraries
Analytics, logging, and error tracking don't block user interaction. Load them after hydration.
**Incorrect (blocks initial bundle):**
```tsx
import { Analytics } from '@vercel/analytics/react'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Analytics />
</body>
</html>
)
}
```
**Correct (loads after hydration):**
```tsx
import dynamic from 'next/dynamic'
const Analytics = dynamic(
() => import('@vercel/analytics/react').then(m => m.Analytics),
{ ssr: false }
)
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Analytics />
</body>
</html>
)
}
```
@@ -0,0 +1,35 @@
---
title: Dynamic Imports for Heavy Components
impact: CRITICAL
impactDescription: directly affects TTI and LCP
tags: bundle, dynamic-import, code-splitting, next-dynamic
---
## Dynamic Imports for Heavy Components
Use `next/dynamic` to lazy-load large components not needed on initial render.
**Incorrect (Monaco bundles with main chunk ~300KB):**
```tsx
import { MonacoEditor } from './monaco-editor'
function CodePanel({ code }: { code: string }) {
return <MonacoEditor value={code} />
}
```
**Correct (Monaco loads on demand):**
```tsx
import dynamic from 'next/dynamic'
const MonacoEditor = dynamic(
() => import('./monaco-editor').then(m => m.MonacoEditor),
{ ssr: false }
)
function CodePanel({ code }: { code: string }) {
return <MonacoEditor value={code} />
}
```
@@ -0,0 +1,50 @@
---
title: Preload Based on User Intent
impact: MEDIUM
impactDescription: reduces perceived latency
tags: bundle, preload, user-intent, hover
---
## Preload Based on User Intent
Preload heavy bundles before they're needed to reduce perceived latency.
**Example (preload on hover/focus):**
```tsx
function EditorButton({ onClick }: { onClick: () => void }) {
const preload = () => {
if (typeof window !== 'undefined') {
void import('./monaco-editor')
}
}
return (
<button
onMouseEnter={preload}
onFocus={preload}
onClick={onClick}
>
Open Editor
</button>
)
}
```
**Example (preload when feature flag is enabled):**
```tsx
function FlagsProvider({ children, flags }: Props) {
useEffect(() => {
if (flags.editorEnabled && typeof window !== 'undefined') {
void import('./monaco-editor').then(mod => mod.init())
}
}, [flags.editorEnabled])
return <FlagsContext.Provider value={flags}>
{children}
</FlagsContext.Provider>
}
```
The `typeof window !== 'undefined'` check prevents bundling preloaded modules for SSR, optimizing server bundle size and build speed.
@@ -0,0 +1,74 @@
---
title: Deduplicate Global Event Listeners
impact: LOW
impactDescription: single listener for N components
tags: client, swr, event-listeners, subscription
---
## Deduplicate Global Event Listeners
Use `useSWRSubscription()` to share global event listeners across component instances.
**Incorrect (N instances = N listeners):**
```tsx
function useKeyboardShortcut(key: string, callback: () => void) {
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.metaKey && e.key === key) {
callback()
}
}
window.addEventListener('keydown', handler)
return () => window.removeEventListener('keydown', handler)
}, [key, callback])
}
```
When using the `useKeyboardShortcut` hook multiple times, each instance will register a new listener.
**Correct (N instances = 1 listener):**
```tsx
import useSWRSubscription from 'swr/subscription'
// Module-level Map to track callbacks per key
const keyCallbacks = new Map<string, Set<() => void>>()
function useKeyboardShortcut(key: string, callback: () => void) {
// Register this callback in the Map
useEffect(() => {
if (!keyCallbacks.has(key)) {
keyCallbacks.set(key, new Set())
}
keyCallbacks.get(key)!.add(callback)
return () => {
const set = keyCallbacks.get(key)
if (set) {
set.delete(callback)
if (set.size === 0) {
keyCallbacks.delete(key)
}
}
}
}, [key, callback])
useSWRSubscription('global-keydown', () => {
const handler = (e: KeyboardEvent) => {
if (e.metaKey && keyCallbacks.has(e.key)) {
keyCallbacks.get(e.key)!.forEach(cb => cb())
}
}
window.addEventListener('keydown', handler)
return () => window.removeEventListener('keydown', handler)
})
}
function Profile() {
// Multiple shortcuts will share the same listener
useKeyboardShortcut('p', () => { /* ... */ })
useKeyboardShortcut('k', () => { /* ... */ })
// ...
}
```
@@ -0,0 +1,56 @@
---
title: Use SWR for Automatic Deduplication
impact: MEDIUM-HIGH
impactDescription: automatic deduplication
tags: client, swr, deduplication, data-fetching
---
## Use SWR for Automatic Deduplication
SWR enables request deduplication, caching, and revalidation across component instances.
**Incorrect (no deduplication, each instance fetches):**
```tsx
function UserList() {
const [users, setUsers] = useState([])
useEffect(() => {
fetch('/api/users')
.then(r => r.json())
.then(setUsers)
}, [])
}
```
**Correct (multiple instances share one request):**
```tsx
import useSWR from 'swr'
function UserList() {
const { data: users } = useSWR('/api/users', fetcher)
}
```
**For immutable data:**
```tsx
import { useImmutableSWR } from '@/lib/swr'
function StaticContent() {
const { data } = useImmutableSWR('/api/config', fetcher)
}
```
**For mutations:**
```tsx
import { useSWRMutation } from 'swr/mutation'
function UpdateButton() {
const { trigger } = useSWRMutation('/api/user', updateUser)
return <button onClick={() => trigger()}>Update</button>
}
```
Reference: [https://swr.vercel.app](https://swr.vercel.app)
@@ -0,0 +1,82 @@
---
title: Batch DOM CSS Changes
impact: MEDIUM
impactDescription: reduces reflows/repaints
tags: javascript, dom, css, performance, reflow
---
## Batch DOM CSS Changes
Avoid changing styles one property at a time. Group multiple CSS changes together via classes or `cssText` to minimize browser reflows.
**Incorrect (multiple reflows):**
```typescript
function updateElementStyles(element: HTMLElement) {
// Each line triggers a reflow
element.style.width = '100px'
element.style.height = '200px'
element.style.backgroundColor = 'blue'
element.style.border = '1px solid black'
}
```
**Correct (add class - single reflow):**
```typescript
// CSS file
.highlighted-box {
width: 100px;
height: 200px;
background-color: blue;
border: 1px solid black;
}
// JavaScript
function updateElementStyles(element: HTMLElement) {
element.classList.add('highlighted-box')
}
```
**Correct (change cssText - single reflow):**
```typescript
function updateElementStyles(element: HTMLElement) {
element.style.cssText = `
width: 100px;
height: 200px;
background-color: blue;
border: 1px solid black;
`
}
```
**React example:**
```tsx
// Incorrect: changing styles one by one
function Box({ isHighlighted }: { isHighlighted: boolean }) {
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
if (ref.current && isHighlighted) {
ref.current.style.width = '100px'
ref.current.style.height = '200px'
ref.current.style.backgroundColor = 'blue'
}
}, [isHighlighted])
return <div ref={ref}>Content</div>
}
// Correct: toggle class
function Box({ isHighlighted }: { isHighlighted: boolean }) {
return (
<div className={isHighlighted ? 'highlighted-box' : ''}>
Content
</div>
)
}
```
Prefer CSS classes over inline styles when possible. Classes are cached by the browser and provide better separation of concerns.
@@ -0,0 +1,80 @@
---
title: Cache Repeated Function Calls
impact: MEDIUM
impactDescription: avoid redundant computation
tags: javascript, cache, memoization, performance
---
## Cache Repeated Function Calls
Use a module-level Map to cache function results when the same function is called repeatedly with the same inputs during render.
**Incorrect (redundant computation):**
```typescript
function ProjectList({ projects }: { projects: Project[] }) {
return (
<div>
{projects.map(project => {
// slugify() called 100+ times for same project names
const slug = slugify(project.name)
return <ProjectCard key={project.id} slug={slug} />
})}
</div>
)
}
```
**Correct (cached results):**
```typescript
// Module-level cache
const slugifyCache = new Map<string, string>()
function cachedSlugify(text: string): string {
if (slugifyCache.has(text)) {
return slugifyCache.get(text)!
}
const result = slugify(text)
slugifyCache.set(text, result)
return result
}
function ProjectList({ projects }: { projects: Project[] }) {
return (
<div>
{projects.map(project => {
// Computed only once per unique project name
const slug = cachedSlugify(project.name)
return <ProjectCard key={project.id} slug={slug} />
})}
</div>
)
}
```
**Simpler pattern for single-value functions:**
```typescript
let isLoggedInCache: boolean | null = null
function isLoggedIn(): boolean {
if (isLoggedInCache !== null) {
return isLoggedInCache
}
isLoggedInCache = document.cookie.includes('auth=')
return isLoggedInCache
}
// Clear cache when auth changes
function onAuthChange() {
isLoggedInCache = null
}
```
Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components.
Reference: [How we made the Vercel Dashboard twice as fast](https://vercel.com/blog/how-we-made-the-vercel-dashboard-twice-as-fast)
@@ -0,0 +1,28 @@
---
title: Cache Property Access in Loops
impact: LOW-MEDIUM
impactDescription: reduces lookups
tags: javascript, loops, optimization, caching
---
## Cache Property Access in Loops
Cache object property lookups in hot paths.
**Incorrect (3 lookups × N iterations):**
```typescript
for (let i = 0; i < arr.length; i++) {
process(obj.config.settings.value)
}
```
**Correct (1 lookup total):**
```typescript
const value = obj.config.settings.value
const len = arr.length
for (let i = 0; i < len; i++) {
process(value)
}
```

Some files were not shown because too many files have changed in this diff Show More