feat: add calendar cache status and actions (#22532) - #2
Conversation
* feat: add calendar cache status dropdown - Add updatedAt field to CalendarCache schema with migration - Create tRPC cacheStatus endpoint for fetching cache timestamps - Add action dropdown to CalendarSwitch for Google Calendar entries - Display formatted last updated timestamp in dropdown - Add placeholder for cache deletion functionality - Include translation strings for dropdown content The dropdown only appears for Google Calendar integrations that have active cache entries and provides cache management options for future extensibility. Co-Authored-By: zomars@cal.com <zomars@me.com> * fix: resolve Prisma type incompatibilities in repository files - Remove problematic satisfies clause in selectedCalendar.ts - Add missing cacheStatus parameter to ConnectedCalendarList component - Fixes type errors that were preventing CI from passing Co-Authored-By: zomars@cal.com <zomars@me.com> * refactor: integrate cache status into connectedCalendars handler - Remove separate cacheStatus tRPC endpoint as requested - Return cache status as separate field in connectedCalendars response - Update UI components to use cache data from connectedCalendars - Fix Prisma type incompatibilities in repository files Co-Authored-By: zomars@cal.com <zomars@me.com> * fix: resolve Prisma type incompatibilities and fix data flow for cache status - Fix Prisma.SortOrder usage in membership.ts orderBy clauses - Remove problematic satisfies clause in selectedCalendar.ts - Fix TeamSelect type reference in team.ts - Update SelectedCalendarsSettingsWebWrapper to properly pass cacheStatus data flow Co-Authored-By: zomars@cal.com <zomars@me.com> * Discard changes to packages/lib/server/repository/membership.ts * Discard changes to packages/lib/server/repository/team.ts * fix: improve calendar cache dropdown with proper formatting and subscription logic - Fix timestamp HTML entity encoding with interpolation escapeValue: false - Only show dropdown for subscribed Google calendars (googleChannelId exists) - Hide delete option when no cache data exists - Include updatedAt and googleChannelId fields upstream in user repository - Update data flow to pass subscription status through components Co-Authored-By: zomars@cal.com <zomars@me.com> * feat: update SelectedCalendar.updatedAt when Google webhooks trigger cache refresh - Add updateManyByCredentialId method to SelectedCalendarRepository - Update fetchAvailabilityAndSetCache to refresh SelectedCalendar timestamps - Ensure webhook flow updates both CalendarCache and SelectedCalendar records - Maintain proper timestamp tracking for calendar cache operations Co-Authored-By: zomars@cal.com <zomars@me.com> * Add script to automate Tunnelmole webhook setup Introduces test-gcal-webhooks.sh to start Tunnelmole, extract the public URL, and update GOOGLE_WEBHOOK_URL in the .env file. Handles process management, rate limits, and ensures environment configuration for Google Calendar webhooks. * Update dev:cron script to use npx tsx Replaces 'ts-node' with 'npx tsx' in the dev:cron script for running cron-tester.ts, likely to improve compatibility or leverage tsx features. * Update cache status string and improve CalendarSwitch UI Renamed 'last_updated' to 'cache_last_updated' in locale file for clarity and updated CalendarSwitch to use the new string. Also added dark mode text color support for cache status display. * refactor: move cache management to credential-level dropdown with Remove App - Create CredentialActionsDropdown component consolidating cache and app removal actions - Add deleteCache tRPC mutation for credential-level cache deletion - Update connectedCalendars handler to include cacheUpdatedAt at credential level - Move dropdown from individual CalendarSwitch to credential level in SelectedCalendarsSettingsWebWrapper - Remove cache-related props from CalendarSwitch component - Add translation strings for cache management actions - Consolidate all credential-level actions (cache management + Remove App) in one dropdown Co-Authored-By: zomars@cal.com <zomars@me.com> * fix: remove duplicate translation keys in common.json - Remove duplicate cache-related keys at lines 51-56 - Keep properly positioned keys later in file - Addresses GitHub comment from zomars about duplicate keys Co-Authored-By: zomars@cal.com <zomars@me.com> * fix: rename translation key to cache_last_updated - Address GitHub comment from zomars - Rename 'last_updated' to 'cache_last_updated' for specificity - Update usage in CredentialActionsDropdown component Co-Authored-By: zomars@cal.com <zomars@me.com> * fix: remove duplicate last_updated translation key Co-Authored-By: zomars@cal.com <zomars@me.com> * fix: add confirmation dialog for cache deletion and use repository pattern - Add confirmation dialog for destructive cache deletion action - Replace direct Prisma calls with CalendarCacheRepository pattern - Add getCacheStatusByCredentialIds method to repository interface - Fix import paths for UI components - Address GitHub review comments from zomars Co-Authored-By: zomars@cal.com <zomars@me.com> * Update CredentialActionsDropdown.tsx * Update common.json * Update common.json * fix: remove nested div wrapper to resolve HTML structure error - Remove wrapping div around DisconnectIntegration component - Fixes nested <p> tag validation error preventing Remove App functionality - Maintains existing confirmation dialog patterns Co-Authored-By: zomars@cal.com <zomars@me.com> * Fix API handler response termination logic Removed unnecessary return values after setting status in the integrations API handler. This clarifies response handling and prevents returning the response object when not needed. Resolves "API handler should not return a value, received object". * fix: 400 is correct error code for computing slot for past booking (#22574) * fix * add test * chore: release v5.5.1 * Refactor credential disconnect to use confirmation dialog Replaces the DisconnectIntegration component with an inline confirmation dialog for removing app credentials. Adds disconnect mutation logic and updates UI to improve user experience and consistency. * Set default value for CalendarCache.updatedAt Added a default value of NOW() for the updatedAt column in the CalendarCache table to ensure existing and future rows have a valid timestamp. Updated the Prisma schema to reflect this change and provide compatibility for legacy data and raw inserts. --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Benny Joo <sldisek783@gmail.com> Co-authored-by: emrysal <me@alexvanandel.com>
There was a problem hiding this comment.
Walkthrough
This PR implements a comprehensive calendar cache management system with UI controls for viewing and deleting cached data. The changes introduce cache status tracking via a new updatedAt timestamp field in the CalendarCache model, along with repository methods to query cache freshness. A new CredentialActionsDropdown component provides users with options to delete cached calendar data and manage credentials. The implementation includes tRPC endpoints for cache deletion, automatic timestamp updates during calendar synchronization, and enhanced type definitions to expose cache metadata. Development tooling improvements include migrating from ts-node to tsx and adding a webhook testing script for Google Calendar integration.
Changes
| File(s) | Summary |
|---|---|
packages/prisma/schema.prismapackages/prisma/migrations/20250715160635_add_calendar_cache_updated_at/migration.sql |
Added updatedAt timestamp field to CalendarCache model with @default(now()) and @updatedAt directives for automatic timestamp tracking. |
packages/features/calendar-cache/calendar-cache.repository.interface.tspackages/features/calendar-cache/calendar-cache.repository.tspackages/features/calendar-cache/calendar-cache.repository.mock.ts |
Added getCacheStatusByCredentialIds method to retrieve cache status for multiple credentials using Prisma groupBy aggregation; mock implementation returns empty array. |
packages/lib/server/repository/selectedCalendar.ts |
Added updateManyByCredentialId method for bulk updates and refactored findMany to directly pass parameters without intermediate variable. |
packages/lib/getConnectedDestinationCalendars.tspackages/lib/server/repository/user.ts |
Extended type definitions and Prisma queries to include updatedAt and googleChannelId fields for selected calendars. |
packages/app-store/googlecalendar/lib/CalendarService.ts |
Added call to SelectedCalendarRepository.updateManyByCredentialId() to update timestamps for all selected calendars after synchronization. |
packages/features/apps/components/CredentialActionsDropdown.tsx |
Introduced new client-side dropdown component for managing credentials with cache deletion and app disconnection actions, including confirmation dialogs and tRPC mutations. |
packages/platform/atoms/selected-calendars/wrappers/SelectedCalendarsSettingsWebWrapper.tsx |
Replaced DisconnectIntegration with CredentialActionsDropdown component, passing additional props for cache status and delegation handling. |
packages/trpc/server/routers/viewer/calendars/_router.tsxpackages/trpc/server/routers/viewer/calendars/deleteCache.handler.ts |
Added deleteCache mutation endpoint with handler that validates credential ownership and deletes associated cache entries. |
packages/trpc/server/routers/viewer/calendars/connectedCalendars.handler.ts |
Enhanced handler to fetch and include cache status information (cacheUpdatedAt) for each connected calendar credential. |
apps/web/public/static/locales/en/common.json |
Added seven i18n keys for cache management UI labels, actions, and user feedback messages. |
apps/web/package.json |
Updated dev:cron script to use npx tsx instead of ts-node for TypeScript execution. |
scripts/test-gcal-webhooks.sh |
Added bash script for automated Tunnelmole tunnel management for Google Calendar webhook testing with environment variable updates. |
Sequence Diagram
This diagram shows the interactions between components:
sequenceDiagram
participant Service as Calendar Service
participant API as External Calendar API
participant Cache as Cache System
participant Repo as SelectedCalendarRepository
participant DB as Database
Service->>API: fetchAvailability(parsedArgs)
activate API
API-->>Service: availability data
deactivate API
Service->>Cache: setAvailabilityInCache(parsedArgs, data)
activate Cache
Cache-->>Service: cache updated
deactivate Cache
Note over Service,Repo: NEW: Update timestamps for all calendars
Service->>Repo: updateManyByCredentialId(credential.id, {})
activate Repo
Repo->>DB: UPDATE SelectedCalendar<br/>SET updatedAt = NOW()<br/>WHERE credentialId = ?
activate DB
DB-->>Repo: update complete
deactivate DB
Repo-->>Service: calendars updated
deactivate Repo
🔗 Cross-Repository Impact Analysis
Enable automatic detection of breaking changes across your dependent repositories. → Set up now
Learn more about Cross-Repository Analysis
What It Does
- Automatically identifies repositories that depend on this code
- Analyzes potential breaking changes across your entire codebase
- Provides risk assessment before merging to prevent cross-repo issues
How to Enable
- Visit Settings → Code Management
- Configure repository dependencies
- Future PRs will automatically include cross-repo impact analysis!
Benefits
- 🛡️ Prevent breaking changes across repositories
- 🔍 Catch integration issues before they reach production
- 📊 Better visibility into your multi-repo architecture
Install the extension
Note for Windsurf
Please change the default marketplace provider to the following in the windsurf settings:Marketplace Extension Gallery Service URL: https://marketplace.visualstudio.com/_apis/public/gallery
Marketplace Gallery Item URL: https://marketplace.visualstudio.com/items
Entelligence.ai can learn from your feedback. Simply add 👍 / 👎 emojis to teach it your preferences. More shortcuts below
Emoji Descriptions:
⚠️ Potential Issue - May require further investigation.- 🔒 Security Vulnerability - Fix to ensure system safety.
- 💻 Code Improvement - Suggestions to enhance code quality.
- 🔨 Refactor Suggestion - Recommendations for restructuring code.
- ℹ️ Others - General comments and information.
Interact with the Bot:
- Send a message or request using the format:
@entelligenceai + *your message*
Example: @entelligenceai Can you suggest improvements for this code?
- Help the Bot learn by providing feedback on its responses.
@entelligenceai + *feedback*
Example: @entelligenceai Do not comment on `save_auth` function !
Also you can trigger various commands with the bot by doing
@entelligenceai command
The current supported commands are
config- shows the current configretrigger_review- retriggers the review
More commands to be added soon.
| } | ||
|
|
||
| // Update SelectedCalendar.updatedAt for all calendars under this credential | ||
| await SelectedCalendarRepository.updateManyByCredentialId(this.credential.id, {}); |
There was a problem hiding this comment.
Correctness: The call to SelectedCalendarRepository.updateManyByCredentialId with an empty object {} will cause a Prisma validation error at runtime, as updateMany requires at least one field to be provided in the data payload. To fulfill the intent of updating the updatedAt timestamp, explicitly pass the field: await SelectedCalendarRepository.updateManyByCredentialId(this.credential.id, { updatedAt: new Date() });.
🤖 AI Agent Prompt for Cursor/Windsurf
📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue
In `packages/app-store/googlecalendar/lib/CalendarService.ts` around line 1024, replace the empty update `{}` passed to `SelectedCalendarRepository.updateManyByCredentialId` with a concrete field update (e.g., `{ updatedAt: new Date() }`) so Prisma doesn't throw on empty update data. Ensure the field name matches the SelectedCalendar schema.
Test 1rnnn
Summary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.
nn---n*Replicated from [ai-code-review-evaluation/cal.com-coderabbit#11](https://github.com/ai-code-review-evaluation/cal.com-coderabbit/pull/11)*EntelligenceAI PR Summary
This PR implements calendar cache management functionality with UI controls for viewing cache status and deleting cached data.
updatedAttimestamp field to CalendarCache model with automatic tracking via Prisma directivesdeleteCachemutation endpoint with ownership validationupdatedAtandgoogleChannelIdfields