Skip to content

Comments

fix: calendar invite organizer reassignment#24395

Closed
husniabad wants to merge 2 commits intocalcom:mainfrom
husniabad:fix/Calendar-invite-owner-updating-after-reassignment
Closed

fix: calendar invite organizer reassignment#24395
husniabad wants to merge 2 commits intocalcom:mainfrom
husniabad:fix/Calendar-invite-owner-updating-after-reassignment

Conversation

@husniabad
Copy link
Contributor

What does this PR do?

Fixes the calendar invite owner not updating when a booking is reassigned to a different team member. After reassignment, the calendar invite now correctly reflects the new host as the owner in both Google Calendar and Outlook.

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):

#Before



#After



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. 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.

##Key changes:

  • Update organizer field to use new user's details when host changes

  • Preserve original iCalUID to prevent duplicate calendar events

  • Update existing calendar event instead of delete+create pattern

  • Remove blocking video integration validation (consistent with initial booking behavior)

  • Show individual host name instead of team name in event title

How should this be tested?

#Prerequisites:

  • Team event type with round-robin assignment
  • At least 2 team members with calendar integration (Google Calendar recommended)
  • No video integration setup required

#Test steps:

  • Create a booking assigned to Team Member A
  • Check calendar - event organizer should be Member A
  • Reassign booking to Team Meamber B via admin panel
  • Check calendar - event organizer should update to Member B
  • Verify no duplicate events exist
  • Verify event title shows "Member B" not team name
  • Reassign back to Member A - should work bidirectionally

#Expected outcome:

  • Calendar event organizer updates to new host

  • Single event (no duplicates)

  • Event title shows individual host name

  • Reassignment completes without errors

  • Are there environment variables that should be set?

  • What are the minimal test data to have?

  • What is expected (happy path) to have (input and output)?

  • Any other important info that could help to test that PR

Checklist

  • I haven't read the contributing guide
  • 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

@vercel
Copy link

vercel bot commented Oct 9, 2025

@husniabad is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions bot added enterprise area: enterprise, audit log, organisation, SAML, SSO High priority Created by Linear-GitHub Sync reactive⚡︎ 🐛 bug Something isn't working labels Oct 9, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 9, 2025

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.

Details:

No release type found in pull request title "fix calendar invite organizer reassignment". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 9, 2025

Walkthrough

  • handleRescheduleEventManager.ts: Cal Video creation failure switched from throwing an error to logging a warning and continuing.
  • roundRobinManualReassignment.ts: newBookingTitle teamName set to undefined; iCalUID added to update payload; organizer fields now conditional on hasOrganizerChanged; removed parsing/deletion logic for prior host events/meetings; reschedule call now always passes changedOrganizer: false; same adjustments mirrored in duplicate path.
  • roundRobinManualReassignment.test.ts: expectations updated to changedOrganizer=false; test renamed and adjusted to expect non-throwing behavior when Cal Video fallback fails, with DB assertion for reassigned booking.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The removal of blocking video integration validation and related Cal Video fallback adjustments in handleRescheduleEventManager.ts and its tests are not referenced in the linked issues, which focus solely on updating the calendar invite owner on reassignment. Consider reverting or extracting the Cal Video fallback changes into a separate pull request so that this PR remains focused on the calendar invite owner update described in the linked issues.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately summarizes the primary change by indicating a fix for calendar invite organizer reassignment, directly reflecting the main objective of updating the invite owner during reassignment.
