Skip to content

Comments

refactor: remove circular dependency between prisma and app-store packages#23475

Merged
keithwillcode merged 22 commits intomainfrom
devin/remove-circular-dependency-1735084368
Sep 12, 2025
Merged

refactor: remove circular dependency between prisma and app-store packages#23475
keithwillcode merged 22 commits intomainfrom
devin/remove-circular-dependency-1735084368

Conversation

@keithwillcode
Copy link
Contributor

@keithwillcode keithwillcode commented Aug 30, 2025

What does this PR do?

Removes the circular dependency between @calcom/prisma and @calcom/app-store packages by eliminating schema exports from the prisma package and moving validation closer to consuming code.

Key Changes:

  • Removed EventTypeAppMetadataSchema and eventTypeAppMetadataOptionalSchema exports from @calcom/prisma/zod-utils
  • Eliminated problematic import: import { appDataSchemas } from "@calcom/app-store/apps.schemas.generated" from prisma package
  • Updated 14 consuming files to import appDataSchemas directly and create local typed schemas using z.object(appDataSchemas).partial().optional() pattern
  • Added type casting for dynamic property access: appSlug as keyof typeof apps

Requested by: @keithwillcode
Devin Session: https://app.devin.ai/sessions/e26d7a824c6d4c9d8ea0803a3714ce33

Visual Demo (For contributors especially)

N/A - This is an internal refactoring with no user-facing changes.

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?

Critical Testing Areas:

  1. Payment flows - Verify payment processing still works correctly with the new schema validation
  2. Event type management - Test creating/updating event types with app configurations
  3. Credential management - Test app credential deletion and updates
  4. CRM integrations - Verify CRM round-robin functionality works
  5. Booking flows - Test booking creation, confirmation, and seat management

Environment Setup:

  • Standard cal.com development environment
  • Test with various app integrations enabled (payment apps, CRM apps, etc.)

Expected Behavior:

  • All existing functionality should work identically
  • No circular dependency errors during build
  • TypeScript compilation should pass
  • All app metadata validation should behave the same as before

Checklist

⚠️ High Risk Areas for Review:

  • Type Safety: Verify type casting operations (appSlug as keyof typeof apps) handle edge cases safely
  • Schema Consistency: Ensure all local schema definitions use identical patterns across files
  • Circular Dependency: Confirm the dependency cycle is actually broken by checking import graphs
  • Validation Behavior: Test that app metadata validation works identically to before the refactor
  • Edge Cases: Test with invalid/missing app keys to ensure graceful error handling
  • Payment Integration: Thoroughly test payment flows as these use dynamic app property access

Files with Highest Risk:

  • packages/lib/payment/handlePayment.ts - Dynamic property access for payment data
  • packages/trpc/server/routers/viewer/eventTypes/update.handler.ts - Complex app iteration logic
  • packages/lib/server/service/eventTypeService.ts - Changed function signature from strict to flexible typing

…kages

- Replace EventTypeAppMetadataSchema with z.record(z.any()).optional() pattern
- Remove appDataSchemas import from packages/prisma/zod-utils.ts
- Add null checks in consuming packages for flexible validation
- Fix test file that no longer needs @ts-expect-error directive

This breaks the circular dependency while maintaining all functionality
by moving strict validation to the business logic layer where operations
actually happen, following existing patterns in the codebase.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 30, 2025

Walkthrough

This change relocates event type app metadata Zod schemas from @calcom/prisma/zod-utils to a new module @calcom/app-store/zod-utils. A new file packages/app-store/zod-utils.ts adds EventTypeAppMetadataSchema, eventTypeAppMetadataOptionalSchema, and eventTypeMetaDataSchemaWithTypedApps. Corresponding imports are updated across web, features, app-store, lib, trpc, and tests/mocks. packages/prisma/zod-utils.ts removes the typed app metadata schemas, retaining only untyped metadata variants. EventManager public types are loosened from Zod-inferred types to Record<string, any>. One internal import path for EventTypeService is localized. No runtime logic changes are introduced in the affected files.

Possibly related PRs

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title concisely and accurately summarizes the primary intent of the changeset: breaking the circular dependency between @calcom/prisma and @calcom/app-store by relocating schema exports/validation. The raw_summary and PR objectives confirm many files were updated to import zod schemas from @calcom/app-store/zod-utils and that prisma schema exports were removed, so the title reflects the main change and is clear for reviewers.
Description Check ✅ Passed The description is on-topic and appropriately detailed for this refactor: it documents the removed prisma schema exports, the removed appDataSchemas import, the set of consumer updates, testing guidance, and high-risk areas, which aligns with the raw_summary and PR objectives. This provides reviewers sufficient context to understand scope, risks, and verification steps.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devin/remove-circular-dependency-1735084368

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.

devin-ai-integration bot and others added 2 commits August 30, 2025 23:51
- Remove EventTypeAppMetadataSchema and eventTypeAppMetadataOptionalSchema exports from prisma/zod-utils.ts
- Update all importing files to use local z.record(z.any()).optional() schemas
- Replace type annotations with Record<string, any> where appropriate
- Maintain validation functionality while breaking circular dependency
- All TypeScript compilation now passes without errors

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
…ng files

- Update handleSeats/createNewSeat.ts to use local schema
- Update payment handlers to use local schemas
- Update eventTypes update handler to use local schema
- All files now define their own validation instead of importing from prisma
- Circular dependency completely eliminated

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
@vercel
Copy link

vercel bot commented Aug 30, 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 Sep 12, 2025 7:13am
cal-eu Ignored Ignored Sep 12, 2025 7:13am

devin-ai-integration bot and others added 2 commits August 31, 2025 01:42
- Remove duplicate z import from handleConfirmation.ts
- Remove duplicate appDataSchemas import from update.handler.ts
- Fix index signature errors in handlePayment.ts by using appData variable consistently
- All type checks now pass successfully

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
- Cast appSlug as keyof typeof apps to resolve index signature error
- Maintains type safety while allowing dynamic property access

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
@github-actions
Copy link
Contributor

github-actions bot commented Aug 31, 2025

E2E results are ready!

@pull-request-size pull-request-size bot added size/M and removed size/L labels Sep 11, 2025
@hbjORbj hbjORbj marked this pull request as ready for review September 12, 2025 02:04
@hbjORbj hbjORbj requested a review from a team as a code owner September 12, 2025 02:04
@hbjORbj hbjORbj requested a review from a team September 12, 2025 02:04
@hbjORbj
Copy link
Contributor

hbjORbj commented Sep 12, 2025

@keithwillcode We've successfully removed the circular dep between prisma and app-store. But as a consequence, some files in calcom/lib now import calcom/app-store, but these files are now moved out of app-store in #23742, so it's not really a concern.

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

Caution

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

⚠️ Outside diff range comments (13)
packages/app-store/_utils/CRMRoundRobinSkip.ts (1)

55-66: Avoid include; select only needed fields from Prisma.

Using include pulls all Credential scalars (including key) by default. Select the minimum fields. If you need the key, prefer the repository helper for consistency.

