Commit Graph
1010 Commits
Author SHA1 Message Date
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ee076d7102 perf: add composite index on EventType(parentId, teamId) (#27099)
* perf: add composite index on EventType(parentId, teamId)

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

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 06:43:05 -03:00
+1
Peer RichelsenGitHublauris@cal.com <lauris@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>eunjae@cal.com <hey@eunjae.dev>Lauris Skraucissupalarrycubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>CarinaWollilauris@cal.com <lauris@cal.com>Morgan
a03722fd7f feat: add OAuth client developer settings page with approval workflow (#25556)
* feat: add OAuth client developer settings page with approval workflow

- Add new developer OAuth page at /settings/developer/oAuth for users to submit OAuth client requests
- Transform admin OAuth page into management dashboard for reviewing/approving submissions
- Add OAuthClientApprovalStatus enum (PENDING, APPROVED, REJECTED) to track submission status
- Add userId and createdAt fields to OAuthClient model for tracking submissions
- Create email notifications for admin (new submission) and user (approval)
- Add sidebar navigation link in developer section below API keys
- Add comprehensive translations for new UI strings
- Create OAuthClientRepository for data access following repository pattern

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

* fix: re-export generateSecret for backward compatibility

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

* feat: make logo mandatory and list items clickable for OAuth clients

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

* fix: add missing translation keys and remove client secret from details dialog

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

* fix: address cubic AI reviewer comments

- Remove duplicate 'there' JSON key in common.json
- Add select clause to findByUserId to avoid exposing clientSecret
- Add @@index([userId]) to OAuthClient model for query performance
- Update migration to include the index

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

* fix: address PR review comments - fix indentation and use useCopy hook

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

* fix: change react-dom/server import to fix Turbopack compatibility

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

* Revert "fix: change react-dom/server import to fix Turbopack compatibility"

This reverts commit c3e0b709c2d88fd221143cb4ce9cd25bb8c94277.

* fix: use email service pattern for OAuth client notifications

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

* fix: add try-catch around email sending to handle Turbopack react-dom/server issue

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

* Revert "fix: add try-catch around email sending to handle Turbopack react-dom/server issue"

This reverts commit fc9d47cd773505ebc5ee2696718aad4a8a98be77.

* fix: improve OAuth client UI with skeleton loaders and smaller dialog styling

- Replace 'Loading...' text with proper skeleton loaders in both developer and admin OAuth client views
- Make client_id and copy button smaller in dialogs using size='sm' and text-sm styling
- Add 'client_id' translation key to common.json for proper i18n

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

* fix: improve skeleton loader to match actual OAuth client list structure

- Remove divide-y from container and use conditional border-b on rows
- Match the exact structure from oauth-clients-view.tsx L126-160
- Use proper spacing for text elements (mt-1 instead of space-y-2)

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

* fix skeleton

* rename the selected oauth client dialog

* fix: address PR feedback - admin auth, dropdown styling, sidebar label

- Add defense-in-depth admin authorization check in updateClientStatus handler
- Fix broken dropdown menu by using DropdownItem with StartIcon prop
- Fix sidebar menu label from 'oAuth' to 'oauth_clients' to match developer view

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

* update common.json

* feat: show client secret in approval email for confidential OAuth clients

- Add regenerateSecret method to OAuthClientRepository
- Regenerate secret when admin approves a PENDING confidential client
- Include client secret in approval notification email
- Add one-time warning message about storing the secret securely
- Only regenerate on first approval (not re-approvals)

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

* feat: add Website URL field, fix logo styling, show client secret after approval

- Add Website URL field to OAuth client forms (admin and developer views)
- Fix Upload Logo section styling by wrapping in Label div with proper gap
- Display client secret in dialog after admin approves a confidential OAuth client
- Add websiteUrl field to Prisma schema with migration
- Update tRPC handlers and repository to support websiteUrl
- Add translation keys for new UI elements

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

* fix: move clientSecret variable declaration outside if block for proper scoping

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

* refactor: dont expose client secret in emails

* refactor: dont regenerate secret upon status change

* refactor: reuse existing hash function

* refactor: rename admin/oAuth to admin/oauth page

* refactor: deduplicate oauth repositories

* refactor: remove withGlobalPrisma from oauth repository

* refactor: developer oauth page

* refactor: oauth status by default accepted

* refactor: request oauth status when creating

* refactor ux

* fix: address Cubic AI code review feedback

- Add purpose field to plain text email body for accessibility
- Convert NewOAuthClientButton to inline JSX to avoid React anti-pattern
- Trigger re-approval when redirectUri changes for security
- Add e.preventDefault() for Space key to prevent page scroll
- Change default approvalStatus to PENDING for defense-in-depth
- Use oauth_clients translation key for consistency
- Add meaningful alt text to Avatar for accessibility
- Remove onClick from DialogClose to prevent double-run close effects
- Return NOT_FOUND for non-owner delete to prevent resource enumeration

Co-Authored-By: unknown <>

* common.json file

* refactor: delete all prisma migrations

* refactor: have just 1 prisma migration

* revert: some devin changes

* fix: typecheck

* test: owner OAuth crud

* test: admin OAuth approval / rejection

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

- schema.prisma: Remove @default("") from purpose field to make it required
- schema.prisma: Use UTC-aware timezone expression for createdAt default
- OAuthClientFormFields.tsx: Localize redirect URI placeholder using t()
- common.json: Add redirect_uri_placeholder translation key

Co-Authored-By: unknown <>

* cubic changes

* refactor: dont log sensitive info and rethrow error

* cubic feedback

* refactor: make oauth client purpose optional

* refactor: admin/oauth not allowed if not logged in

* refactor: admin view skeleton

* refactor: rename state

* refactor: get rid of redundant mapping

* refactor: remove redundant handler

* refactor: remove redundant handler

* refactor: re-usable new oauth client button

* refactor: dialogs

* refactor: modals

* refactor: handler names, dialog, skeleton

* fix: purpose being null

* refactor: rename handler and delete old oauth admin page

* fix: purpose in submission

* refactor: handler names

* refactor: rename

* refactor: update handler

* refactor: rename approvalStatus -> status

* refactor: simplify modal

* refactor: name

* dont require repproval if redirectUri changes

* fix: remove integration sync index creation

* refactor: require re-approval if redirectUri updated

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: remove duplicate common.json keys

* refactor: replace team@cal.com with SUPPORT_MAIL_ADDRESS

* refactor: generate client secret on handler level

* fix: authorization code only available to approved clients

* refactor: cubic review dont display exclamation

* refactor: cubic review website_url in common json

* fix: dont default in ui to approved status

* refactor: optiona logo in schema create handler

* fix: tests

* fix: tests

* fix: /authorize redirect if client not approved or show error

* test: authorize page with invalid client id

* refactor: dont allow refreshing tokens unless approved client

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* chore: warn that pending client is not usable

* fix: approve and reject buttons

* fix: /authorize show error if client not approved

* refactor: info message about editing oauth client and status

* change info alert to warning

* try to fix ci test

* debug: failing e2e test

* fix: improve session propagation in oauth-client-admin E2E test

- Add navigateToAdminOAuthPage helper that waits for listClients API call
- If the API call doesn't arrive (session issue), reload page to force session refresh
- This fixes the CI flakiness where admin page wasn't loading due to session not having ADMIN role

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

* fix: register waitForResponse before navigating in E2E test

- Register the listClients waitForResponse promise BEFORE page.goto()
- This ensures the response isn't missed during page load
- Also register the promise before reload in the catch block

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

* fix: rename oAuth folder to oauth for case-sensitive filesystems

The admin OAuth page route was at /settings/admin/oAuth (capital A) but the
code references /settings/admin/oauth (lowercase). This caused 404 errors
on case-sensitive filesystems (Linux).

Also improved the E2E test navigation helper to retry with delays if the
admin page doesn't load immediately, handling session propagation timing.

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

* test style

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: eunjae@cal.com <hey@eunjae.dev>
Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: lauris@cal.com <lauris@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-21 12:23:51 -03:00
devin-ai-integration[bot]GitHubali@cal.com <ali@cal.com>ali@cal.com <ali@cal.com>unknown <>ali@cal.com <ali@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>ali@cal.com <ali@cal.com>Syed Ali Shahbaz
cb567a91c5 feat: add option to hide duration selector in booking page for multiple durations (#27033)
* feat: add option to hide duration selector in booking page for multiple durations

- Add 'hideDurationSelectorInBookingPage' field to event type metadata schema
- Add checkbox under Default Duration select in event type settings
- Modify Duration component to hide selector when setting is enabled
- URL params can still set duration when selector is hidden
- Add i18n translation for the new checkbox label
- Add e2e tests for the new functionality

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

* fix: rename checkbox label to 'Hide duration selector'

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

* fix: replace text locator with data-testid in E2E test

Replace `text=Multiple duration` locator with `page.getByTestId("event-types").locator('a[title="Multiple duration"]')` to follow E2E test best practices.

Co-Authored-By: unknown <>

* fix: add data-testid to hide duration selector checkbox for E2E tests

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2026-01-21 10:39:36 +02:00
Volnei MunhozandGitHub 5ddb4dce3f Add calendar subscription error better management (#27019) 2026-01-20 18:47:03 +02:00
sean-brydonandGitHub e0c637b8ec feat: add seat tracking infrastructure for monthly proration (#27001)
Part 1 of monthly proration feature.

Adds seat change tracking infrastructure with operationId for idempotency.

**Dependency chain:**
- This PR (seat tracking)
- PR #27002  depends on this
2026-01-19 13:56:30 +00:00
Joe Au-YeungandGitHub 40a7f53d1f Add IF NOT EXISTS (#26893) 2026-01-15 16:46:09 +00:00
Joe Au-YeungandGitHub adb7509d96 Rename migration file (#26889) 2026-01-16 01:06:19 +09:00
Joe Au-YeungGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Hariom Balharacubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
6501743e5e feat: Add attribute sync logic from Salesforce (#26517)
* Add db schema

* Add `CredentialRepository.findByTeamIdAndSlugs`

* Add enabled app slugs for attribute syncing

* Create repository for `IntegrationAttributeSync`

* Create zod schemas

* Create `AttributeSyncUserRuleOutputMapper`

* Create `IntegrationAttributeSyncService`

* Create DI contianer

* Create trpc endpoints

* Create page

* Include team name in `CredentialRepository.findByTeamIdAndSlugs`

* Update schema and relations

* Update types and schemas

* Add more methods to IntegrationAttributeSyncRepository

* Add more services to `IntegrationAttributeSyncService`
- getById
- Init updateIncludeRulesAndMappings

* Refactor `getTeams.handler` to use repository

* Create `createAttributeSync` trpc endpoint

* Create `updateAttributeSync` trpc endpoint

* Add router to trpc

* Create attribute sync child components

* Pass custom actions to `FormCard`

* Create `IntegrationAttributeSyncCard`

* Pass inital props via server side

* Fix prop

* Only refetch on mutation

* Fixes

* Add form error when duplicate field and attribute combo

* Add `updateTransactionWithRUleAndMappings` logic

* Adjust zod schemas

* Service add `updateIncludeRulesAndMappings`

* Pass orgId from server to component

* Rename types

* Add deleteById method to repository

* Add name to integrationAttributeSync

* Add deleteById method to service

* Rename method

* Add deleteAttributeSync trpc endpoint

* Make the IntegrationAttributeSyncCard a dummy component

* test: add tests for IntegrationAttributeSync feature

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

* Move creating a attribute sync record to the service

* Add i18n strings

* Safe select credential in find by id and team

* Fix default credentialId value in form

* Update repository return types

* Add i18n string

* Make credentialId optional for form schema

* Fix label

* Add cascade deletes

* Add verification that syncs belong to org

* Create mapper for repository output

* Type fixes

* Remove old test file

* Pass `attributeOptions` from parent to children

* Infer types from zod schema

* Type fixes

* Type fix

* Clean up

* Add i18n strings

* Remove unused file

* Address feedback

* Add migration file

* Address feedback

* Add validation for new integration values

* Remove unused router

* Move away from z.infer to z.ZodType

* Clean up comments

* Type fix

* Type fixes

* Type fix

* fix: add passthrough to syncFormDataSchema to preserve extra fields

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

* fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema

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

* Add endpoint for SF to call

* Create scratch org config

* Create sf cli scripts

* Create package logic

* Update README

* Remove unused file

* Add indexes

* Add aria label

* Address feedback - consistent validation

* Fix import paths for attribute types

* Add `CredentialRepository.findByAppIdAndKeyValue`

* Get credential by instance URL

* Verify incoming sfdc orgId matches credential sfdc orgId

* Rename method

* Get user name integration syncs

* refactor: change attributeSyncRules array to singular attributeSyncRule

The database schema enforces a one-to-one relationship between
IntegrationAttributeSync and AttributeSyncRule (via @unique constraint),
and the UI only supports a single rule. This change makes the TypeScript
type match the database schema and UI behavior.

Changes:
- Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null
- Update mapper to return singular rule instead of wrapping in array
- Update UI component to access sync.attributeSyncRule directly
- Update IIntegrationAttributeSyncUpdateParams Omit type
- Update tests to use attributeSyncRule: null instead of attributeSyncRules: []

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

* Convert `membershipRepository.findAllByUserId` to a normal method

* Add temp files to git ignore

* Init  and process team conditions

* Biome formatting

* Add `AttributeService` to get user attributes

* Add DI container for AttributeService

* AttributeSyncService evaluate attribute conditions

* Create DI container for attributeSyncService

* Return result for full condition

* Evaluate if attribute sync should apply to user

* Add  method

* Change PrismaAttributeOptionRepository to instance methods

* Init AttributeSyncFieldMappingsService and process attribute syncs

* Add AttributeSyncFieldMappingService DI container

* Refactor orgId to organizationId

* Add membership validation to sync field service

* AttributeSYncFieldMappingService use repository methods

* AttributeSyncFieldMappingService.processMappings add mapping logic

* Add DI tokens

* user-sync endpoint to implement attribute syncing

* Validate team belongs to org for rule

* test: add tests for AttributeSyncRuleService, AttributeSyncFieldMappingService, and AttributeService

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

* Remove duplicate migration file

* Fix merge conflict

* fix: resolve type errors in attribute sync feature (#26814)

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

* Rename  variable

* Fix log typo

* Fix file name

* Add error logging

* Use credential teamId

* fix: add missing mockTeamRepository and team validation to tests

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

* Fix naming

* Fix file import

* Type fix

* Pass MembershipRepository as a dep in AttributeSyncFieldMappingService

* Type fix

* fix: add mockMembershipRepository to AttributeSyncFieldMappingService tests

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

* Update packages/app-store/salesforce/api/user-sync.ts

Add error handling when getting orgId from stored salesforce id

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

* fix: address Cubic code review comments

- PrismaAttributeRepository: use nested select instead of include: true for options
- CredentialRepository: use this.primaClient instead of global prisma, use select instead of include for relations
- AttributeSyncFieldMappingService: optimize O(n*m) complexity with Map lookup for O(1) access

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

* Fix typo in CredentialRepository

* Update README

* Update sfdx-project

* Add SFDC package tests

* fix: improve Salesforce Apex test assertions to verify actual behavior

- Enhanced CalComHttpMock to track HTTP callout invocations and capture requests
- Updated UserUpdateHandlerTest to verify HTTP callouts are made with correct data
- Updated CalComCalloutQueueableTest to verify HTTP callouts are made correctly
- Replaced System.assert(true, ...) with meaningful assertions that verify:
  - Correct number of HTTP callouts
  - Request body contains expected fields
  - Request method is POST

Addresses Cubic AI review feedback (confidence 9/10 issues only)

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-15 09:19:57 -05:00
Joe Au-YeungandGitHub d04bc970e0 Add missing migration (#26799) 2026-01-15 13:49:40 +02:00
2881961859 feat: add custom calendar reminder for Google Calendar events (#26078)
* feat: add custom calendar reminder for Google Calendar events

Allows users to set default reminder notifications (10, 30, or 60 minutes)
for events created via Cal.com bookings in Google Calendar. This addresses
the issue where Google Calendar's default reminders don't apply to
API-created events.

- Add customCalendarReminder field to DestinationCalendar model
- Create reminder selector UI in destination calendar settings
- Update GoogleCalendarService to apply custom reminders (popup + email)
- Add TRPC endpoint for updating reminder settings

* fix: address code review feedback

- Use z.union with literal values (10, 30, 60) for stricter schema validation
- Add localization for toast messages using t()
- Fix test data to use null for customCalendarReminder to match test intent

* fix: add customCalendarReminder to DestinationCalendar types

Update manually-defined DestinationCalendar types to include the new
customCalendarReminder field added in the previous commit. This fixes
type mismatches when passing Prisma-persisted destination calendars to
functions using these local type definitions.

* fix: update customCalendarReminder type in test to match Prisma schema

The customCalendarReminder field is defined as a non-nullable Int with
default value of 10 in the Prisma schema. Changed test value from null
to 10 to fix TS2345 type error.

* feat: add 'just in time' reminder option for Google Calendar events

- Add 0 (just in time) as a valid reminder option alongside 10, 30, 60 minutes
- Update TRPC schema to accept 0 as valid reminder value
- Add 'Just in time' option to reminder dropdown selector UI
- Add translation for 'just_in_time' key in English locale
- Include comprehensive test case for 0-minute (just in time) reminders
- Remove unused import from test file

This addresses reviewer feedback to provide flexible 'just in time' option that allows reminders to fire at exact event start time.

🤖 Generated with Claude Code

* fix: add customCalendarReminder to calendars service mock

- Add missing customCalendarReminder field to destination calendar mock
- Matches the Prisma schema requirement
- Fixes type error in calendars controller e2e test

* fix: add customCalendarReminder to destination calendars controller test

- Add missing customCalendarReminder field to mock destination calendar
- Matches Prisma schema requirement
- Fixes type error in destination-calendars controller e2e test

* fix: cast customCalendarReminder to ReminderMinutes type

- Add type cast for reminderValue to ensure type safety
- Use nullish coalescing (??) to preserve 0 as valid reminder value
- Ensures database number type is properly cast to ReminderMinutes union

* refactor: simplify translation logic in DestinationReminderSelector

- Remove conditional check for 'just_in_time' label
- Pass count parameter to all translations uniformly
- Translation function handles unused parameters gracefully

Addresses review feedback from @Khaan25

* refactor: make custom calendar reminder opt-in and use repository pattern

- Change default from 10 to null (opt-in feature)
- Add DestinationCalendarRepository to avoid direct Prisma usage
- Add 'Use default reminders' option to UI

* refactor: remove redundant migration file

The original migration already creates customCalendarReminder as nullable,
so this second migration to make it nullable is not needed.

* fix: type error for customCalendarReminder in destination calendar settings

* refactor: validate customCalendarReminder with Zod schema instead of type casting

* refactor: use instance methods in DestinationCalendarRepository

Changed from static to instance methods with getInstance() pattern as requested in review.

* refactor: replace singleton with DI for DestinationCalendarRepository

- Remove getInstance() singleton pattern
- Add DI tokens, module, and container
- Update GoogleCalendarService and tRPC handler to use DI

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2026-01-14 12:32:00 +01:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
75d611c2e8 chore: Integrate creation/rescheduling booking audit for Recurring/regular booking/seated bookings (#26046)
* Integrate creation/rescheduling booking audit

* fix: add missing hostUserUuid to booking audit test data

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

* fix-ci

* feat: enhance booking audit with seat reference

- Added support for seat reference in booking audit actions.
- Updated localization for booking creation to include seat information.
- Modified relevant services to pass attendee seat ID during booking creation.

* fix: update test data to match schema requirements

- Add seatReferenceUid: null to default mock audit log data
- Add seatReferenceUid: null to multiple audit logs test case
- Convert SEAT_RESCHEDULED test data to use numeric timestamps instead of ISO strings

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

* Allow nullish seatReferenceUid

* feat: enhance booking audit to support rescheduledBy information

- Updated booking audit actions to include rescheduledBy details, allowing tracking of who rescheduled a booking.
- Refactored related services to accommodate the new rescheduledBy parameter in booking events.
- Adjusted type definitions and function signatures to reflect the changes in the booking audit context.

* Avoid possible run time issue

* Fix imoport path

* fix failing test due to merge from main\

* Pass useruuid

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 13:16:16 +00:00
Eunjae LeeGitHubeunjae@cal.com <hey@eunjae.dev>eunjae@cal.com <hey@eunjae.dev>eunjae@cal.com <hey@eunjae.dev>eunjae@cal.com <hey@eunjae.dev>eunjae@cal.com <hey@eunjae.dev>eunjae@cal.com <hey@eunjae.dev>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
829d6c4714 feat(pbac): add FeatureOptIn resource to permission registry (#26761)
* feat(pbac): add Feature resource to permission registry

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

* feat(pbac): add migration for Feature resource permissions

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

* feat(pbac): add English translations for Feature resource

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

* feat(pbac): update Feature resource for opt-in/opt-out control (read and update only)

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

* feat(pbac): rename Feature to FeatureOptIn resource

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

* feat(pbac): simplify update description text

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 10:17:41 +00:00
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Eunjae Lee
8dbe3848e7 feat: Create Integration Attribute Sync records (#26007)
* Add db schema

* Add `CredentialRepository.findByTeamIdAndSlugs`

* Add enabled app slugs for attribute syncing

* Create repository for `IntegrationAttributeSync`

* Create zod schemas

* Create `AttributeSyncUserRuleOutputMapper`

* Create `IntegrationAttributeSyncService`

* Create DI contianer

* Create trpc endpoints

* Create page

* Include team name in `CredentialRepository.findByTeamIdAndSlugs`

* Update schema and relations

* Update types and schemas

* Add more methods to IntegrationAttributeSyncRepository

* Add more services to `IntegrationAttributeSyncService`
- getById
- Init updateIncludeRulesAndMappings

* Refactor `getTeams.handler` to use repository

* Create `createAttributeSync` trpc endpoint

* Create `updateAttributeSync` trpc endpoint

* Add router to trpc

* Create attribute sync child components

* Pass custom actions to `FormCard`

* Create `IntegrationAttributeSyncCard`

* Pass inital props via server side

* Fix prop

* Only refetch on mutation

* Fixes

* Add form error when duplicate field and attribute combo

* Add `updateTransactionWithRUleAndMappings` logic

* Adjust zod schemas

* Service add `updateIncludeRulesAndMappings`

* Pass orgId from server to component

* Rename types

* Add deleteById method to repository

* Add name to integrationAttributeSync

* Add deleteById method to service

* Rename method

* Add deleteAttributeSync trpc endpoint

* Make the IntegrationAttributeSyncCard a dummy component

* test: add tests for IntegrationAttributeSync feature

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

* Move creating a attribute sync record to the service

* Add i18n strings

* Safe select credential in find by id and team

* Fix default credentialId value in form

* Update repository return types

* Add i18n string

* Make credentialId optional for form schema

* Fix label

* Add cascade deletes

* Add verification that syncs belong to org

* Create mapper for repository output

* Type fixes

* Remove old test file

* Pass `attributeOptions` from parent to children

* Infer types from zod schema

* Type fixes

* Type fix

* Clean up

* Add i18n strings

* Remove unused file

* Address feedback

* Add migration file

* Address feedback

* Add validation for new integration values

* Remove unused router

* Move away from z.infer to z.ZodType

* Clean up comments

* Type fix

* Type fixes

* Type fix

* fix: add passthrough to syncFormDataSchema to preserve extra fields

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

* fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema

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

* Add indexes

* Add aria label

* Address feedback - consistent validation

* Fix import paths for attribute types

* refactor: change attributeSyncRules array to singular attributeSyncRule

The database schema enforces a one-to-one relationship between
IntegrationAttributeSync and AttributeSyncRule (via @unique constraint),
and the UI only supports a single rule. This change makes the TypeScript
type match the database schema and UI behavior.

Changes:
- Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null
- Update mapper to return singular rule instead of wrapping in array
- Update UI component to access sync.attributeSyncRule directly
- Update IIntegrationAttributeSyncUpdateParams Omit type
- Update tests to use attributeSyncRule: null instead of attributeSyncRules: []

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

* feat: implement FeatureOptInService (#25805)

* feat: implement FeatureOptInService WIP

* clean up

* feat: consolidate feature repositories and add updateFeatureForUser

- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository

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

* refactor: rename updateFeatureForUser to setUserFeatureState

Rename to match the convention used for setTeamFeatureState

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

* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState

* fix integration tests

* clean up logics

* update services and router

* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array

- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query

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

* feat: add getFeatureStateForTeams for batch querying multiple teams

- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method

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

* refactor: combine org and team state queries into single call

- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams

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

* refactor: use team.isOrganization and clarify computeEffectiveState comment

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

* refactor: use MembershipRepository.findAllByUserId with isOrganization

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

* feat: add featureId validation using isOptInFeature type guard

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

* less queries

* add fallback value

* fix type error

* move files

* add autoOptInFeatures column

* use autoOptInFeatures flag within FeatureOptInService

* add setUserAutoOptIn and setTeamAutoOptIn

* fix computeEffectiveState logic

* rewrite computeEffectiveState

* clean up integration tests

* clean up in afterEach

* fix type error

* refactor: use FeaturesRepository methods instead of direct Prisma calls

Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.

Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts

This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).

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

* clean up

* fix the logic

* extract some logic into applyAutoOptIn()

* remove wrong code

* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union

- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests

* fix type error

* use Promise.all

* fix

---------

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

* Prevent duplicate field and attribute mappings

* Add validation that attribute belongs to the org

* fix: address Cubic AI review feedback

- Add @@index([credentialId]) to IntegrationAttributeSync model for efficient cascade deletes and credential-based queries (confidence: 9/10)
- Fix translation key from 'credential_required' to 'attribute_sync_credential_required' to match existing locale definition (confidence: 10/10)

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

* fix: address remaining cubic review feedback

- RuleBuilder.tsx: Use unique IDs for React keys instead of array index to prevent reconciliation bugs when removing conditions
- updateAttributeSync.handler.ts: Add early organization check before service calls for consistency
- createAttributeSync.handler.ts: Add CredentialNotFoundError class for type-safe error handling instead of string matching
- IntegrationAttributeSyncService.test.ts: Replace expect.fail() with proper Vitest rejects.toSatisfy() pattern

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

* Pull test file from main

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2026-01-12 22:57:28 +00:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
77f59b1e4d chore: Integrate confirmation booking audit (#26523)
* chore: Integrate booking confirmation booking audit

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

* fix: Use BookingStatus type instead of string for booking.status

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

* Make booking-audit integration test utils reusable

* refactor: enhance handlePaymentSuccess to accept appSlug and actor identification

- Updated handlePaymentSuccess function to accept an object with paymentId, bookingId, appSlug, and traceContext.
- Introduced getActor function to determine the actor based on appSlug and credentialId.
- Modified webhook handlers for Alby, BTCPayServer, HitPay, PayPal, and Stripe to pass the new parameters.
- Improved logging for missing credentialId in payment processing.
- Adjusted related schemas to ensure proper type handling for booking status and actor identification.

* fix: Correct import paths and getActor function call

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

* fix: Use ActorIdentification type instead of AuditActor in getActor

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

* fix: Add guard clause for undefined actor in fireBookingAcceptedEvent

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

* fix: Add actionSource to all confirm calls

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

* refactor: Integrate actor identification and action source updates across booking services

- Added `makeUserActor` to various booking service files to enhance actor identification.
- Updated action source handling in booking confirmation and related functions to include "MAGIC_LINK".
- Refactored schemas to accommodate new actor and action source requirements, ensuring consistent type handling.
- Improved error handling and logging for booking actions to enhance traceability.

* Remvoe formatting changes

* Add test

* refactor: Enhance booking confirmation tests and event handling

- Updated `confirm.handler.test.ts` to improve test coverage for booking acceptance and rejection scenarios, including bulk bookings.
- Refactored the mock implementation of `BookingEventHandlerService` to streamline event handling for accepted and rejected bookings.
- Adjusted the `handleConfirmation` function to utilize `acceptedBookings` for better clarity and maintainability.
- Added tests to ensure correct invocation of event handler methods for both single and bulk booking confirmations and rejections.

* fix tests

* refactor: Use confirmHandler directly in link and verify-booking-token routes

Refactors the link and verify-booking-token API routes to call confirmHandler directly instead of using the tRPC caller pattern. This simplifies the code by removing the need for session getter, legacy request building, and context creation.

Changes:
- apps/web/app/api/link/route.ts: Use confirmHandler directly with ctx and input
- apps/web/app/api/verify-booking-token/route.ts: Use confirmHandler directly with ctx and input
- Updated tests to mock confirmHandler instead of tRPC caller

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

* fix ts errors due to merge frommain

* feat: introduce getAppActor utility for actor creation

This commit adds a new utility function, getAppActor, to streamline the process of creating actor objects for apps based on their slug and credential ID. The function is integrated into handlePaymentSuccess and handleStripePaymentSuccess, replacing the previous inline actor creation logic. This refactor enhances code maintainability and readability by centralizing actor creation logic.

Changes:
- New file: packages/app-store/_utils/getAppActor.ts
- Updated handlePaymentSuccess and handleStripePaymentSuccess to use getAppActor
- Removed redundant actor creation code from these functions

* refactor: Update appSlug in payment success handlers to use appConfig.slug

This commit modifies the appSlug parameter in the handlePaymentSuccess function across multiple payment webhook handlers to utilize the appConfig.slug value instead of hardcoded strings. This change enhances consistency and maintainability of the code.

Changes:
- Updated appSlug in handlePaymentSuccess for btcpayserver, hitpay, and paypal webhooks.
- Adjusted a test case to reflect the new appSlug value for consistency.

* test: Enhance booking token verification and audit action tests

This commit adds additional assertions to the booking token verification tests to ensure that the confirmHandler is not called when an error occurs. It also introduces a mechanism to clean up additional booking UIDs after each test in the accepted action integration tests, improving test reliability. Furthermore, it updates the action source schema comment for clarity.

Changes:
- Updated tests in `verify-booking-token` to check that `mockConfirmHandler` is not called on error.
- Implemented cleanup logic for additional booking UIDs in `accepted-action.integration-test.ts`.
- Clarified comment in `actionSource.ts` regarding the schema for action sources.
- Refactored `handleConfirmation.ts` and `confirm.handler.ts` to include tracing logger for error handling in booking events.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 08:17:26 -03:00
sean-brydonGitHubunknown <>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>Anik Dhabal BabuDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Keith Williams
ac90caa81b feat: add DAL for monthly proration tracking (#26588)
* feat(billing): add database schema for monthly proration tracking

add new database models and migration for tracking seat changes and monthly proration on annual subscriptions

- new models: SeatChangeLog, MonthlyProration
- new enums: SeatChangeType, ProrationStatus
- extend TeamBilling and OrganizationBilling with billingPeriod, pricePerSeat, paidSeats fields
- add feature flag 'monthly-proration' (disabled by default)
- squashed migration: 20260106093811_add_monthly_proration_tracking

the schema supports:
- tracking seat additions/removals per month with metadata
- storing proration calculations and stripe invoice details
- high-water mark billing via paidSeats field
- proper foreign key relationships and indexes for query performance

* feat(billing): add repository layer for monthly proration

add repository pattern for proration data access

- MonthlyProrationRepository: crud operations for proration records
  - create, update, and query proration records
  - status management (pending, invoice_created, charged, failed)
  - retry count tracking

- MonthlyProrationTeamRepository: team-specific queries with billing context
  - fetch teams with billing information
  - query annual teams with unprocessed seat changes
  - update billing info and paidSeats
  - metadata fallback for legacy teams without billing records

- update IBillingRepository interface to include proration fields

these repositories provide clean data access layer without business logic

* feat(billing): add seat change tracking service

add service for logging and querying seat changes per month

- SeatChangeTrackingService: track seat additions and removals
  - log seat additions with user and metadata context
  - log seat removals with optional triggered-by info
  - calculate monthly changes (additions, removals, net change)
  - retrieve unprocessed changes for a given month
  - mark changes as processed after proration calculation
  - auto-detect billing entity (team vs organization)

- stripe-subscription-utils: extract billing data from stripe subscriptions
  - determine billing period (monthly vs annually)
  - extract price per seat and quantity

includes comprehensive unit tests

* feat(billing): add billing period service

add service to determine billing period and proration eligibility

- BillingPeriodService: query and manage billing period information
  - check if team is on annual vs monthly plan
  - check if team is in trial period
  - determine if monthly proration should apply (annual + not in trial + feature flag)
  - lazy load billing data from stripe if missing in database
  - backfill missing billing data automatically

supports both TeamBilling and OrganizationBilling models
includes comprehensive unit tests with stripe mocking

* feat(billing): add monthly proration service

add core service for calculating and processing monthly seat prorations

- MonthlyProrationService: orchestrate monthly proration workflow
  - process monthly prorations for teams with seat changes
  - calculate prorated amounts based on remaining subscription days
  - create stripe invoice items for seat additions
  - handle payment success and failure webhooks
  - track high-water mark (paidSeats) for billing
  - update stripe subscription quantities after payment
  - lazy load and backfill missing billing data from stripe
  - support retry logic for failed payments

calculation logic:
- only charge for net seat increases (additions - removals, capped at 0)
- prorate based on remaining days in annual subscription
- track separately from stripe's built-in proration to aggregate monthly

includes unit tests and integration tests with stripe mocking

* refactor(billing): extract prisma logic from services to repositories

move database access logic from services to repository layer for better separation of concerns

- add SeatChangeLogRepository for seat change log data access
- add BillingPeriodRepository for billing period queries and updates
- refactor SeatChangeTrackingService to use SeatChangeLogRepository
- refactor BillingPeriodService to use BillingPeriodRepository
- add create methods to MonthlyProrationTeamRepository for billing records
- refactor MonthlyProrationService to use repository for billing creation
- remove direct prisma calls from services (except FeaturesRepository dependency)

services now focus on business logic while repositories handle data access

* refactor(billing): inject prisma via constructor in repositories

make repositories more testable by accepting prisma client via constructor

- SeatChangeLogRepository: accept optional prisma in constructor
- BillingPeriodRepository: accept optional prisma in constructor
- MonthlyProrationRepository: accept optional prisma in constructor
- MonthlyProrationTeamRepository: accept optional prisma in constructor

all repositories default to global prisma instance when not provided
enables easier mocking in tests by injecting test prisma instances

* refactor: remove verbose comments and unnecessary try-catch

* refactor: change pricePerSeat and proratedAmount to cents (Int)

store monetary values as integers in cents instead of floats for precision
remove unnecessary schema comments

* fix tests and add back try catch error handlign

* Update packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts

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

* add faeture flag to config.ts

* Update packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts

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

* restore schema

* add hooks types for flag

* fix: correct pricePerSeat calculations for cents-based storage

MonthlyProrationService now correctly handles pricePerSeat stored as
cents (INTEGER) instead of dollars (DOUBLE PRECISION). Removed duplicate
conversions to cents that were causing 100x price inflation.

* Use cents for money values

* fix type error

* Move integration to test to use cents value

* fix integration import

* mock subscription

* include paid seats tracking in proration service

* add mocks for invoice creation

* feat: use stripebilling service instead of using stripe directly

* fix validation erorr handler in proration service

* fix: fix sub

* use correct seat value

* fix(billing): mark seat changes as processed when netChange is zero

When a team has additions and removals that net to zero, the function
was returning null without calling markAsProcessed(). This left seat
change logs in an unprocessed state indefinitely, causing subsequent
proration runs to re-query the same changes repeatedly.

Changed the early return condition from checking netChange === 0 to
checking if there are no changes at all (additions === 0 && removals === 0).
This ensures that when there are actual seat changes that net to zero,
a proration record is still created and seat changes are marked as processed.

Co-Authored-By: unknown <>

* update test to reflect new return type of proration

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-12 10:58:21 +00:00
Amit SharmaGitHubamit@cal.com <samit91848@gmail.com>amit@cal.com <samit91848@gmail.com>amit@cal.com <samit91848@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
a12ab5bb65 chore: add database-backed feature flag for sidebar tips section (#26516)
* chore: remove tips section from sidebar

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: add feature flag for sidebar tips section

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: use database-backed feature flag for sidebar tips section

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 22:31:45 +05:30
Udit TakkarandGitHub 0330d14210 feat: system admin blocklist table (#25039)
* feat: system admin blocklist table

* chore: text

* fix: type error

* fix: type error

* fix: type error

* fix: frontend bug

* chore: improvments

* refactor: use shared components

* refactor: improvements

* fix: delete

* refactor: support multiple watchlist

* chore: update translation

* fix: type err

* fix: bulk bug

* tests: add unit test

* refactor: file

* refactor: file

* fix: type error

* fix: type error

* chore: translation

* refactor: use shared comments

* fix: imports

* fix: type error
2026-01-09 08:19:54 -03:00
Syed Ali ShahbazGitHubcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
59fca85d92 fix: use graceful filtering for previously hard failing blocked users in team events (#26446)
* init

* typefix

* --

* fix test

* update index

* cleanup

* rm unnecessary comments

* improvements

* add tests

* test fixes

* fixes

* fixes

* fixes

* add try catch to make booking fail-open

* Update packages/features/watchlist/operations/check-user-blocking.ts

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

* fix type

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-08 08:30:54 -03:00
Amit SharmaGitHubamit@cal.com <samit91848@gmail.com>amit@cal.com <samit91848@gmail.com>amit@cal.com <samit91848@gmail.com>amit@cal.com <samit91848@gmail.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
eacfcd15a4 feat: Hubspot write to meeting object (#26039)
* feat: Hubspot write to meeting object

* fix: translate hardcoded strings and remove debug console.log

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor

* fix: improve static value detection for placeholder replacement

- Changed condition from startsWith/endsWith to includes('{') to properly detect embedded placeholders
- Strings like 'Hello {name}!' are now correctly processed for placeholder replacement
- Pure placeholder tokens that can't be resolved return null
- Partially resolved values are returned as-is

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor: split WriteToObjectSettings into types and utils files

- Extract interfaces, enums, and type definitions to WriteToObjectSettings.types.ts
- Extract constants and utility functions to WriteToObjectSettings.utils.ts
- Update main component to use the new utility functions
- Improves code organization and maintainability

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* revert: restore original static value detection logic

Per user request - the startsWith/endsWith check was intentional

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* test: add unit tests for HubSpot CRM service

Tests cover:
- ensureFieldsExistOnMeeting: field validation against HubSpot properties
- getTextValueFromBookingTracking: UTM parameter extraction
- getTextValueFromBookingResponse: placeholder replacement
- getDateFieldValue: date field resolution for different date types
- getFieldValue: main field value resolution for all field types
- generateWriteToMeetingBody: write-to-meeting body generation
- getContacts: contact search functionality

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: correct type errors in HubSpot CRM service tests

- Import WhenToWrite enum from crm-enums
- Replace string literals with WhenToWrite.EVERY_BOOKING enum values
- Add missing whenToWrite property to field config objects

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: use type casting for intentional type errors in tests

- Cast numeric fieldValue to string for testing non-string handling
- Cast invalid field type string to CrmFieldType for testing unsupported types

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: prevent unhandled promise rejections in HubSpot CRM tests

- Re-apply mockGetAppKeysFromSlug implementation in beforeEach to ensure
  mock is always set correctly after clearAllMocks
- Change vi.resetAllMocks() to vi.clearAllMocks() to preserve mock
  implementations between tests
- Add explicit types to satisfy biome lint rules
- This fixes the 'Cannot read properties of undefined (reading client_id)'
  errors that were causing CI to fail with exit code 1

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* refactor: convert HubSpot tests to black-box testing through public methods

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: properly type mock CalendarEvent in HubSpot tests

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: properly type TFunction in mock CalendarEvent

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* chore: graceful owner fail test

* refactor

* fix: type check

* fix: remove null fields

* Update packages/app-store/hubspot/lib/CrmService.ts

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-06 14:58:46 -03:00
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f4248bf20d feat: implement FeatureOptInService (#25805)
* feat: implement FeatureOptInService WIP

* clean up

* feat: consolidate feature repositories and add updateFeatureForUser

- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository

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

* refactor: rename updateFeatureForUser to setUserFeatureState

Rename to match the convention used for setTeamFeatureState

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

* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState

* fix integration tests

* clean up logics

* update services and router

* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array

- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query

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

* feat: add getFeatureStateForTeams for batch querying multiple teams

- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method

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

* refactor: combine org and team state queries into single call

- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams

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

* refactor: use team.isOrganization and clarify computeEffectiveState comment

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

* refactor: use MembershipRepository.findAllByUserId with isOrganization

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

* feat: add featureId validation using isOptInFeature type guard

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

* less queries

* add fallback value

* fix type error

* move files

* add autoOptInFeatures column

* use autoOptInFeatures flag within FeatureOptInService

* add setUserAutoOptIn and setTeamAutoOptIn

* fix computeEffectiveState logic

* rewrite computeEffectiveState

* clean up integration tests

* clean up in afterEach

* fix type error

* refactor: use FeaturesRepository methods instead of direct Prisma calls

Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.

Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts

This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).

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

* clean up

* fix the logic

* extract some logic into applyAutoOptIn()

* remove wrong code

* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union

- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests

* fix type error

* use Promise.all

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 16:55:53 +01:00
Hariom BalharaandGitHub a056c3217e chore: Add impersonation context support to booking audit (#26014)
## What does this PR do?

Adds infrastructure to track impersonation context in booking audit records and displays it in the UI. When an admin impersonates another user and performs booking actions, the audit system now:
- Records the **admin** as the actor (who actually performed the action)
- Stores the **impersonated user's UUID** in a separate `context` field
- Displays **"Impersonated By"** in the booking logs UI when viewing audit details

This separation ensures audit trail integrity (the admin is accountable) while preserving full context about whose account was being used.

### Changes
- Added `uuid` to `impersonatedBy` session object for actor identification
- Added `uuid` to top-level `User` type in next-auth types for session enrichment
- Added `context Json?` field to `BookingAudit` Prisma model
- Added `BookingAuditContextSchema` for type-safe context handling with `actingAsUserUuid` field
- Updated producer service interface and implementation to pass context through all queue methods
- Updated consumer service to persist context to database
- Updated repository to store and fetch context in BookingAudit records
- Added `impersonatedBy` field to `EnrichedAuditLog` type in `BookingAuditViewerService`
- Added `enrichImpersonationContext` method to resolve impersonated user details
- Updated booking logs UI to display "Impersonated By" in expanded details
- Added `impersonated_by` translation key

Link to Devin run: https://app.devin.ai/sessions/3f1252527aef4ead9401bdf055c0817b
Requested by: hariom@cal.com (@hariombalhara)

## Mandatory Tasks (DO NOT REMOVE)

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

## How should this be tested?

1. Verify type checks pass: `yarn type-check:ci --force`
2. Verify existing audit tests still pass: `TZ=UTC yarn test`
3. To fully test impersonation context display:
   - Have an admin impersonate a user
   - Perform a booking action (create, cancel, reschedule)
   - Navigate to the booking's audit logs
   - Expand the details for the action
   - Verify "Impersonated By" row appears showing the impersonated user's name
   - Verify the BookingAudit record has:
     - `actorId` pointing to the admin's AuditActor
     - `context` containing `{ actingAsUserUuid: "<impersonated-user-uuid>" }`

## Human Review Checklist

- [ ] Verify the `context` field schema design is appropriate for future extensibility
- [ ] Confirm the `uuid` addition to User type in next-auth doesn't break existing auth flows
- [ ] Check that the optional `context` parameter doesn't break existing queue method callers
- [ ] Verify no migration file is needed (or if squashing is handled separately)
- [ ] Verify the UI displays "Impersonated By" correctly when impersonation context is present
- [ ] Confirm `enrichImpersonationContext` handles edge cases (null context, invalid context, deleted user)

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings
2026-01-06 16:16:18 +05:30
Keith WilliamsGitHubkeith@cal.com <keithwillcode@gmail.com>keith@cal.com <keithwillcode@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
bc6ff386a4 refactor: move eventTypeSlug and eventTypeLocations to @calcom/lib/zod (#26115)
* refactor: move eventTypeSlug and eventTypeLocations to @calcom/lib/zod

Move shared Zod schemas from @calcom/prisma/zod-utils to @calcom/lib/zod
to avoid prisma imports in non-repository code.

Changes:
- Create packages/lib/zod/eventType.ts with eventTypeSlug, eventTypeLocations,
  and EventTypeLocation type
- Re-export from @calcom/prisma/zod-utils for backwards compatibility
- Update packages/features/eventtypes/lib/schemas.ts to import from @calcom/lib/zod
- Remove unused slugify function from zod-utils.ts

This allows files like schemas.ts to avoid importing from @calcom/prisma,
which helps maintain the architectural boundary that prisma should only
be imported in repository code.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: remove barrel file and use explicit imports

Address PR feedback:
- Delete packages/lib/zod/index.ts barrel file
- Update imports to use explicit path @calcom/lib/zod/eventType
- Simplify EventTypeLocation type to use z.infer

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: use explicit type definition with z.ZodType for eventTypeLocations

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-30 13:03:10 -03:00
Keith WilliamsandGitHub 716e66b0c3 chore: Use relative imports for @calcom/prisma inside of @calcom/prisma (#26245)
<!-- This is an auto-generated description by cubic. -->
## Summary by cubic
Switch @calcom/prisma to use relative imports for client and enums. This removes self-references, stabilizes builds, and improves type resolution.

- **Refactors**
  - Replaced imports from "@calcom/prisma/*" with local "./client" and "./enums" across extensions, selects, mocks, and availability check.
  - Updated safeJSONStringify parameter type from any to unknown.
  - Minor formatting cleanup in zod-utils.

<sup>Written for commit 85c0a7b75fb1291be5b848a73d1ccb5543283f49. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-12-29 00:52:12 -03:00
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
44586c7dec chore: lock all package versions to match yarn.lock (#26204)
This commit pins all dependency versions in package.json files to exact
versions matching the yarn.lock file, removing ^ and ~ prefixes.

Changes:
- Locked 427 dependencies across 47 package.json files
- Versions now match exactly what is resolved in yarn.lock
- Ensures reproducible builds and prevents unexpected version drift

This change improves build reproducibility by ensuring that the versions
specified in package.json files match exactly what yarn.lock resolves to.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-26 11:54:30 -03:00
Keith WilliamsGitHubkeith@cal.com <keithwillcode@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
851cca25aa perf: add z.ZodType annotations to high-impact schemas (#26114)
* perf: add z.ZodType annotations to high-impact schemas

Add explicit type annotations to reduce TypeScript type inference overhead
and .d.ts file bloat in the tRPC package.

Changes:
- packages/prisma/zod-utils.ts: Add EventTypeLocation type and annotate eventTypeLocations schema
- packages/features/eventtypes/lib/schemas.ts: Add TEventTypeDuplicateInput and TCreateEventTypeInput types with annotations
- packages/app-store/routing-forms/zod.ts: Add FieldOption, TNonRouterField, TRouterField, TField, TFields types with annotations for zodField and zodFields

These schemas feed into multiple tRPC routers and were identified as high-impact
targets for reducing type checking time and declaration file sizes.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: replace z.infer with explicit types and define EventTypeLocation locally

Address PR feedback:
- Replace z.infer<typeof calVideoSettingsSchema> with explicit CalVideoSettings type
- Define EventTypeLocation type locally instead of importing from prisma
- Add z.ZodType annotation to calVideoSettingsSchema

Note: Still importing Zod schemas from @calcom/prisma/zod-utils for validation.
Awaiting guidance on whether to move those to @calcom/lib.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 23:15:04 -03:00
Volnei MunhozGitHubVolnei MunhozDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Keith Williams
83ee986bbd fix: lock package versions and organize devDependencies (#26095)
* fix: lock package versions to exact versions from yarn.lock

Replace version ranges (^, ~) with exact resolved versions from yarn.lock
to ensure consistent dependency resolution across all environments.

This change affects 26 package.json files with 89 version updates including:
- TypeScript: ^5.9.0-beta -> 5.9.2
- Zod: ^3.22.4 -> 3.25.76
- React: ^18 -> 18.2.0
- Various Radix UI, Vite, PostCSS, and other dependencies

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

* fix: preserve npm alias format for @radix-ui packages

The previous commit incorrectly converted npm aliases like
'npm:@radix-ui/react-dialog@^1.0.4' to just '1.0.4', which broke
yarn install as it tried to find non-existent packages.

This fix restores the npm alias format while keeping the pinned versions:
- @radix-ui/react-dialog-atoms: npm:@radix-ui/react-dialog@1.0.4
- @radix-ui/react-tooltip-atoms: npm:@radix-ui/react-tooltip@1.0.6

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

* refactor: move dev dependencies to devDependencies section

Move 26 dependencies that are clearly development-only to the
devDependencies section across 10 packages:

- Testing: @types/jest, jest, ts-jest, @golevelup/ts-jest
- Build tools: typescript, ts-node, concurrently, dotenv-cli
- Linting: eslint-*, eslint-config-*, eslint-plugin-*
- Types: @types/express, @types/turndown, @types/uuid

This improves dependency organization and ensures production builds
don't include unnecessary development dependencies.

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-21 10:18:07 -03:00
Keith WilliamsGitHubkeith@cal.com <keithwillcode@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
0e3696f20c chore: dedupe yarn.lock to remove duplicate package versions (#26068)
* chore: dedupe yarn.lock to remove duplicate package versions

- Consolidated 762 duplicate package versions
- Reduced yarn.lock from 51,211 lines (1.7MB) to 44,471 lines (1.5MB)
- Removed 7,071 lines (~200KB) of redundant dependency entries
- Major packages deduplicated include: resolve, semver, type-fest, commander, glob, lru-cache, dotenv, @babel/* packages, typescript, tslib, postcss, and many more

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: resolve type errors in managed event types and react-select components

- Add Zod-compatible versions of allManagedEventTypeProps and unlockedManagedEventTypeProps
  that only include scalar fields (excludes Prisma relation fields)
- Update handleChildrenEventTypes.ts and queries.ts to use the new Zod-compatible props
- Fix react-select CSS type errors in Select.tsx files by using Object.assign
  instead of spread operator to avoid TypeScript type inference issues
- Fix lint warning in updateNewTeamMemberEventTypes by using if statement

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: derive eventType parameter type from actual query result

Use Awaited<ReturnType<typeof getEventTypesToAddNewMembers>>[number] to ensure
type safety at call sites, avoiding Prisma type namespace mismatches.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: disable turbo cache for @calcom/trpc#build to prevent stale type errors

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: correct field names in API v1 validation schemas

- Remove timeZone from booking schema (field doesn't exist on Booking model)
- Remove bookingId from destination-calendar schema (field doesn't exist, only booking relation)
- Change avatar to avatarUrl in user schema (correct field name)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use Object.assign for react-select styles to fix TypeScript spread type errors

The spread operator causes TypeScript to compute an incompatible type with
CSSObjectWithLabel due to the accentColor property. Using Object.assign
preserves the correct type inference.

Fixed files:
- FormEdit.tsx
- DestinationCalendarSelector.tsx (features and platform)
- TimezoneSelect.tsx
- ApiKeyDialogForm.tsx
- Select.tsx (features/form)
- WebhookForm.tsx

Also fixed pre-existing lint warnings:
- Constant truthiness in label assignment
- Unused variant parameter

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove extra fields from allManagedEventTypePropsForZod to match original behavior

The Zod-compatible version should only include scalar fields that were in the
original allManagedEventTypeProps. Removed instantMeetingScheduleId, profileId,
rrSegmentQueryValue, and assignRRMembersUsingSegment which were incorrectly
added and caused test failures by including extra fields in Prisma update payloads.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove access to fields not in Zod schema

- Remove unnecessary destructuring of profileId and instantMeetingScheduleId
  from managedEventTypeValues in handleChildrenEventTypes.ts (these fields
  are already sourced from other variables)
- Set rrSegmentQueryValue to undefined directly in queries.ts instead of
  accessing it from managedEventTypeValues (not applicable for managed children)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add name property to mock credentials and revert turbo cache change

- Add name property to MockCredential type and factory function in
  InstallAppButtonChild.test.tsx to match expected credentials type
- Revert turbo cache disable for @calcom/trpc#build (per review comment)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: revert API v1 validation changes and restore eslint comment

- Revert API v1 validation changes (booking.ts, destination-calendar.ts,
  user.ts) since API v1 is deprecated and these could be breaking changes
- Restore eslint-disable comment for @typescript-eslint/no-empty-function
  in Select.tsx that was accidentally removed

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add inputs to @calcom/trpc#build to properly invalidate cache

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: properly fix API v1 validation schemas for stricter zod 3.25.76

The yarn dedupe upgraded zod from 3.22.4 to 3.25.76, which has stricter
.pick() typing that now properly rejects picking non-existent fields.

Changes:
- user.ts: Pick avatarUrl (actual Prisma field) and extend with avatar
  for API v1 backward compatibility
- booking.ts: Remove timeZone from pick (not a field on Booking model,
  only exists in nested attendees/user objects)
- destination-calendar.ts: Remove bookingId from pick (not a field on
  DestinationCalendar model)

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: remove turbo.json inputs for @calcom/trpc#build to use cached artifacts

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: use robust selector for react-select option in routing forms E2E test

The previous selector used .nth(1) which assumed the email text appeared
exactly twice in the DOM in a specific order. This broke when react-select
was upgraded from 5.7.2 to 5.8.0 via yarn dedupe.

The new approach waits for the react-select listbox to appear and clicks
the option within it, which is more robust against DOM structure changes.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-20 23:30:03 -03:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f1011ddd08 chore: Improves the core booking audit architecture by adding new capabilities and simplifying the existing interfaces. (#25872)
* feat(booking-audit): extract core audit system changes from PR 25125

This PR extracts core audit infrastructure changes without integration changes:

1. New action services introduced:
   - SeatBookedAuditActionService
   - SeatRescheduledAuditActionService

2. Simplification of ActionService interface:
   - Streamlined IAuditActionService interface
   - Reduced TypeScript burden with cleaner type definitions

3. ActionSource support:
   - Added BookingAuditSource enum (API_V1, API_V2, WEBAPP, WEBHOOK, UNKNOWN)
   - Added source and operationId fields to BookingAudit model

4. New AuditAction types:
   - SEAT_BOOKED
   - SEAT_RESCHEDULED
   - APP actor type

5. New BookingAuditAccessService:
   - Permission-based access control for audit logs
   - Added readTeamAuditLogs and readOrgAuditLogs permissions

6. Fixes in the logs viewer flow:
   - Enhanced BookingAuditViewerService with improved filtering
   - Local AttendeeRepository for actor enrichment

Changes are contained within packages/features/booking-audit with minimal
outside changes (permission registry only).

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

* refactor(booking-audit): streamline action handling and enhance localization

- Replaced action icon retrieval with a mapping object for improved clarity and performance.
- Introduced constants for actor role labels to simplify role retrieval.
- Added new localization strings for audit log permission errors and organization requirements.
- Updated various service and repository interfaces to enhance type safety and clarity.
- Removed deprecated architecture documentation and adjusted related imports for consistency.

These changes aim to improve code maintainability and user experience in the booking audit system.

* fix(booking-audit): enhance actor role localization and operation ID tracking

- Updated actor role labels in the booking logs view to use lowercase for consistency.
- Improved localization by wrapping actor role display in a translation function.
- Added operationId field to audit logs for better correlation of actions across multiple bookings.
- Enhanced BookingAuditViewerService to include operationId in enriched audit logs.
- Updated integration tests to verify consistent operationId across related audit logs.

These changes aim to improve localization accuracy and facilitate better tracking of user actions in the booking audit system.

* feat: integrate credential repository and enhance app actor handling

- Added CredentialRepository to manage app credentials, including a method to find credentials by ID.
- Updated BookingAudit system to support app actors identified by credential ID, improving actor attribution and audit clarity.
- Introduced a new utility function to map app slugs to display names, enhancing the user experience in audit logs.
- Modified relevant interfaces and types to accommodate the new credential handling and app actor structure.
- Enhanced BookingAuditViewerService to display app names based on credentials, ensuring accurate representation in audit logs.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-18 12:46:24 +00:00
Eunjae LeeGitHubeunjae@cal.com <hey@eunjae.dev>eunjae@cal.com <hey@eunjae.dev>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
cef8610925 feat: add enabled column to UserFeatures and TeamFeatures for tri-state semantics (#25765)
* feat: add enabled column to UserFeatures and TeamFeatures for tri-state semantics

- Add enabled Boolean column to UserFeatures model with default true
- Add enabled Boolean column to TeamFeatures model with default true
- Update FeaturesRepository to use tri-state semantics:
  - enabled=true: feature is explicitly enabled
  - enabled=false: feature is explicitly disabled (blocks inheritance)
  - No row: inherit from team/org level
- Update SQL queries to check enabled=true for feature access
- Add enableFeatureForTeam method to interface and implementation

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

* update comments

* add integration tests

* add more test

* select enabled only

* no @default(true)

* fix types and tests

* add missing enabled

* add missing enabled

* rename enableFeatureForTeam to updateFeatureForTeam and support FeatureState

* refactor: rename updateFeatureForTeam to setTeamFeatureState

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

* fix integration test

* fix tests

* add more tests

* add missing enabled

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-18 07:16:20 -03:00
Syed Ali ShahbazandGitHub 056922b6ee feat: add webhook versioning (#23861)
* add webhook version schema

* version the code

* update version from numeric to date val

* migration

* update schema and build factory

* update string

* move version picker

* tooltip instead of infobadge

* --

* fix type

* --

* fix type

* fix type

* --

* fix messed up merge

* improvements to payloadfactory

* extract version off of DB and instead keep it in IWebhookRepository

* fix webhookform

* fix type safety and routing ambiguity

* scalable with easier factory extensions and base definition

* fix types

* --

* --

* clean up prisma/client type imports

* fix

* type fix

* type fix

* cleanup

* add tests and registry changes

* unintended file inclusion

* type-fix

* select in repo

* --

* explicit return type

* --

* fix type

* fixes

* feedback 1

* feedback 2

* use enum instead of string

* fixes
2025-12-18 09:36:22 +02:00
5fe3714edd feat: auto skip consent screen for trusted oauth clients (#25640)
* auto constent for trusted clients

* add loading state

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-12-17 13:00:12 +00:00
Alex van AndelandGitHub db2caa17ce fix: Allow single-label domains and missing dots (#25899) 2025-12-16 05:10:22 +05:30
Dhairyashil ShindeandGitHub 12e07f20d4 feat: Add Holidays feature to block availability on public holidays (#25561)
* feat: add holidays feature for automatic availability blocking- Add UserHolidaySettings model for storing user preferences- Generate static holiday data for 20 countries using date-holidays- Create HolidayService for runtime holiday queries- Add TRPC router with endpoints for country selection and holiday toggles- Create Holidays tab UI in Availability page with conflict warnings- Integrate holiday blocking into getUserAvailability calculation- Show holiday indicator on blocked dates in booker page- Add warning in OOO modal when dates overlap with holidays

* feat: add optimizations, tests, and code quality improvements

- Add memoization/caching to HolidayService for better performance
- Optimize checkConflicts DB query with OR conditions for specific dates
- Add HolidayService unit tests (10 tests)
- Add error handling with Alert component for failed queries
- Memoize HolidayListItem component to prevent unnecessary re-renders
- Extract magic numbers into constants.ts
- Use TRPCError consistently in handlers
- Add missing i18n keys for error messages
- Update handlers to follow Cal.com patterns (default exports, minimal comments)
- Add regeneration instructions in constants

* refactor: replace static JSON with Google Calendar API integration

- Add GoogleHolidayService to fetch holidays from Google Calendar public calendars
- Add HolidayCache Prisma model for caching API responses
- Add GOOGLE_CALENDAR_API_KEY and HOLIDAY_CACHE_DAYS env variables
- Support 38 countries via Google Calendar holiday calendars
- Update HolidayService methods to async with database caching
- Update all TRPC handlers for async holiday methods
- Fix UI to display holiday dates correctly
- Remove static holidays.json and generate script

* use we instead of calcom in i18n message

* address cubics comments

* move holidays from availability to ooo

* public holidays filter for holidays

* follow i18n _one and _other pattern

* remove holiday feature flag

* revert lint command code change

* revert lint command code change 2.0

* revert lint command code change 3.0

* bye bye my christmas emoji :crying-emoji

* remove comments

* refactor(holidays): add repository pattern, split services, and add tests

- Create HolidayRepository for database operations
- Split GoogleHolidayService into GoogleCalendarClient and HolidayCacheService
- Add dependency injection to HolidayService and HolidayCacheService
- Update TRPC handlers to use HolidayRepository
- Add tests for HolidayRepository and calculateHolidayBlockedDates
- Update calendar IDs to use official holiday format (244 countries + religions)

* fix: address PR review feedback

- Remove unused date-holidays package
- Add pluralization for and_more_holidays_with_conflicts translation
- DRY: spread GOOGLE_RELIGIOUS_HOLIDAY_CALENDARS into GOOGLE_HOLIDAY_CALENDARS
- Add select to userHolidaySettings query in getUserAvailability
- Optimize checkConflicts with pre-computed timestamps

* refactor(holidays): apply proxy pattern and move logic to service

- Rename HolidayCacheService to HolidayServiceCachingProxy (proxy pattern)
- Remove HOLIDAY_CACHE_DAYS env var, use constant directly
- Add isSupportedCountry() method to HolidayService
- Add getUserSettings() and updateSettings() to HolidayService
- Move toggleHoliday logic from handler to service
- Move checkConflicts logic from handler to service
- Add findBookingsInDateRanges() to HolidayRepository
- Simplify all handlers to just call service methods

* feat(bookings): add backend validation to prevent booking on holidays

Adds explicit holiday conflict validation during booking creation to
handle the race condition where a host enables a holiday after a guest
selects a date but before they submit the booking.

Changes:
- Add checkHolidayConflict validation with HolidayRepository integration
- Integrate ensureNoHolidayConflict in RegularBookingService
- Add BookingOnHoliday error code with proper HTTP 400 response
- Handle holiday error display in BookEventForm with name interpolation
- Hide trace ID for expected validation errors
- Add unit tests for holiday conflict validation

* fix failing type check

* fix: address PR review comments for holiday feature

- Change error code from BAD_REQUEST to INTERNAL_SERVER_ERROR in
  toggleHoliday handler (errors are internal failures, not bad input)
- Refactor ensureNoHolidayConflict to use Promise.all for parallel
  user checking instead of sequential loop

* refactor: use Promise.all with logging in loop for holiday check

- Check all users in parallel using Promise.all
- Log conflicts inside the loop as they are detected
- Wait for all checks to complete before throwing error

* fix(holidays): use host timezone for holiday conflict checks

The holiday feature was checking booking dates against holidays using
server/local timezone instead of the host's timezone. This caused
bookings near midnight boundaries to incorrectly pass or fail the
holiday check.

Example: A booking at Dec 24th 8PM UTC (which is Dec 25th in IST)
was not being blocked for an Indian host with Christmas as a holiday.

Changes:
- Add .utc() to holiday date formatting for consistency
- Fetch host's timezone in checkHolidayConflict
- Convert booking time to host's timezone before comparison
- Add findUserSettingsWithTimezone to HolidayRepository
- Update error message to clarify it's the host's local time
- Add timezone edge case tests

* fix(holidays): align holiday blocking with OOO pattern for consistent timezone handling

- Simplify calculateHolidayBlockedDates to match OOO pattern using dayjs.utc()
- Fix date range query to use full day bounds (startOfDay/endOfDay) so holidays
  stored at midnight UTC are correctly found during booking validation
- Remove separate checkHolidayConflict booking-time validation - holidays now
  block through oooExcludedDateRanges like OOO does
- Remove getHolidayOnDate from HolidayService (no longer needed)
- Remove findUserSettingsWithTimezone from HolidayRepository (no longer needed)
- Clean up related tests

Holiday blocking now works exactly like OOO:
1. Holidays are added to datesOutOfOffice in calculateHolidayBlockedDates
2. buildDateRanges processes them via processOOO with .tz(timeZone, true)
3. oooExcludedDateRanges excludes those dates from availability
4. ensureAvailableUsers uses oooExcludedDateRanges to block bookings

This ensures consistent timezone handling where Dec 25th blocks all hours
of Dec 25th in the host's timezone, regardless of booker's timezone.

* update test

* update .env.example file
2025-12-15 16:39:10 +00:00
Eunjae LeeGitHubeunjae@cal.com <hey@eunjae.dev>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>sean-brydon
52d5261b51 feat(booking): implement cross-page/week navigation in booking details sheet with view persistence (#25545)
* display UTM parameters

* persist view (list | calendar) in localStorage

* move to next page on clicking "next" of last item in the page

improve navigation

^ Conflicts:
^	apps/web/modules/bookings/components/BookingCalendarContainer.tsx

* fix navigation on calendar view

* Delete apps/web/modules/bookings/NAVIGATION_IMPLEMENTATION.md

* avoid page size being 0

* check feature flag on user level

* use map to improve useBookingListData

* address feedback

* feat(bookings): add smart navigation for calendar view

- Add sort option to tRPC bookings.get schema and handler
- Create NAVIGATION_PROBE_WINDOW_MONTHS constant (3 months)
- Create useNearestFutureBooking hook to find nearest future booking
- Create useNearestPastBooking hook to find nearest past booking
- Update useCalendarNavigationCapabilities to use probe results
- Update BookingCalendarContainer to wire up probe hooks

This enables the booking details sheet to:
- Disable next/prev buttons when no bookings exist in that direction
- Jump directly to the week containing the nearest booking

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

* fix type error

* feat: add booking selection state when using slideover (#25637)

* implement booking selection when using slideover

* remove pixel shift

* fix

* auto scroll to selected event on calendar

* make DateValues header sticky when scrolling

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>

* prefetch previous / next weeks on calendar view

* clean up classes

* handle "fetched & but no data" situation more correctly in useCalendarAutoSelector

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-12-15 16:04:00 +00:00
Dhairyashil ShindeandGitHub 983af06787 fix: allow two dots in exclude email (#24968)
* add test and fix two dots bug in exclude email

* add test and fix two dots bug in exclude email
2025-12-13 02:06:42 +05:30
sean-brydonandGitHub b46fb82695 feat: minium reschedule notice on events (#25575)
* wip

* add i18n and essential tests

* fix UI and add migration

* fixes

* add logic on book event

* restore comment

* remove dev debug box

* extract min reschedule notice to util

* one more replace

* add to disable reschedule component

* tidy up state

* restore lock

* restore file

* fix zod utils

* respond to cubic feedback

* fix type error

* unit tests

* add zod util

* build tests with nul minReshceuldeNotice

* fix stuff
2025-12-12 10:53:01 -03:00
Dhairyashil ShindeandGitHub 26b4385679 feat: Add public OOO notes display on booking pages (#25471)
* feat: ooo message on booking page

* make ooo days selectable even when no redirect booking

* handle long notes

* remove unused i18n key

* Private notes stay private on the server, No accidental data leaks through client-side payloads

* address cubics comments

* fix: replace toggle with checkbox for OOO note visibility

- Replace Switch with Checkbox for "show note publicly" option
- Remove "OOO Message:" prefix from displayed notes on booking page
- Update i18n text to "Show note on public booking page"
- Remove unused ooo_message i18n key

* fix the accessibility issue by using proper htmlFor and id association

* only allow selecting OOO dates when the note is public
2025-12-11 11:31:59 +00:00
Eunjae LeeandGitHub 3986d61f40 feat(bookings): improve bookings redesign (#25251)
* use booking.uid instead of booking.id for url param

* show timezone on calendar

* fix type

* restore horizontal tab and remove header and subtitle

* clean up sidebar items

* fix event propagation from attendees

* fetch all statuses except for cancelled on calendar view

* clean up styles of the badges on BookingListItem

* fix useMediaQuery

* add close button to the header

* add assignment reason to the details sheet

* use separator row

* use ToggleGroup for the top bookings tab

* move ViewToggleButton

* resize the action button

* remove wrong prop

* fix type error

* fix type error

* hide view toggle button on mobile (and fix the breakpoint)

* remove unused e2e tests

* fix e2e tests

* hide toggle button when feature flag is off

* update skeleton

* improve attendees on booking list item and slide over

* improve attendee dropdown

* fix type error

* move query to containers

* select attendee email

* infinite fetching for calendar view

* update styles

* fix compatibility

* fix: add backward compatibility for status field in getAllUserBookings

* increase calendar height

* fix type error

* support Member filter only for admin / owners

* add debug log (TEMP)

* add event border color

* show Reject / Accept buttons on BookingDetailsSheet

* move description section to the top

* update When section

* update style of Who section

* add CancelBookingDialog WIP

* fix CancelBookingDialog

* increase clickable area

* add schedule info section WIP

* fix flaky reject button

* fixing reschedule info WIP

* add fromReschedule index to Booking

* improve rescheduled information

* improve reassignment

* fix type error

* fix unit test

* respect user's weekStart value on the booking calendar view

* update debug log

* improve payment section

* clean up

* fix log message

* reposition filters on list view

* fix bookings controller api2 e2e test

* clean up file by extracting logic into custom hooks

* rename files

* merge BookingCalendar into its container

* extract logic into separate hook files

* remove redundant logic

* rearrange items on calendar view

* add WeekPicker

* extract filter button

* responsive header on list view

* horizontal scroll for ToggleGroup WIP

* fix type error

* fix cancelling recurring event

* address feedback

* fix e2e tests

* fix unit test

* fix e2e tests

* make hover style more visible for ToggleGroup

* fix margin on CancelBookingDialog

* update styles on the slide over (mostly font weight)

* update style of CancelBookingDialog

* update styles

* update margin top for the header

* refactor getBookingDetails handler

* fix gap in who section

* auto-filter the current user on the calendar view

* calculate calendar height considering top banners

* improve booking details sheet interaction without overlay

* update calendar event styles

* update reject dialog style

* put uid first in the query params

* fix class name

* memoize functions in useMediaQuery

* query attendee with id instead of email

* update margins

* replace TRPCError with ErrorWithCode

* move calculation outside loop

* remove dead code
2025-12-10 13:40:04 +00:00
MorganGitHubmorgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
6b62557a92 feat: add hostSubsetIds parameter for round robin host filtering (#25627)
* feat: add hostSubsetIds parameter for round robin host filtering

Add support for filtering round robin event type hosts via API v2.
When hostSubsetIds is provided, only the specified hosts are considered
for availability calculation and booking assignment.

Changes:
- Add hostSubsetIds to slots API input (GET /slots/available)
- Add hostSubsetIds to booking API input (POST /bookings)
- Update _findQualifiedHostsWithDelegationCredentials to filter by hostSubsetIds
- Pass hostSubsetIds through all layers: API -> tRPC -> slots/booking services

This allows API consumers to request availability and create bookings
for a subset of hosts within a round robin event type.

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

* chore: add e2e tests

* chore: add enableHostSubset team event-type setting

* fixup! chore: add enableHostSubset team event-type setting

* fix tests

* fix tests

* improve isWithinRRHostSubset

* rename to rrHost subset

* fix ai review

* fix: add booker platform wrapper rrHostSubsetIds prop

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-10 10:37:39 +00:00
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
3a59cd41cc feat: add toggle to opt out of booking title translation in instant meetings (#25547)
* feat: add toggle to opt out of booking title translation in instant meetings

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

* fix: add autoTranslateTitleEnabled to test builder

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

* fix: respect autoTranslateTitleEnabled toggle in InstantBookingCreateService

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

* fix: fetch autoTranslateTitleEnabled directly in InstantBookingCreateService

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

* refactor: rename autoTranslateTitleEnabled to autoTranslateInstantMeetingTitleEnabled

- Renamed field to clarify it only applies to instant meeting title translation
- Moved Prisma query to EventTypeRepository.findInstantMeetingConfigById()
- Removed title translation logic from update.handler.ts (flag only controls instant meeting title)
- Updated all references across the codebase
- Added new i18n translation keys for the renamed field

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

* fix: add autoTranslateInstantMeetingTitleEnabled to test destructuring patterns

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

* fix: use Prisma.TeamCreateInput type for metadata in test helper

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

* fix: add autoTranslateInstantMeetingTitleEnabled to mockUpdatedEventType in test

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

* refactor: use generic findByIdMinimal instead of business-specific method

- Add autoTranslateInstantMeetingTitleEnabled to eventTypeSelect constant
- Remove findInstantMeetingConfigById from EventTypeRepository
- Update InstantBookingCreateService to use findByIdMinimal

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

* refactor: remove autoTranslateInstantMeetingTitleEnabled from eventTypeSelect (not needed for findByIdMinimal)

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

* feat: add autoTranslateInstantMeetingTitleEnabled to event type form defaults

- Rename shouldTranslateTitle to shouldAutoTranslateInstantMeetingTitle for clarity
- Add autoTranslateInstantMeetingTitleEnabled to findById and findByIdForOrgAdmin selects
- Add autoTranslateInstantMeetingTitleEnabled to useEventTypeForm defaultValues

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

* fix: only update autoTranslateInstantMeetingTitleEnabled when explicitly provided

Fixes issue where omitting the field in update requests would overwrite
the saved opt-out setting with the default value (true). Now the field
is only included in the update payload when explicitly provided.

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-09 13:51:51 +00:00
Hariom BalharaandGitHub 0fc26f782f feat: Add support to audit and view audit log with Booking CREATED action (#25468)
## What does this PR do?

This PR introduces the booking audit infrastructure with a viewer service to fetch, enrich, and format audit logs. This is the first iteration that includes only the CREATED action with versioned schema

Note: Additional audit actions, UI improvements to match with Figma will be taken care of in followup PRs, to ensure the PR size remains as small as possible(as it is large enough already)

Demo - Loom - https://www.loom.com/share/22c2f38b052b480b8be3716e1608eaf6

### Key Changes

**New Booking Audit Package** (`packages/features/booking-audit/`):

- `BookingAuditViewerService` - Fetches, enriches, and formats audit logs for display
- `BookingAuditTaskConsumer` - Processes audit tasks asynchronously via Tasker
- `CreatedAuditActionService` (v1) - Handles RECORD_CREATED action with versioned schema

**Repository Layer**:

- `BookingAuditRepository` - CRUD operations for audit records
- `AuditActorRepository` - Actor management (users, guests, system)
- `UserRepository.findByUuid()` - User lookup for actor enrichment

**UI Components**:

- New page at `/booking/logs/[bookinguid]` for viewing audit history
- Filterable audit log list with search, type, and actor filters
- Expandable log entries showing detailed change information

**Infrastructure**:

- `bookingAudit` Tasker task type for async processing
- `booking-audit` feature flag (disabled by default)
- tRPC endpoint `viewer.bookings.getAuditLogs`

### Updates since last revision

- **Refactored `Task` class to `TaskRepository`**: Converted all static methods to instance methods following the repository pattern. A singleton `Task` is exported for backward compatibility, so existing call sites continue to work unchanged.

### Important Notes for Reviewers

- **Permission check is TODO**: `checkPermissions()` in `BookingAuditViewerService` is not yet implemented
- **Only CREATED action supported**: Other actions will throw an error - additional actions will be added iteratively in follow-up PRs
- **Feature flag controlled**: System is behind `booking-audit` flag, disabled by default
- **UI strings need i18n**: Some UI text in `booking-logs-view.tsx` may need translation

### Human Review Checklist

- [ ] Verify permission enforcement strategy for audit log access
- [ ] Review DI wiring in module files
- [ ] Confirm error handling in `BookingAuditTaskConsumer` is appropriate for retry scenarios
- [ ] Check if UI strings need to be added to translation files
- [ ] Verify `TaskRepository` refactoring maintains backward compatibility (singleton export `Task` should work for all existing call sites)

## Mandatory Tasks (DO NOT REMOVE)

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

## How should this be tested?

Run the integration tests:

```bash
TZ=UTC yarn test packages/features/booking-audit/lib/service/BookingAuditViewerService.integration-test.ts
TZ=UTC yarn test packages/features/booking-audit/lib/service/BookingAuditTaskConsumer.integration-test.ts
```

To test the UI:

1. Enable the `booking-audit` feature flag in the database
2. Create a booking (only CREATED action is supported in this PR)
3. Navigate to `/booking/logs/{bookingUid}` to view the audit trail

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings

<!-- Link to Devin run: https://app.devin.ai/sessions/a8ae61c253b549429401c9651dcbcf44 -->
<!-- Requested by: hariom@cal.com (@hariombalhara) -->
2025-12-08 17:38:58 +05:30
Syed Ali ShahbazandGitHub c78552ce60 fix: OnDelete SetNull for watchlist delete on watchlistAudit (#25690)
* OnDelete SetNull for watchlist delete on watchlistAudit

* make watchlistId nullable

* type fix
2025-12-08 05:22:01 +00:00
Udit TakkarandGitHub 35d6c41fff feat: Disable booking emails to guests (#25217)
* feat: disable SMS org setting

* chore: undo

* fix: cal evnet

* feat: add more settings

* tests: add email manager unit tests

* fix: update

* fix: type error

* fix: test

* refactor: UI

* refactor: UI

* perf: fetch only once

* perf: fetch only once

* chore: use org

* fix: test

* test: add unit tests

* refactor: email manager

* fix: add confirmation dialog for individual checkbox

* fix: sms

* chore: common.json
2025-12-03 17:21:31 +00:00
Carina WollendorferGitHubcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>CarinaWollicubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
4e0798577a feat: OAuth PKCE (#25313)
* add public client

* implement PKCE

* pass codeChallenge and codeChallengeMethod to handler

* fixes for secure oauth flow

* fix type error

* clean up refresh token endpoint

* only support S256

* fix type error

* remove comment

* add tests

* fix type errors in route.test.ts

* add missing support for refresh token

* add e2e test for public client refresh tokens

* allow pkce for confidential clients

* fix type error

* fix e2e

* fix option pkce for confidential clients

* e2e test improvements

* fix test

* remove only

* add delay

* fix e2e tests

* remove only

* don't skip pkce if codeChallenge is set

* add service functions for token endpoint

* use service function in refreshToken endpoint

* use repository

* remove return types

* e2e test fixes

* fix e2e test

* remove .only in e2e test

* remove pause

* fix error responses in token endpoints

* adjust tests to new error responses

* fix error responses

* e2e improvements

* redirect on error

* adjust tests

* Update apps/web/modules/auth/oauth2/authorize-view.tsx

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

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2025-11-26 17:02:42 +01:00
sean-brydonandGitHub 2a7c6590a3 feat: add permission for editUsers + implement UI (#25402)
## What does this PR do?
This PR implements attributes PBAC - router checks + UI

## Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change **(video / image - any one)**.

#### Video Demo (if applicable):

- Show screen recordings of the issue or feature.
- Demonstrate how to reproduce the issue, the behavior before and after the change.

#### Image Demo (if applicable):

- Add side-by-side screenshots of the original and updated change.
- Highlight any significant change(s).

## Mandatory Tasks (DO NOT REMOVE)

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

## How should this be tested?
Enable PBAC on an org 
Create a custom role -> advanced -> organizations -> "editUser" 
Assign it to a user
impersonate user
test they have access to all things attributes
remove permissions
check they dont have permissions. 

## Checklist

<!-- Remove bullet points below that don't apply to you -->

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my changes generate no new warnings










<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds a new PBAC “editUsers” permission and read gating for Attributes, updating the UI and backend so users can view and edit attributes only when allowed.

- **New Features**
  - Added CustomAction.EditUsers to the permission registry for organization-scoped attribute editing.
  - Settings computes canViewAttributes and shows the Attributes tab only when allowed.
  - Members page fetches Attributes permissions and exposes canViewAttributes and canEditAttributesForUser to the UI.
  - User Edit Sheet hides attributes without read permission and shows attribute editing and the bulk “Mass Assign Attributes” action only with editUsers; other user edits depend on changeMemberRole.
  - Attributes TRPC router gates create/edit/delete/toggle via PBAC and requires organization.attributes.editUsers for assign/bulk-assign; added a helper to create PBAC-aware procedures.

- **Migration**
  - Run the new Prisma migration to seed the admin role with editUsers.
  - If using custom roles, grant Edit Users under Attributes as needed.

<sup>Written for commit 856aa2e8e1521fc22cd71cb0fa6d720036efe8a2. Summary will update automatically on new commits.</sup>

<!-- End of auto-generated description by cubic. -->
2025-11-26 13:58:29 +00:00
Eunjae LeeandGitHub dd7f108f08 fix: put booking details and calendar behind feature flag (#25175)
* Revert "fix: revert bookings redesign (#25172)"

This reverts commit 1f102bf3b4.

* add bookings-v3 feature flag

* put things behind a feature flag

* remove no longer needed test

* revert e2e tests

* put back description

* revert AvatarGroup

* apply feedback

* remove "view" booking action

* remove Alert (When the bookings query errors, this branch now renders only the alert and skips the data-table filter/segment controls. Those controls moved into BookingsList, so in error states users can no longer clear or tweak filters to recover from the failure, effectively trapping them behind the alert.)

* address feedback

* revert useMediaQuery
2025-11-19 16:27:13 +01:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
105a82f97d feat: add uuidv7 and @db.Uuid to AuditActor and BookingAudit models (#25269)
- Update AuditActor.id to use uuid(7) with @db.Uuid
- Add @db.Uuid to BookingAudit.bookingUid and actorId fields
- Create migration to convert existing TEXT columns to UUID type

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 13:17:02 +00:00
Hariom BalharaandGitHub c04402e7ee feat: [Booking Audit Stack - 1] Add Booking Audit System foundation (database schema and repositories) (#24838)
* feat: Implement Booking Audit System with database architecture and repository interfaces

- Added `ARCHITECTURE.md` detailing the design and structure of the Booking Audit System, including core tables `AuditActor` and `BookingAudit`.
- Created repository interfaces `IAuditActorRepository` and `IBookingAuditRepository` for managing audit actor and booking audit records.
- Implemented `PrismaAuditActorRepository` and `PrismaBookingAuditRepository` for database interactions.
- Defined enums for `BookingAuditType`, `BookingAuditAction`, and `AuditActorType` in the Prisma schema.
- Added migration scripts to create necessary database tables and enums for the audit system.

This commit establishes a robust framework for tracking booking-related actions, ensuring compliance and data integrity.

* feat(audit): add system actor migration
2025-11-19 08:21:34 -03:00
Anik Dhabal BabuGitHubanik@cal.com <adhabal2002@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
a0eca13c18 feat: add organization-level autofill disable setting (#23504)
* feat: add organization-level autofill disable setting

- Create DisableAutofillOnBookingPageSwitch component following existing patterns
- Add toggle to organization general page alongside other settings
- Update tRPC organizations update handler to support new field
- Add organization-level check to useShouldBeDisabledDueToPrefill hook
- Add translation keys for new autofill disable setting
- Include database migration for disableAutofillOnBookingPage field
- Maintain backward compatibility with individual field settings

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

* feat: complete autofill disable implementation

- Add disableAutofillOnBookingPage to orgSettings type definition
- Update Prisma schema with new organization setting field
- Clean up test file formatting

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

* fix: resolve tRPC mocking issues in tests and add missing disableAutofillOnBookingPage to organization repository

- Fix tRPC module mocking in useShouldBeDisabledDueToPrefill tests
- Add disableAutofillOnBookingPage to organization repository select and return statements
- All form builder tests now pass (24/24)
- Organization-level autofill disable tests working correctly

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

* test: simplify autofill disable test to single focused test

- Replace multiple tests with one test that verifies org setting blocks autocomplete
- Test includes searchParams with prefill data to verify blocking behavior
- Removes unnecessary test complexity as requested

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

* fix: add missing disableAutofillOnBookingPage to organizationSettings select statements

- Add disableAutofillOnBookingPage to both parent and main organizationSettings select statements in getTeamWithMembers
- Resolves TypeScript error in getServerSideProps.tsx where MinimumOrganizationSettings type requires this property
- Ensures organization settings type compatibility across the codebase

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

* Remove disableAutofillOnBookingPage setting

Removed 'disableAutofillOnBookingPage' setting from organization configuration.

* update

* Remove duplicate settings in common.json

Removed duplicate entries for automatic transcription and autofill settings.

* Fix syntax error in common.json

* update

* add tests

* Remove comments for autofill disabled check

Removed comments explaining scenarios for autofill check.

* addressed review

* fix

* change

* Add handling for disableAutofillOnBookingPage input

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-19 08:25:46 +00:00
Anik Dhabal BabuandGitHub 5cda123a4c fix test flakes (#25240) 2025-11-19 09:57:10 +02:00