Linked Issues Check ✅ Passed The PR implements the objectives from the linked issues by updating organizer fields to the new host’s details, preserving the original iCalUID to prevent duplicates, updating the existing calendar event instead of deleting and recreating it, and adjusting the event title to show the individual host name for both Google Calendar and Outlook.
Description Check ✅ Passed The description thoroughly explains the purpose of the PR, outlines the bug being fixed, references the relevant issues, details key changes and testing steps, and remains directly related to the changeset.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@husniabad husniabad changed the title fix calendar invite organizer reassignment fix: calendar invite organizer reassignment Oct 9, 2025
@husniabad husniabad marked this pull request as ready for review October 9, 2025 21:41
@graphite-app graphite-app bot requested a review from a team October 9, 2025 21:41
@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Oct 9, 2025
@dosubot dosubot bot added the teams area: teams, round robin, collective, managed event-types label Oct 9, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/features/ee/round-robin/roundRobinManualReassignment.test.ts (1)

655-665: Align the expectation with an organizer change.

Here the booking is reassigned from the Google Meet host to the Zoom host, so the organizer switches. The test should assert changedOrganizer: true; keeping it false hides the bug and will fail once the implementation is corrected.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2a23911 and 1d0dd0f.

📒 Files selected for processing (3)
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts (1 hunks)
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts (5 hunks)
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.test.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: anglerfishlyy
PR: calcom/cal.com#0
File: :0-0
Timestamp: 2025-08-27T16:39:38.192Z
Learning: anglerfishlyy successfully implemented CAL-3076 email invitation feature for Cal.com team event-types in PR #23312. The feature allows inviting people via email directly from assignment flow, with automatic team invitation if email doesn't belong to existing team member. Implementation includes Host type modifications (userId?: number, email?: string, isPending?: boolean), CheckedTeamSelect component updates with CreatableSelect, TRPC schema validation with zod email validation, and integration with existing teamInvite system.
🧬 Code graph analysis (2)
packages/features/ee/round-robin/roundRobinManualReassignment.ts (1)
packages/features/ee/round-robin/handleRescheduleEventManager.ts (1)
  • handleRescheduleEventManager (28-207)
packages/features/ee/round-robin/roundRobinManualReassignment.test.ts (1)
apps/web/test/utils/bookingScenario/expects.ts (1)
  • expectBookingToBeInDatabase (418-435)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache

Comment on lines 302 to 306
expectEventManagerCalledWith(eventManagerRescheduleSpy, {
uid: bookingToReassignUid,
changedOrganizer: true,
changedOrganizer: false,
destinationCalendars: expect.arrayContaining([expect.objectContaining(testDestinationCalendar)]),
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Expect changedOrganizer to be true when the host actually changes.

In this scenario the booking organizer moves from the original host to newHost, so hasOrganizerChanged evaluates to true. Forcing the expectation to false masks regressions and contradicts the intended behavior once we pass the correct flag to the rescheduler. Please update the assertion to expect true (and adjust mocks accordingly).

🤖 Prompt for AI Agents
In packages/features/ee/round-robin/roundRobinManualReassignment.test.ts around
lines 302 to 306, the test currently asserts changedOrganizer: false even though
the booking organizer is moved to newHost; update the expectation to
changedOrganizer: true to match hasOrganizerChanged being true, and ensure any
related mocks/spies that construct or validate the rescheduler payload are
updated to reflect the organizer change (e.g., mock
destinationCalendar/organizer fields and any helper that computes
hasOrganizerChanged) so the test consistently reflects the new organizer state.

Comment on lines 334 to 339
const { evtWithAdditionalInfo } = await handleRescheduleEventManager({
evt,
rescheduleUid: booking.uid,
newBookingId: undefined,
changedOrganizer: hasOrganizerChanged,
changedOrganizer: false,
previousHostDestinationCalendar: previousHostDestinationCalendar ? [previousHostDestinationCalendar] : [],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Restore hasOrganizerChanged when calling handleRescheduleEventManager.

Hard-coding changedOrganizer: false means the reschedule flow is never told that the host/organizer switched. Two concrete regressions follow:

  1. Inside handleRescheduleEventManager, skipDeleteEventsAndMeetings is derived from this flag, so we go back to deleting/recreating the event instead of updating it—exactly what the PR set out to avoid.
  2. EventManager.reschedule never receives the organizer-change signal, so connectors (Google/Outlook) keep the old organizer, reintroducing the original bug.

Please pass hasOrganizerChanged as before:

     newBookingId: undefined,
-    changedOrganizer: false,
+    changedOrganizer: hasOrganizerChanged,

This keeps the deletion skip in place and ensures external calendars get the organizer update.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { evtWithAdditionalInfo } = await handleRescheduleEventManager({
evt,
rescheduleUid: booking.uid,
newBookingId: undefined,
changedOrganizer: hasOrganizerChanged,
changedOrganizer: false,
previousHostDestinationCalendar: previousHostDestinationCalendar ? [previousHostDestinationCalendar] : [],
const { evtWithAdditionalInfo } = await handleRescheduleEventManager({
evt,
rescheduleUid: booking.uid,
newBookingId: undefined,
changedOrganizer: hasOrganizerChanged,
previousHostDestinationCalendar: previousHostDestinationCalendar ? [previousHostDestinationCalendar] : [],
🤖 Prompt for AI Agents
In packages/features/ee/round-robin/roundRobinManualReassignment.ts around lines
334 to 339, the call to handleRescheduleEventManager hard-codes
changedOrganizer: false which prevents signaling organizer changes; replace the
hard-coded false with the existing hasOrganizerChanged variable (i.e., pass
changedOrganizer: hasOrganizerChanged) so skipDeleteEventsAndMeetings logic and
EventManager.reschedule receive the correct organizer-change flag.

@ibex088
Copy link
Contributor

ibex088 commented Oct 13, 2025

Hi @husniabad,
Thanks for the PR! However, the pr fails to address the issue.
When the host is changed, the event should be removed from the original host’s calendar and added to the new host’s calendar.

@ibex088 ibex088 closed this Oct 13, 2025
@husniabad
Copy link
Contributor Author

Hi @ibex088 thanks for your valuable feedback
However I double checked it, and it is working fine.

When I re-assign booking, the event got removed from host's A linked calendar and recreate it in host's B linked calendar using update method.

how update method works:

  • Preserve Event IdentityiCalUID: booking.iCalUID

    • Keep same iCalUID → Calendar systems recognize it as the SAME event
  • Update Organizer Metadata

    • Change organizer email/name/timezone to new host
    • Calendar event object now has new owner info
  • Call UPDATE Instead of DELETE+CREATE

    • changedOrganizer: false → Triggers UPDATE path in EventManager
    • EventManager calls updateAllCalendarEvents() instead of deleteEventsAndMeetings() + create()
  • Calendar API Does the Migration

    • Google Calendar: events.update(eventId, {organizer: newEmail})
    • Outlook: PATCH /events/{id} with new organizer
    • Calendar system automatically:
      • Removes event from old organizer's calendar
      • Adds event to new organizer's calendar
      • Uses same iCalUID → No duplicates

Key Point

By keeping the same iCalUID and using UPDATE, the calendar system handles the migration atomically. DELETE+CREATE would use different UIDs and risk duplicates/orphans.

@husniabad
Copy link
Contributor Author

cc: @CarinaWolli

@ibex088
Copy link
Contributor

ibex088 commented Oct 14, 2025

Call UPDATE Instead of DELETE+CREATE
changedOrganizer: false → Triggers UPDATE path in EventManager
EventManager calls updateAllCalendarEvents() instead of deleteEventsAndMeetings() + create()

Problem: This causes the event to be updated in the old host’s calendar instead of being deleted there(old host's calendar) and created in the new host’s calendar -- which is not the intended behavior.

@husniabad husniabad deleted the fix/Calendar-invite-owner-updating-after-reassignment branch October 16, 2025 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working community Created by Linear-GitHub Sync enterprise area: enterprise, audit log, organisation, SAML, SSO High priority Created by Linear-GitHub Sync reactive⚡︎ size/M teams area: teams, round robin, collective, managed event-types

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Calendar invite owner not updating after reassignment

2 participants