Skip to content

Async import of the appStore packages - #10

Open
ShashankFC wants to merge 1 commit into
appstore-sync-refactor-basefrom
appstore-async-improvements
Open

Async import of the appStore packages#10
ShashankFC wants to merge 1 commit into
appstore-sync-refactor-basefrom
appstore-async-improvements

Conversation

@ShashankFC

@ShashankFC ShashankFC commented Feb 4, 2026

Copy link
Copy Markdown

Test 2nn

Summary by CodeRabbit

Release Notes

  • Refactor
    • Improved reliability of calendar event operations during booking creation, updates, and cancellations.
    • Enhanced video meeting provisioning for better performance and stability.
    • Streamlined payment processing to ensure proper app loading before transactions.

✏️ Tip: You can customize this high-level summary in your review settings.

nn---n*Replicated from [ai-code-review-evaluation/cal.com-coderabbit#2](https://github.com/ai-code-review-evaluation/cal.com-coderabbit/pull/2)*

EntelligenceAI PR Summary

Refactored app store architecture from synchronous to asynchronous module loading using dynamic imports for improved performance and code splitting.

  • Converted getCalendar() function and appStore access to async operations requiring await throughout codebase
  • Replaced 29 static imports with dynamic import() calls in app store index
  • Updated CalendarManager methods (getConnectedCalendars, getCachedResults, createEvent, updateEvent, deleteEvent) to handle async calendar retrieval
  • Converted getVideoAdapters factory function to async and updated all video client call sites
  • Added await to calendar and payment app retrievals in booking handlers and payment processing
  • Refactored some forEach loops to for...of for proper async handling, though some files still use async callbacks with forEach (potential issue)
  • Changes span calendar management, event handling, video clients, booking operations, and payment processing modules

@entelligence-ai-pr-reviews entelligence-ai-pr-reviews Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Walkthrough

This PR refactors the app store architecture from synchronous to asynchronous module loading by implementing dynamic imports and lazy loading. The core change converts appStore property access and getCalendar() function to async operations, requiring await keywords throughout the codebase. This enables code splitting and on-demand loading of app modules (calendar, video, payment integrations), improving initial bundle size and startup performance. The refactoring touches calendar management, event handling, video clients, booking operations, and payment processing. Several files also fix improper async handling in forEach loops, though some potential issues remain where forEach is used with async callbacks instead of proper async iteration patterns.

Changes

File(s) Summary
packages/app-store/index.ts Refactored from static imports to dynamic imports for all 29 app modules, enabling lazy loading and code splitting while maintaining backward compatibility.
packages/app-store/_utils/getCalendar.ts Converted getCalendar function to async, changing return type from Calendar | null to Promise<Calendar | null> and added await for appStore access.
packages/core/CalendarManager.ts Updated all getCalendar() calls to async/await across getConnectedCalendars(), getCachedResults(), createEvent(), updateEvent(), and deleteEvent(). Made deleteEvent() async and wrapped calendar promises in Promise.all() in getCachedResults().
packages/core/EventManager.ts Added await to getCalendar() call to properly handle Promise before deleting calendar events.
packages/core/videoClient.ts Converted getVideoAdapters factory function to async using for...of loop instead of reduce. Updated all call sites (getBusyVideoTimes, createMeeting, updateMeeting, deleteMeeting, createMeetingWithCalVideo, getRecordingsOfCalVideoByRoomName, getDownloadLinkOfCalVideoByRecordingId) to await the function.
packages/features/bookings/lib/handleCancelBooking.ts Added await to all five getCalendar() calls and appStore access for payment app retrieval. Refactored forEach loop to for...of loop for proper async handling of calendar credentials.
packages/features/bookings/lib/handleNewBooking.ts Added await to getCalendar(credential) call in booking cancellation/rescheduling flow.
packages/lib/payment/deletePayment.ts
packages/lib/payment/handlePayment.ts Added await to appStore property access when retrieving payment app instances.
packages/app-store/vital/lib/reschedule.ts
packages/app-store/wipemycalother/lib/reschedule.ts
packages/trpc/server/routers/viewer/bookings.tsx Made forEach callbacks async and added await to getCalendar() calls. Note: Using async callbacks with forEach may require refactoring to Promise.all() with map() or for...of loop for proper async handling.

Sequence Diagram

This diagram shows the interactions between components:

sequenceDiagram
    participant Caller
    participant CalendarManager
    participant AppStore
    participant CalendarApp
    participant CalendarService

    Caller->>CalendarManager: getCalendar(credential)
    
    alt credential is null or has no key
        CalendarManager-->>Caller: return null
    else credential is valid
        CalendarManager->>CalendarManager: Extract and process calendarType
        Note over CalendarManager: Remove "_other_calendar" suffix if present
        
        CalendarManager->>AppStore: await appStore[calendarType]
        activate AppStore
        AppStore-->>CalendarManager: calendarApp
        deactivate AppStore
        
        alt calendarApp has lib.CalendarService
            CalendarManager->>CalendarApp: Access CalendarService
            CalendarApp-->>CalendarManager: CalendarService instance
            CalendarManager-->>Caller: return Calendar
        else calendarApp missing CalendarService
            Note over CalendarManager: Log warning about<br/>unimplemented calendar type
            CalendarManager-->>Caller: return null
        end
    end
Loading

🔗 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

  1. Visit Settings → Code Management
  2. Configure repository dependencies
  3. 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

▶️AI Code Reviews for VS Code, Cursor, Windsurf
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

  1. config - shows the current config
  2. retrigger_review - retriggers the review

More commands to be added soon.

Comment on lines +3 to 31
applecalendar: import("./applecalendar"),
caldavcalendar: import("./caldavcalendar"),
closecom: import("./closecom"),
dailyvideo: import("./dailyvideo"),
googlecalendar: import("./googlecalendar"),
googlevideo: import("./googlevideo"),
hubspot: import("./hubspot"),
huddle01video: import("./huddle01video"),
jitsivideo: import("./jitsivideo"),
larkcalendar: import("./larkcalendar"),
office365calendar: import("./office365calendar"),
office365video: import("./office365video"),
plausible: import("./plausible"),
salesforce: import("./salesforce"),
zohocrm: import("./zohocrm"),
sendgrid: import("./sendgrid"),
stripepayment: import("./stripepayment"),
tandemvideo: import("./tandemvideo"),
vital: import("./vital"),
zoomvideo: import("./zoomvideo"),
wipemycalother: import("./wipemycalother"),
giphy: import("./giphy"),
zapier: import("./zapier"),
exchange2013calendar: import("./exchange2013calendar"),
exchange2016calendar: import("./exchange2016calendar"),
exchangecalendar: import("./exchangecalendar"),
facetime: import("./facetime"),
sylapsvideo: import("./sylapsvideo"),
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Correctness: In appStore, replacing static imports with import() expressions changes the property values from module namespaces to Promise objects. This breaks all synchronous consumers of this export. Revert to static imports or, if lazy loading is intended, use factory functions (e.g., applecalendar: () => import("./applecalendar")) and update all call sites to handle the asynchronous resolution.

🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

File: packages/app-store/index.ts (lines 3-31). The appStore entries now use dynamic import, which returns Promise and breaks synchronous consumers. Decide on the contract: (1) revert to static imports to preserve sync usage, or (2) change entries to lazy loader functions `() => import("./...")` and update all call sites to await the loader before accessing module exports.

Comment on lines 44 to 51
const connectedCalendars = await Promise.all(
calendarCredentials.map(async (item) => {
try {
const { calendar, integration, credential } = item;

const { integration, credential } = item;
const calendar = await item.calendar;
// Don't leak credentials to the client
const credentialId = credential.id;
if (!calendar) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Correctness: In getConnectedCalendars, the if (!calendar) block (line 49) returns the raw integration object, which contains sensitive app credentials (e.g., access tokens). This security leak was previously unreachable because item.calendar was a Promise (always truthy), but the change to await item.calendar makes this path active. Wrap integration with cleanIntegrationKeys(integration) in this return statement to prevent leaking credentials to the client.

Comment on lines +125 to 129
bookingRefsFiltered.forEach(async (bookingRef) => {
if (bookingRef.uid) {
if (bookingRef.type.endsWith("_calendar")) {
const calendar = getCalendar(credentialsMap.get(bookingRef.type));
const calendar = await getCalendar(credentialsMap.get(bookingRef.type));
return calendar?.deleteEvent(bookingRef.uid, builder.calendarEvent);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Correctness: The bookingRefsFiltered.forEach call does not await the async callback. This results in fire-and-forget execution where the surrounding try/catch block fails to catch rejections, and the function proceeds to send emails before deletions are finished. Replace this with a for...of loop or await Promise.all() to ensure all operations are properly awaited and errors are caught.

Affected Locations:

  • packages/app-store/vital/lib/reschedule.ts:125-129
  • packages/app-store/wipemycalother/lib/reschedule.ts:124-131
  • packages/trpc/server/routers/viewer/bookings.tsx:552-552
🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

File: packages/app-store/vital/lib/reschedule.ts. Replace the `bookingRefsFiltered.forEach(async ...)` block (lines ~125-129) with an awaited `Promise.all(bookingRefsFiltered.map(async ...))` (or a `for...of` with `await`) so deletions are awaited and errors are caught by the surrounding try/catch. Keep the existing logic inside the loop unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants