* Add db schema
* Add `CredentialRepository.findByTeamIdAndSlugs`
* Add enabled app slugs for attribute syncing
* Create repository for `IntegrationAttributeSync`
* Create zod schemas
* Create `AttributeSyncUserRuleOutputMapper`
* Create `IntegrationAttributeSyncService`
* Create DI contianer
* Create trpc endpoints
* Create page
* Include team name in `CredentialRepository.findByTeamIdAndSlugs`
* Update schema and relations
* Update types and schemas
* Add more methods to IntegrationAttributeSyncRepository
* Add more services to `IntegrationAttributeSyncService`
- getById
- Init updateIncludeRulesAndMappings
* Refactor `getTeams.handler` to use repository
* Create `createAttributeSync` trpc endpoint
* Create `updateAttributeSync` trpc endpoint
* Add router to trpc
* Create attribute sync child components
* Pass custom actions to `FormCard`
* Create `IntegrationAttributeSyncCard`
* Pass inital props via server side
* Fix prop
* Only refetch on mutation
* Fixes
* Add form error when duplicate field and attribute combo
* Add `updateTransactionWithRUleAndMappings` logic
* Adjust zod schemas
* Service add `updateIncludeRulesAndMappings`
* Pass orgId from server to component
* Rename types
* Add deleteById method to repository
* Add name to integrationAttributeSync
* Add deleteById method to service
* Rename method
* Add deleteAttributeSync trpc endpoint
* Make the IntegrationAttributeSyncCard a dummy component
* test: add tests for IntegrationAttributeSync feature
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Move creating a attribute sync record to the service
* Add i18n strings
* Safe select credential in find by id and team
* Fix default credentialId value in form
* Update repository return types
* Add i18n string
* Make credentialId optional for form schema
* Fix label
* Add cascade deletes
* Add verification that syncs belong to org
* Create mapper for repository output
* Type fixes
* Remove old test file
* Pass `attributeOptions` from parent to children
* Infer types from zod schema
* Type fixes
* Type fix
* Clean up
* Add i18n strings
* Remove unused file
* Address feedback
* Add migration file
* Address feedback
* Add validation for new integration values
* Remove unused router
* Move away from z.infer to z.ZodType
* Clean up comments
* Type fix
* Type fixes
* Type fix
* fix: add passthrough to syncFormDataSchema to preserve extra fields
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Add indexes
* Add aria label
* Address feedback - consistent validation
* Fix import paths for attribute types
* refactor: change attributeSyncRules array to singular attributeSyncRule
The database schema enforces a one-to-one relationship between
IntegrationAttributeSync and AttributeSyncRule (via @unique constraint),
and the UI only supports a single rule. This change makes the TypeScript
type match the database schema and UI behavior.
Changes:
- Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null
- Update mapper to return singular rule instead of wrapping in array
- Update UI component to access sync.attributeSyncRule directly
- Update IIntegrationAttributeSyncUpdateParams Omit type
- Update tests to use attributeSyncRule: null instead of attributeSyncRules: []
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* feat: implement FeatureOptInService (#25805)
* feat: implement FeatureOptInService WIP
* clean up
* feat: consolidate feature repositories and add updateFeatureForUser
- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* refactor: rename updateFeatureForUser to setUserFeatureState
Rename to match the convention used for setTeamFeatureState
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState
* fix integration tests
* clean up logics
* update services and router
* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array
- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* feat: add getFeatureStateForTeams for batch querying multiple teams
- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* refactor: combine org and team state queries into single call
- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* refactor: use team.isOrganization and clarify computeEffectiveState comment
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* refactor: use MembershipRepository.findAllByUserId with isOrganization
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* feat: add featureId validation using isOptInFeature type guard
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* less queries
* add fallback value
* fix type error
* move files
* add autoOptInFeatures column
* use autoOptInFeatures flag within FeatureOptInService
* add setUserAutoOptIn and setTeamAutoOptIn
* fix computeEffectiveState logic
* rewrite computeEffectiveState
* clean up integration tests
* clean up in afterEach
* fix type error
* refactor: use FeaturesRepository methods instead of direct Prisma calls
Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.
Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts
This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* clean up
* fix the logic
* extract some logic into applyAutoOptIn()
* remove wrong code
* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union
- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests
* fix type error
* use Promise.all
* fix
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Prevent duplicate field and attribute mappings
* Add validation that attribute belongs to the org
* fix: address Cubic AI review feedback
- Add @@index([credentialId]) to IntegrationAttributeSync model for efficient cascade deletes and credential-based queries (confidence: 9/10)
- Fix translation key from 'credential_required' to 'attribute_sync_credential_required' to match existing locale definition (confidence: 10/10)
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* fix: address remaining cubic review feedback
- RuleBuilder.tsx: Use unique IDs for React keys instead of array index to prevent reconciliation bugs when removing conditions
- updateAttributeSync.handler.ts: Add early organization check before service calls for consistency
- createAttributeSync.handler.ts: Add CredentialNotFoundError class for type-safe error handling instead of string matching
- IntegrationAttributeSyncService.test.ts: Replace expect.fail() with proper Vitest rejects.toSatisfy() pattern
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Pull test file from main
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
* feat(api): add bookingUrl field to event types API v2 response
Add a new bookingUrl field to EventTypeOutput_2024_06_14 that contains
the full, correct booking URL for each event type. This fixes the issue
where companion app and Chrome extension were hardcoding cal.com URLs
instead of using organization subdomains.
Changes:
- Add bookingUrl field to EventTypeOutput_2024_06_14 type definition
- Update repository to include organization data when fetching users
- Add buildBookingUrl method to compute URL using getOrgFullOrigin
- Include bookingUrl in getResponseEventType return object
The booking URL is computed using the first user's organization slug
(if any) to generate the correct subdomain URL (e.g., i.cal.com/keith/30min
for organization users instead of cal.com/keith/30min).
* fix: include organization data in getEventTypeByIdWithHosts
Update getEventTypeByIdWithHosts to use usersInclude to fetch
organization slug data, ensuring bookingUrl is computed correctly
for the GET /v2/event-types/{eventTypeId} endpoint.
* test: add unit tests and E2E assertions for bookingUrl field
* fix(api-v2): correct bookingUrl format for org users and fix double slashes
Fix issues with bookingUrl field in event types API v2 response:
- Remove trailing slashes from base URLs to prevent double slashes
- Use profile.username instead of user.username for organization users
(profile contains clean username without org suffix)
- Include user profiles in repository queries to access profile data
- Create local org-domains utility to replace @calcom/features dependency
which isn't available in API v2 runtime
Changes:
- Add apps/api/v2/src/lib/org-domains.ts with getOrgFullOrigin function
adapted from @calcom/features/ee/organizations/lib/orgDomains
- Update event-types.repository.ts to include profiles in usersInclude
- Update buildBookingUrl() to prioritize profile data when available
- Update unit tests to cover organization user profile scenarios
Fixes:
- Double slashes in URLs (e.g., http://localhost:3000//user/slug)
- Incorrect username format for org users (e.g., owner1-acme instead
of owner1)
- Missing organization subdomain in booking URLs (e.g., should be
http://acme.localhost:3000/owner1/30min not
http://localhost:3000/owner1-acme/30min)
* deslop ai code
* handle empty username in both code and write test for it, use select instead of include
* feat(api-v2): reuse core org domain logic for event type bookingUrl
Export getOrgFullOrigin and subdomainSuffix from @calcom/platform-libraries/organizations
to reuse existing core logic instead of duplicating it in API v2. This ensures consistency
across the codebase and reduces maintenance burden.
- Export getOrgFullOrigin and subdomainSuffix from platform-libraries/organizations
- Update output-event-types.service to import from @calcom/platform-libraries/organizations
- Remove duplicate org-domains.ts file from API v2
- Update test mocks to use platform-libraries import path
- buildBookingUrl method now uses core getOrgFullOrigin function
This addresses feedback to reuse core code rather than introducing duplicate logic.
* test(api-v2): exclude bookingUrl from output comparison in e2e test
* refactor(api-v2): reuse core logic for event type bookingUrl
Replace duplicated username/org extraction logic in buildBookingUrl with
core functions. Use getBookerBaseUrlSync from @calcom/platform-libraries/organizations
for base URL generation, and add enrichUserWithProfile method that follows
the same pattern as core's UserRepository.enrichUsersWithTheirProfiles.
The enrichment logic is applied synchronously since profiles are already
fetched by the repository, avoiding the need to make the service async.
This ensures consistency with core patterns while maintaining the existing
synchronous API contract.
- Replace getOrgFullOrigin with getBookerBaseUrlSync
- Add enrichUserWithProfile method following core enrichment pattern
- Simplify buildBookingUrl to use enriched user data
- Update tests to mock getBookerBaseUrlSync and verify enrichment flow
* trailing slash cubic comment
* address review comments
* address review comments 2
* better code
* Updated the test to give the user an organization
* address review comments again
* Revert "address review comments again"
This reverts commit 622ea3fc8dcd7f5c3113614afcfc86beadecca0e.
* allow both the full UserWithProfile and the partial EventTypeUser (from select queries) to use the same getUserMainProfile() method, eliminating code duplication without changing the performance-optimized repository queries.
* reveiw points
* use cross-platform rimraf for build scripts
* fix: use cross-platform rimraf for build scripts
* fix: replace cp with npx shx cp for cross-platform compatibility
* Update schema.prisma
* chore: Integrate booking confirmation booking audit
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Use BookingStatus type instead of string for booking.status
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Make booking-audit integration test utils reusable
* refactor: enhance handlePaymentSuccess to accept appSlug and actor identification
- Updated handlePaymentSuccess function to accept an object with paymentId, bookingId, appSlug, and traceContext.
- Introduced getActor function to determine the actor based on appSlug and credentialId.
- Modified webhook handlers for Alby, BTCPayServer, HitPay, PayPal, and Stripe to pass the new parameters.
- Improved logging for missing credentialId in payment processing.
- Adjusted related schemas to ensure proper type handling for booking status and actor identification.
* fix: Correct import paths and getActor function call
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Use ActorIdentification type instead of AuditActor in getActor
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Add guard clause for undefined actor in fireBookingAcceptedEvent
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Add actionSource to all confirm calls
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Integrate actor identification and action source updates across booking services
- Added `makeUserActor` to various booking service files to enhance actor identification.
- Updated action source handling in booking confirmation and related functions to include "MAGIC_LINK".
- Refactored schemas to accommodate new actor and action source requirements, ensuring consistent type handling.
- Improved error handling and logging for booking actions to enhance traceability.
* Remvoe formatting changes
* Add test
* refactor: Enhance booking confirmation tests and event handling
- Updated `confirm.handler.test.ts` to improve test coverage for booking acceptance and rejection scenarios, including bulk bookings.
- Refactored the mock implementation of `BookingEventHandlerService` to streamline event handling for accepted and rejected bookings.
- Adjusted the `handleConfirmation` function to utilize `acceptedBookings` for better clarity and maintainability.
- Added tests to ensure correct invocation of event handler methods for both single and bulk booking confirmations and rejections.
* fix tests
* refactor: Use confirmHandler directly in link and verify-booking-token routes
Refactors the link and verify-booking-token API routes to call confirmHandler directly instead of using the tRPC caller pattern. This simplifies the code by removing the need for session getter, legacy request building, and context creation.
Changes:
- apps/web/app/api/link/route.ts: Use confirmHandler directly with ctx and input
- apps/web/app/api/verify-booking-token/route.ts: Use confirmHandler directly with ctx and input
- Updated tests to mock confirmHandler instead of tRPC caller
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix ts errors due to merge frommain
* feat: introduce getAppActor utility for actor creation
This commit adds a new utility function, getAppActor, to streamline the process of creating actor objects for apps based on their slug and credential ID. The function is integrated into handlePaymentSuccess and handleStripePaymentSuccess, replacing the previous inline actor creation logic. This refactor enhances code maintainability and readability by centralizing actor creation logic.
Changes:
- New file: packages/app-store/_utils/getAppActor.ts
- Updated handlePaymentSuccess and handleStripePaymentSuccess to use getAppActor
- Removed redundant actor creation code from these functions
* refactor: Update appSlug in payment success handlers to use appConfig.slug
This commit modifies the appSlug parameter in the handlePaymentSuccess function across multiple payment webhook handlers to utilize the appConfig.slug value instead of hardcoded strings. This change enhances consistency and maintainability of the code.
Changes:
- Updated appSlug in handlePaymentSuccess for btcpayserver, hitpay, and paypal webhooks.
- Adjusted a test case to reflect the new appSlug value for consistency.
* test: Enhance booking token verification and audit action tests
This commit adds additional assertions to the booking token verification tests to ensure that the confirmHandler is not called when an error occurs. It also introduces a mechanism to clean up additional booking UIDs after each test in the accepted action integration tests, improving test reliability. Furthermore, it updates the action source schema comment for clarity.
Changes:
- Updated tests in `verify-booking-token` to check that `mockConfirmHandler` is not called on error.
- Implemented cleanup logic for additional booking UIDs in `accepted-action.integration-test.ts`.
- Clarified comment in `actionSource.ts` regarding the schema for action sources.
- Refactored `handleConfirmation.ts` and `confirm.handler.ts` to include tracing logger for error handling in booking events.
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* chore: Integrate add guests booking audit
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* chore: Add actionSource parameter to support API_V2 audit logging
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: update attendee audit action service to use new email schema
- Modified the `AttendeeAddedAuditActionService` to replace the old attendees schema with a new `emailSchema` for better validation.
- Adjusted the `addGuestsHandler` to pass the action source explicitly and updated the audit logging to reflect the new structure.
- Cleaned up the code for better readability and consistency.
* test: add happy path integration test for attendee added action
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat(billing): add database schema for monthly proration tracking
add new database models and migration for tracking seat changes and monthly proration on annual subscriptions
- new models: SeatChangeLog, MonthlyProration
- new enums: SeatChangeType, ProrationStatus
- extend TeamBilling and OrganizationBilling with billingPeriod, pricePerSeat, paidSeats fields
- add feature flag 'monthly-proration' (disabled by default)
- squashed migration: 20260106093811_add_monthly_proration_tracking
the schema supports:
- tracking seat additions/removals per month with metadata
- storing proration calculations and stripe invoice details
- high-water mark billing via paidSeats field
- proper foreign key relationships and indexes for query performance
* feat(billing): add repository layer for monthly proration
add repository pattern for proration data access
- MonthlyProrationRepository: crud operations for proration records
- create, update, and query proration records
- status management (pending, invoice_created, charged, failed)
- retry count tracking
- MonthlyProrationTeamRepository: team-specific queries with billing context
- fetch teams with billing information
- query annual teams with unprocessed seat changes
- update billing info and paidSeats
- metadata fallback for legacy teams without billing records
- update IBillingRepository interface to include proration fields
these repositories provide clean data access layer without business logic
* feat(billing): add seat change tracking service
add service for logging and querying seat changes per month
- SeatChangeTrackingService: track seat additions and removals
- log seat additions with user and metadata context
- log seat removals with optional triggered-by info
- calculate monthly changes (additions, removals, net change)
- retrieve unprocessed changes for a given month
- mark changes as processed after proration calculation
- auto-detect billing entity (team vs organization)
- stripe-subscription-utils: extract billing data from stripe subscriptions
- determine billing period (monthly vs annually)
- extract price per seat and quantity
includes comprehensive unit tests
* feat(billing): add billing period service
add service to determine billing period and proration eligibility
- BillingPeriodService: query and manage billing period information
- check if team is on annual vs monthly plan
- check if team is in trial period
- determine if monthly proration should apply (annual + not in trial + feature flag)
- lazy load billing data from stripe if missing in database
- backfill missing billing data automatically
supports both TeamBilling and OrganizationBilling models
includes comprehensive unit tests with stripe mocking
* feat(billing): add monthly proration service
add core service for calculating and processing monthly seat prorations
- MonthlyProrationService: orchestrate monthly proration workflow
- process monthly prorations for teams with seat changes
- calculate prorated amounts based on remaining subscription days
- create stripe invoice items for seat additions
- handle payment success and failure webhooks
- track high-water mark (paidSeats) for billing
- update stripe subscription quantities after payment
- lazy load and backfill missing billing data from stripe
- support retry logic for failed payments
calculation logic:
- only charge for net seat increases (additions - removals, capped at 0)
- prorate based on remaining days in annual subscription
- track separately from stripe's built-in proration to aggregate monthly
includes unit tests and integration tests with stripe mocking
* refactor(billing): extract prisma logic from services to repositories
move database access logic from services to repository layer for better separation of concerns
- add SeatChangeLogRepository for seat change log data access
- add BillingPeriodRepository for billing period queries and updates
- refactor SeatChangeTrackingService to use SeatChangeLogRepository
- refactor BillingPeriodService to use BillingPeriodRepository
- add create methods to MonthlyProrationTeamRepository for billing records
- refactor MonthlyProrationService to use repository for billing creation
- remove direct prisma calls from services (except FeaturesRepository dependency)
services now focus on business logic while repositories handle data access
* refactor(billing): inject prisma via constructor in repositories
make repositories more testable by accepting prisma client via constructor
- SeatChangeLogRepository: accept optional prisma in constructor
- BillingPeriodRepository: accept optional prisma in constructor
- MonthlyProrationRepository: accept optional prisma in constructor
- MonthlyProrationTeamRepository: accept optional prisma in constructor
all repositories default to global prisma instance when not provided
enables easier mocking in tests by injecting test prisma instances
* refactor: remove verbose comments and unnecessary try-catch
* refactor: change pricePerSeat and proratedAmount to cents (Int)
store monetary values as integers in cents instead of floats for precision
remove unnecessary schema comments
* fix tests and add back try catch error handlign
* Update packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* add faeture flag to config.ts
* Update packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* restore schema
* add hooks types for flag
* fix: correct pricePerSeat calculations for cents-based storage
MonthlyProrationService now correctly handles pricePerSeat stored as
cents (INTEGER) instead of dollars (DOUBLE PRECISION). Removed duplicate
conversions to cents that were causing 100x price inflation.
* Use cents for money values
* fix type error
* Move integration to test to use cents value
* fix integration import
* mock subscription
* include paid seats tracking in proration service
* add mocks for invoice creation
* feat: use stripebilling service instead of using stripe directly
* fix validation erorr handler in proration service
* fix: fix sub
* use correct seat value
* fix(billing): mark seat changes as processed when netChange is zero
When a team has additions and removals that net to zero, the function
was returning null without calling markAsProcessed(). This left seat
change logs in an unprocessed state indefinitely, causing subsequent
proration runs to re-query the same changes repeatedly.
Changed the early return condition from checking netChange === 0 to
checking if there are no changes at all (additions === 0 && removals === 0).
This ensures that when there are actual seat changes that net to zero,
a proration record is still created and seat changes are marked as processed.
Co-Authored-By: unknown <>
* update test to reflect new return type of proration
---------
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
* fix: return 400 instead of 500 for invalid eventTypeId in booking flow
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* refactor: use ErrorWithCode instead of HttpError in BotDetectionService
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* refactor: use vi.stubEnv for safer environment variable handling in tests
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(api): remove OAuth client ID suffix from email in booking API responses
Fixes#25494 | Linear: CAL-6843
When managed users create or receive bookings, their emails were being returned with an internal OAuth client ID suffix (e.g., bob+cuid123@example.com). This suffix is used internally for user identification but should not be exposed in API responses.
Changes:
- Add cleanOAuthEmailSuffix() helper using CUID regex pattern
- Clean email suffix in hosts[], attendees[], bookingFieldsResponses.email, bookingFieldsResponses.guests[], and reassignedTo.email
- Pattern consistent with google-calendar.service.ts implementation
Affected output methods:
- getOutputBooking
- getOutputRecurringBooking
- getOutputSeatedBooking
- getOutputRecurringSeatedBooking
- getOutputReassignedBooking
- getHost
* refactor(api): preserve original email, add displayEmail field
Per team discussion, keep original email unchanged to avoid breaking changes for platform customers.
Add displayEmail field with CUID suffix removed for display purposes
* feat(api): add displayEmail to booking output DTOs
Add displayEmail property to BookingAttendee, BookingHost and ReassignedToDto for API documentation and type safety
* test(api): add e2e tests for displayEmail fields in managed user bookings
Add tests to verify that displayEmail fields correctly strip CUID suffix from OAuth managed user emails in booking API responses:
- Test host displayEmail returns email without CUID suffix
- Test attendee displayEmail returns email without CUID suffix
- Test bookingFieldsResponses.displayEmail returns clean email
- Test displayGuests array returns emails without CUID suffix
* false positive breaking change
* false positive breaking change
* test(api): update existing e2e tests to expect displayEmail field
* fix(api): add missing displayEmail to seated booking test assertions
The seated booking tests were missing displayEmail in the attendee
assertions for the second booking test and cancel-as-host test,
causing CI test failures
---------
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
* refactor: Extract schedule determination to seperate fn
* refactor: Extract schedule detection to seperate file and add tests
* RouterOutputs should be used in hooks, not direct type imports
When a user signs up to a team/org from onboarding v3, the subscription
now includes source: 'onboarding' in its metadata. This helps track
which subscriptions originated from the onboarding flow.
Changes:
- Add source: 'onboarding' to subscription_data.metadata in team checkout
when isOnboarding is true
- Add source: 'onboarding' to subscription metadata for organization
onboarding flow
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
* fix: mock CRM services to prevent test flakes in handlePaymentSuccess.test.ts
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: add global CRM services mock to prevent test flakes
The test flakes were caused by the Salesforce CRM service importing @urql/core,
which triggers fetch calls during module loading. These fetch calls remain
pending when the Vitest worker shuts down, causing the error:
'[vitest-worker]: Closing rpc while fetch was pending'
This fix adds a global mock for CrmServiceMap in setupVitest.ts, similar to
how payment services are already mocked. This prevents the Salesforce module
from being loaded during test execution.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Add logging
* fix: Add response status checking to MS Teams adapter error handling
- Add response.ok checks before parsing JSON in createMeeting and updateMeeting
- Remove console.log statements that could leak credential information
- Ensure error handling matches original handleErrorsRaw behavior for tests
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Fix logs
* Revert "fix: Add response status checking to MS Teams adapter error handling"
This reverts commit 35820d21e1a54d9e04d83fd5f53584d64a5459b6.
* fix: Add response status checking to MS Teams adapter error handling
- Check response.ok before parsing JSON in createMeeting and updateMeeting
- Re-throw HttpError instances instead of wrapping them in catch blocks
- This ensures HTTP errors (like 500) are properly propagated
Co-Authored-By: unknown <>
* fix: Correct log message in updateMeeting to say 'updating' instead of 'creating'
Co-Authored-By: unknown <>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
The integration tests were flaky because they relied on a shared booking
created in beforeAll, which could cause race conditions when tests run
in parallel or when cleanup from previous runs interfered.
Changes:
- Use seed user (member0-acme@example.com) when available, fallback to
creating a test user for local development
- Create a fresh booking in beforeEach instead of sharing one across tests
- Track created bookings and clean them up properly in afterEach
- Fix import organization to satisfy linter
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The integration tests were flaky because they used fixed identifiers
(email, username, uid) that could conflict across parallel test runs
or with leftover data from previous runs.
Changes:
- Add unique testRunId using timestamp and random suffix
- Use testRunId in email, username, and booking uid
- Change afterAll cleanup to use deleteMany instead of delete to
prevent failures when records are already deleted
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor: move WebWrapper files from packages/platform to apps/web/modules
Move the following WebWrapper files to their appropriate locations in apps/web/modules:
- EventTypeWebWrapper and related tab wrappers to apps/web/modules/event-types/components/wrappers/
- BookerWebWrapper to apps/web/modules/bookings/components/
- ConferencingAppsViewWebWrapper to apps/web/modules/apps/components/
- SelectedCalendarsSettingsWebWrapper to apps/web/modules/calendars/components/
- AddMembersWithSwitchWebWrapper to apps/web/modules/event-types/components/
This reduces the number of files in packages/platform that import from @calcom/web,
improving the separation between platform and web-specific code.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: move web-specific hooks to apps/web and update imports
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix
* fix
* fix
* fix
* fix
* fix
* fix
* fix
* add back comments
* fix
* fix
* fix
* fix
* fix: correct relative import paths in moved WebWrapper files
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* final
* fix: use package alias for event-type hooks instead of deeply nested relative paths
- Move sortHosts function to @calcom/lib/bookings/hostGroupUtils.ts for shared access
- Add exports for useEventTypeForm, useHandleRouteChange, useTabsNavigations to @calcom/atoms package.json
- Update EventTypeWebWrapper.tsx to use @calcom/atoms package alias instead of ../../../../../packages/... paths
- Update useEventTypeForm.ts to import sortHosts from @calcom/lib instead of @calcom/web
- Re-export sortHosts from HostEditDialogs.tsx for backward compatibility
This addresses the Cubic AI review feedback about fragile deeply nested relative paths that bypass proper package resolution.
Co-Authored-By: unknown <>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Make and instance method
* Refactor files
* fix: update MembershipRepository mocks to use vi.hoisted() for proper hoisting
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: cursor visibility in input fields
* fix: cursor visibility in input fields with suffix addons
* fix: text cursor visibility in input fields
---------
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
* fix(auth): sanitize unverified accounts during OAuth linking
- Add AccountSanitizationService for secure account cleanup
- Clear webhooks, API keys, credentials, and sessions for unverified accounts
- Reset password and 2FA settings during OAuth conversion
- Nullify redirect URLs on event types
Only affects accounts that never completed email verification
* fix(auth): block OAuth linking for unverified accounts
Replace sanitization with simpler blocking approach:
- Unverified CAL accounts cannot link to OAuth (Google/SAML)
- Add user-friendly error message with recovery path
- Remove AccountSanitizationService (no data loss risk)
## What does this PR do?
Adds audit logging for the reschedule request flow. When an organizer requests an attendee to reschedule a booking, this action is now logged to the booking audit system.
This is part of the booking audit integration effort, following the pattern established in PR #26046 (booking creation/rescheduling audit) and PR #26458 (cancellation audit).
## Changes
- Added audit logging call to `requestReschedule.handler.ts` using `BookingEventHandlerService.onRescheduleRequested()`
- Captures audit data:
- `rescheduleReason`: The reason provided for requesting the reschedule (nullable string)
- `rescheduledRequestedBy`: Email of the user who requested the reschedule
- Uses `makeUserActor(user.uuid)` to identify the actor performing the action
- Added required `source` parameter for action source tracking (passed as `"WEBAPP"` from tRPC router)
- Updated `RescheduleRequestedAuditActionService` schema to use simpler field structure
- Updated test helper `getTrpcHandlerData` to pass `source: "WEBAPP"` parameter
## Updates since last revision
- Changed `source` parameter from optional with default to required - tests now explicitly pass `source: "WEBAPP"` instead of relying on a default value
## Mandatory Tasks (DO NOT REMOVE)
- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. N/A - follows established audit pattern with existing infrastructure tests.
## How should this be tested?
1. Log in as a user with a booking
2. Navigate to the booking and click "Request Reschedule"
3. Provide a reschedule reason and submit
4. Verify the audit log is created with the correct data (requires access to audit log storage/database)
The audit logging follows the same pattern as other booking audit integrations, so if those are working, this should work as well.
## Checklist
- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings
---
**Link to Devin run**: https://app.devin.ai/sessions/ae84d093c4594a5d89b88c45639a6a06
**Requested by**: @hariombalhara
## Human Review Checklist
- [ ] Verify the audit data schema matches `RescheduleRequestedAuditActionService` expectations (fields: `rescheduleReason`, `rescheduledRequestedBy`)
- [ ] Confirm the schema change from change-based fields (`{ old, new }`) to simple nullable strings is intentional
- [ ] Confirm `user.uuid` is available in the tRPC session context
- [ ] Note: API v2 does not have a reschedule request endpoint, so no API v2 changes are needed
* 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
* 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>
* 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>
* 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>
* 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.