refactor: remove circular dependency between prisma and app-store packages#23475
refactor: remove circular dependency between prisma and app-store packages#23475keithwillcode merged 22 commits intomainfrom
Conversation
…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 EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
WalkthroughThis 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)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
- 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>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
- 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>
E2E results are ready! |
…ependency-1735084368
|
@keithwillcode We've successfully removed the circular dep between prisma and app-store. But as a consequence, some files in |
There was a problem hiding this comment.
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: Avoidinclude; select only needed fields from Prisma.Using
includepulls all Credential scalars (includingkey) by default. Select the minimum fields. If you need thekey, 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: Replaceincludewithselectfor nested credential.Avoid
includeand return only the needed fields. You only comparecredential.appIdand need the destination calendarid.- 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 globalprismaclient, not the transactionaltx, 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; dropcredentials.
booking.user.credentialsisn'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: Avoidinclude; 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 breakstypeofusage.
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 whenappsis undefined/null. Also,inonappthrows when it’s undefined. Iterate safely overObject.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 forpaymentOption,price, andcurrency.- Stale import remains — packages/lib/defaultEvents.ts:7 imports
eventTypeMetaDataSchemaWithTypedAppsfrom@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
includewithselectand 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 omitkey) 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 usingappsinstead.Using
typeof appDataSchemaswith animport typecan break compilation. Index against the parsedappsvalue 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 foundSearch 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
routingFormBookingFormHandleras 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
handleChildrenEventTypesas 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
timeUnitwill yieldNaN. 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?.bookingIdcheck 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 onappsmetadata.
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.
📒 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.tsxpackages/features/eventtypes/components/tabs/instant/EventInstantTab.tsxpackages/features/eventtypes/components/tabs/recurring/EventRecurringTab.tsxapps/web/modules/bookings/views/bookings-single-view.tsxpackages/features/eventtypes/components/EventTypeDescription.tsxapps/web/modules/apps/installation/[[...step]]/step-view.tsxapps/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.tsxpackages/features/ee/managed-event-types/lib/handleChildrenEventTypes.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/lib/payment/shouldChargeNoShowCancellationFee.test.tspackages/lib/getPaymentAppData.tspackages/app-store/_utils/payments/checkForMultiplePaymentApps.tspackages/app-store/salesforce/lib/routingFormBookingFormHandler.tspackages/features/eventtypes/lib/getPublicEvent.tspackages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.tspackages/features/eventtypes/components/tabs/instant/EventInstantTab.tsxpackages/lib/payment/shouldChargeNoShowCancellationFee.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/ee/payments/api/webhook.tspackages/features/eventtypes/components/tabs/recurring/EventRecurringTab.tsxpackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/lib/payment/processNoShowFeeOnCancellation.tspackages/lib/defaultEvents.tspackages/lib/payment/handleNoShowFee.tsapps/web/modules/bookings/views/bookings-single-view.tsxpackages/lib/EventManager.tspackages/app-store/zod-utils.tspackages/features/ee/round-robin/roundRobinReassignment.tspackages/features/eventtypes/components/EventTypeDescription.tsxpackages/app-store/salesforce/lib/eventTypeService.tspackages/app-store/_utils/CRMRoundRobinSkip.tspackages/app-store/_utils/getEventTypeAppData.tspackages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.tspackages/features/bookings/lib/handleConfirmation.tspackages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.tsapps/web/modules/apps/installation/[[...step]]/step-view.tsxapps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsxpackages/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tsapps/web/playwright/integrations-stripe.e2e.tspackages/features/noShow/handleSendingAttendeeNoShowDataToApps.tspackages/features/bookings/lib/handleCancelBooking.tspackages/features/bookings/lib/handlePayment.tsapps/web/modules/test-setup.tspackages/features/credentials/handleDeleteCredential.tspackages/lib/event-types/getEventTypeById.tspackages/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.tsxpackages/features/ee/managed-event-types/lib/handleChildrenEventTypes.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/lib/payment/shouldChargeNoShowCancellationFee.test.tspackages/lib/getPaymentAppData.tspackages/app-store/_utils/payments/checkForMultiplePaymentApps.tspackages/app-store/salesforce/lib/routingFormBookingFormHandler.tspackages/features/eventtypes/lib/getPublicEvent.tspackages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.tspackages/features/eventtypes/components/tabs/instant/EventInstantTab.tsxpackages/lib/payment/shouldChargeNoShowCancellationFee.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/ee/payments/api/webhook.tspackages/features/eventtypes/components/tabs/recurring/EventRecurringTab.tsxpackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/lib/payment/processNoShowFeeOnCancellation.tspackages/lib/defaultEvents.tspackages/lib/payment/handleNoShowFee.tsapps/web/modules/bookings/views/bookings-single-view.tsxpackages/lib/EventManager.tspackages/app-store/zod-utils.tspackages/features/ee/round-robin/roundRobinReassignment.tspackages/features/eventtypes/components/EventTypeDescription.tsxpackages/app-store/salesforce/lib/eventTypeService.tspackages/app-store/_utils/CRMRoundRobinSkip.tspackages/app-store/_utils/getEventTypeAppData.tspackages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.tspackages/features/bookings/lib/handleConfirmation.tspackages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.tsapps/web/modules/apps/installation/[[...step]]/step-view.tsxapps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsxpackages/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tsapps/web/playwright/integrations-stripe.e2e.tspackages/features/noShow/handleSendingAttendeeNoShowDataToApps.tspackages/features/bookings/lib/handleCancelBooking.tspackages/features/bookings/lib/handlePayment.tsapps/web/modules/test-setup.tspackages/features/credentials/handleDeleteCredential.tspackages/lib/event-types/getEventTypeById.tspackages/features/eventtypes/lib/types.ts
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
**/*.ts: For Prisma queries, only select data you need; never useinclude, always useselect
Ensure thecredential.keyfield is never returned from tRPC endpoints or APIs
Files:
packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.tsapps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.tspackages/lib/payment/shouldChargeNoShowCancellationFee.test.tspackages/lib/getPaymentAppData.tspackages/app-store/_utils/payments/checkForMultiplePaymentApps.tspackages/app-store/salesforce/lib/routingFormBookingFormHandler.tspackages/features/eventtypes/lib/getPublicEvent.tspackages/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.handler.tspackages/lib/payment/shouldChargeNoShowCancellationFee.tspackages/features/bookings/lib/handleNewBooking.tspackages/features/ee/payments/api/webhook.tspackages/app-store/_utils/payments/handlePaymentSuccess.tspackages/lib/payment/processNoShowFeeOnCancellation.tspackages/lib/defaultEvents.tspackages/lib/payment/handleNoShowFee.tspackages/lib/EventManager.tspackages/app-store/zod-utils.tspackages/features/ee/round-robin/roundRobinReassignment.tspackages/app-store/salesforce/lib/eventTypeService.tspackages/app-store/_utils/CRMRoundRobinSkip.tspackages/app-store/_utils/getEventTypeAppData.tspackages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.tspackages/features/bookings/lib/handleConfirmation.tspackages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.tspackages/features/ee/round-robin/roundRobinManualReassignment.tspackages/features/bookings/lib/handleSeats/create/createNewSeat.tsapps/web/playwright/integrations-stripe.e2e.tspackages/features/noShow/handleSendingAttendeeNoShowDataToApps.tspackages/features/bookings/lib/handleCancelBooking.tspackages/features/bookings/lib/handlePayment.tsapps/web/modules/test-setup.tspackages/features/credentials/handleDeleteCredential.tspackages/lib/event-types/getEventTypeById.tspackages/features/eventtypes/lib/types.ts
**/*Service.ts
📄 CodeRabbit inference engine (.cursor/rules/review.mdc)
Service files must include
Servicesuffix, 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.tspackages/lib/getPaymentAppData.tspackages/app-store/salesforce/lib/routingFormBookingFormHandler.tspackages/features/eventtypes/lib/getPublicEvent.tspackages/features/bookings/lib/handleNewBooking.tspackages/lib/defaultEvents.tspackages/lib/payment/handleNoShowFee.tsapps/web/modules/bookings/views/bookings-single-view.tsxpackages/lib/EventManager.tspackages/features/eventtypes/components/EventTypeDescription.tsxpackages/app-store/salesforce/lib/eventTypeService.tspackages/app-store/_utils/getEventTypeAppData.tspackages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.tspackages/features/bookings/lib/handleConfirmation.tspackages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.tsapps/web/modules/apps/installation/[[...step]]/step-view.tsxapps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsxpackages/features/bookings/lib/handleSeats/create/createNewSeat.tspackages/features/noShow/handleSendingAttendeeNoShowDataToApps.tspackages/features/bookings/lib/handleCancelBooking.tspackages/features/credentials/handleDeleteCredential.tspackages/lib/event-types/getEventTypeById.tspackages/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.tspackages/features/bookings/lib/handleNewBooking.tsapps/web/modules/bookings/views/bookings-single-view.tsxpackages/features/bookings/lib/handleConfirmation.tsapps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsxpackages/features/bookings/lib/handleSeats/create/createNewSeat.tspackages/features/bookings/lib/handleCancelBooking.tsapps/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.tspackages/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.tspackages/lib/defaultEvents.tspackages/lib/EventManager.tspackages/features/eventtypes/components/EventTypeDescription.tsxpackages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.tspackages/features/bookings/lib/handleConfirmation.tsapps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsxpackages/features/bookings/lib/handleSeats/create/createNewSeat.tspackages/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.tspackages/lib/EventManager.tspackages/features/eventtypes/components/EventTypeDescription.tsxapps/web/modules/bookings/views/bookings-single-view.getServerSideProps.tsxpackages/features/bookings/lib/handleSeats/create/createNewSeat.tspackages/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-utilskeeps 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 reporipgrep 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 || truepackages/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-utilsremoves the prisma→app-store coupling; usage ofeventTypeAppMetadataOptionalSchema.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-utilskeeps 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
eventTypeAppMetadataOptionalSchemafrom 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' || trueprintf "\n--- 2: prisma select including key (select: { key: true }) ---\n"
rg -n --hidden -S 'select\s*:\s*{[^}]*\bkey\b' || trueprintf "\n--- 3: prisma.credential find* usages ---\n"
rg -n --hidden -S 'prisma.credential.(findUnique|findFirst|findMany|find|create|update|upsert|delete)([^)]*)' || trueprintf "\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)' || trueprintf "\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' || trueprintf "\n--- 6: show files selecting credential.key (full lines) ---\n"
rg -n --hidden -S 'select\s*:\s*{[^}]*\bkey\b' || trueprintf "\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' || trueecho -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.22Repo 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)
|
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'
|
What does this PR do?
Removes the circular dependency between
@calcom/prismaand@calcom/app-storepackages by eliminating schema exports from the prisma package and moving validation closer to consuming code.Key Changes:
EventTypeAppMetadataSchemaandeventTypeAppMetadataOptionalSchemaexports from@calcom/prisma/zod-utilsimport { appDataSchemas } from "@calcom/app-store/apps.schemas.generated"from prisma packageappDataSchemasdirectly and create local typed schemas usingz.object(appDataSchemas).partial().optional()patternappSlug as keyof typeof appsRequested 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)
How should this be tested?
Critical Testing Areas:
Environment Setup:
Expected Behavior:
Checklist
appSlug as keyof typeof apps) handle edge cases safelyFiles with Highest Risk:
packages/lib/payment/handlePayment.ts- Dynamic property access for payment datapackages/trpc/server/routers/viewer/eventTypes/update.handler.ts- Complex app iteration logicpackages/lib/server/service/eventTypeService.ts- Changed function signature from strict to flexible typing