Skip to content

Comments

fix: Selected calendar delegation credentials#24190

Merged
volnei merged 4 commits intomainfrom
fix/calendar_cache_delegation_creds
Oct 1, 2025
Merged

fix: Selected calendar delegation credentials#24190
volnei merged 4 commits intomainfrom
fix/calendar_cache_delegation_creds

Conversation

@volnei
Copy link
Contributor

@volnei volnei commented Oct 1, 2025

What does this PR do?

  • Fix delegation credentials not being used
  • Remove shouldServeCache to avoid relaying on old cache service.

@volnei volnei marked this pull request as ready for review October 1, 2025 01:17
@graphite-app graphite-app bot requested review from a team and removed request for a team October 1, 2025 01:17
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 1, 2025

Walkthrough

  • CalendarSubscriptionService now obtains credentials by passing the full SelectedCalendar to a new delegation helper and early-returns if neither credentialId nor delegationCredentialId yields a credential; log messages updated to reference selectedCalendar.id/channelId and credential presence.
  • A new public function getCredentialForSelectedCalendar was added to the delegationCredential server module to resolve delegation or non-delegation credentials from a SelectedCalendar.
  • SelectedCalendarRepository method findByIdWithCredentials was renamed to findById and no longer includes related credential data.
  • CalendarCacheWrapper.getAvailability removed the optional shouldServeCache path and now always reads from cache.
  • Tests and mocks updated to use the renamed repository method and the new getCredentialForSelectedCalendar; mocked SelectedCalendar objects include delegationCredentialId where relevant.

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title “fix: Selected calendar delegation credentials” succinctly captures the primary change—correcting how delegation credentials are handled for selected calendars—without extraneous details. It is concise, clearly related to the core issue addressed by the pull request, and avoids vague or generic language. While it does not mention cache removal, PR titles are not required to enumerate every change. This phrasing enables a reader to quickly grasp the main purpose of the update.
Description Check ✅ Passed The description clearly outlines the two main modifications: fixing unused delegation credentials and removing the shouldServeCache flag to discontinue reliance on the legacy cache service. It directly corresponds to the changes observed in credential handling and cache logic within the code. Although brief, the description conveys relevant information about the PR’s purpose and scope. It is neither off-topic nor overly vague.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/calendar_cache_delegation_creds

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.

@keithwillcode keithwillcode added core area: core, team members only foundation labels Oct 1, 2025
@dosubot dosubot bot added the 🐛 bug Something isn't working label Oct 1, 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: 1

Caution

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

⚠️ Outside diff range comments (1)
packages/lib/server/repository/__tests__/SelectedCalendarRepository.test.ts (1)

59-79: Fix test data inconsistency.

The test mock returns a calendar with nested credential.delegationCredential data (lines 60-68, 70), and the assertion expects this data (line 78). However, the actual findById implementation no longer includes credential relations in its query.

The test should mock and assert only the data that findById actually returns (a plain SelectedCalendar without nested credentials).

Apply this diff to fix the test:

     test("should find selected calendar by id with credential delegation", async () => {
-      const mockCalendarWithCredential = {
-        ...mockSelectedCalendar,
-        credential: {
-          delegationCredential: {
-            id: "delegation-id",
-            key: { client_email: "test@service.com" },
-          },
-        },
-      };
-
-      vi.mocked(mockPrismaClient.selectedCalendar.findUnique).mockResolvedValue(mockCalendarWithCredential);
+      vi.mocked(mockPrismaClient.selectedCalendar.findUnique).mockResolvedValue(mockSelectedCalendar);
 
       const result = await repository.findById("test-calendar-id");
 
       expect(mockPrismaClient.selectedCalendar.findUnique).toHaveBeenCalledWith({
         where: { id: "test-calendar-id" },
       });
 
-      expect(result).toEqual(mockCalendarWithCredential);
+      expect(result).toEqual(mockSelectedCalendar);
     });

Also consider updating the test description on line 59 since it mentions "with credential delegation" but the method no longer includes credentials.