-  const crmCredential = await prisma.credential.findUnique({
-    where: {
-      id: crmRoundRobinLeadSkip.credentialId,
-    },
-    include: {
-      user: {
-        select: {
-          email: true,
-        },
-      },
-    },
-  });
+  const crmCredential = await prisma.credential.findUnique({
+    where: { id: crmRoundRobinLeadSkip.credentialId },
+    select: {
+      id: true,
+      type: true,
+      key: true,
+      appId: true,
+      userId: true,
+      teamId: true,
+      invalid: true,
+      delegatedToId: true,
+      delegationCredentialId: true,
+      user: { select: { email: true } },
+    },
+  });

Alternatively:

-  const crmCredential = await prisma.credential.findUnique({
+  const crmCredential = await CredentialRepository.findFirstByIdWithKeyAndUser({
     where: { id: crmRoundRobinLeadSkip.credentialId },
-    ...
+    // repository returns key + user safely with minimal fields
   });
packages/features/credentials/handleDeleteCredential.ts (3)

91-96: Replace include with select for nested credential.

Avoid include and return only the needed fields. You only compare credential.appId and need the destination calendar id.

-      destinationCalendar: {
-        include: {
-          credential: true,
-        },
-      },
+      destinationCalendar: {
+        select: {
+          id: true,
+          credential: { select: { appId: true } },
+        },
+      },

167-184: Interactive transaction is not actually transactional; avoid network calls inside.

Inside prisma.$transaction(async () => { ... }) you’re using the global prisma client, not the transactional tx, so ops may not be part of the same transaction. Also, calling external APIs (deletePayment) inside an open DB transaction risks long-held locks and partial failures.

-        await prisma.$transaction(async () => {
-          await prisma.eventType.update({
+        // 1) Use the interactive tx client
+        const results = await prisma.$transaction(async (tx) => {
+          await tx.eventType.update({
             where: { id: eventType.id },
             data: {
               hidden: true,
               metadata: {
                 ...metadata,
                 apps: { ...appMetadata },
               },
             },
           });
-        });
+          // Collect unpaid bookings and affected payments within the tx
+          const unpaidBookings = await tx.booking.findMany({
+            where: {
+              userId: userId,
+              eventTypeId: eventType.id,
+              status: "PENDING",
+              paid: false,
+              payment: { every: { success: false } },
+            },
+            select: {
+              id: true,
+              payment: { select: { id: true } },
+              attendees: { select: { id: true } },
+              references: { select: { id: true } },
+              uid: true,
+              // keep other fields only if strictly required after tx
+            },
+          });
+          // Mark bookings as cancelled and delete attendees/references/payments records
+          for (const booking of unpaidBookings) {
+            await tx.booking.update({
+              where: { id: booking.id },
+              data: { status: BookingStatus.CANCELLED, cancellationReason: "Payment method removed" },
+            });
+            await tx.attendee.deleteMany({ where: { bookingId: booking.id } });
+            await tx.bookingReference.deleteMany({ where: { bookingId: booking.id } });
+          }
+          return unpaidBookings.flatMap((b) => b.payment.map((p) => p.id));
+        });
+
+        // 2) After commit, perform external payment gateway deletions
+        for (const paymentId of results) {
+          try {
+            await deletePayment(paymentId, credential);
+          } catch (e) {
+            console.error(e);
+          }
+          await prisma.payment.delete({ where: { id: paymentId } });
+        }

Note: If you still need additional booking/user fields for emails, fetch them after commit with a separate, read-only query.

Also applies to: 196-371


230-241: Over-selecting user data; drop credentials.

booking.user.credentials isn't used in this flow. Remove it to reduce data exposure and query cost.

-              user: {
-                select: {
-                  id: true,
-                  credentials: true,
-                  email: true,
-                  timeZone: true,
-                  name: true,
-                  destinationCalendar: true,
-                  locale: true,
-                },
-              },
+              user: {
+                select: {
+                  id: true,
+                  email: true,
+                  timeZone: true,
+                  name: true,
+                  destinationCalendar: true,
+                  locale: true,
+                },
+              },
packages/features/ee/round-robin/roundRobinManualReassignment.ts (1)

315-318: Avoid include; select only needed credential fields.

Return minimal credential fields and user email; this reduces payload and follows Prisma selection guidelines.

-  const credentials = await prisma.credential.findMany({
-    where: { userId: newUser.id },
-    include: { user: { select: { email: true } } },
-  });
+  const credentials = await prisma.credential.findMany({
+    where: { userId: newUser.id },
+    select: {
+      id: true,
+      type: true,
+      key: true,
+      appId: true,
+      user: { select: { email: true } },
+    },
+  });
packages/lib/getPaymentAppData.ts (1)

9-14: Type-only import of Zod schema breaks typeof usage.

z.infer<typeof EventTypeMetaDataSchema> needs a value import.

-import type { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
+import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
packages/app-store/_utils/payments/checkForMultiplePaymentApps.ts (1)

23-34: Fix: for…in over possibly undefined causes runtime TypeError.

for (const k in metadata?.apps) throws when apps is undefined/null. Also, in on app throws when it’s undefined. Iterate safely over Object.entries(metadata?.apps ?? {}).

-  for (const appKey in metadata?.apps) {
-    const app = metadata?.apps[appKey as keyof typeof appDataSchemas];
-
-    if ("appCategories" in app) {
-      const isPaymentApp = app.appCategories.includes("payment");
-      if (isPaymentApp && app.enabled) {
-        enabledPaymentApps++;
-      }
-    } else if ("price" in app && app.enabled) {
-      enabledPaymentApps++;
-    }
-  }
+  for (const [appKey, app] of Object.entries(metadata?.apps ?? {}) as [
+    keyof typeof appDataSchemas,
+    (typeof appDataSchemas)[keyof typeof appDataSchemas] | undefined
+  ][]) {
+    if (!app || typeof app !== "object") continue;
+    const isPaymentApp =
+      ("appCategories" in app && Array.isArray((app as any).appCategories) && (app as any).appCategories.includes("payment")) ||
+      "price" in app;
+    if (isPaymentApp && (app as any).enabled) enabledPaymentApps++;
+  }
packages/features/ee/payments/api/webhook.ts (1)

56-60: Prisma: select only needed fields.

Avoid fetching whole rows; select just what’s used (id, data, bookingId).

Apply this diff:

   const payment = await prisma.payment.findFirst({
     where: {
       externalId: setupIntent.id,
     },
-  });
+    select: {
+      id: true,
+      data: true,
+      bookingId: true,
+    },
+  });
packages/features/bookings/lib/handlePayment.ts (1)

60-63: Minor: avoid repeated indexed lookups; remove stale schema import

  • Store const app = apps?.[paymentAppCredentials.appId]; and reuse for paymentOption, price, and currency.
  • Stale import remains — packages/lib/defaultEvents.ts:7 imports eventTypeMetaDataSchemaWithTypedApps from @calcom/app-store/zod-utils; remove or update this import to eliminate the circular dependency.
packages/features/ee/round-robin/roundRobinReassignment.ts (1)

348-355: Prisma guideline: prefer select over include.

Replace include with select and pick only used fields to minimize payloads and align with repo standards.

Example adjustment:

-  include: {
-    user: {
-      select: {
-        email: true,
-      },
-    },
-  },
+  select: {
+    // select only credential fields the downstream code actually uses
+    id: true,
+    key: true,
+    type: true,
+    userId: true,
+    user: { select: { email: true } },
+  },
packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts (1)

30-37: Remove credential.key from exported select — it's returning secrets.

credentialForCalendarServiceSelect in packages/prisma/selects/credential.ts currently contains key: true — remove that entry (use safeCredentialSelect or explicitly omit key) and update callers to never return credential.key (e.g. the many places importing credentialForCalendarServiceSelect, including packages/features/bookings/***).

packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts (2)

543-552: Avoid typeof on type-only import; index using apps instead.

Using typeof appDataSchemas with an import type can break compilation. Index against the parsed apps value instead.

-  const apps = eventTypeAppMetadataOptionalSchema.parse(input.metadata?.apps);
-  for (const appKey in apps) {
-    const app = apps[appKey as keyof typeof appDataSchemas];
+  const apps = eventTypeAppMetadataOptionalSchema.parse(input.metadata?.apps);
+  for (const appKey in apps) {
+    const app = apps[appKey as keyof typeof apps];

1-30: Circular dependency still present — prisma ↔ app-store imports found

Search output shows prisma imports app-store metadata and app-store imports prisma (client/enums/zod-utils). Actionable pointers:

  • prisma -> app-store: packages/prisma/seed.ts, packages/prisma/seed-performance-testing.ts, packages/prisma/seed-app-store.ts (import @calcom/app-store/* _metadata / appStoreMetaData).
  • app-store -> prisma: packages/app-store/zod-utils.ts (imports @calcom/prisma/zod-utils), packages/app-store/zoomvideo/lib/VideoApiAdapter.ts, packages/app-store/server.ts, packages/app-store/_appRegistry.ts, routing-forms/* and many app-store packages import @calcom/prisma (client/enums/prisma).
  • Fix: break the cycle — remove prisma imports of app-store (e.g., move seed metadata/shared schemas to a neutral package or refactor seeds), or extract shared zod-utils/metadata into a separate package that both can depend on.
🧹 Nitpick comments (21)
packages/app-store/salesforce/lib/routingFormBookingFormHandler.ts (1)

44-44: Prefer named export over default.

To align with repo guidelines on named exports for utilities, consider exporting routingFormBookingFormHandler as a named export.

-export default routingFormBookingFormHandler;
+export { routingFormBookingFormHandler };
packages/features/credentials/handleDeleteCredential.ts (1)

490-490: Prefer named export over default.

Align with the repo guideline to favor named exports for utilities.

-export default handleDeleteCredential;
+export { handleDeleteCredential };
packages/lib/EventManager.ts (2)

132-132: Type surface was loosened; consider a minimal contract or a generic.

Decoupling from Zod is fine, but Record<string, any> loses safety. Consider a generic type parameter with a sensible default, or a minimal shape to retain autocompletion at call sites.

-export type EventManagerInitParams = {
+export type EventManagerInitParams<TApps extends Record<string, unknown> = Record<string, unknown>> = {
   user: EventManagerUser;
-  eventTypeAppMetadata?: Record<string, any>;
+  eventTypeAppMetadata?: TApps;
 };
 
-export default class EventManager {
+export default class EventManager<TApps extends Record<string, unknown> = Record<string, unknown>> {
   ...
-  appOptions?: Record<string, any>;
+  appOptions?: TApps;
   ...
-  constructor(user: EventManagerUser, eventTypeAppMetadata?: Record<string, any>) {
+  constructor(user: EventManagerUser, eventTypeAppMetadata?: TApps) {
     ...
   }

Also applies to: 140-140, 145-145


135-135: Prefer named export over default.

Utility classes benefit from named exports for tree-shaking and refactors.

-export default class EventManager {
+export class EventManager {

And update imports accordingly.

packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts (1)

89-89: Prefer named export over default.

Consider exporting handleChildrenEventTypes as a named export to follow project conventions.

-export default async function handleChildrenEventTypes({
+export async function handleChildrenEventTypes({
packages/lib/payment/shouldChargeNoShowCancellationFee.ts (1)

44-50: Guard against unexpected time units.

If schema evolves, an unknown timeUnit will yield NaN. Add a fallback to avoid silent mischarges.

-  const timeInMinutes = timeValue * multiplier[timeUnit];
+  const unit = multiplier[timeUnit];
+  if (!unit) return false;
+  const timeInMinutes = timeValue * unit;
packages/features/ee/round-robin/roundRobinManualReassignment.ts (1)

609-609: Prefer named export over default.

Align with the repo’s preference for named exports.

-export default roundRobinManualReassignment;
+export { roundRobinManualReassignment };
packages/lib/payment/handleNoShowFee.ts (1)

64-64: Fix variable name typo: eventTypeMetdata → eventTypeMetadata.

Minor readability/maintainability nit.

-  const eventTypeMetdata = eventTypeMetaDataSchemaWithTypedApps.parse(booking.eventType?.metadata ?? {});
+  const eventTypeMetadata = eventTypeMetaDataSchemaWithTypedApps.parse(booking.eventType?.metadata ?? {});
...
-    await sendNoShowFeeChargedEmail(attendee, evt, eventTypeMetdata);
+    await sendNoShowFeeChargedEmail(attendee, evt, eventTypeMetadata);

Also applies to: 160-160

packages/platform/atoms/event-types/hooks/useTabsNavigations.tsx (2)

145-151: Localize “Cal.ai” tab label (or mark as brand if intentionally untranslated).

Frontend strings should use t(); if “Cal.ai” is a brand, consider a comment to clarify.

-      navigation.push({
-        name: "Cal.ai",
+      navigation.push({
+        name: t("cal_ai"),
         href: `/event-types/${eventType.id}?tabName=ai`,
         icon: "sparkles",
-        info: t("cal_ai_event_tab_description"), // todo `cal_ai_event_tab_description`,
+        info: t("cal_ai_event_tab_description"),
         "data-testid": "Cal.ai",
       });

219-225: Localize “apps, X active” string.

Use t() with variables for proper i18n and pluralization.

-      info: `${installedAppsNumber} apps, ${enabledAppsNumber} ${t("active")}`,
+      info: t("apps_summary", { count: installedAppsNumber, active: enabledAppsNumber }),
packages/lib/defaultEvents.ts (1)

213-213: Prefer named exports over default exports.

Improves tree-shaking and refactors across the monorepo.

-export default defaultEvents;
+export { defaultEvents };

Note: Update import sites accordingly if you adopt this.

packages/features/ee/payments/api/webhook.ts (1)

45-50: Remove duplicate not-found check.

The second !payment?.bookingId check is redundant.

Apply this diff:

   if (!payment?.bookingId) {
     log.error("Stripe: Payment Not Found", safeStringify(paymentIntent), safeStringify(payment));
     throw new HttpCode({ statusCode: 204, message: "Payment not found" });
   }
-  if (!payment?.bookingId) throw new HttpCode({ statusCode: 204, message: "Payment not found" });
packages/features/eventtypes/components/EventTypeDescription.tsx (1)

71-79: Localize the “m” suffix.

Frontend text should use t(). Replace the literal "m" with a localized token (for example, t("minutes_short")), or render via a minutes formatter.

packages/features/eventtypes/lib/getPublicEvent.ts (1)

116-123: Prefer select over include in Prisma queries.
Current getPublicEventSelect uses include for workflows.steps. Our guideline is to always use select to limit data.

Apply this minimal change:

-    workflows: {
-      include: {
-        workflow: {
-          include: {
-            steps: true,
-          },
-        },
-      },
-    },
+    workflows: {
+      select: {
+        workflow: {
+          select: {
+            steps: true,
+          },
+        },
+      },
+    },
apps/web/modules/bookings/views/bookings-single-view.tsx (1)

478-479: Localize remaining hardcoded UI strings.

Per frontend guidelines, wrap these in t(): alt “Gif from Giphy”, button “Go Back”, textarea placeholder, and “Link”.

-<img src={giphyImage} className="w-full rounded-lg" alt="Gif from Giphy" />
+<img src={giphyImage} className="w-full rounded-lg" alt={t("gif_from_giphy")} />

-<Button ...>Go Back</Button>
+<Button ...>{t("go_back")}</Button>

-<TextArea ... placeholder="Next time I would like to ..." />
+<TextArea ... placeholder={t("feedback_placeholder")} />

-{providerName || "Link"}
+{providerName || t("link")}

Also applies to: 899-899, 1055-1055, 1139-1139

packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts (1)

88-95: Guard on credentialId and return booleans in filter.

Avoid creating an "undefined" key and return explicit booleans for clarity.

-  for (const appKey in eventTypeAppMetadata) {
-    const app = eventTypeAppMetadata[appKey as keyof typeof eventTypeAppMetadata];
-    if (app.appCategories && app.appCategories.some((category: string) => category === "crm")) {
-      eventTypeCrmCredentials[app.credentialId] = {
-        enabled: app.enabled,
-      };
-    }
-  }
+  for (const appKey in eventTypeAppMetadata) {
+    const app = eventTypeAppMetadata[appKey as keyof typeof eventTypeAppMetadata];
+    if (
+      Array.isArray(app.appCategories) &&
+      app.appCategories.some((category: string) => category === "crm") &&
+      typeof app.credentialId === "number"
+    ) {
+      eventTypeCrmCredentials[app.credentialId] = { enabled: app.enabled };
+    }
+  }
-  allCredentials = allCredentials.filter((credential) => {
+  allCredentials = allCredentials.filter((credential) => {
     if (!credential.type.includes("_crm") && !credential.type.includes("_other_calendar")) {
-      return credential;
+      return true;
     }
     ...
-        return credential;
+        return true;
       }
     }
-  });
+    return false;
+  });
packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts (1)

553-559: Remove console logs or downgrade to debug logger.

Console noise in server path.

-  console.log("multiplePrivateLinks", multiplePrivateLinks);
+  // logger.debug({ multiplePrivateLinks }, "multiplePrivateLinks");
 ...
-  console.log("connectedLinks", connectedLinks);
+  // logger.debug({ connectedLinks }, "connectedLinks");
apps/web/modules/apps/installation/[[...step]]/step-view.tsx (1)

994-1005: Localize placeholder.

Wrap the email placeholder with t() for i18n.

- placeholder="rick.astley@cal.com"
+ placeholder={t("email_placeholder")}
packages/lib/event-types/getEventTypeById.ts (1)

73-76: Drop redundant || {} after Zod.parse.

Zod.parse returns a value or throws; the fallback is dead code.

-  const newMetadata = eventTypeMetaDataSchemaWithTypedApps.parse(metadata || {}) || {};
+  const newMetadata = eventTypeMetaDataSchemaWithTypedApps.parse(metadata || {});
packages/features/noShow/handleSendingAttendeeNoShowDataToApps.ts (1)

44-52: Defensive guard for missing appCategories.

Avoid potential runtime error if schema changes or data missing.

-  for (const slug in eventTypeAppMetadata) {
+  for (const slug in eventTypeAppMetadata) {
     if (noShowEnabledApps.includes(slug)) {
       const app = eventTypeAppMetadata[slug as keyof typeof eventTypeAppMetadata];
-
-      const appCategory = app.appCategories[0];
+      const appCategory = app.appCategories?.[0];
 
       if (appCategory === "crm") {
         await handleCRMNoShow(bookingUid, app, attendees);
       }
     }
   }
packages/app-store/zod-utils.ts (1)

7-9: Be explicit about unknown-key behavior on apps metadata.

z.object(...) defaults to “strip” unknown keys. Confirm this matches prior behavior; otherwise choose strict (error) or passthrough (preserve) to avoid silent data loss.

Option A (strict):

-export const EventTypeAppMetadataSchema = z.object(appDataSchemas).partial();
+export const EventTypeAppMetadataSchema = z.object(appDataSchemas).partial().strict();

Option B (passthrough):

-export const EventTypeAppMetadataSchema = z.object(appDataSchemas).partial();
+export const EventTypeAppMetadataSchema = z.object(appDataSchemas).partial().passthrough();

Consider exporting a type for consumers:

 export const eventTypeAppMetadataOptionalSchema = EventTypeAppMetadataSchema.optional();
+export type EventTypeAppMetadata = z.infer<typeof EventTypeAppMetadataSchema>;
📜 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 c28eb90 and efc551a.

📒 Files selected for processing (42)
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts (1 hunks)
  • apps/web/modules/apps/installation/[[...step]]/step-view.tsx (1 hunks)
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx (2 hunks)
  • apps/web/modules/bookings/views/bookings-single-view.tsx (2 hunks)
  • apps/web/modules/test-setup.ts (1 hunks)
  • apps/web/playwright/integrations-stripe.e2e.ts (1 hunks)
  • packages/app-store/_utils/CRMRoundRobinSkip.ts (1 hunks)
  • packages/app-store/_utils/getEventTypeAppData.ts (1 hunks)
  • packages/app-store/_utils/payments/checkForMultiplePaymentApps.ts (1 hunks)
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts (1 hunks)
  • packages/app-store/salesforce/lib/eventTypeService.ts (1 hunks)
  • packages/app-store/salesforce/lib/routingFormBookingFormHandler.ts (1 hunks)
  • packages/app-store/zod-utils.ts (1 hunks)
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts (1 hunks)
  • packages/features/bookings/lib/handleCancelBooking.ts (2 hunks)
  • packages/features/bookings/lib/handleConfirmation.ts (2 hunks)
  • packages/features/bookings/lib/handleNewBooking.ts (2 hunks)
  • packages/features/bookings/lib/handlePayment.ts (1 hunks)
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts (1 hunks)
  • packages/features/credentials/handleDeleteCredential.ts (2 hunks)
  • packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts (1 hunks)
  • packages/features/ee/payments/api/webhook.ts (1 hunks)
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts (1 hunks)
  • packages/features/ee/round-robin/roundRobinReassignment.ts (1 hunks)
  • packages/features/eventtypes/components/EventTypeDescription.tsx (1 hunks)
  • packages/features/eventtypes/components/tabs/instant/EventInstantTab.tsx (1 hunks)
  • packages/features/eventtypes/components/tabs/recurring/EventRecurringTab.tsx (1 hunks)
  • packages/features/eventtypes/lib/getPublicEvent.ts (1 hunks)
  • packages/features/eventtypes/lib/types.ts (1 hunks)
  • packages/features/noShow/handleSendingAttendeeNoShowDataToApps.ts (1 hunks)
  • packages/lib/EventManager.ts (1 hunks)
  • packages/lib/defaultEvents.ts (1 hunks)
  • packages/lib/event-types/getEventTypeById.ts (2 hunks)
  • packages/lib/getPaymentAppData.ts (1 hunks)
  • packages/lib/payment/handleNoShowFee.ts (1 hunks)
  • packages/lib/payment/processNoShowFeeOnCancellation.ts (1 hunks)
  • packages/lib/payment/shouldChargeNoShowCancellationFee.test.ts (1 hunks)
  • packages/lib/payment/shouldChargeNoShowCancellationFee.ts (1 hunks)
  • packages/platform/atoms/event-types/hooks/useTabsNavigations.tsx (1 hunks)
  • packages/prisma/zod-utils.ts (0 hunks)
  • packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts (2 hunks)
  • packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/prisma/zod-utils.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.tsx

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

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • packages/platform/atoms/event-types/hooks/useTabsNavigations.tsx
  • packages/features/eventtypes/components/tabs/instant/EventInstantTab.tsx
  • packages/features/eventtypes/components/tabs/recurring/EventRecurringTab.tsx
  • apps/web/modules/bookings/views/bookings-single-view.tsx
  • packages/features/eventtypes/components/EventTypeDescription.tsx
  • apps/web/modules/apps/installation/[[...step]]/step-view.tsx
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx
**/*.{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/platform/atoms/event-types/hooks/useTabsNavigations.tsx
  • packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/lib/payment/shouldChargeNoShowCancellationFee.test.ts
  • packages/lib/getPaymentAppData.ts
  • packages/app-store/_utils/payments/checkForMultiplePaymentApps.ts
  • packages/app-store/salesforce/lib/routingFormBookingFormHandler.ts
  • packages/features/eventtypes/lib/getPublicEvent.ts
  • packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
  • packages/features/eventtypes/components/tabs/instant/EventInstantTab.tsx
  • packages/lib/payment/shouldChargeNoShowCancellationFee.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/features/ee/payments/api/webhook.ts
  • packages/features/eventtypes/components/tabs/recurring/EventRecurringTab.tsx
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/lib/payment/processNoShowFeeOnCancellation.ts
  • packages/lib/defaultEvents.ts
  • packages/lib/payment/handleNoShowFee.ts
  • apps/web/modules/bookings/views/bookings-single-view.tsx
  • packages/lib/EventManager.ts
  • packages/app-store/zod-utils.ts
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • packages/features/eventtypes/components/EventTypeDescription.tsx
  • packages/app-store/salesforce/lib/eventTypeService.ts
  • packages/app-store/_utils/CRMRoundRobinSkip.ts
  • packages/app-store/_utils/getEventTypeAppData.ts
  • packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts
  • apps/web/modules/apps/installation/[[...step]]/step-view.tsx
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • apps/web/playwright/integrations-stripe.e2e.ts
  • packages/features/noShow/handleSendingAttendeeNoShowDataToApps.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • packages/features/bookings/lib/handlePayment.ts
  • apps/web/modules/test-setup.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/lib/event-types/getEventTypeById.ts
  • packages/features/eventtypes/lib/types.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/platform/atoms/event-types/hooks/useTabsNavigations.tsx
  • packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/lib/payment/shouldChargeNoShowCancellationFee.test.ts
  • packages/lib/getPaymentAppData.ts
  • packages/app-store/_utils/payments/checkForMultiplePaymentApps.ts
  • packages/app-store/salesforce/lib/routingFormBookingFormHandler.ts
  • packages/features/eventtypes/lib/getPublicEvent.ts
  • packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
  • packages/features/eventtypes/components/tabs/instant/EventInstantTab.tsx
  • packages/lib/payment/shouldChargeNoShowCancellationFee.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/features/ee/payments/api/webhook.ts
  • packages/features/eventtypes/components/tabs/recurring/EventRecurringTab.tsx
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/lib/payment/processNoShowFeeOnCancellation.ts
  • packages/lib/defaultEvents.ts
  • packages/lib/payment/handleNoShowFee.ts
  • apps/web/modules/bookings/views/bookings-single-view.tsx
  • packages/lib/EventManager.ts
  • packages/app-store/zod-utils.ts
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • packages/features/eventtypes/components/EventTypeDescription.tsx
  • packages/app-store/salesforce/lib/eventTypeService.ts
  • packages/app-store/_utils/CRMRoundRobinSkip.ts
  • packages/app-store/_utils/getEventTypeAppData.ts
  • packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts
  • apps/web/modules/apps/installation/[[...step]]/step-view.tsx
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • apps/web/playwright/integrations-stripe.e2e.ts
  • packages/features/noShow/handleSendingAttendeeNoShowDataToApps.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • packages/features/bookings/lib/handlePayment.ts
  • apps/web/modules/test-setup.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/lib/event-types/getEventTypeById.ts
  • packages/features/eventtypes/lib/types.ts
**/*.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/managed-event-types/lib/handleChildrenEventTypes.ts
  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/lib/payment/shouldChargeNoShowCancellationFee.test.ts
  • packages/lib/getPaymentAppData.ts
  • packages/app-store/_utils/payments/checkForMultiplePaymentApps.ts
  • packages/app-store/salesforce/lib/routingFormBookingFormHandler.ts
  • packages/features/eventtypes/lib/getPublicEvent.ts
  • packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
  • packages/lib/payment/shouldChargeNoShowCancellationFee.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/features/ee/payments/api/webhook.ts
  • packages/app-store/_utils/payments/handlePaymentSuccess.ts
  • packages/lib/payment/processNoShowFeeOnCancellation.ts
  • packages/lib/defaultEvents.ts
  • packages/lib/payment/handleNoShowFee.ts
  • packages/lib/EventManager.ts
  • packages/app-store/zod-utils.ts
  • packages/features/ee/round-robin/roundRobinReassignment.ts
  • packages/app-store/salesforce/lib/eventTypeService.ts
  • packages/app-store/_utils/CRMRoundRobinSkip.ts
  • packages/app-store/_utils/getEventTypeAppData.ts
  • packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • apps/web/playwright/integrations-stripe.e2e.ts
  • packages/features/noShow/handleSendingAttendeeNoShowDataToApps.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • packages/features/bookings/lib/handlePayment.ts
  • apps/web/modules/test-setup.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/lib/event-types/getEventTypeById.ts
  • packages/features/eventtypes/lib/types.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/app-store/salesforce/lib/eventTypeService.ts
🧠 Learnings (12)
📓 Common learnings
Learnt from: nangelina
PR: calcom/cal.com#23486
File: packages/app-store/kyzonspacevideo/package.json:7-12
Timestamp: 2025-09-01T10:25:51.923Z
Learning: In Cal.com's monorepo, app-store packages don't need to declare `zod` as a direct dependency in their package.json files. The monorepo uses yarn workspaces with dependency hoisting, where `zod` is available through workspace-level dependency management. Most app-store packages successfully import zod without declaring it as a dependency, following the established monorepo pattern.
📚 Learning: 2025-08-21T13:44:06.805Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.805Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.

Applied to files:

  • apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts
  • packages/lib/getPaymentAppData.ts
  • packages/app-store/salesforce/lib/routingFormBookingFormHandler.ts
  • packages/features/eventtypes/lib/getPublicEvent.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • packages/lib/defaultEvents.ts
  • packages/lib/payment/handleNoShowFee.ts
  • apps/web/modules/bookings/views/bookings-single-view.tsx
  • packages/lib/EventManager.ts
  • packages/features/eventtypes/components/EventTypeDescription.tsx
  • packages/app-store/salesforce/lib/eventTypeService.ts
  • packages/app-store/_utils/getEventTypeAppData.ts
  • packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts
  • apps/web/modules/apps/installation/[[...step]]/step-view.tsx
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • packages/features/noShow/handleSendingAttendeeNoShowDataToApps.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • packages/features/credentials/handleDeleteCredential.ts
  • packages/lib/event-types/getEventTypeById.ts
  • packages/features/eventtypes/lib/types.ts
📚 Learning: 2025-08-27T13:32:46.887Z
Learnt from: supalarry
PR: calcom/cal.com#23364
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/transformers/internal-to-api/internal-to-api.spec.ts:295-296
Timestamp: 2025-08-27T13:32:46.887Z
Learning: In calcom/cal.com, when transforming booking fields from internal to API format, tests in organizations-event-types.e2e-spec.ts already expect name field label and placeholder to be empty strings ("") rather than undefined. PR changes that set these to explicit empty strings are typically fixing implementation to match existing test expectations rather than breaking changes.

Applied to files:

  • packages/lib/payment/shouldChargeNoShowCancellationFee.test.ts
  • packages/features/bookings/lib/handleNewBooking.ts
  • apps/web/modules/bookings/views/bookings-single-view.tsx
  • packages/features/bookings/lib/handleConfirmation.ts
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • apps/web/modules/test-setup.ts
📚 Learning: 2025-09-01T10:25:51.923Z
Learnt from: nangelina
PR: calcom/cal.com#23486
File: packages/app-store/kyzonspacevideo/package.json:7-12
Timestamp: 2025-09-01T10:25:51.923Z
Learning: In Cal.com's monorepo, app-store packages don't need to declare `zod` as a direct dependency in their package.json files. The monorepo uses yarn workspaces with dependency hoisting, where `zod` is available through workspace-level dependency management. Most app-store packages successfully import zod without declaring it as a dependency, following the established monorepo pattern.

Applied to files:

  • packages/app-store/_utils/payments/checkForMultiplePaymentApps.ts
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts
📚 Learning: 2025-08-26T20:23:28.396Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/features/calAIPhone/providers/retellAI/services/AgentService.ts:83-88
Timestamp: 2025-08-26T20:23:28.396Z
Learning: In calcom/cal.com PR #22995, the workflow update handler in packages/trpc/server/routers/viewer/workflows/update.handler.ts includes workflow-level authorization via isAuthorized(userWorkflow, ctx.user.id, "workflow.update") which validates the user can update the workflow before calling updateToolsFromAgentId (per maintainer Udit-takkar).

Applied to files:

  • packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts
📚 Learning: 2025-09-03T09:52:51.182Z
Learnt from: hariombalhara
PR: calcom/cal.com#23541
File: packages/features/bookings/lib/di/modules/RegularBookingServiceModule.ts:22-28
Timestamp: 2025-09-03T09:52:51.182Z
Learning: The IBookingServiceDependencies interface in packages/features/bookings/lib/handleNewBooking.ts contains 6 properties: cacheService, checkBookingAndDurationLimitsService, prismaClient, bookingRepository, featuresRepository, and checkBookingLimitsService. This interface is used by RegularBookingService and matches the depsMap structure in RegularBookingServiceModule.

Applied to files:

  • packages/features/bookings/lib/handleNewBooking.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma select uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.

Applied to files:

  • packages/features/ee/payments/api/webhook.ts
  • packages/lib/defaultEvents.ts
  • packages/lib/EventManager.ts
  • packages/features/eventtypes/components/EventTypeDescription.tsx
  • packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts
  • packages/features/bookings/lib/handleConfirmation.ts
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • packages/features/credentials/handleDeleteCredential.ts
📚 Learning: 2025-09-03T11:54:05.409Z
Learnt from: supalarry
PR: calcom/cal.com#23514
File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts:579-582
Timestamp: 2025-09-03T11:54:05.409Z
Learning: In calcom/cal.com bookings repository methods, when Prisma include uses `eventType: true`, all eventType fields including seatsShowAttendees are automatically included in the selection. Explicit field selection is not required when using `true` for nested relations.

Applied to files:

  • packages/features/ee/payments/api/webhook.ts
  • packages/lib/EventManager.ts
  • packages/features/eventtypes/components/EventTypeDescription.tsx
  • apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx
  • packages/features/bookings/lib/handleSeats/create/createNewSeat.ts
  • packages/features/credentials/handleDeleteCredential.ts
📚 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: Four calendar integrations in Cal.com still use direct prisma.selectedCalendar.create instead of SelectedCalendarRepository.create: feishucalendar, zohocalendar, office365calendar, and larkcalendar. These bypass repository hooks and won't trigger reconnection logic for BookingReferences.

Applied to files:

  • packages/lib/EventManager.ts
📚 Learning: 2025-08-21T12:28:42.018Z
Learnt from: alishaz-polymath
PR: calcom/cal.com#23247
File: packages/features/webhooks/lib/factory/WebhookPayloadFactory.ts:274-282
Timestamp: 2025-08-21T12:28:42.018Z
Learning: In webhook DTOs in packages/features/webhooks/lib/dto/types.ts, the booking fields are restricted structures containing only specific fields (id, eventTypeId, userId, and sometimes additional fields like startTime or smsReminderNumber) rather than full database booking objects, so there are no security or PII leakage concerns when using these booking objects in webhook payloads.

Applied to files:

  • packages/features/bookings/lib/handleCancelBooking.ts
📚 Learning: 2025-08-08T09:12:08.280Z
Learnt from: hariombalhara
PR: calcom/cal.com#22968
File: packages/features/auth/lib/next-auth-options.ts:327-327
Timestamp: 2025-08-08T09:12:08.280Z
Learning: In packages/features/auth/lib/next-auth-options.ts, do not log credentials in authorize() handlers (e.g., the "saml-idp" CredentialsProvider). Remove accidental console.log statements and avoid including credential contents in logs; prefer either no logging or structured logs without sensitive data.

Applied to files:

  • packages/features/credentials/handleDeleteCredential.ts
📚 Learning: 2025-09-09T03:29:43.025Z
Learnt from: emrysal
PR: calcom/cal.com#23692
File: packages/lib/server/service/InsightsBookingBaseService.ts:16-16
Timestamp: 2025-09-09T03:29:43.025Z
Learning: In the Cal.com codebase, readonlyPrisma is still an instance of PrismaClient, making type changes from `typeof readonlyPrisma` to `PrismaClient` less critical since they are fundamentally compatible types.

Applied to files:

  • packages/lib/event-types/getEventTypeById.ts
🧬 Code graph analysis (1)
packages/app-store/zod-utils.ts (2)
packages/app-store/apps.schemas.generated.ts (1)
  • appDataSchemas (55-105)
packages/prisma/zod-utils.ts (1)
  • eventTypeMetaDataSchemaWithoutApps (134-134)
🔇 Additional comments (47)
packages/app-store/salesforce/lib/routingFormBookingFormHandler.ts (1)

5-5: Import path change looks good.

The localizing of EventTypeService removes the cross-package coupling here. No functional issues spotted.

packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts (1)

4-4: Import relocation LGTM.

Switching to @calcom/app-store/zod-utils keeps schema ownership aligned with apps. No behavior change here.

packages/features/ee/round-robin/roundRobinManualReassignment.ts (1)

4-4: Schema import relocation LGTM.

No behavioral changes; parsing remains local to the consumer.

packages/lib/getPaymentAppData.ts (1)

7-7: Import relocation LGTM.

Parsing with the app-store-owned schema keeps validation close to apps. No behavior change.

packages/lib/payment/handleNoShowFee.ts (2)

3-3: Schema import relocation LGTM.

Importing from @calcom/app-store/zod-utils aligns with the PR’s objective and avoids prisma→app-store coupling.


3-3: Verify no lingering @calcom/prisma/zod-utils imports across the repo

ripgrep in the sandbox skipped files; cannot confirm. Run these from the repo root and attach the outputs:

rg -nS "@calcom/prisma/zod-utils" --hidden -g '!.git/**' -g '!node_modules/**' -g '!dist/**' -n -C2 || true
rg -nS "\b(eventTypeMetaDataSchemaWithTypedApps|eventTypeAppMetadataOptionalSchema|EventTypeAppMetadataSchema)\b" --hidden -g '!.git/**' -g '!node_modules/**' -g '!dist/**' -n -C2 || true
rg -nS "@calcom/app-store/zod-utils" --hidden -g '!.git/**' -g '!node_modules/**' -g '!dist/**' -n -C2 || true
packages/platform/atoms/event-types/hooks/useTabsNavigations.tsx (1)

8-8: Schema import path update looks good.

packages/app-store/_utils/payments/checkForMultiplePaymentApps.ts (1)

3-3: Type-only schema import relocation LGTM.

packages/lib/defaultEvents.ts (1)

7-7: Schema import path update LGTM.

apps/web/playwright/integrations-stripe.e2e.ts (1)

3-3: Test import path switch LGTM.

Keeps tests aligned with the relocated schemas.

packages/app-store/_utils/payments/handlePaymentSuccess.ts (1)

1-1: Schema import relocation LGTM.

No behavior change; parse site remains identical.

packages/features/eventtypes/components/tabs/instant/EventInstantTab.tsx (1)

1-1: Import path update LGTM.

packages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.ts (1)

1-1: Import path update LGTM.

Handler logic, auth, and parse semantics remain unchanged.

packages/features/bookings/lib/handleSeats/create/createNewSeat.ts (1)

5-5: Import migration to app-store/zod-utils looks correct.

Switching to @calcom/app-store/zod-utils removes the prisma→app-store coupling; usage of eventTypeAppMetadataOptionalSchema.parse(...) remains type-safe.

packages/app-store/_utils/getEventTypeAppData.ts (1)

3-3: Type-only import relocation LGTM.

Using the schema type from @calcom/app-store/zod-utils keeps typed inference without reintroducing the circular dependency.

packages/lib/payment/shouldChargeNoShowCancellationFee.test.ts (1)

4-4: Test import path update is correct.

No behavior change; keeps type inference aligned with the new schema location.

packages/features/eventtypes/components/tabs/recurring/EventRecurringTab.tsx (1)

1-1: Schema import move LGTM.

Parsing via eventTypeMetaDataSchemaWithTypedApps.parse(...) remains unchanged; no runtime impact.

packages/features/ee/payments/api/webhook.ts (1)

6-6: Good: decouples from prisma zod-utils.

Importing from app-store avoids the circular dependency while preserving parsing behavior.

packages/features/eventtypes/components/EventTypeDescription.tsx (1)

3-3: Import path update LGTM.

Keeps parsing local to UI, aligned with the schema relocation.

packages/features/bookings/lib/handlePayment.ts (1)

3-3: Schema import move LGTM.

Parsing metadata from app-store zod-utils keeps payment app typing without the previous package cycle.

packages/features/ee/round-robin/roundRobinReassignment.ts (1)

5-5: Import migration LGTM.

Using eventTypeAppMetadataOptionalSchema from app-store is consistent with the refactor goal.

packages/features/bookings/lib/handleConfirmation.ts (2)

1-1: Import relocation LGTM; maintains typed apps without prisma↔app-store cycle.
Usage with EventManager(new EventManager(user, apps)) remains type-safe.


27-27: Keep untyped EventTypeMetaDataSchema here.
Parsing metadata first and then apps via eventTypeAppMetadataOptionalSchema is correct and avoids reintroducing the circular dependency.

apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts (1)

4-4: Import moved to app-store/zod-utils — looks good.
Parse site unchanged; behavior preserved.

packages/features/bookings/lib/handleCancelBooking.ts (2)

5-5: Schema import moved to app-store — OK.
SafeParse + logging on failure below keeps behavior stable.


36-36: Prisma zod-utils imports unchanged — OK.
bookingMetadataSchema and bookingCancelInput remain in prisma; consistent with the split.

packages/features/bookings/lib/handleNewBooking.ts (3)

13-15: Typed event-type schema imports relocated — OK.
No logic changes; downstream parse usage is untouched.


81-81: User metadata stays in prisma zod-utils — OK.
Matches the new ownership boundaries.


2035-2057: ```shell
#!/bin/bash
set -euo pipefail
echo "Searching repo for credential.key and possible exposures..."

printf "\n--- 1: literal 'credential.key' ---\n"
rg -n --hidden -S '\bcredential.key\b' || true

printf "\n--- 2: prisma select including key (select: { key: true }) ---\n"
rg -n --hidden -S 'select\s*:\s*{[^}]*\bkey\b' || true

printf "\n--- 3: prisma.credential find* usages ---\n"
rg -n --hidden -S 'prisma.credential.(findUnique|findFirst|findMany|find|create|update|upsert|delete)([^)]*)' || true

printf "\n--- 4: logger/console lines (context 3) ---\n"
rg -n --hidden -S -C3 '(console.log|logger.(info|debug|error|warn))' || true
printf "\n--- 4b: logger/console lines filtered for 'credential'|'credentials'|'key' ---\n"
rg -n --hidden -S '(console.log|logger.(info|debug|error|warn)).*(credential|credentials|key)' || true

printf "\n--- 5: return/res.json/send occurrences returning 'credential' (context 3) ---\n"
rg -n --hidden -S -C3 'return\s+[^;{]\bcredential\b' || true
rg -n --hidden -S -C3 'res.json([^)]credential[^)])' || true
rg -n --hidden -S -C3 'res.send([^)]credential[^)])' || true
rg -n --hidden -S -C3 '\breturn\s+{[^}]
\bcredential\b' || true

printf "\n--- 6: show files selecting credential.key (full lines) ---\n"
rg -n --hidden -S 'select\s*:\s*{[^}]*\bkey\b' || true

printf "\n--- 7: locate handleNewBooking occurrences to inspect surrounding code ---\n"
rg -n --hidden -S -C5 'handleNewBooking' || true
rg -n --hidden -S -C5 'Booking .*requires payment' || true

echo -e "\nDone."


</blockquote></details>
<details>
<summary>apps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsx (2)</summary><blockquote>

`5-5`: **Import relocation to app-store — OK.**
SSR code path remains identical.

---

`16-16`: **customInputSchema still from prisma — OK.**
No behavior change.

</blockquote></details>
<details>
<summary>packages/app-store/salesforce/lib/eventTypeService.ts (2)</summary><blockquote>

`2-2`: **EventTypeAppMetadataSchema now sourced from app-store — good.**
Avoids prisma→app-store dependency.

---

`5-5`: **EventTypeMetaDataSchema stays in prisma — correct split.**
SafeParse + second parse with typed apps is the right flow.

</blockquote></details>
<details>
<summary>packages/lib/payment/processNoShowFeeOnCancellation.ts (1)</summary><blockquote>

`1-1`: **Import move to app-store — OK.**
No functional change; fee logic unaffected.

</blockquote></details>
<details>
<summary>packages/features/eventtypes/lib/getPublicEvent.ts (1)</summary><blockquote>

`4-4`: **Import move to app-store — OK.**
All parse sites (event, profile, shared) continue to use the same schema.

</blockquote></details>
<details>
<summary>apps/web/modules/bookings/views/bookings-single-view.tsx (2)</summary><blockquote>

`16-16`: **Import relocation LGTM.**

Switching eventTypeMetaDataSchemaWithTypedApps to @calcom/app-store/zod-utils matches the PR goal and keeps usage unchanged.

---

`49-49`: **Prisma bookingMetadataSchema import LGTM.**

Parsing bookingInfo.metadata via bookingMetadataSchema.safeParse is correct and side-effect free.

</blockquote></details>
<details>
<summary>packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts (2)</summary><blockquote>

`1-1`: **Type-only z import is correct.**

This avoids bundling zod at runtime for types. Good.

---

`3-3`: **Schema import relocation LGTM.**

eventTypeAppMetadataOptionalSchema now sourced from app-store, behavior unchanged.

</blockquote></details>
<details>
<summary>packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts (1)</summary><blockquote>

`5-5`: **Import relocation LGTM.**

Using eventTypeAppMetadataOptionalSchema from app-store is consistent with the refactor.

</blockquote></details>
<details>
<summary>apps/web/modules/apps/installation/[[...step]]/step-view.tsx (1)</summary><blockquote>

`12-12`: **Import relocation LGTM.**

Consistent with moving typed app schemas to app-store.

</blockquote></details>
<details>
<summary>packages/lib/event-types/getEventTypeById.ts (1)</summary><blockquote>

`4-4`: **Import relocation LGTM.**

Typed apps schema now from app-store; behavior unchanged.

</blockquote></details>
<details>
<summary>apps/web/modules/test-setup.ts (1)</summary><blockquote>

`131-134`: **Mocks updated correctly.**

bookingMetadataSchema added to prisma mock; eventTypeMetaDataSchemaWithTypedApps moved under app-store mock. Good alignment with refactor.



Also applies to: 136-140

</blockquote></details>
<details>
<summary>packages/features/noShow/handleSendingAttendeeNoShowDataToApps.ts (1)</summary><blockquote>

`4-4`: **Import relocation LGTM.**

Parsing EventTypeMetaDataSchema and app metadata from correct modules.



Also applies to: 8-8

</blockquote></details>
<details>
<summary>packages/features/eventtypes/lib/types.ts (1)</summary><blockquote>

`3-3`: **Import/type hygiene LGTM.**

- eventTypeMetaDataSchemaWithTypedApps imported as type-only is correct for z.infer usage.
- PeriodType as type-only avoids bundling enums twice.
- Splitting runtime vs type-only zod-utils imports is appropriate.



Also applies to: 9-19

</blockquote></details>
<details>
<summary>packages/app-store/zod-utils.ts (2)</summary><blockquote>

`3-3`: **Confirm the cycle is actually broken (prisma → app-store).**

The previous scan errored with "unrecognized file type: tsx" so results are inconclusive — re-run this corrected scan from the repo root:

```shell
#!/bin/bash
set -euo pipefail

echo "Scanning for static imports of @calcom/app-store in packages/prisma…"
rg -nP -C0 "\\bfrom\\s+[\"']@calcom/app-store" packages/prisma -g 'packages/prisma/**/*.ts' -g 'packages/prisma/**/*.tsx' -g 'packages/prisma/**/*.js' -g 'packages/prisma/**/*.jsx' || echo "OK: none"

echo "Scanning for dynamic imports of @calcom/app-store in packages/prisma…"
rg -nP -C0 "import\\s*\\(\\s*[\"']@calcom/app-store" packages/prisma -g 'packages/prisma/**/*.ts' -g 'packages/prisma/**/*.tsx' -g 'packages/prisma/**/*.js' -g 'packages/prisma/**/*.jsx' || echo "OK: none"

10-17: Verify hoisted Zod version — .unwrap() requires Zod ≥ 3.22

Repo scan found no package.json declaring zod and no yarn.lock present; cannot confirm the workspace Zod version. Confirm the workspace root package.json or lockfile (yarn.lock, pnpm-lock.yaml, or package-lock.json) declares zod >= 3.22, or avoid using .unwrap() here (e.g., export a non‑nullable base schema or use a non‑.unwrap() pattern).

File: packages/app-store/zod-utils.ts (lines 10–17)

@gustavohellwig
Copy link

Hi. Since version v5.6.19 (the files was removed on the v.5.6.20) I'm receiving this error trying to run the app in a docker:

`Error: Cannot find module './seed-app-store.ts'
Require stack:

  • /calcom/packages/prisma/imaginaryUncacheableRequireResolveScript
    at Module._resolveFilename (node:internal/modules/cjs/loader:1140:15)
    at Function.resolve (node:internal/modules/helpers:188:19)
    at requireResolveNonCached (/calcom/node_modules/ts-node/dist/bin.js:549:16)
    at getProjectSearchDir (/calcom/node_modules/ts-node/dist/bin.js:519:40)
    at phase3 (/calcom/node_modules/ts-node/dist/bin.js:267:27)
    at bootstrap (/calcom/node_modules/ts-node/dist/bin.js:47:30)
    at main (/calcom/node_modules/ts-node/dist/bin.js:33:12)
    at Object. (/calcom/node_modules/ts-node/dist/bin.js:579:5)
    at Module._compile (node:internal/modules/cjs/loader:1364:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [
    '/calcom/packages/prisma/imaginaryUncacheableRequireResolveScript'
    ]
    }`
    What I'm doing wrong? Thank you!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants