'the the event type' (slots API property description), 'for for new
booking' (EventManager debug log), and 'one-one one template'
(en locale).
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
The first member of a dynamic group decides which conferencing app the group
booking uses. getPublicEvent read users[0] straight from findUsersByUsername,
which does not guarantee the order given in the URL, so /alice+bob could end up
using bob's preference — or fall back to Cal Video when only alice has one set.
handleNewBooking already sorts by the dynamic user list for this exact reason
(sortUsersByDynamicList in getLocationValuesForDb.ts). Applying the same order
here keeps the advertised location and the booked location in sync.
* fix(bookings): refund all seat payments when cancelling a paid seated booking
A paid seated booking creates one Payment row per seat on the same bookingId (each seat's payment_intent.succeeded webhook flips only its own payment via handlePaymentSuccess). processPaymentRefund only refunded payment.find((p) => p.success) — the first successful payment — so fully cancelling a multi-seat paid booking with an auto-refund policy refunded a single seat and left the other attendees charged with no error surfaced.
Refund every successful, not-yet-refunded payment instead.
Tests: unit regression in processPaymentRefund.test.ts (all payments refunded, verified red before the fix); integration test in handleCancelBooking.test.ts proving a full cancel of a seated multi-payment booking hands all payments to the refund path.
* fix(bookings): make seat refunds resilient and drop dayjs in test
Address CodeRabbit review on #29685:
- processPaymentRefund now attempts every seat's refund independently and throws an aggregate error, so one provider failure no longer skips the remaining seats.
- Add a regression test for that resilience, and use native Date instead of dayjs for fixed-offset test timestamps.
* fix: load more users on table scroll
Signed-off-by: Chayan Das <daschayan8837@gmail.com>
* refactor: move user listing logic to UserRepository
Add a dedicated listUsers method with search and cursor pagination support.
Add repository tests covering filtering and pagination.
Ensure user listing metadata remains consistent with the returned results.
Signed-off-by: Chayan Das <daschayan8837@gmail.com>
---------
Signed-off-by: Chayan Das <daschayan8837@gmail.com>
* refactor: use userRepository class methods for signup handlers
* feat: add user repo modules for DI
* feat: build user repo container
* test: integration test for user repository
* fix: use DI container in selfhosted
* refactor: tests, module, container and handlers
---------
Co-authored-by: Bandhan Majumder <bandhanmajumder16@gmail.com>
* cleanup(webhooks): remove instant meeting trigger support
* remove dead code
* remove instant meeting from prisma enums and related cleanup
* fix(webhooks): make instant meeting enum migration atomic
* feat: Cal.diy — community-driven MIT-licensed fork of Cal.com
This squashed commit contains all Cal.diy changes applied on top of calcom/cal.com main:
- Rebrand Cal.com to Cal.diy across the entire codebase
- Remove Enterprise Edition (EE) features, license checks, and AGPL restrictions
- Switch license from AGPL-3.0 to MIT
- Remove docs/ directory (migrated to Nextra at cal.diy)
- Remove dead code: org tests, EE tips, platform nav, premium username, SAML/SSO, etc.
- Clean up .env.example for self-hosted Cal.diy
- Update Docker image references to calcom/cal.diy
- Update README, CONTRIBUTING.md, and issue templates for Cal.diy community fork
- Add PR welcome bot for Cal.diy contributors
- Fix API v2 breaking changes oasdiff ignore entries
- Replace Blacksmith CI runners with default GitHub Actions
3893 files changed, 20789 insertions(+), 411020 deletions(-)
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* refactor: remove org-specific /organizations/:orgId endpoints from API v2 atoms controllers (#1701)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: revert Cal.diy Inc to Cal.com, Inc. in license files, copyright notices, and package metadata (#1702)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* rip out org related comments in api v2
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: add vi.mock calls to prevent InstantBookingCreateService test flake
Add two vi.mock() calls ported from cal repo to prevent
'Closing rpc while fetch was pending' errors:
1. Mock @calcom/app-store/calendar.services.generated with a Proxy
to prevent real calendar modules (feishu, lark) from triggering
async getAppAccessToken fetch calls during test worker shutdown.
2. Mock @calcom/features/ee/organizations/di/OrganizationRepository.container
to prevent deep transitive import chain from triggering a Vitest
module-resolution RPC still in flight at shutdown.
Also removes the narrow feishucalendar mock which is now covered by
the broader calendar.services.generated Proxy mock.
* fix: update bookingScenario to use Proxy-based CalendarServiceMap
Replace the plain-object CalendarServiceMap mock with a Proxy-based
implementation that catches ALL calendar service accesses. This prevents
real calendar modules (feishu, lark, etc.) from being imported during
tests, which was causing 'Closing rpc while fetch was pending' errors
when the Vitest worker shut down.
Also update mockCalendar to use a shared mock map directly instead of
dynamically importing calendar.services.generated, avoiding loading
real calendar service modules during test execution.
* feat(bookings): add booking audit logging to instant bookings
wire up BookingEventHandlerService.onBookingCreated in
InstantBookingCreateService to emit audit events, matching the
pattern already used in RegularBookingService and
RecurringBookingService.
* refactor: extract fireBookingEvents and reuse existing orgId
* refactor: derive orgId once and pass to both webhook trigger and audit event
* fix: add missing return in webhook map callback
* refactor: make creationSource required for instant bookings
Both callers (WEBAPP and API_V2) always set creationSource, so validate
it upfront and use CreationSource enum type instead of string | null.
* fix: use ErrorWithCode instead of Error, pass userUuid to audit events
* fix: pass null for hostUserUuid in instant booking audit data
Instant bookings have status AWAITING_HOST with no assigned host,
so the booker's UUID should not be recorded as hostUserUuid.
* fix: address devin review - hostUserUuid and creationSource validation
* fix: address review - bookingMeta, getOrgIdFromMemberOrTeamId, required creationSource
- pass userUuid via bookingMeta instead of separate param (matches RegularBookingService pattern)
- restore getOrgIdFromMemberOrTeamId for proper org resolution instead of eventType.team.parentId
- make creationSource required with runtime validation instead of defaulting to WEBAPP
* fix: enforce creationSource at compile time instead of runtime
use Required<Pick<>> to make creationSource required in the type
signature. removes the runtime check since TypeScript catches
missing creationSource at build time.
* fix: simplify type signature and derive hostUserUuid from booking relation
- Replace Required<Pick<CreateInstantBookingData, 'creationSource'>> with inline { creationSource: CreationSource }
- Include user relation in booking create query to derive hostUserUuid
- Pass newBooking.user?.uuid instead of hardcoding null for userUuid in audit data
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* chore: trigger CI
* fix: add missing impersonatedByUserUuid to instant booking meta
The CreateBookingMeta type requires impersonatedByUserUuid. Set it to
null for non-impersonated instant bookings.
* fix: show 'awaiting host' in audit log for instant bookings
Use booking status AWAITING_HOST to display "Booked (awaiting host)"
instead of "Booked with Unknown" when no host has accepted yet.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add booking audit for instant meeting accept via connect-and-join
Extract fireInstantBookingAcceptedAuditEvent to InstantBookingCreateService
and fire it right after the DB update, before side-effect notifications.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add audit logging tests for instant booking creation
* fix: simulate audit failure in resilience test (identified by cubic)
The test 'should not throw when booking audit event fails' was not
actually simulating an audit failure. Added vi.spyOn on
BookingEventHandlerService.prototype.onBookingCreated to reject with
an error, and assert the spy was called, proving the try/catch in
fireBookingEvents properly catches the error without breaking the
booking flow.
Co-Authored-By: bot_apk <apk@cognition.ai>
* test: add audit event tests for connectAndJoin and fix InstantBooking audit test
* test
---------
Co-authored-by: Hariom Balhara <1780212+hariombalhara@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: hariom@cal.com <hariombalhara@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: bot_apk <apk@cognition.ai>
* fix: mock @calcom/lib/i18n in EventManager.test.ts to prevent vitest worker shutdown flake
TranslationService transitively imports @calcom/lib/i18n which triggers slow
module resolution via vite's RPC. When the vitest worker shuts down before it
completes, it causes 'Closing rpc while fetch was pending' errors.
Mocking the module prevents the actual module resolution during test loading.
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
* chore: remove explanatory comments per review feedback
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: mock delegationCredential in getRoutedUsers test to prevent flaky worker shutdown errors
The getRoutedUsers.test.ts file only tests the pure sync function
getRoutedUsersWithContactOwnerAndFixedUsers, but importing getRoutedUsers.ts
triggers a heavy transitive import chain:
getRoutedUsers.ts
-> @calcom/app-store/delegationCredential
-> _utils/getCalendar
-> calendar.services.generated (all calendar services)
-> CalendarService.ts -> ics/tsdav
Sometimes the vitest worker finishes tests and shuts down before all async
module resolution completes, causing:
Error: [vitest-worker]: Closing rpc while "fetch" was pending
Mock @calcom/app-store/delegationCredential to cut off the import chain
since the tested function doesn't use it.
* Clean up comments in getRoutedUsers.test.ts
Removed comments about mocking delegationCredential to improve code clarity.
* refactor: evt creation
* refactor: evt creation
* refactor: evt creation
* fix: type
* test: update unit tests
* chore: add comments
* fix: handle undefined in withConditional to match NonNullable<T> type
Co-Authored-By: unknown <>
* refactor: evt
* fix: type err
* refactor: remove add videoCallData
* refactor: use error with code
* test: update unit test
* refactor: feedback
* refactor: remove conditional
* refactor: more strict types
* fix: type err
* chor: remove un used
* refactor: improve recurring event handling in RegularBookingService
Removed unnecessary whitespace and clarified comments regarding the attachment of recurring configurations in the booking handler. Adjusted logic to ensure that recurring settings are only applied when relevant.
* refactor: test
* fix: type error
* refactor: improve code
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: remove attendee endpoint
* fix: remove attendee email from error logs to avoid logging PII
Co-Authored-By: unknown <>
* fix: add isBookingAuditEnabled to removeAttendee handler
Align removeAttendee.handler.ts with the new onAttendeeRemoved interface
that requires isBookingAuditEnabled, following the same pattern used in
addGuests.handler.ts.
Co-Authored-By: bot_apk <apk@cognition.ai>
* style: apply biome formatting to conflict-resolved files
Co-Authored-By: bot_apk <apk@cognition.ai>
* chore: implement PR feedback
* fixup
* revert: biome formatting changes
* chore: implement feedback part 1
* chore: implement feedback part 2
* fix: await cancellation email flow to prevent uncaught promise rejections
The fire-and-forget .then() chain on prepareAttendeePerson() left
rejections from that promise uncaught. Await both prepareAttendeePerson()
and sendCancelledEmailToAttendee() so errors are properly handled.
sendCancelledEmailToAttendee() already has an internal try/catch, so
awaiting it will not cause the overall removeAttendee flow to fail on
email errors.
Addresses Cubic AI review (confidence 9/10).
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* chore: implement feedback part 3
* chore: implement devin feedback
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
* fix: add missing vi.mock() calls to prevent vitest worker shutdown flakiness
Add vi.mock() calls for modules that trigger background network requests
or database connections during import. These transitive imports can cause
the vitest worker RPC to shut down while pending fetch/network operations
are still in flight, resulting in flaky test failures with:
Error: [vitest-worker]: Closing rpc while "fetch" was pending
The primary modules mocked are:
- @calcom/app-store/delegationCredential (triggers credential lookups)
- @calcom/prisma (triggers database initialization)
- @calcom/features/calendars/lib/CalendarManager (triggers calendar API calls)
- @calcom/features/auth/lib/verifyEmail (triggers email service)
- @calcom/lib/domainManager/organization (triggers domain lookups)
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: remove conflicting empty prisma mocks from files with prismock/prismaMock setups
- Remove vi.mock('@calcom/prisma', () => ({ default: {}, prisma: {} })) from 28 files
that already have prismock/prismaMock test doubles. Vitest hoists all vi.mock() calls
and the last one wins, so these empty mocks were overriding the functional test doubles.
- Fix CalendarSubscriptionService.test.ts to reuse the shared mock from
__mocks__/delegationCredential instead of creating a new unconfigured vi.fn()
- Remove DelegationCredentialRepository.test.ts empty prisma mock (different pattern)
- Remove vi.mock from inside beforeEach in intentToCreateOrg.handler.test.ts
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: add comprehensive delegationCredential mock exports to prevent CI test failures
The vi.mock blocks for @calcom/app-store/delegationCredential were missing
exports that the code under test transitively imports (e.g.
enrichUsersWithDelegationCredentials, enrichUserWithDelegationCredentialsIncludeServiceAccountKey,
buildAllCredentials, getFirstDelegationConferencingCredentialAppLocation).
Added all exports with passthrough implementations so the booking flow
works correctly without triggering real network requests.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: correct credential mock return shapes to match real module API
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: revert unintended yarn.lock changes
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: Sink url shortner for sms workflow reminders
* fix: remove hardcoded dub values
* update .env.example
* fix: unit tests
* chore: add tests for scheduleSmsReminder and utils
* review refactor
* fix: type check
* review refactor
* fix: update test to account for smsReminderNumber fallback from main
Co-Authored-By: unknown <>
* feat: add feature flag for sink and more tests to verify
* fix: type check
* use proper feature flags for sink
* Apply suggestion from @keithwillcode
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
* feat: add platform URL support for reschedule and cancel links in workflow emails
Co-Authored-By: morgan@cal.com <morgan@cal.com>
* feat: pass platform URL data to CalendarEventBuilder in workflow emails
Co-Authored-By: morgan@cal.com <morgan@cal.com>
* Revert "feat: pass platform URL data to CalendarEventBuilder in workflow emails"
This reverts commit 1d4d3623c93cd4eeeef18ffdad0597fe583b6a55.
* chore: provide platform metadat to workflow email task
* fixup! chore: provide platform metadat to workflow email task
* test: add unit tests for platform URL handling in EmailWorkflowService
Co-Authored-By: morgan@cal.com <morgan@cal.com>
* test: update WorkflowService tests to include platform params in tasker payload
Co-Authored-By: morgan@cal.com <morgan@cal.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor: move useAppsData to features + replace useIsPlatform with isPlatform prop in DisconnectIntegrationModal
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
* refactor: remove old useAppsData from web (moved to features)
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: align checkBookingAccessWithPBAC with listing logic for personal event types
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* fix: align permission strings with doesUserIdHaveAccessToBooking granular permissions
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* change implementation
* remove unused code
* test: add getBookingDetails tests for personal event type booking access
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* fix: remove unused MembershipRole import
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* test: convert BookingDetailsService tests to integration tests
Replace unit tests with mocks by integration tests using real database.
Tests verify org/team admin access to personal event type bookings.
- Org admin viewing team member's personal event booking (fails on main, passes on PR)
- Team admin viewing team member's personal event booking (fails on main, passes on PR)
- Non-admin denied access (passes on both)
- Owner viewing own booking (passes on both)
- Non-existent booking returns Forbidden (passes on both)
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* test: refactor integration tests to use repositories instead of direct prisma calls
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* test: replace direct prisma usage with TestXXXRepository pattern in integration tests
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* test: use production repositories (OrganizationRepository, BookingRepository, UserRepository) instead of test repos for setup
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* test: inline test repository logic into integration test file
The TestXXXRepository classes were thin wrappers around single prisma
calls with barely any logic, so the indirection wasn't justified.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: correct admin password banner message to require both password length and 2FA
The banner message incorrectly used 'or' implying only one condition was needed,
but the code requires BOTH a password of at least 15 characters AND 2FA enabled.
Updated the message to clearly state both requirements and added a hint that
users need to log out and log back in after updating their security settings.
Fixes#9527
Co-Authored-By: unknown <>
* fix: auto-sign-out INACTIVE_ADMIN users after enabling 2FA
When an INACTIVE_ADMIN user enables 2FA, automatically sign them out so
they can log back in with refreshed session role, dismissing the banner.
This matches the existing behavior for password changes.
Co-Authored-By: unknown <>
* feat: add dynamic admin banner message based on inactiveAdminReason
Co-Authored-By: unknown <>
* Remove and add various localization strings
* Update common.json
* Add cookie consent checkbox message and remove entries
* test: add unit tests for AdminPasswordBanner and inactiveAdminReason logic
Co-Authored-By: unknown <>
* fix: add expires field to session mock to fix type check
Co-Authored-By: unknown <>
* fix: wrap CALENDSO_ENCRYPTION_KEY mutations in try/finally to prevent env state leaks
Addresses Cubic AI review feedback (confidence 9/10): when a test fails
early, the CALENDSO_ENCRYPTION_KEY env var was not being restored, which
could leak state into subsequent tests. Wrapped the env mutation in
try/finally blocks to guarantee cleanup.
Co-Authored-By: bot_apk <apk@cognition.ai>
* fix: add missing 'expires' field to buildSession in AdminPasswordBanner test
The Session type requires 'expires' to be a string, but buildSession was
not providing it, causing a type error caught by CI type-check.
Co-Authored-By: bot_apk <apk@cognition.ai>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
* perf: add paginated host endpoints and delta-based host updates for event type editor
- New cursor-paginated tRPC endpoints: getHostsForAssignment, getHostsForAvailability, searchTeamMembers, getChildrenForAssignment, exportHostsForWeights, getHostsWithLocationOptions
- Delta-based host update support in update.handler.ts (pendingHostChanges, pendingChildrenChanges)
- Repository additions: EventTypeRepository.findChildrenByParentId, HostRepository pagination, MembershipRepository.searchMembers, UserRepository.findByIdsWithPagination
- Remove teamMembers from getEventTypeById initial load
- Shared types: PendingHostChangesInput, PendingChildrenChangesInput, HostUpdateInput
Co-Authored-By: unknown <>
* fix: revert getTranslation import path to @calcom/i18n/server
Co-Authored-By: unknown <>
* fix: guard findChildrenByParentId to only run when pendingChildrenChanges exists
Co-Authored-By: unknown <>
* refactor: remove delta-based saving logic from backend PR
Move pendingHostChanges/pendingChildrenChanges processing out of backend PR.
These changes belong in the frontend PR since they are tightly coupled
to the new frontend delta tracking components.
Backend PR now contains only read-side optimizations:
- Paginated host/children/member endpoints
- Repository methods
- getEventTypeById optimizations
Co-Authored-By: unknown <>
* refactor: move getEventTypeById changes to frontend PR for type safety
Reverts getEventTypeById.ts, eventTypeRepository.ts, API v2 atom service,
and platform libraries to main. The backend PR now only adds new
infrastructure (paginated endpoints, repository methods, findChildrenByParentId)
without changing existing return types. The getEventTypeById optimizations
will be in the frontend PR instead.
Co-Authored-By: unknown <>
* refactor: move findTeamMembersMatchingAttributeLogic pagination to frontend PR
The handler's return type change (adding nextCursor/total) breaks frontend
files on main that expect the old shape. Moving these changes to the
frontend PR keeps the backend PR purely additive.
Co-Authored-By: unknown <>
* fix: address Cubic review comments - empty array filter, stable total count, Set lookup
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Fix inifnite pagination loop
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: derive teamId from event type to prevent cross-team enumeration in exportHostsForWeights
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* fix: restore doc comment to correct method hasAnyTeamMembershipByUserId
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* fix: use memberUserIds?.length to handle empty array filter in findHostsForAssignmentPaginated
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* fix: use explicit undefined check for memberUserIds to preserve empty array semantics
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* refactor: rename findChildrenByParentId to findChildrenByParentIdIncludeOwner
The method selects owner with user profile data, so the name should
reflect the included relation per Cal.com repository naming conventions.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* refactor: rename host repository methods to follow naming conventions
- findHostsForAvailabilityPaginated -> findHostsPaginatedIncludeUser
- findHostsForAssignmentPaginated -> findHostsPaginatedIncludeUserForAssignment
Repository methods should not be named after use-cases (Availability/Assignment)
but should describe what data they include, per Cal.com conventions.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* refactor: standardize slice(0, limit) across all pagination methods
Replace slice(0, -1) with slice(0, limit) in all HostRepository
pagination methods for consistency. slice(0, limit) is clearer about
intent since it directly references the limit parameter.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* perf: only run total count query on first page in findByIdsWithPagination
Wrap the count query in a !cursor guard so it only runs on the first
page request, avoiding an extra database query on every scroll.
Consistent with the hasFixedHosts optimization in HostRepository.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* test: add integration tests for paginated host endpoints
Tests cover getHostsForAvailability and getHostsForAssignment handlers:
- Basic host retrieval
- Cursor-based pagination across multiple pages
- Host data fields (isFixed, priority, weight, name, email)
- Search filtering by name
- memberUserIds filtering (including empty array returning zero results)
- hasFixedHosts only present on first page
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* refactor: extract EventTypeHostService and make TRPC handlers thin
- Create EventTypeHostService at packages/features/host/services/ with all
DTO types and business logic for 5 event-type-host endpoints
- Refactor all 5 handlers to delegate to the service (thin handlers)
- Add 17 unit tests covering DTO mapping, authorization, segment filtering,
default values, and pagination pass-through
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* docs: add PR review context comments to EventTypeHostService
Reference key review decisions from PR #28156 as code comments:
- searchTeamMembers: membership check + repository delegation per @eunjae-lee
- exportHostsForWeights: cross-team enumeration security fix per @hariombalhara
- exportHostsForWeights: repository method instead of direct Prisma per @hariombalhara
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Revert "docs: add PR review context comments to EventTypeHostService"
This reverts commit 1a1596e012e971f349f01339ce7572516042f1b3.
* fix: use explicit undefined/null check for memberUserIds in searchMembers
Fixes empty array semantics so memberUserIds: [] correctly returns zero
results instead of all members. Now consistent with HostRepository pattern
which uses 'memberUserIds !== undefined' instead of 'memberUserIds?.length'.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* refactor: replace TRPCError with ErrorWithCode in EventTypeHostService
Per AGENTS.md rules, services in packages/features/ should use
ErrorWithCode instead of TRPCError. The errorConversionMiddleware
will automatically convert it to the appropriate TRPCError at the
router layer.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Remove comment
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: remove unused teamId from exportHostsForWeights schema
teamId was originally accepted by the schema when the handler used it
directly. After the security fix to derive teamId server-side from the
event type, the field became dead code. Removing it to keep the API
contract accurate.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Abstract types
* Update imports
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
* 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
* chore: retrigger CI (flaky unit test)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: add context parameter to bulk audit methods for impersonation support
- Add context parameter to queueBulkCreatedAudit and queueBulkRescheduledAudit in BookingAuditProducerService interface
- Add context parameter to BookingAuditTaskerProducerService implementation
- Add context parameter to onBulkBookingsCreated and onBulkBookingsRescheduled in BookingEventHandlerService
- Update RegularBookingService.fireBookingEvents to accept and pass impersonation context
- Update RecurringBookingService.fireBookingEvents to accept and pass impersonation context
- Update handleSeats to accept and pass impersonation context
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* chore: Integrate mark-no-show booking audit
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Simplify host no-show audit and add comment for attendee actor
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: make impersonatedByUserUuid required with explicit null for non-impersonation cases
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: integrate impersonatedByUserUuid into booking cancellation audit flow
- Add impersonatedByUserUuid to CancelBookingInput and CancelBookingMeta types
- Pass audit context with impersonatedBy to onBookingCancelled and onBulkBookingsCancelled
- Update all cancel booking call sites to pass impersonatedByUserUuid:
- Web app cancel route: uses session impersonatedBy
- API v1 and v2: explicitly set to null (no impersonation support)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: make impersonatedByUserUuid optional and remove explicit null assignments
- Changed impersonatedByUserUuid from required (string | null) to optional (string?)
- Removed explicit null assignments from API v1 and v2 endpoints
- Keep impersonatedByUserUuid only where impersonation actually occurs (web app)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Apply suggestions from code review
Rfemove unnecessary comment
* fix: restore bookingMeta variable in createBookingForApiV1
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Make actionSource required with ValidActionSource type and remove unnecessary comments
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Remove merge conflict markers from bookings.service.ts
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: implement SYSTEM as a booking audit source for background tasks, including no-show triggers.
* refactor: Move prisma query to BookingRepository for audit logging
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Conflict resolution
* refactor: introduce `handleMarkHostNoShow` for public viewer and standardize actor and action source parameters for no-show actions.
* refactor: Combine HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService into NoShowUpdatedActionService
- Create new NoShowUpdatedAuditActionService with combined schema supporting both noShowHost and noShowAttendee as optional fields
- Update BookingAuditActionServiceRegistry to use combined service with NO_SHOW_UPDATED action type
- Update BookingAuditTaskerProducerService with single queueNoShowUpdatedAudit method
- Update BookingAuditProducerService.interface.ts with combined method
- Update BookingEventHandlerService with single onNoShowUpdated method
- Update handleMarkNoShow.ts to use combined audit service
- Update tasker tasks (triggerGuestNoShow, triggerHostNoShow) to use combined service
- Add NO_SHOW_UPDATED to Prisma BookingAuditAction enum
- Remove old separate HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService files
This allows a single API action (e.g., API V2 markAbsent) that updates both host and attendee no-show status to be logged as a single audit event.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* chore: Add migration for NO_SHOW_UPDATED audit action enum value
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Update no-show audit schema to use host and attendees array
- Rename noShowHost to host and noShowAttendee to attendees (remove redundant prefix)
- Change attendees from single value to array to support multiple attendees in single audit entry
- Update handleMarkNoShow.ts to create single audit entry for all attendees
- Update tasker tasks (triggerGuestNoShow, triggerHostNoShow) to use new schema
- Update display data types to reflect new schema structure
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Update schema to be more clear. Call onNoShowUpdated immediately after DB update as audit only cares about DB update, and this would avoid any accidental Audit update on DB change
* chore: accommodate schema changes and fix type errors for no-show audit
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update migration to remove old no-show enum values
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Use updated attendees in webhook payload for guest no-show
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Remove duplicate imports and fix actor parameter in bookings.service.ts
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Move booking query to BookingRepository and remove unused method
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: centralize no-show audit event firing and attendee fetching within `handleMarkNoShow` for improved clarity.
* fix: Build attendeesNoShow as Record with attendee IDs as keys
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Fix and add tests for handleMarkBoShow
* refactor: Move prisma queries to AttendeeRepository and BookingRepository
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Correct return type for updateNoShow method (noShow can be null)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update handleMarkNoShow tests to mock new repository methods
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix triggerGuestNoShow
* refactor: Move triggerGuestNoShow queries to AttendeeRepository and add unit tests
- Add new methods to AttendeeRepository:
- findByBookingId: Get attendees with id, email, noShow
- findByBookingIdWithDetails: Get full attendee details
- updateManyNoShowByBookingIdAndEmails: Update specific attendees
- updateManyNoShowByBookingIdExcludingEmails: Update all except specific emails
- Refactor triggerGuestNoShow.ts to use AttendeeRepository instead of direct Prisma calls
- Add comprehensive unit tests for triggerGuestNoShow following handleMarkNoShow.test.ts pattern:
- Mock repositories and external services
- In-memory DB simulation
- Test core functionality, audit logging, webhook payload, error handling, and edge cases
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Move triggerHostNoShow queries to repositories and delete unit test file
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Convert repository methods to use named parameters objects
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Enhance no-show handling by consolidating audit logging and updating repository interactions
- Refactor `buildResultPayload` to accept a structured argument for better clarity.
- Update `updateAttendees` to use a named parameter object for improved readability.
- Introduce `fireNoShowUpdatedEvent` to centralize no-show audit logging for both hosts and guests.
- Remove redundant methods and streamline attendee retrieval in `AttendeeRepository`.
- Add comprehensive unit tests for no-show event handling, ensuring accurate audit logging and webhook triggering.
* test: Add tests for handleMarkHostNoShow guest actor and unmarking host no-show
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: update attendeesNoShow validation to handle numeric keys
- Changed attendeesNoShow schema to use z.coerce.number() for key validation, ensuring string keys are correctly coerced to numbers.
- Updated test to validate attendeesNoShow data using numeric key comparison, improving robustness of the audit data checks.
* test: Add integration tests for NoShowUpdatedAuditActionService coerce fix
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: add graceful error handling for audit log enrichment
- Add hasError field to EnrichedAuditLog type
- Create buildFallbackAuditLog() method for failed enrichments
- Wrap enrichAuditLog() in try-catch to handle errors gracefully
- Add booking_audit_action.error_processing translation key
- Update BookingHistory.tsx to show warning icon for error logs
- Hide 'Show details' button for logs with hasError
- Add comprehensive test cases for error handling scenarios
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: Enhance booking audit action services with new display fields and improved validation
- Added "attendee_no_show_updated" and "no_show_updated" translations to common.json.
- Updated IAuditActionService to include new methods for handling display fields and migration.
- Enhanced NoShowUpdatedAuditActionService to differentiate between host and attendee no-show updates.
- Improved ReassignmentAuditActionService to ensure consistent handling of audit data.
- Refactored BookingAuditViewerService for better clarity and maintainability.
* refactor: Use attendeeEmail instead of attendeeId as key in audit data and store host's userUuid
- Updated schema to use attendee email as key instead of attendee ID because attendee records can be reused with different person's data
- Store host's userUuid in audit data with format: host: { userUuid, noShow: { old, new } }
- Updated fireNoShowUpdated to accept hostUserUuid parameter
- Added uuid field to BookingRepository.findByUidIncludeEventTypeAttendeesAndUser
- Updated NoShowUpdatedAuditActionService getDisplayFields to work with email-based keys
- Added attendeeRepository to DI modules for BookingAuditTaskConsumer
- Updated tests to match new schema format
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* test: Update integration tests to use new schema format with host.userUuid and email keys
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: correct audit schema for SYSTEM source and ensure attendee lookup by bookingId
- Fix schema inconsistency: use host.userUuid format instead of hostNoShow
- Add user.uuid to getBooking select for audit logging
- Log warning when hostUserUuid is undefined but host no-show is being updated
- Use email as key for attendeesNoShow (not attendee ID) to match schema
- Fetch attendees by bookingId before updating to ensure correct scoping
- Remove unused safeStringify import
* refactor: Change attendeesNoShow schema from Record to Array format
- Update NoShowUpdatedAuditActionService schema to use array format:
attendeesNoShow: Array<{attendeeEmail: string, noShow: {old, new}}>
- Update handleMarkNoShow.ts to build attendeesNoShow as array
- Update common.ts fireNoShowUpdatedEvent to convert Map to array
- Update all tests to use new array format with attendeeEmail property
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Update attendeesNoShow schema to use array format in triggerNoShow tasks
- Refactor `triggerGuestNoShow` and `triggerHostNoShow` to replace Map with array for `attendeesNoShowAudit`.
- Update `fireNoShowUpdatedEvent` to handle the new array format for attendees.
- Ensure consistent data structure across no-show audit logging for better clarity and maintainability.
* fix: Update ReassignmentAuditActionService to use GetDisplayFieldsParams interface
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update ReassignmentAuditActionService tests to use GetDisplayFieldsParams interface
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Use handleMarkAttendeeNoShow for API v2 mark absent endpoint
- Export handleMarkAttendeeNoShow from platform-libraries
- Update API v2 bookings service to use handleMarkAttendeeNoShow with actionSource
- Add validation for userUuid before calling handleMarkAttendeeNoShow
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Enhance display fields structure in booking audit components
- Updated `BookingHistory.tsx` to allow for more flexible display fields, including optional raw values and arrays of values.
- Introduced `DisplayFieldValue` component for rendering display fields, improving clarity and maintainability.
- Adjusted `IAuditActionService` and `NoShowUpdatedAuditActionService` to align with the new display fields structure.
- Ensured consistent handling of display fields across the booking audit service for better data representation.
* fix: Remove debug code that duplicated first attendee in display fields
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Update attendee repository methods to use structured parameters
- Modified `updateNoShow`, `updateManyNoShowByBookingIdAndEmails`, and `updateManyNoShowByBookingIdExcludingEmails` methods to accept structured `where` and `data` parameters for better clarity and maintainability.
- Updated calls to these methods throughout the codebase to reflect the new parameter structure.
- Removed unused `findByIdWithNoShow` method and adjusted related logic to streamline attendee data retrieval.
* feat: Add infrastructure for no-show audit integration
- Add Prisma migrations for SYSTEM source and NO_SHOW_UPDATED audit action
- Add NoShowUpdatedAuditActionService with array-based attendeesNoShow schema
- Update BookingAuditActionServiceRegistry to include NO_SHOW_UPDATED
- Update BookingAuditTaskConsumer and BookingAuditViewerService
- Add AttendeeRepository methods for no-show queries
- Update IAuditActionService interface with values array support
- Update locales with no-show audit translation keys
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Add NO_SHOW_UPDATED to BookingAuditAction and SYSTEM to ActionSource types
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Remove HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED from BookingAuditAction type to match Prisma schema
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update BookingAuditActionSchema to use NO_SHOW_UPDATED instead of HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Remove deprecated no-show audit services and unify to NoShowUpdatedAuditActionService
- Delete HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService
- Update BookingAuditProducerService.interface.ts to use queueNoShowUpdatedAudit
- Update BookingAuditTaskerProducerService.ts to use queueNoShowUpdatedAudit
- Update BookingEventHandlerService.ts to use onNoShowUpdated
- Add integration tests for NoShowUpdatedAuditActionService
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update test mock to match new AttendeeRepository.updateNoShow signature
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: rename handleMarkAttendeeNoShow to handleMarkNoShow and update related types
- Renamed `handleMarkAttendeeNoShow` to `handleMarkNoShow` for clarity.
- Updated type definitions to reflect the new naming convention.
- Modified the `markNoShow` handler to require `userUuid` and adjusted related logic.
- Enhanced the `fireNoShowUpdatedEvent` to accommodate changes in event type structure.
- Updated references across various files to ensure consistency with the new function name.
* handle null value
* fix: add explicit parentheses for operator precedence clarity
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Fix cubic reported bug
* feat: add impersonation audit support to no-show flow (#27601)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: add impersonatedByUserUuid context to all BookingEventHandler calls (#27602)
- Add context parameter to confirm.handler.ts (onBulkBookingsRejected, onBookingRejected)
- Add context parameter to requestReschedule.handler.ts (onRescheduleRequested)
- Add context parameter to editLocation.handler.ts (onLocationChanged)
- Add context parameter to addGuests.handler.ts (onAttendeeAdded)
- Add context parameter to handleConfirmation.ts (onBulkBookingsAccepted, onBookingAccepted)
- Update _router.tsx to pass impersonatedByUserUuid from session to handlers
This ensures all BookingEventHandler method calls that have loggedInUser context
now properly support impersonation tracking for audit logging.
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: remove stray merge artifact in RegularBookingService
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: remove duplicate imports in BookingRepository
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: resolve type errors and duplicate declarations from merge
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: remove duplicate test assertions and duplicate test from merge artifacts
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: remove redundant ?? undefined from impersonatedByUserUuid
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: update impersonatedByUserUuid type to string | null for consistency
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: make impersonatedByUserUuid required in booking audit flows
Changes impersonatedByUserUuid from optional (?: string | null) to
required (: string | null) in all booking-related type definitions.
This ensures audit-critical parameters are never accidentally omitted.
Fixed all call sites to explicitly pass the value or null.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: add impersonatedByUserUuid to remaining callers and tests
Adds impersonatedByUserUuid: null to API v1, API v2, and test callers
of handleCancelBooking that were missing the now-required parameter.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: require impersonatedByUserUuid in DTOs and pass it across all booking flows (coalesce to null)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: add impersonatedByUserUuid to remaining call sites (confirm, markNoShow, webhook, tests)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: add impersonatedByUserUuid to confirm handler test and API v2 confirm/decline calls
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: derive impersonatedByUserUuid from session in reportBooking handler instead of hardcoding null
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: reorder spread to ensure impersonatedByUserUuid null fallback is not overwritten
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: add missing impersonatedByUserUuid to CalendarSyncService cancel and reschedule calls
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: update CalendarSyncService tests to expect impersonatedByUserUuid
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* ci: retrigger failed checks (attempt 1)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* ci: retrigger failed checks (attempt 2)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* ci: retrigger failed checks (attempt 3)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* chore: bust prisma cache with comment change
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* ci: retrigger after cache bust (attempt 2)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* ci: retrigger after cache bust (attempt 3)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
* perf: batch DB operations in performance test setup to avoid CI timeout
Replace ~5200 sequential DB inserts with batch createMany() operations
in createHugeAttributesOfTypeSingleSelect. The test was timing out at
60s on 2-vCPU CI runners because the setup phase alone (creating 400
users, 800 memberships, 4000 attribute assignments one-by-one) exceeded
the timeout before the actual logic under test even ran.
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
* perf: optimize createAttributesScenario with batch DB operations
Move batch DB operations (createMany) into the shared createAttributesScenario
helper so all tests benefit, not just the performance test. Simplify
createHugeAttributesOfTypeSingleSelect to delegate to the optimized helper.
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
* Revert "perf: optimize createAttributesScenario with batch DB operations"
This reverts commit c739edd3718796d61f6510ea3a9155065b69a1ce.
* Revert "perf: batch DB operations in performance test setup to avoid CI timeout"
This reverts commit ff6642ae49190c42dd8673a12ee11c8c971370b4.
* perf: optimize createAttributesScenario with batch DB operations
Replace sequential prisma.*.create() calls in the shared createAttributesScenario
helper with batch createMany() calls, reducing ~5,200 sequential DB operations to
~10 batch operations. Simplify createHugeAttributesOfTypeSingleSelect to delegate
to the optimized helper instead of duplicating batch logic.
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
* fix: preserve deterministic user ordering in createAttributesScenario
Map users by email after findMany to ensure the index-based attribute
assignment matches the original userDataList order, since findMany does
not guarantee return order.
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
* revert: make test timeout back to 1 min
* refactor: extract batch helpers createTestUsers, createTestMembershipsForUsers, createTestAttributeAssignments
Organize batch DB operations from createAttributesScenario into
reusable helper functions mirroring the existing single-record helpers.
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
* cleanup: remove unused single-record helpers and JSDoc comments
Remove createTestUser, createTestMemberships, createTestAttributeAssignment
(now replaced by batch versions). Remove added comments.
Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>
* chore
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: make source required on EventBusyDetails for Troubleshooter display
- Make source a required property on EventBusyDetails type
- Update LimitManager to accept and store source when adding busy times
- Add user-friendly source names for all busy time types:
- 'Booking Limit' for booking limit busy times
- 'Duration Limit' for duration limit busy times
- 'Team Booking Limit' for team booking limit busy times
- 'Buffer Time' for seated event buffer times
- 'Calendar' for external calendar busy times
- Ensure all entries in detailedBusyTimes have source set
- Cover includeManagedEventsInLimits and teamBookingLimits branches
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: add limit value and unit metadata to busy time sources
- Include limit value and unit in source strings for Troubleshooter display
- Booking Limit: shows as 'Booking Limit: 5 per day'
- Duration Limit: shows as 'Duration Limit: 120 min per week'
- Team Booking Limit: shows as 'Team Booking Limit: 10 per month'
- Preserves existing calendar sources (e.g., 'google-calendar')
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: enhance busy time management with new limit sources
- Introduced new limit sources for busy times, including event booking and duration limits, with user-friendly titles for display.
- Updated LimitManager to accept and store detailed busy time information, including title and source.
- Refactored busy time addition logic across various services to utilize the new structure, improving clarity and maintainability.
* fixes
* feat: conditionally include source and translate busy time titles
- Add withSource parameter to conditionally include/exclude source from response
- Translate busy time titles on frontend using useLocale hook
- Source is only included when withSource=true (for Troubleshooter display)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: enhance user availability service and busy time handling
- Updated LargeCalendar component to include event ID check for enabling busy times.
- Added translation for "busy" in common.json for better user experience.
- Refactored getUserAvailability service to include new method for fetching user availability with busy times from limits.
- Introduced parseLimits function to streamline booking and duration limit parsing.
- Improved error handling in user handler for better user feedback.
* refactor: remove unnecessary timeZone: undefined from addBusyTime calls
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: add buffer_time and calendar translation keys for busy times
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: add event source to calendar components and improve busy time handling
- Updated EventList component to include event source in data attributes for better tracking.
- Enhanced LargeCalendar component to pass event
* fix: add missing source property to Date Override calendar event
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: use 'date-override' as source for Date Override calendar events
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Avoid type assertion
* fix: pass both bookingLimits and durationLimits to getStartEndDateforLimitCheck (#27898)
* test: add unit tests for getUserAvailabilityIncludingBusyTimesFromLimits
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: pass both bookingLimits and durationLimits to getStartEndDateforLimitCheck
- Fix bug where bookingLimits || durationLimits was passed as single param
- Skip getBusyTimesForLimitChecks when eventType has no limits
- Remove as never casts, use proper typing for mock dependencies
- Replace expect.any(String) with exact ISO date assertions
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: replace loose assertions with exact values in tests
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: address review feedback on busy time sources
- Fix t("busy") fallback to t("busy_time.busy") for correct translation lookup
- Add missing title property to buffer time entries for Troubleshooter display
- Use descriptive debug strings for buffer time source field
- Fix import ordering in LargeCalendar.tsx
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-Authored-By: unknown <>
* fix: preserve pre-existing busyTimesFromLimitsBookings from initialData
Address review feedback from @hariombalhara (comment #30, #31):
- Initialize busyTimesFromLimitsBookings from initialData instead of []
to avoid silently overwriting pre-existing data with an empty array
- Use conditional spread to only include busyTimesFromLimitsBookings
when it has a value
- Add test verifying pre-existing busyTimesFromLimitsBookings is
preserved and passed through to _getUserAvailability
- Add test verifying busyTimesFromLimitsBookings is not passed when
there are no limits and no initialData bookings
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-Authored-By: bot_apk <apk@cognition.ai>
* fix: pass fetched eventType to _getUserAvailability to avoid duplicate DB query
Addresses Devin Review comment r2863593564: the wrapper method fetches
eventType but wasn't passing it through, causing _getUserAvailability to
re-fetch the same eventType from the database.
Also adds a test verifying eventType is forwarded correctly.
Co-Authored-By: bot_apk <apk@cognition.ai>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
* feat: add booking attendees endpoint to API v2
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
* feat: add rate limiting to booking attendees endpoint
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
* refactor: simplify attendees output to id, bookingId, name, email, timeZone
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
* test: add E2E tests for booking attendees endpoint
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
* chore: update bookings repository
* fixup: add pbac guards and update service logic
* chore: update openapi spec
* test: add rate limiting E2E test for booking attendees endpoint
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
* fix: tests
* fix: return 404 instead of 403 for non-existent booking in BookingPbacGuard
The BookingPbacGuard was returning 403 (Forbidden) for non-existent bookings
because doesUserIdHaveAccessToBooking returns false when a booking doesn't
exist, which the guard treated as an access denial.
Added an explicit booking existence check in the guard before the access
check, so non-existent bookings now correctly return 404 (Not Found) as
documented in the PR description.
Updated the E2E test to expect 404 for non-existent booking UIDs.
Issue identified by cubic.
Co-Authored-By: unknown <>
* fixup
* fix: return 404 instead of 403 for non-existent booking in attendees endpoint
BookingPbacGuard now checks booking existence before the access check,
returning 404 (Not Found) instead of 403 (Forbidden) for non-existent
booking UIDs. Updated the E2E test assertion and description to match.
Issue identified by cubic (confidence 9/10).
Co-Authored-By: unknown <>
* chore: implement PR feedback
* chore: update tests
* fixup
* chore: update endpoint decsription
* feat: endpoint to retrieve specific attendee
* chore: update e2e tests
* chore: implement cubic feedback
* fix: update test to expect 403 for non-existent booking UID (BookingPbacGuard behavior)
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
* fix: merge conflicts
* feat: endpoint to get attendees
* chore: update findByUidIncludeEventTypeAttendeesAndUser method
* chore: implement PR feedback
* fix: e2e tests
* chore: update e2e tests
* fixup fixup
* fix: remove phoneNumber assertion since it's optional and not provided in test
* chore: implement PR feedback
* fix: keep the same output shape for get attendees and get attendee endpoint
* chore: update openapi spec
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>