🧹 Nitpick comments (2)
packages/features/calendar-subscription/lib/cache/CalendarCacheWrapper.ts (1)

63-65: Remove commented parameter.

The commented _shouldServeCache?: boolean parameter on line 64 should be removed entirely rather than left as a comment. Dead code in method signatures can cause confusion for future maintainers.

Apply this diff to clean up the signature:

   async getAvailability(
     dateFrom: string,
     dateTo: string,
-    selectedCalendars: IntegrationCalendar[]
-    // _shouldServeCache?: boolean
+    selectedCalendars: IntegrationCalendar[]
     // _fallbackToPrimary?: boolean
   ): Promise<EventBusyDate[]> {
packages/lib/server/repository/SelectedCalendarRepository.ts (1)

8-12: Consider using explicit select if not all fields are needed.

The query now correctly avoids include for relations. However, per coding guidelines for Prisma queries, you should "only select data you need; never use include, always use select".

If consumers of this method don't require all SelectedCalendar fields, consider adding a select clause to fetch only necessary fields.

Example if only core fields are needed:

   async findById(id: string) {
     return this.prismaClient.selectedCalendar.findUnique({
       where: { id },
+      select: {
+        id: true,
+        userId: true,
+        integration: true,
+        externalId: true,
+        credentialId: true,
+        delegationCredentialId: true,
+        // ... other required fields
+      },
     });
   }
📜 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 e2b2a18 and 45b204b.

📒 Files selected for processing (8)
  • packages/features/calendar-subscription/lib/CalendarSubscriptionService.ts (6 hunks)
  • packages/features/calendar-subscription/lib/__mocks__/delegationCredential.ts (1 hunks)
  • packages/features/calendar-subscription/lib/__tests__/CalendarSubscriptionService.test.ts (6 hunks)
  • packages/features/calendar-subscription/lib/cache/CalendarCacheWrapper.ts (1 hunks)
  • packages/lib/delegationCredential/server.ts (2 hunks)
  • packages/lib/server/repository/SelectedCalendarRepository.interface.ts (1 hunks)
  • packages/lib/server/repository/SelectedCalendarRepository.ts (1 hunks)
  • packages/lib/server/repository/__tests__/SelectedCalendarRepository.test.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.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/server/repository/__tests__/SelectedCalendarRepository.test.ts
  • packages/lib/server/repository/SelectedCalendarRepository.interface.ts
  • packages/features/calendar-subscription/lib/__mocks__/delegationCredential.ts
  • packages/lib/server/repository/SelectedCalendarRepository.ts
  • packages/lib/delegationCredential/server.ts
  • packages/features/calendar-subscription/lib/__tests__/CalendarSubscriptionService.test.ts
  • packages/features/calendar-subscription/lib/cache/CalendarCacheWrapper.ts
  • packages/features/calendar-subscription/lib/CalendarSubscriptionService.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/server/repository/__tests__/SelectedCalendarRepository.test.ts
  • packages/lib/server/repository/SelectedCalendarRepository.interface.ts
  • packages/features/calendar-subscription/lib/__mocks__/delegationCredential.ts
  • packages/lib/server/repository/SelectedCalendarRepository.ts
  • packages/lib/delegationCredential/server.ts
  • packages/features/calendar-subscription/lib/__tests__/CalendarSubscriptionService.test.ts
  • packages/features/calendar-subscription/lib/cache/CalendarCacheWrapper.ts
  • packages/features/calendar-subscription/lib/CalendarSubscriptionService.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/lib/server/repository/__tests__/SelectedCalendarRepository.test.ts
  • packages/lib/server/repository/SelectedCalendarRepository.interface.ts
  • packages/features/calendar-subscription/lib/__mocks__/delegationCredential.ts
  • packages/lib/server/repository/SelectedCalendarRepository.ts
  • packages/lib/delegationCredential/server.ts
  • packages/features/calendar-subscription/lib/__tests__/CalendarSubscriptionService.test.ts
  • packages/features/calendar-subscription/lib/cache/CalendarCacheWrapper.ts
  • packages/features/calendar-subscription/lib/CalendarSubscriptionService.ts
**/*Repository.ts

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

Repository files must include Repository suffix, prefix with technology if applicable (e.g., PrismaAppRepository.ts), and use PascalCase matching the exported class

Files:

  • packages/lib/server/repository/SelectedCalendarRepository.ts
**/*Service.ts

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

Service files must include Service suffix, use PascalCase matching exported class, and avoid generic names (e.g., MembershipService.ts)

Files:

  • packages/features/calendar-subscription/lib/CalendarSubscriptionService.ts
🧠 Learnings (1)
📚 Learning: 2025-09-08T07:27:42.903Z
Learnt from: vijayraghav-io
PR: calcom/cal.com#16878
File: packages/app-store/feishucalendar/api/callback.ts:72-79
Timestamp: 2025-09-08T07:27:42.903Z
Learning: In the Cal.com codebase, some calendar integrations like google-calendar already use SelectedCalendarRepository.create for selectedCalendar creation, which automatically triggers reconnection logic, while others like feishucalendar use direct prisma.selectedCalendar.create calls that bypass the repository hooks.

Applied to files:

  • packages/lib/server/repository/SelectedCalendarRepository.ts
🧬 Code graph analysis (6)
packages/lib/server/repository/SelectedCalendarRepository.interface.ts (1)
packages/types/Calendar.d.ts (1)
  • SelectedCalendar (320-323)
packages/features/calendar-subscription/lib/__mocks__/delegationCredential.ts (1)
packages/lib/delegationCredential/server.ts (1)
  • getCredentialForSelectedCalendar (659-680)
packages/lib/delegationCredential/server.ts (3)
packages/types/Calendar.d.ts (1)
  • SelectedCalendar (320-323)
packages/lib/server/repository/credential.ts (1)
  • CredentialRepository (28-288)
packages/lib/delegationCredential/clientAndServer.ts (1)
  • buildNonDelegationCredential (23-41)
packages/features/calendar-subscription/lib/__tests__/CalendarSubscriptionService.test.ts (2)
packages/features/calendar-subscription/lib/__mocks__/delegationCredential.ts (1)
  • getCredentialForSelectedCalendar (3-8)
packages/lib/delegationCredential/server.ts (1)
  • getCredentialForSelectedCalendar (659-680)
packages/features/calendar-subscription/lib/cache/CalendarCacheWrapper.ts (1)
packages/types/Calendar.d.ts (1)
  • IntegrationCalendar (245-254)
packages/features/calendar-subscription/lib/CalendarSubscriptionService.ts (3)
packages/types/Calendar.d.ts (1)
  • SelectedCalendar (320-323)
packages/features/calendar-subscription/lib/CalendarSubscriptionPort.interface.ts (1)
  • CalendarCredential (42-42)
packages/lib/delegationCredential/server.ts (1)
  • getCredentialForSelectedCalendar (659-680)
⏰ 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
🔇 Additional comments (2)
packages/lib/server/repository/SelectedCalendarRepository.interface.ts (1)

5-9: LGTM!

The method rename from findByIdWithCredentials to findById appropriately reflects that credentials are no longer fetched with the query. The interface change aligns cleanly with the implementation.

packages/features/calendar-subscription/lib/__mocks__/delegationCredential.ts (1)

3-12: LGTM!

The mock function rename from getCredentialForCalendarCache to getCredentialForSelectedCalendar correctly aligns with the new API introduced in packages/lib/delegationCredential/server.ts. The mock return value structure is appropriate for testing the credential retrieval flow.

@vercel
Copy link

vercel bot commented Oct 1, 2025

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

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
cal Ignored Ignored Oct 1, 2025 11:28am
cal-eu Ignored Ignored Oct 1, 2025 11:28am

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 (1)
packages/lib/server/repository/credential.ts (1)

29-36: Consider making all methods instance methods for consistency.

The class now mixes static methods (using the global prisma import) with an instance method (using injected primaClient). This creates two different usage patterns and makes testing more complex.

For better consistency and testability, consider either:

  1. Converting all static methods to instance methods using the injected client, or
  2. Making this new method static like the existing findByIdIncludeDelegationCredential (line 117)
📜 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 45b204b and 315ca69.

📒 Files selected for processing (2)
  • packages/lib/delegationCredential/server.ts (2 hunks)
  • packages/lib/server/repository/credential.ts (3 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/lib/server/repository/credential.ts
  • packages/lib/delegationCredential/server.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/server/repository/credential.ts
  • packages/lib/delegationCredential/server.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/lib/server/repository/credential.ts
  • packages/lib/delegationCredential/server.ts
🧠 Learnings (1)
📚 Learning: 2025-09-01T08:56:14.071Z
Learnt from: nangelina
PR: calcom/cal.com#23486
File: packages/app-store/kyzon-space/lib/tokenManager.ts:25-31
Timestamp: 2025-09-01T08:56:14.071Z
Learning: In token refresh utilities like tokenManager.ts, accessing credential.key from Prisma is legitimate and necessary for OAuth token refresh flows. These internal utilities need stored credentials to refresh tokens and don't expose them in API responses.

Applied to files:

  • packages/lib/server/repository/credential.ts
🧬 Code graph analysis (2)
packages/lib/server/repository/credential.ts (2)
packages/prisma/index.ts (1)
  • PrismaClient (84-84)
packages/prisma/selects/credential.ts (1)
  • credentialForCalendarServiceSelect (3-17)
packages/lib/delegationCredential/server.ts (3)
packages/types/Calendar.d.ts (1)
  • SelectedCalendar (320-323)
packages/lib/server/repository/credential.ts (1)
  • CredentialRepository (28-297)
packages/lib/delegationCredential/clientAndServer.ts (1)
  • buildNonDelegationCredential (23-41)
🔇 Additional comments (3)
packages/lib/server/repository/credential.ts (1)

169-169: LGTM!

Minor formatting improvement.

packages/lib/delegationCredential/server.ts (2)

11-12: LGTM!

Import changes correctly use named imports and add the necessary SelectedCalendar type.


659-663: Ignore type mismatch concern The Prisma SelectedCalendar model (in packages/prisma/schema.prisma) defines delegationCredentialId, so the function’s Partial<SelectedCalendar> signature is correct.

Likely an incorrect or invalid review comment.

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

📜 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 33ccf4a and e71f31a.

📒 Files selected for processing (1)
  • packages/lib/server/repository/credential.ts (3 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/lib/server/repository/credential.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/server/repository/credential.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/lib/server/repository/credential.ts
🧠 Learnings (1)
📚 Learning: 2025-09-01T08:56:14.071Z
Learnt from: nangelina
PR: calcom/cal.com#23486
File: packages/app-store/kyzon-space/lib/tokenManager.ts:25-31
Timestamp: 2025-09-01T08:56:14.071Z
Learning: In token refresh utilities like tokenManager.ts, accessing credential.key from Prisma is legitimate and necessary for OAuth token refresh flows. These internal utilities need stored credentials to refresh tokens and don't expose them in API responses.

Applied to files:

  • packages/lib/server/repository/credential.ts
🧬 Code graph analysis (1)
packages/lib/server/repository/credential.ts (2)
packages/prisma/index.ts (1)
  • PrismaClient (84-84)
packages/prisma/selects/credential.ts (1)
  • credentialForCalendarServiceSelect (3-17)

Copy link
Contributor

@emrysal emrysal left a comment

Choose a reason for hiding this comment

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

LGTM

@volnei volnei merged commit 2ac3104 into main Oct 1, 2025
60 of 61 checks passed
@volnei volnei deleted the fix/calendar_cache_delegation_creds branch October 1, 2025 14:20
@github-actions
Copy link
Contributor

github-actions bot commented Oct 1, 2025

E2E results are ready!

emrysal pushed a commit that referenced this pull request Oct 1, 2025
* Fix selected calendar delegation credentials
@volnei volnei mentioned this pull request Oct 3, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working core area: core, team members only foundation ready-for-e2e size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants