## What does this PR do? Implements booking audit logging for round-robin reassignment events (both manual and automatic). This is part of the booking audit integration plan (PR 7). Changes: - Added audit logging to `roundRobinManualReassignment.ts` for manual host reassignments - Added audit logging to `roundRobinReassignment.ts` for automatic round-robin reassignments - Updated tRPC handlers to pass `actionSource: "WEBAPP"` and `reassignedByUuid` - Updated API v2 bookings service to pass `actionSource: "API_V2"` and `reassignedByUuid` - Updated `ReassignmentAuditActionService.ts` with proper field schemas and translation keys The audit logging uses `BookingEventHandlerService.onReassignment()` with proper actor identification and action source tracking. ## Updates since last revision Addressed review feedback: - Renamed `title` field to `hostName` for semantic clarity (tracks host name changes, not booking titles) - Fixed `assignedById` schema: changed from `NumberChangeSchema` to `z.number()` (no old/new pattern needed - it's always the user who performed the reassignment) - Fixed `reassignmentReason` schema: changed from `StringChangeSchema` to `z.string().nullable()` (no old/new pattern needed) - Added `ValidActionSource` type that excludes `UNKNOWN` - clients must pass explicit action sources - Made `actionSource` required in both reassignment functions (no longer optional) - Added integration tests for `ReassignmentAuditActionService` (15 tests covering all methods) - Updated `roundRobinManualReassign.handler.ts` to pass required `actionSource` and `reassignedByUuid` params **Latest fixes:** - Fixed `hasAttendeeUpdated` check in `ReassignmentAuditActionService.ts`: changed from `!== null` to `!= null` to properly handle undefined values - Updated test expectations in `ReassignmentAuditActionService.test.ts` to match the new display JSON field names (`hostAttendeeUserUuidNew`/`hostAttendeeUserUuidOld` instead of `newAssignedRRHostUuid`/`previousAssignedRRHostUuid`) - Fixed async `getDisplayFields` tests to properly await the Promise and include the `previous_assignee` field - Fixed `hasAttendeeUpdated` to check for `hostAttendeeUpdated` object presence instead of optional `id` field - host changes with only `withUserUuid` populated were being ignored (identified by Cubic AI, confidence 9/10) - Fixed test expectation in `getDisplayJson` test: removed incorrect null expectations for `hostAttendeeIdUpdated`, `hostAttendeeUserUuidNew`, `hostAttendeeUserUuidOld` - the implementation uses conditional spreading to omit these fields when `hostAttendeeUpdated` is not present, rather than setting them to null ## Mandatory Tasks (DO NOT REMOVE) - [x] I have self-reviewed the code (A decent size PR without self-review might be rejected). - [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed. - [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. ## How should this be tested? 1. Trigger a manual round-robin reassignment via the webapp and verify audit logs are created with `actionSource: "WEBAPP"` 2. Trigger an automatic round-robin reassignment and verify audit logs are created 3. Use API v2 to reassign a booking and verify audit logs are created with `actionSource: "API_V2"` 4. Verify the audit data contains correct values for `organizerUuid`, `hostAttendeeUpdated`, `reassignmentReason`, and `reassignmentType` ## Checklist - [x] My code follows the style guidelines of this project - [x] I have checked if my changes generate no new warnings ## Human Review Checklist - [x] Verify the `hasAttendeeUpdated` fix is correct: now checks `fields.hostAttendeeUpdated != null` to detect any host attendee update regardless of whether `id` is populated - [x] Verify `getDisplayJson` test fix: fields are correctly omitted (not set to null) when `hostAttendeeUpdated` is not present, matching the conditional spreading implementation - [ ] Verify all callers of reassignment functions pass required `actionSource` and `reassignedByUuid` - [ ] Confirm `getDisplayFields` is properly awaited in all call sites (it's now async) - [ ] Check that `ValidActionSource` type properly excludes `UNKNOWN` for client-side validation ## Important Notes for Reviewer 1. **Dependency on base PR**: The translation key changes use the format from base PR (#26046). This PR should be merged after the base PR. 2. **Schema changes**: The `organizerUuid` and `hostAttendeeUpdated` fields track both organizer changes and round-robin host attendee changes separately for complete audit trail. --- Link to Devin run: https://app.devin.ai/sessions/e4353e2ec6ea4a51ab33313bdc630aba Requested by: @hariombalhara
Commercial License of API
Welcome to the Commercial License of the Cal.com API.
Our philosophy is simple, all "Singleplayer APIs" are open-source under AGPLv3. All "Multiplayer APIs" are under a commercial license.
The /ee subfolder is the place for all the Commercial License features from our hosted plan.
❗ WARNING: This repository is copyrighted (unlike our main repo). You are not allowed to use this code to host your own version of app.cal.com without obtaining a proper license first❗