Skip to content

fix: event not removed from calendar when reassigned#23099

Merged
anikdhabal merged 11 commits intomainfrom
rr_reassignment_issue
Aug 14, 2025
Merged

fix: event not removed from calendar when reassigned#23099
anikdhabal merged 11 commits intomainfrom
rr_reassignment_issue

Conversation

@anikdhabal
Copy link
Contributor

What does this PR do?

  • Fixes #XXXX (GitHub issue number)
  • Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

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

  • 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

@anikdhabal anikdhabal requested a review from a team as a code owner August 14, 2025 17:30
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 14, 2025

Walkthrough

  • Added a new optional boolean parameter skipDeleteEventsAndMeetings to EventManager.reschedule as the last argument.
  • Updated handleNewBooking.ts to compute skipDeleteEventsAndMeetings from changedOrganizer and pass it to reschedule.
  • Modified reschedule logic to use skipDeleteEventsAndMeetings when deciding whether to delete previous events/meetings, affecting both requiresConfirmation and changedOrganizer branches.
  • Introduced a new end-to-end test (roundRobinDeleteEvents.test.ts) verifying deletion and reassignment behavior during round-robin organizer changes, including Google Calendar delete/create calls, booking reassignment, and email dispatch.

Possibly related PRs

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch rr_reassignment_issue

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@graphite-app graphite-app bot requested a review from a team August 14, 2025 17:30
@keithwillcode keithwillcode added the core area: core, team members only label Aug 14, 2025
@dosubot dosubot bot added bookings area: bookings, availability, timezones, double booking 🐛 bug Something isn't working labels Aug 14, 2025
joeauyeung
joeauyeung previously approved these changes Aug 14, 2025
@anikdhabal anikdhabal changed the title fix: event not removed from calendar when reassign fix: event not removed from calendar when reassigned Aug 14, 2025
@graphite-app
Copy link

graphite-app bot commented Aug 14, 2025

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (08/14/25)

1 reviewer was added to this PR based on Keith Williams's automation.

@anikdhabal anikdhabal requested a review from emrysal August 14, 2025 17:38
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: 1

🔭 Outside diff range comments (1)
packages/lib/EventManager.ts (1)

641-656: Critical: requiresConfirmation flow now bypasses confirmation when skipDeleteEventsAndMeetings is true

Replacing !changedOrganizer with !skipDeleteEventsAndMeetings alters semantics: for bookings that require confirmation, passing skipDeleteEventsAndMeetings = true now executes the "else" branch and proceeds to create/update events even though confirmation is required. This contradicts the comment and previous behavior that avoided creating/updating until confirmation (except for the changed-organizer branch).

Restore gating on changedOrganizer for the requires-confirmation path, and use skipDeleteEventsAndMeetings solely to control whether we delete, not whether we bypass confirmation logic.

Suggested fix:

-    if (evt.requiresConfirmation && !skipDeleteEventsAndMeetings) {
-      log.debug("RescheduleRequiresConfirmation: Deleting Event and Meeting for previous booking");
-      // As the reschedule requires confirmation, we can't update the events and meetings to new time yet. So, just delete them and let it be handled when organizer confirms the booking.
-      await this.deleteEventsAndMeetings({
-        event: { ...event, destinationCalendar: previousHostDestinationCalendar },
-        bookingReferences: booking.references,
-      });
-    } else {
+    if (evt.requiresConfirmation && !changedOrganizer) {
+      // As the reschedule requires confirmation, we can't update the events and meetings to new time yet.
+      // Only perform deletion if not explicitly skipped.
+      if (!skipDeleteEventsAndMeetings) {
+        log.debug("RescheduleRequiresConfirmation: Deleting Event and Meeting for previous booking");
+        await this.deleteEventsAndMeetings({
+          event: { ...event, destinationCalendar: previousHostDestinationCalendar },
+          bookingReferences: booking.references,
+        });
+      }
+    } else {
       if (changedOrganizer) {
-        if (!skipDeleteEventsAndMeetings) {
+        if (!skipDeleteEventsAndMeetings) {
           log.debug("RescheduleOrganizerChanged: Deleting Event and Meeting for previous booking");
           await this.deleteEventsAndMeetings({
             event: { ...event, destinationCalendar: previousHostDestinationCalendar },
             bookingReferences: booking.references,
           });
         }

This maintains legacy behavior (no update/create when confirmation is required and organizer didn’t change) while still letting you skip deletion when you’ve already handled it upstream.

If desired, I can follow up with a focused unit test for:

  • requiresConfirmation=true, changedOrganizer=false, skip=true → no update/create nor deletion;
  • requiresConfirmation=true, changedOrganizer=false, skip=false → deletion only;
  • requiresConfirmation=true, changedOrganizer=true, skip=true → no deletion in reschedule(), but create with new organizer.
🧹 Nitpick comments (1)
packages/lib/EventManager.ts (1)

573-575: Avoid boolean flag parameter; add default and consider options object

Adding a trailing optional boolean increases ambiguity at call sites (boolean trap) and is error-prone for future maintenance.

  • Short term: add a default value to make intent explicit.
  • Medium term: switch to a typed options object, e.g. reschedule(event, rescheduleUid, { newBookingId, changedOrganizer, previousHostDestinationCalendar, isBookingRequestedReschedule, skipDeleteEventsAndMeetings }).

Apply the minimal change to add an explicit default:

-    isBookingRequestedReschedule?: boolean,
-    skipDeleteEventsAndMeetings?: boolean
+    isBookingRequestedReschedule?: boolean,
+    skipDeleteEventsAndMeetings: boolean = false
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e237749 and c5b1ac5.

📒 Files selected for processing (2)
  • packages/features/bookings/lib/handleNewBooking.ts (1 hunks)
  • packages/lib/EventManager.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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/lib/EventManager.ts
  • packages/features/bookings/lib/handleNewBooking.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/lib/EventManager.ts
  • packages/features/bookings/lib/handleNewBooking.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Check for E2E label
🔇 Additional comments (1)
packages/features/bookings/lib/handleNewBooking.ts (1)

1705-1707: EventManager.reschedule — skip/delete behavior audited

Checked all call sites of EventManager.reschedule. Findings:

  • packages/features/bookings/lib/handleNewBooking.ts — passes skipDeleteEventsAndMeetings = true (7th arg) and explicitly calls originalHostEventManager.deleteEventsAndMeetings(...) immediately before the reschedule call — intentional/correct.
  • packages/features/ee/round-robin/handleRescheduleEventManager.ts — calls reschedule(..., changedOrganizer, previousHostDestinationCalendar) without skip flag and does not delete elsewhere — reschedule will handle deletion as needed.
  • packages/features/bookings/lib/handleSeats/reschedule/owner/moveSeatedBookingToNewTimeSlot.ts — calls reschedule(copyEvent, rescheduleUid, newBooking.id) with no skip flag and no prior deletion — OK.
  • packages/features/bookings/lib/handleSeats/reschedule/owner/combineTwoSeatedBookings.ts — same as above — OK.

No other call sites found that pass the skip flag. No changes required.

@vercel
Copy link

vercel bot commented Aug 14, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
cal ⬜️ Ignored Aug 14, 2025 8:24pm
cal-eu ⬜️ Ignored Aug 14, 2025 8:24pm

joeauyeung
joeauyeung previously approved these changes Aug 14, 2025
@anikdhabal anikdhabal enabled auto-merge (squash) August 14, 2025 17:53
@github-actions
Copy link
Contributor

github-actions bot commented Aug 14, 2025

E2E results are ready!

joeauyeung
joeauyeung previously approved these changes Aug 14, 2025
Copy link
Contributor

@joeauyeung joeauyeung left a comment

Choose a reason for hiding this comment

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

Thanks for adding the tests

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 97cf3ac and 7ff06fc.

📒 Files selected for processing (1)
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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/roundRobinReassignment.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/roundRobinReassignment.test.ts
🧠 Learnings (1)
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.

Applied to files:

  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
🧬 Code Graph Analysis (1)
packages/features/ee/round-robin/roundRobinReassignment.test.ts (1)
apps/web/test/utils/bookingScenario/bookingScenario.ts (8)
  • getOrganizer (1496-1552)
  • TestData (1215-1487)
  • getGoogleCalendarCredential (1168-1176)
  • getDate (1069-1116)
  • createBookingScenario (954-985)
  • getScenarioData (1554-1640)
  • getMockBookingAttendee (2248-2266)
  • mockCalendarToHaveNoBusySlots (1901-1914)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (2)
packages/features/ee/round-robin/roundRobinReassignment.test.ts (2)

10-13: Good additions: new test helpers are appropriate for calendar-backed scenarios.

Importing getOrganizer, getGoogleCalendarCredential, and mockCalendarToHaveNoBusySlots is the right move for constructing Google Calendar-capable users and mocking the provider.


23-23: LGTM: appStoreMetadata import is correct.

Using appStoreMetadata.googlecalendar.type for the booking reference aligns with how other tests/type checks identify app types.

… robin reassignment

- Remove existing tests and replace with focused test for organizer change scenario
- Verify deleteEventsAndMeetings is called when organizer changes
- Mock reschedule method to simulate real behavior while tracking deletion calls
- Test verifies original host's calendar events are properly deleted
- Ensures booking reassignment and email notifications work correctly

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
@anikdhabal anikdhabal marked this pull request as draft August 14, 2025 19:43
auto-merge was automatically disabled August 14, 2025 19:43

Pull request was converted to draft

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

♻️ Duplicate comments (2)
packages/features/ee/round-robin/roundRobinReassignment.test.ts (2)

134-138: Fix parameter name in email expectation: use prevOrganizer

The helper expects prevOrganizer, not previousOrganizer. This will fail at runtime.

Apply this diff:

-    expectSuccessfulRoundRobinReschedulingEmails({
-      previousOrganizer: originalHost,
-      newOrganizer: newHost,
-      emails,
-    });
+    expectSuccessfulRoundRobinReschedulingEmails({
+      prevOrganizer: originalHost,
+      newOrganizer: newHost,
+      emails,
+    });

85-96: Avoid hard-coded credentialId; derive it from the organizer’s created credential

Hard-coding credentialId: 1 risks flakiness. Use the actual credential ID from originalHost to ensure the correct provider lookup.

Apply this diff:

                 externalCalendarId: "MOCK_EXTERNAL_CALENDAR_ID",
-                credentialId: 1,
+                credentialId: originalHost.credentials?.[0]?.id as number,
                 deleted: null,
🧹 Nitpick comments (2)
packages/features/ee/round-robin/roundRobinReassignment.test.ts (2)

115-122: Don’t couple deletion to “new host” credentials; relax the assertion

Asserting delete uses the new host’s credentials bakes in an implementation detail and may break if the deletion is performed via the original host’s credential (which is arguably more correct). Focus the assertion on the event ID and calendar ID being targeted.

Apply this diff:

-    expect(deleteCall.args.event.organizer.email).toBe(newHost.email); // Current implementation uses new host credentials
+    // Deletion may use either original or new host credentials; avoid coupling to a specific one.
+    expect([originalHost.email, newHost.email]).toContain(deleteCall.args.event.organizer.email);

106-109: Nit: remove unused update mock to keep setup minimal

The test doesn’t assert on update calls; dropping the unused update UID simplifies the setup.

Apply this diff:

-    const calendarMock = mockCalendarToHaveNoBusySlots("googlecalendar", {
-      create: { uid: "NEW_EVENT_ID" },
-      update: { uid: "UPDATED_EVENT_ID" },
-    });
+    const calendarMock = mockCalendarToHaveNoBusySlots("googlecalendar", {
+      create: { uid: "NEW_EVENT_ID" },
+    });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7ff06fc and ffddf7f.

📒 Files selected for processing (1)
  • packages/features/ee/round-robin/roundRobinReassignment.test.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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/roundRobinReassignment.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/roundRobinReassignment.test.ts
🧠 Learnings (1)
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.

Applied to files:

  • packages/features/ee/round-robin/roundRobinReassignment.test.ts
🧬 Code Graph Analysis (1)
packages/features/ee/round-robin/roundRobinReassignment.test.ts (2)
apps/web/test/utils/bookingScenario/bookingScenario.ts (7)
  • getOrganizer (1496-1552)
  • TestData (1215-1487)
  • getGoogleCalendarCredential (1168-1176)
  • getDate (1069-1116)
  • createBookingScenario (954-985)
  • getScenarioData (1554-1640)
  • mockCalendarToHaveNoBusySlots (1901-1914)
apps/web/test/utils/bookingScenario/expects.ts (2)
  • expectBookingToBeInDatabase (413-430)
  • expectSuccessfulRoundRobinReschedulingEmails (710-753)
🔇 Additional comments (1)
packages/features/ee/round-robin/roundRobinReassignment.test.ts (1)

31-47: Good use of scenario builders and Google Calendar test utilities

Using getOrganizer with getGoogleCalendarCredential and selectedCalendars ensures the calendar mock is exercised realistically for both original and new hosts.

@anikdhabal anikdhabal marked this pull request as ready for review August 14, 2025 20:24
@anikdhabal anikdhabal enabled auto-merge (squash) August 14, 2025 20:24
@anikdhabal anikdhabal requested a review from joeauyeung August 14, 2025 20:33
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: 1

🧹 Nitpick comments (5)
packages/features/ee/round-robin/roundRobinDeleteEvents.test.ts (5)

128-132: Strengthen expectations: assert no update path was taken

Given this scenario re-creates the event for the new organizer, we shouldn’t see any update calls. This guards against regressions where the system attempts an update instead of creating anew.

     // Verify that creation occurred with new host credentials
     expect(calendarMock.createEventCalls.length).toBe(1);
     const createCall = calendarMock.createEventCalls[0];
     expect(createCall.args.calEvent.organizer.email).toBe(newHost.email);
+    // Ensure we didn't go down the update path by mistake
+    expect(calendarMock.updateEventCalls.length).toBe(0);

121-121: Minor: prefer “toBeGreaterThan(0)” over “toBeGreaterThanOrEqual(1)”

Both are equivalent here; the former is slightly clearer.

-    expect(calendarMock.deleteEventCalls.length).toBeGreaterThanOrEqual(1);
+    expect(calendarMock.deleteEventCalls.length).toBeGreaterThan(0);

34-35: Prefer static import for roundRobinReassignment unless there’s a solid reason for dynamic

Static imports simplify type-checking, test readability, and toolchain optimizations. Use dynamic import only if you’re avoiding a circular dependency or a heavy module that must be lazily loaded.

-    const roundRobinReassignment = (await import("./roundRobinReassignment")).default;
+    // statically imported at top of file

Add this at the top-level imports:

import roundRobinReassignment from "./roundRobinReassignment";

133-144: Add DB reference assertions to fully validate cleanup and re-creation

Right now we validate calendar client interactions and booking owner change. Consider also asserting:

  • The original Google reference is marked deleted/soft-deleted.
  • A new Google reference exists for the new event/host.

This ensures data integrity matches the external side-effects.

If there’s a helper like expectBookingReferences or access to the booking’s references via your test utils, I can wire up precise assertions. Otherwise, I can add a small helper to fetch the booking by UID and validate references directly.


28-33: Add a companion test for “skipDeleteEventsAndMeetings = true” path

This PR introduces a flag that controls deletion. We currently cover the “deletion happens” case; please add a test where the flag is true (or where the code path computes it as such) to assert that:

  • No delete calls occur,
  • The booking is reassigned correctly,
  • Email behavior aligns with the non-deletion flow.

If roundRobinReassignment doesn’t expose a way to force the skip flag, I can help craft a focused test that calls the lower-level reschedule API or sets up a scenario that yields skipDeleteEventsAndMeetings = true.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ffddf7f and 67b2835.

📒 Files selected for processing (1)
  • packages/features/ee/round-robin/roundRobinDeleteEvents.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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/roundRobinDeleteEvents.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/roundRobinDeleteEvents.test.ts
🧠 Learnings (1)
📚 Learning: 2025-07-22T11:42:47.623Z
Learnt from: CarinaWolli
PR: calcom/cal.com#22296
File: packages/lib/bookings/filterHostsBySameRoundRobinHost.ts:41-42
Timestamp: 2025-07-22T11:42:47.623Z
Learning: The filterHostsBySameRoundRobinHost function in packages/lib/bookings/filterHostsBySameRoundRobinHost.ts has a known limitation where it doesn't work correctly with fixed hosts or round robin groups. This is pre-existing technical debt that was already broken before the round robin groups feature. CarinaWolli has documented this in Linear issue CAL-6134 for future fix.

Applied to files:

  • packages/features/ee/round-robin/roundRobinDeleteEvents.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (2)
packages/features/ee/round-robin/roundRobinDeleteEvents.test.ts (2)

98-100: Avoid hard-coding credentialId — derive it from the seeded host to prevent flakiness

Using a magic number for credentialId can break if fixture ordering changes; tie the id to the seeded organizer’s actual Google credential so deletion uses the correct account.

  • File: packages/features/ee/round-robin/roundRobinDeleteEvents.test.ts — around lines 98–100

Suggested change:

-                credentialId: 1,
+                // Use the actual credential ID of the original host to guarantee correct account usage
+                credentialId: originalHost.credentials[0].id,

If originalHost.credentials[0].id isn’t available in the fixture, derive the ID from your test helpers or adjust fixture utilities to expose the credential ID. I attempted to locate this test file in the repo but couldn't find it — please confirm the path so I can re-verify.


36-53: No action needed — seeded organizers get distinct mocked credentials

getGoogleCalendarCredential() returns a fresh mocked credential object on each call (apps/web/test/utils/bookingScenario/bookingScenario.ts → getMockedCredential). createBookingScenario inserts users (and their credentials) before inserting bookings (createBookingScenario → addUsers then addBookings), so the booking reference in the test will point at the original host’s created credential. The test (packages/features/ee/round-robin/roundRobinDeleteEvents.test.ts) calls getGoogleCalendarCredential() separately for each organizer, so they will not share the same DB credential.

  • Files inspected:
    • apps/web/test/utils/bookingScenario/bookingScenario.ts — getMockedCredential / createBookingScenario / addUsers
    • packages/features/ee/round-robin/roundRobinDeleteEvents.test.ts — test uses two separate getGoogleCalendarCredential() calls

@anikdhabal anikdhabal merged commit 18a0e2d into main Aug 14, 2025
37 of 38 checks passed
@anikdhabal anikdhabal deleted the rr_reassignment_issue branch August 14, 2025 20:42
zomars pushed a commit that referenced this pull request Aug 14, 2025
* fix: event not removed from calendar when reassign

* fix test

* tweak

* add test

* test: add comprehensive test for calendar event deletion during round robin reassignment

- Remove existing tests and replace with focused test for organizer change scenario
- Verify deleteEventsAndMeetings is called when organizer changes
- Mock reschedule method to simulate real behavior while tracking deletion calls
- Test verifies original host's calendar events are properly deleted
- Ensures booking reassignment and email notifications work correctly

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

* update

* revert roundRobinReassignment.test.ts

* revert

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
zomars pushed a commit that referenced this pull request Aug 15, 2025
* fix: event not removed from calendar when reassign

* fix test

* tweak

* add test

* test: add comprehensive test for calendar event deletion during round robin reassignment

- Remove existing tests and replace with focused test for organizer change scenario
- Verify deleteEventsAndMeetings is called when organizer changes
- Mock reschedule method to simulate real behavior while tracking deletion calls
- Test verifies original host's calendar events are properly deleted
- Ensures booking reassignment and email notifications work correctly

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

* update

* revert roundRobinReassignment.test.ts

* revert

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@coderabbitai coderabbitai bot mentioned this pull request Oct 15, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bookings area: bookings, availability, timezones, double booking 🐛 bug Something isn't working core area: core, team members only ready-for-e2e

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants