* 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
* 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>
* 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>
* 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)
* 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>
* 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>
* 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>
* 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>
* 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>
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.
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>
* 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>
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
* 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>
* 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.
* 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>
* 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>
## 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: 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
* refactor: Delete mockTRPCContext and mockData, and relocate mockStripeSubscription to stripe mock.
* chore: Delete unused Stripe, video client, and reminder scheduler mock files.
* 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>
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>
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
* 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
* 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>
* 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>
* 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>
* 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(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>
## 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
* 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>
* 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
- 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)
* 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>
* 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>
## 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)
* 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>
* 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>
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>
* 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
* 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
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>
* 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>
* 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>
- 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.
* 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>
* 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
* 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
* 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>
* 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>
- 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.
* 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>
- 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>
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>
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>
* 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>
* 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>
* 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>
- 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
* 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
* 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>
* 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>
* 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>
* 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>
* 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>
- 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>
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>
* 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>
* 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>
- 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>
* longpress ios - event type, booking, availability
* new booking details page for ios
* remove comments
* address cubics comments
* use lowercase type same as api v2
* 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>
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>
* 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>
* 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>
* 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>
* 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
<!-- 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. -->
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>
* 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>
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
* 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.
* 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 ' 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
* 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>
* 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
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>
* 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>
* 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>
* 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>
* 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.
* 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>
* 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>
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>
- 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>
* 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
* feat: store ads clickid when creating an account
* fix: type check
* fix: google campaignId not being added to stripe
* remove tracking in stripe app
* 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>
* 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>
* 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>
* 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>
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>
* 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>
* 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>
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>
* 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>
* 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>
* 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>
* 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.
* 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>
* 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>
- 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>
* 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
* 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.
* 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>
* 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>
* 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>
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
- 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
* 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>
* 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>
* 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>
* 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>
- 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>
* 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>
* 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>
* 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>
* 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
* 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>
* chore: Change atoms build command to build-npm to avoid turbo compilations
* Updated turbo.json atoms#build reference
* Updated atoms production build for CI
* 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>
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
* 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.
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>
* 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>
* 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>
* 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.
* 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
* 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
* 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>
* 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
* 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>
* 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>
* 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
* 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>
You can use any of these credentials to sign in at [http://localhost:3000](http://localhost:3000)
> **Tip**: To view the full list of seeded users and their details, run `yarn db-studio` and visit [http://localhost:5555](http://localhost:5555)
#### Development tip
1. Add `export NODE_OPTIONS=“--max-old-space-size=16384”` to your shell script to increase the memory limit for the node process. Alternatively, you can run this in your terminal before running the app. Replace 16384 with the amount of RAM you want to allocate to the node process.
@@ -193,7 +207,7 @@ yarn dx
The logger will include all logs that are at the specified level or higher. For example: \
- If you set `NEXT_PUBLIC_LOGGER_LEVEL=2`, it will log from level 2 (debug) upwards, meaning levels 2 (debug), 3 (info), 4 (warn), 5 (error), and (fatal) will be logged. \
- If you set `NEXT_PUBLIC_LOGGER_LEVEL=2`, it will log from level 2 (debug) upwards, meaning levels 2 (debug), 3 (info), 4 (warn), 5 (error), and 6 (fatal) will be logged. \
- If you set `NEXT_PUBLIC_LOGGER_LEVEL=3`, it will log from level 3 (info) upwards, meaning levels 3 (info), 4 (warn), 5 (error), and 6 (fatal) will be logged, but level 2 (debug) and level 1 (trace) will be ignored. \
@@ -255,7 +255,55 @@ import { TRPCError } from "@trpc/server";
### packages/features Import Restrictions
Files in `packages/features/**` should NOT import from `trpc`. This keeps the features package decoupled from the tRPC layer, making the code more reusable and testable. Use `ErrorWithCode` for error handling in these files, and let the tRPC middleware handle the conversion.
Files in `packages/features/**` should NOT import from `@calcom/trpc`. This keeps the features package decoupled from the tRPC layer, making the code more reusable and testable. Use `ErrorWithCode` for error handling in these files, and let the tRPC middleware handle the conversion.
**Architecture: packages/features vs apps/web/modules**
The `packages/features` package should contain only framework-agnostic code:
- Repositories (data access layer)
- Services (business logic)
- Core utilities and helpers
- Types and interfaces
Web-specific code, particularly anything that uses tRPC, should live in `apps/web/modules/...`. This includes:
- React hooks that use tRPC queries/mutations
- tRPC-specific utilities
- Web-only UI components that depend on tRPC
**Example:**
If you have a feature called `feature-opt-in`:
```
packages/features/feature-opt-in/
├── repository/
│ └── FeatureOptInRepository.ts # Data access - OK here
├── service/
│ └── FeatureOptInService.ts # Business logic - OK here
└── types.ts # Types - OK here
apps/web/modules/feature-opt-in/
└── hooks/
└── useFeatureOptIn.ts # tRPC hook - MUST be here, not in packages/features
This separation ensures that `packages/features` remains portable and can be used by other apps (like `apps/api/v2`) without pulling in web-specific dependencies like tRPC React hooks.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.