Skip to content

Comments

refactor: remove circular dependency between appstore and trpc#23768

Merged
hbjORbj merged 49 commits intomainfrom
refactor/circular-dep-between-appstore-trpc
Sep 14, 2025
Merged

refactor: remove circular dependency between appstore and trpc#23768
hbjORbj merged 49 commits intomainfrom
refactor/circular-dep-between-appstore-trpc

Conversation

@hbjORbj
Copy link
Contributor

@hbjORbj hbjORbj commented Sep 11, 2025

Impact

Screenshot 2025-09-14 at 12 30 07 PM

Problem Statement

Files in packages/app-store were importing tRPC client utilities, creating circular dependencies between the core app-store package and higher-level web application packages. This violated architectural boundaries and could cause build issues, increased bundle sizes, and runtime dependency resolution problems.

Solution Overview

This PR resolves the circular dependency by migrating UI components and pages from packages/app-store to apps/web/components/apps/, establishing clear separation between core app logic and presentation layer.

📊 Impact Metrics

  • tRPC client imports reduced: From 19 to 0 remaining in packages/app-store
  • Apps migrated: 18 complete app integrations restructured
  • Files migrated: 40+ component and page files moved to new architecture

🚚 Complete File Migration Details

18 Apps Migrated to apps/web/components/apps/:

Payment Integration Apps (4 apps):

📁 alby/
  ├── packages/app-store/alby/components/AlbyPaymentComponent.tsx
  │   → apps/web/components/apps/alby/AlbyPaymentComponent.tsx
  └── packages/app-store/alby/components/Setup.tsx
      → apps/web/components/apps/alby/Setup.tsx

📁 btcpayserver/
  ├── packages/app-store/btcpayserver/components/BtcpayPaymentComponent.tsx
  │   → apps/web/components/apps/btcpayserver/BtcpayPaymentComponent.tsx
  └── packages/app-store/btcpayserver/components/Setup.tsx
      → apps/web/components/apps/btcpayserver/Setup.tsx

📁 hitpay/
  ├── packages/app-store/hitpay/components/HitpayPaymentComponent.tsx
  │   → apps/web/components/apps/hitpay/HitpayPaymentComponent.tsx
  └── packages/app-store/hitpay/components/Setup.tsx
      → apps/web/components/apps/hitpay/Setup.tsx

📁 paypal/
  ├── packages/app-store/paypal/components/PaypalPaymentComponent.tsx
  │   → apps/web/components/apps/paypal/PaypalPaymentComponent.tsx
  └── packages/app-store/paypal/components/Setup.tsx
      → apps/web/components/apps/paypal/Setup.tsx

📁 stripepayment/
  └── packages/app-store/stripepayment/components/Setup.tsx
      → apps/web/components/apps/stripepayment/Setup.tsx

Calendar Integration Apps (6 apps):

📁 applecalendar/
  └── packages/app-store/applecalendar/components/Setup.tsx
      → apps/web/components/apps/applecalendar/Setup.tsx

📁 caldavcalendar/
  └── packages/app-store/caldavcalendar/components/Setup.tsx
      → apps/web/components/apps/caldavcalendar/Setup.tsx

📁 exchangecalendar/
  └── packages/app-store/exchangecalendar/components/Setup.tsx
      → apps/web/components/apps/exchangecalendar/Setup.tsx

📁 exchange2013calendar/
  └── packages/app-store/exchange2013calendar/components/Setup.tsx
      → apps/web/components/apps/exchange2013calendar/Setup.tsx

📁 exchange2016calendar/
  └── packages/app-store/exchange2016calendar/components/Setup.tsx
      → apps/web/components/apps/exchange2016calendar/Setup.tsx

📁 ics-feedcalendar/
  └── packages/app-store/ics-feedcalendar/components/Setup.tsx
      → apps/web/components/apps/ics-feedcalendar/Setup.tsx

Automation & Integration Apps (3 apps):

📁 make/
  └── packages/app-store/make/components/Setup.tsx
      → apps/web/components/apps/make/Setup.tsx

📁 sendgrid/
  └── packages/app-store/sendgrid/components/Setup.tsx
      → apps/web/components/apps/sendgrid/Setup.tsx

📁 zapier/
  └── packages/app-store/zapier/components/Setup.tsx
      → apps/web/components/apps/zapier/Setup.tsx

Routing Forms Complete Migration (1 app, 6 components):

📁 routing-forms/
  ├── packages/app-store/routing-forms/components/FormActions.tsx
  │   → apps/web/components/apps/routing-forms/FormActions.tsx
  ├── packages/app-store/routing-forms/components/FormSettingsSlideover.tsx
  │   → apps/web/components/apps/routing-forms/FormSettingsSlideover.tsx
  ├── packages/app-store/routing-forms/components/Header.tsx
  │   → apps/web/components/apps/routing-forms/Header.tsx
  ├── packages/app-store/routing-forms/components/SingleForm.tsx
  │   → apps/web/components/apps/routing-forms/SingleForm.tsx
  ├── packages/app-store/routing-forms/components/TestForm.tsx
  │   → apps/web/components/apps/routing-forms/TestForm.tsx
  └── packages/app-store/routing-forms/components/TestFormDialog.test.tsx
      → apps/web/components/apps/routing-forms/TestFormDialog.test.tsx

📁 routing-forms pages/
  └── packages/app-store/routing-forms/pages/app-routing.client-config.tsx
      → apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/app-routing.client-config.tsx

Utility Apps (1 app):

📁 wipemycalother/
  ├── packages/app-store/wipemycalother/components/confirmDialog.tsx
  │   → apps/web/components/apps/wipemycalother/confirmDialog.tsx
  └── packages/app-store/wipemycalother/components/wipeMyCalActionButton.tsx
      → apps/web/components/apps/wipemycalother/wipeMyCalActionButton.tsx

🏗️ Infrastructure Changes

New Files Created:

  • apps/web/components/apps/AppSetupPage.tsx - Centralized setup page routing

Files Removed:

  • packages/app-store/_pages/setup/index.tsx - Old setup handler
  • packages/app-store/routing-forms/types/shared.ts - Migrated shared types
  • packages/app-store/wipemycalother/components/index.ts - Component exports

Import Path Updates:

50+ files updated across the codebase including:

  • Payment processing flows
  • App installation sequences
  • Routing forms functionality
  • Server-side props handlers

🎯 Architecture After Migration

packages/app-store/ now contains only:

  • Core business logic and utilities
  • Event type interfaces and configurations
  • App metadata and manifests
  • Server-side integrations (8 remaining tRPC imports for legitimate server use)

apps/web/components/apps/ now contains:

  • All UI components requiring tRPC client
  • Setup flows and installation wizards
  • Payment processing interfaces
  • Form components and interactions

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 11, 2025

Walkthrough

This PR is a large-scale import and type-surface refactor: many relative imports were replaced with canonical aliases (e.g., @calcom/app-store, @calcom/web, @calcom/features), several prop/type definitions were moved into their server-side props modules, routing-forms client config was rehomed (removed from app-store and added under web), routing-forms error handling switched from TRPCError to HttpError, and multiple components gained or forwarded an onAppInstallSuccess callback. No control-flow or core business logic was introduced beyond error-type and exported-symbol adjustments. (≈77 words)

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately captures the primary change—refactoring to remove a circular dependency between the app-store package and tRPC—which aligns with the changeset that migrates UI components out of packages/app-store and updates import paths across the repo.
Description Check ✅ Passed The PR description is comprehensive and directly related to the changeset: it explains the architectural problem, summarizes the migration approach, lists migrated files and apps, and describes import/path changes and impact metrics that match the provided raw summary. The level of detail (file lists, new/removed files, and stated goals) makes the description useful for reviewers. There are minor inconsistencies in reported counts across comments, but the description is still clearly on-topic and relevant to the diff.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/circular-dep-between-appstore-trpc

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.

@graphite-app graphite-app bot requested review from a team September 11, 2025 13:50
@hbjORbj hbjORbj marked this pull request as draft September 11, 2025 13:50
@hbjORbj hbjORbj changed the title refactor: circular dep between appstore trpc refactor: circular dep between appstore and trpc Sep 11, 2025
@keithwillcode keithwillcode added core area: core, team members only foundation labels Sep 11, 2025
@vercel
Copy link

vercel bot commented Sep 11, 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 14, 2025 8:30am
cal-eu Ignored Ignored Sep 14, 2025 8:30am

@github-actions
Copy link
Contributor

github-actions bot commented Sep 13, 2025

E2E results are ready!

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

🧹 Nitpick comments (2)
.eslintrc.js (2)

11-21: Make the app-store boundary symmetric by failing imports from @calcom/app-store in lib/prisma

Today this is only a warning; consider failing CI the same way to prevent regressions.

Apply this diff:

       rules: {
         "no-restricted-imports": [
-          "warn",
-          {
-            paths: ["@calcom/app-store"],
-            patterns: ["@calcom/app-store/*"],
-          },
+          "error",
+          {
+            paths: [
+              { name: "@calcom/app-store", message: "Core packages (lib/prisma) must not depend on app-store." }
+            ],
+            patterns: [
+              { group: "@calcom/app-store/*", message: "Do not import app-store subpaths from core packages." }
+            ],
+            allowTypeImports: false
+          },
         ],
       },

25-31: Hardened boundary is correct; add guidance + block type-only imports

Scan of packages/app-store found no @calcom/trpc imports.

         "no-restricted-imports": [
-          "error",
-          {
-            paths: ["@calcom/trpc"],
-            patterns: ["@calcom/trpc/*"],
-          },
+          "error",
+          {
+            paths: [
+              { name: "@calcom/trpc", message: "packages/app-store must not depend on @calcom/trpc. Move UI to apps/web and keep routers in packages/trpc." }
+            ],
+            patterns: [
+              { group: "@calcom/trpc/*", message: "packages/app-store must not import any subpath of @calcom/trpc." }
+            ],
+            allowTypeImports: false
+          },
         ],

Apply the diff to add explanatory messages and prevent type-only import leaks.

📜 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 7f113ca and 9dcce26.

📒 Files selected for processing (1)
  • .eslintrc.js (1 hunks)

@hbjORbj hbjORbj enabled auto-merge (squash) September 14, 2025 03:30
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: 0

♻️ Duplicate comments (1)
apps/web/components/apps/routing-forms/SingleForm.tsx (1)

18-18: Resolved: SSR helper is type-only.

Good fix. Prevents bundling server code in the client.

🧹 Nitpick comments (5)
apps/web/components/apps/routing-forms/SingleForm.tsx (5)

26-38: Public prop contract is clear; minor type polish.

Consider extracting the inline Page prop object into a named type to reduce repetition and improve discoverability.

Apply:

+export type SingleFormPageProps = {
+  form: RoutingFormWithResponseCount;
+  appUrl: string;
+  hookForm: UseFormReturn<RoutingFormWithResponseCount>;
+};
 export type SingleFormComponentProps = {
   form: RoutingFormWithResponseCount;
   appUrl: string;
-  Page: React.FC<{
-    form: RoutingFormWithResponseCount;
-    appUrl: string;
-    hookForm: UseFormReturn<RoutingFormWithResponseCount>;
-  }>;
+  Page: React.FC<SingleFormPageProps>;
   enrichedWithUserProfileForm: inferSSRProps<
     typeof getServerSidePropsForSingleFormView
   >["enrichedWithUserProfileForm"];
   permissions: inferSSRProps<typeof getServerSidePropsForSingleFormView>["permissions"];
 };

106-107: useFormContext requires an ancestor FormProvider.

This component calls useFormContext before rendering the

that likely provides the context. If no provider wraps SingleForm higher up, this will throw at runtime.

If there is no upstream provider, initialize the form locally:

-import { useFormContext } from "react-hook-form";
+import { useForm } from "react-hook-form";
@@
-  const hookForm = useFormContext<RoutingFormWithResponseCount>();
+  const hookForm = useForm<RoutingFormWithResponseCount>({ values: form });

If there is an upstream provider, consider removing the redundant provider in or avoid re-providing the same instance.


142-143: Localize fallback error toast.

Avoid hardcoded strings in UI; use t().

-      showToast(`Something went wrong`, "error");
+      showToast(t("something_went_wrong"), "error");

148-157: Test preview may be stale for non-route fields.

uptoDateForm re-renders only when routes changes. Other field edits won’t refresh the preview.

Minimal change to watch the whole form:

-  const uptoDateForm = {
-    ...hookForm.getValues(),
-    routes: hookForm.watch("routes"),
+  const watchedForm = hookForm.watch();
+  const uptoDateForm = {
+    ...watchedForm,
+    routes: watchedForm?.routes,
     user: enrichedWithUserProfileForm.user,
     team: enrichedWithUserProfileForm.team,
     nonOrgUsername: enrichedWithUserProfileForm.nonOrgUsername,
     nonOrgTeamslug: enrichedWithUserProfileForm.nonOrgTeamslug,
     userOrigin: enrichedWithUserProfileForm.userOrigin,
     teamOrigin: enrichedWithUserProfileForm.teamOrigin,
   } as UptoDateForm;

If re-render cost is a concern, move the watch into a small preview-only child (e.g., inside TestFormRenderer) using useWatch to isolate updates.


231-236: Run RHF validation before saving from the dialog.

Directly mutating with getValues bypasses client-side validation and normalization.

-          <InfoLostWarningDialog
-            handleSubmit={() => {
-              mutation.mutate({
-                ...hookForm.getValues(),
-              });
-            }}
+          <InfoLostWarningDialog
+            handleSubmit={hookForm.handleSubmit((values) => {
+              mutation.mutate(values);
+            })}
📜 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 9dcce26 and 6e12304.

📒 Files selected for processing (1)
  • apps/web/components/apps/routing-forms/SingleForm.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.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:

  • apps/web/components/apps/routing-forms/SingleForm.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:

  • apps/web/components/apps/routing-forms/SingleForm.tsx
**/*.{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:

  • apps/web/components/apps/routing-forms/SingleForm.tsx
🧠 Learnings (2)
📚 Learning: 2025-08-29T22:57:30.382Z
Learnt from: bandhan-majumder
PR: calcom/cal.com#23454
File: packages/features/form-builder/FormBuilder.tsx:11-11
Timestamp: 2025-08-29T22:57:30.382Z
Learning: FormBuilder.tsx in packages/features/form-builder/ does not have "use client" directive at the top despite using client-side React hooks and event handlers, which suggests it should be a client component.

Applied to files:

  • apps/web/components/apps/routing-forms/SingleForm.tsx
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.

Applied to files:

  • apps/web/components/apps/routing-forms/SingleForm.tsx
🧬 Code graph analysis (1)
apps/web/components/apps/routing-forms/SingleForm.tsx (2)
packages/app-store/routing-forms/types/types.d.ts (1)
  • RoutingFormWithResponseCount (106-114)
apps/web/lib/apps/routing-forms/[...pages]/getServerSidePropsSingleForm.ts (1)
  • getServerSidePropsForSingleFormView (9-166)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (4)
apps/web/components/apps/routing-forms/SingleForm.tsx (4)

6-6: Type-only import for UseFormReturn is correct.

Keeps runtime bundle clean.


13-13: Type-only import for inferSSRProps is correct.

Ties client props to SSR safely without runtime coupling.


22-24: Import path consolidation looks good.

Localizing TestForm/Header usage under the same directory improves cohesion.


8-9: Verify no tRPC usage inside app-store InfoLostWarningDialog.

Search script produced no output; verification inconclusive. Confirm @calcom/app-store/routing-forms/components/InfoLostWarningDialog (imported in apps/web/components/apps/routing-forms/SingleForm.tsx — lines 8–9) and all transitive imports do not import @calcom/trpc to avoid reintroducing circular deps.

Comment on lines -33 to -37
utils.viewer.apps.appById.invalidate({ appId });
utils.viewer.apps.integrations.invalidate({
extendsFeature: "EventType",
...(teamId && { teamId }),
});
Copy link
Contributor Author

@hbjORbj hbjORbj Sep 14, 2025

Choose a reason for hiding this comment

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

To remove the import of trpc client in this file (appstore package), I moved this logic to one level higher: packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx.

I am aware that features shouldn't import trpc ideally but that's another huddle we have to address cc @keithwillcode

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 (5)
packages/app-store/paypal/components/EventTypeAppCardInterface.tsx (1)

39-46: Persist the toggle to app data (parity with other apps)

Switch only updates local state; it doesn’t persist to app data. This diverges from others using updateEnabled/setAppData and likely won’t survive save/navigation.

Apply:

-      switchOnClick={(enabled) => {
-        setRequirePayment(enabled);
-      }}
+      switchOnClick={(enabled) => {
+        setRequirePayment(enabled);
+        setAppData("enabled", enabled);
+      }}
packages/app-store/mock-payment-app/components/EventTypeAppCardInterface.tsx (1)

43-47: Switch toggling isn’t persisted to app data

Local state requirePayment diverges from stored “enabled”. Use useIsAppEnabled(app) and updateEnabled to persist, and gate UI on enabled.

+import useIsAppEnabled from "@calcom/app-store/_utils/useIsAppEnabled";
@@
-  const enable = getAppData("enabled");
-
-  const [requirePayment, setRequirePayment] = useState(enable);
+  const { enabled, updateEnabled } = useIsAppEnabled(app);
@@
-      switchChecked={requirePayment}
-      switchOnClick={(enabled) => {
-        setRequirePayment(enabled);
-      }}
+      switchChecked={enabled}
+      switchOnClick={(e) => {
+        updateEnabled(e);
+      }}
@@
-          requirePayment && (
+          enabled && (

Also applies to: 57-61, 66-68, 111-116

packages/app-store/insihts/components/EventTypeAppCardInterface.tsx (1)

1-3: Fix misspelled directory: packages/app-store/insihts → packages/app-store/insights

Confirmed packages/app-store/insihts exists and no occurrences of "insights" were found; rename the directory and update any imports/registry/slug references.
Affected example: packages/app-store/insihts/ (e.g. packages/app-store/insihts/components/EventTypeAppCardInterface.tsx).

packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx (2)

243-247: Avoid mutating state objects in place

Deleting keys on onBookingWriteToEventObjectMap mutates the same reference; updates may not propagate.

Apply:

-                          const newObject = onBookingWriteToEventObjectMap;
-                          delete onBookingWriteToEventObjectMap[key];
-                          setAppData("onBookingWriteToEventObjectMap", newObject);
+                          const { [key]: _omit, ...rest } = onBookingWriteToEventObjectMap;
+                          setAppData("onBookingWriteToEventObjectMap", rest);

40-41: Type mismatch: array vs string in input value

onBookingChangeRecordOwnerName defaults to [] but is bound to a text input (string). This can cause runtime issues and incorrect data shape.

Apply:

-  const onBookingChangeRecordOwnerName = getAppData("onBookingChangeRecordOwnerName") ?? [];
+  const onBookingChangeRecordOwnerName =
+    (getAppData("onBookingChangeRecordOwnerName") as string | undefined) ?? "";
@@
-                <InputField
+                <InputField
                   id="on-booking-change-record-owner-name"
                   size="sm"
                   value={onBookingChangeRecordOwnerName}
                   onChange={(e) => setAppData("onBookingChangeRecordOwnerName", e.target.value)}
                 />

If multiple owners are required, switch to a multiselect or chips input and persist an array consistently.

Also applies to: 348-352

🧹 Nitpick comments (33)
packages/app-store/matomo/components/EventTypeAppCardInterface.tsx (1)

26-46: Localize user-facing labels/placeholders

TextField labels/placeholders should use t() per guidelines.

Apply:

-        <TextField
-          dataTestid={`${app.slug}-url`}
-          name="Matomo URL"
-          placeholder="Enter your Matomo URL here"
+        <TextField
+          data-testid={`${app.slug}-url`}
+          name={t("matomo_url")}
+          placeholder={t("enter_matomo_url")}
           value={matomoUrl}
           disabled={disabled}
           onChange={(e) => {
             setAppData("MATOMO_URL", e.target.value);
           }}
         />
-        <TextField
-          dataTestid={`${app.slug}-site-id`}
+        <TextField
+          data-testid={`${app.slug}-site-id`}
           disabled={disabled}
-          name="Site ID"
-          placeholder="Enter your Site ID"
+          name={t("site_id")}
+          placeholder={t("enter_site_id")}
           value={siteId}
           onChange={(e) => {
             setAppData("SITE_ID", e.target.value);
           }}
         />

And add t():

 import { TextField } from "@calcom/ui/components/form";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
@@
-const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({ app, eventType, onAppInstallSuccess }) {
+const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({ app, eventType, onAppInstallSuccess }) {
+  const { t } = useLocale();
packages/app-store/paypal/components/EventTypeAppCardInterface.tsx (2)

43-45: Localize description and fix brand casing

Use t() and “PayPal”.

-      description={<>Add Paypal payment to your events</>}
+      description={t("add_paypal_payment_to_your_events")}

21-22: Remove stale TODO about pathname brackets

Comment no longer applies; remove to avoid confusion.

-  /** TODO "pathname" no longer contains square-bracket expressions. Rewrite the code relying on them if required. **/
packages/app-store/umami/components/EventTypeAppCardInterface.tsx (1)

29-47: Avoid controlled + defaultValue mix; localize labels/placeholders

Passing both value and defaultValue is an anti-pattern; also localize text.

-        <TextField
-          disabled={disabled}
-          name="Script URL"
-          value={scriptURL}
-          defaultValue="https://us.umami.is/script.js"
-          placeholder="Enter the script source URL"
+        <TextField
+          disabled={disabled}
+          name={t("script_url")}
+          value={scriptURL}
+          placeholder={t("enter_script_source_url")}
           onChange={(e) => {
             setAppData("SCRIPT_URL", e.target.value);
           }}
         />
-        <TextField
-          disabled={disabled}
-          name="Site ID"
+        <TextField
+          disabled={disabled}
+          name={t("site_id")}
           value={siteId}
-          placeholder="Enter your Site ID"
+          placeholder={t("enter_site_id")}
           onChange={(e) => {
             setAppData("SITE_ID", e.target.value);
           }}
         />

Add t():

 import { TextField } from "@calcom/ui/components/form";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
@@
-  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { t } = useLocale();
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)

27-27: Localize ErrorBoundary message

User-facing string should use t().

-import { ErrorBoundary } from "@calcom/ui/components/errorBoundary";
+import { ErrorBoundary } from "@calcom/ui/components/errorBoundary";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
@@
-export const EventTypeAppCard = (props: {
+export const EventTypeAppCard = (props: {
@@
-  return (
+  const { t } = useLocale();
+  return (
     <ErrorBoundary message={`There is some problem with ${app.name} App`}>

Prefer:

-    <ErrorBoundary message={`There is some problem with ${app.name} App`}>
+    <ErrorBoundary message={t("there_is_a_problem_with_app", { appName: app.name })}>
packages/app-store/_components/OmniInstallAppButton.tsx (1)

33-36: Guard callback to avoid breaking success flow

A thrown error in onAppInstallSuccess would suppress the toast. Wrap it.

-      onAppInstallSuccess();
+      try {
+        onAppInstallSuccess();
+      } catch (err) {
+        console.error("onAppInstallSuccess failed", err);
+      }
packages/app-store/types.d.ts (1)

74-76: Tiny doc nit: stray backslash

Remove the trailing backslash in the comment.

-  // Limit what data should be accessible to apps\
+  // Limit what data should be accessible to apps
packages/app-store/twipla/components/EventTypeAppCardInterface.tsx (1)

23-31: Localize user‑visible strings

Replace hardcoded “Site ID” and “Enter your Site ID” with t(). Also add useLocale.

+import { useLocale } from "@calcom/lib/hooks/useLocale";
@@
-  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { t } = useLocale();
@@
-      <TextField
+      <TextField
         disabled={disabled}
-        name="Site ID"
+        name={t("site_id")}
         value={siteId}
-        placeholder="Enter your Site ID"
+        placeholder={t("enter_your_site_id")}
         onChange={(e) => {
           setAppData("SITE_ID", e.target.value);
         }}
       />

[coding_guidelines]

packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx (1)

23-33: Localize placeholders/labels and avoid duplicate disabled

Use t() for “Site ID”/placeholder and drop redundant disabled on TextField (fieldset already disables children).

+import { useLocale } from "@calcom/lib/hooks/useLocale";
@@
-  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { t } = useLocale();
@@
-      <fieldset className="space-y-2" disabled={disabled}>
-        <TextField
-          disabled={disabled}
-          name="Site ID"
+      <fieldset className="space-y-2" disabled={disabled}>
+        <TextField
+          name={t("site_id")}
           value={siteId}
-          placeholder="Enter your Site ID"
+          placeholder={t("enter_your_site_id")}
           onChange={(e) => {
             setAppData("SITE_ID", e.target.value);
           }}
         />

[coding_guidelines]

packages/app-store/fathom/components/EventTypeAppCardInterface.tsx (1)

23-31: Localize user‑visible strings

Use t() for “Site ID” and its placeholder; add useLocale.

+import { useLocale } from "@calcom/lib/hooks/useLocale";
@@
-  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { t } = useLocale();
@@
-      <EventTypeAppSettingsInterface
+      <EventTypeAppSettingsInterface
         eventType={eventType}
         slug={app.slug}
         disabled={disabled}
         getAppData={getAppData}
         setAppData={setAppData}
       />

And in the TextField below (keep current structure), change:

- name="Site ID"
- placeholder="Enter your Site ID"
+ name={t("site_id")}
+ placeholder={t("enter_your_site_id")}

[coding_guidelines]

packages/app-store/mock-payment-app/components/EventTypeAppCardInterface.tsx (3)

61-61: Localize user‑visible strings

Wrap description, “Price”, and “Payment option” in t().

[coding_guidelines]

-      description={<>Add a mock payment to your events</>}
+      description={<>{t("add_mock_payment_to_your_events")}</>}
@@
-                  label="Price"
+                  label={t("price")}
@@
-                  placeholder="Price"
+                  placeholder={t("price")}
@@
-                <label className="text-default mb-1 block text-sm font-medium" htmlFor="currency">
-                  Payment option
-                </label>
+                <label className="text-default mb-1 block text-sm font-medium" htmlFor="currency">
+                  {t("payment_option")}
+                </label>

Also applies to: 71-81, 112-114


82-87: Avoid floating‑point currency errors

Store cents as integers using Math.round.

-                    setAppData("price", Number(e.target.value) * 100);
+                    setAppData("price", Math.round(Number(e.target.value) * 100));

25-30: Stale TODO around pathname

If no longer relying on bracketed segments, remove or update the comment.

packages/app-store/basecamp3/components/EventTypeAppCardInterface.tsx (1)

5-5: Prefer path alias over relative import

Use monorepo alias for consistency and easier refactors.

-import useIsAppEnabled from "../../_utils/useIsAppEnabled";
+import useIsAppEnabled from "@calcom/app-store/_utils/useIsAppEnabled";
packages/app-store/gtm/components/EventTypeAppCardInterface.tsx (3)

22-22: Use nullish coalescing for teamId

Avoid || which treats 0 as falsy; prefer ??.

Apply:

-      teamId={eventType.team?.id || undefined}>
+      teamId={eventType.team?.id ?? undefined}>

34-34: Prefer named export (optional)

Consider a named export for better tree‑shaking and refactors.

-export default EventTypeAppCard;
+export { EventTypeAppCard };

9-22: Replace || undefined with ?? for teamId and confirm onAppInstallSuccess forwarding

  • Scan result: all EventTypeAppCardInterface files forward onAppInstallSuccess to except packages/app-store/_components/EventTypeAppCardInterface.tsx (it references onAppInstallSuccess but contains no — confirm intended behavior).
  • Files that still use teamId={eventType.team?.id || undefined} (update to teamId={eventType.team?.id ?? undefined} or simply teamId={eventType.team?.id}):
    • packages/app-store/zohocrm/components/EventTypeAppCardInterface.tsx
    • packages/app-store/zoho-bigin/components/EventTypeAppCardInterface.tsx
    • packages/app-store/umami/components/EventTypeAppCardInterface.tsx
    • packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx
    • packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx
    • packages/app-store/twipla/components/EventTypeAppCardInterface.tsx
    • packages/app-store/stripepayment/components/EventTypeAppCardInterface.tsx
    • packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx
    • packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx
    • packages/app-store/pipedrive-crm/components/EventTypeAppCardInterface.tsx
    • packages/app-store/plausible/components/EventTypeAppCardInterface.tsx
    • packages/app-store/posthog/components/EventTypeAppCardInterface.tsx
    • packages/app-store/metapixel/components/EventTypeAppCardInterface.tsx
    • packages/app-store/matomo/components/EventTypeAppCardInterface.tsx
    • packages/app-store/insihts/components/EventTypeAppCardInterface.tsx
    • packages/app-store/hubspot/components/EventTypeAppCardInterface.tsx
    • packages/app-store/gtm/components/EventTypeAppCardInterface.tsx
    • packages/app-store/giphy/components/EventTypeAppCardInterface.tsx
    • packages/app-store/hitpay/components/EventTypeAppCardInterface.tsx
    • packages/app-store/ga4/components/EventTypeAppCardInterface.tsx
    • packages/app-store/fathom/components/EventTypeAppCardInterface.tsx
    • packages/app-store/closecom/components/EventTypeAppCardInterface.tsx
packages/app-store/stripepayment/components/EventTypeAppCardInterface.tsx (1)

38-38: Use ?? instead of || for teamId

Prevents dropping a valid 0 id.

-      teamId={eventType.team?.id || undefined}
+      teamId={eventType.team?.id ?? undefined}
packages/app-store/btcpayserver/components/EventTypeAppCardInterface.tsx (1)

38-38: Localize user‑visible text

Wrap description in t() per frontend i18n guideline.

-      description={<>Add lightning payments to your events and booking</>}
+      description={<>{t("add_lightning_payments_to_your_events_and_booking")}</>}
packages/app-store/pipedrive-crm/components/EventTypeAppCardInterface.tsx (1)

18-18: Use ?? for teamId

Avoid falsy pitfalls.

-      teamId={eventType.team?.id || undefined}
+      teamId={eventType.team?.id ?? undefined}
packages/app-store/closecom/components/EventTypeAppCardInterface.tsx (2)

32-32: Use ?? for teamId

Safer nullish handling.

-      teamId={eventType.team?.id || undefined}
+      teamId={eventType.team?.id ?? undefined}

34-44: Localize strings in UI

User‑visible strings should use t().

-          <span className="ltr:mr-2 rtl:ml-2">
+          <span className="ltr:mr-2 rtl:ml-2">
             <Icon name={isSunrise ? "sunrise" : "sunset"} />
           </span>
-          I am an AppCard for Event with Title: {eventType.title}
+          {t("appcard_for_event_with_title", { title: eventType.title })}
         </div>{" "}
         <div className="mt-2">
-          Edit <span className="italic">packages/app-store/{app.slug}/EventTypeAppCardInterface.tsx</span> to
-          play with me
+          {t("edit_event_type_appcard_interface_to_play", { slug: app.slug })}
         </div>
packages/app-store/alby/components/EventTypeAppCardInterface.tsx (1)

43-45: Localize description

Use t() for the description string.

-      description={<>Add bitcoin lightning payments to your events</>}
+      description={<>{t("add_bitcoin_lightning_payments_to_your_events")}</>}
packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx (1)

49-49: Prefer named export (optional)

Consider exporting EventTypeAppCard as a named export in templates as well.

-export default EventTypeAppCard;
+export { EventTypeAppCard };
packages/app-store/hitpay/components/EventTypeAppCardInterface.tsx (1)

38-38: Use ?? for teamId

Avoid || here.

-      teamId={eventType.team?.id || undefined}
+      teamId={eventType.team?.id ?? undefined}
packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx (2)

28-35: Localize user‑visible strings

"Tracking ID" should use t() per guidelines. Add useLocale and wrap labels/placeholders.

Apply:

+import { useLocale } from "@calcom/lib/hooks/useLocale";
@@
-  const { getAppData, setAppData } = useAppContextWithSchema<typeof appDataSchema>();
+  const { getAppData, setAppData } = useAppContextWithSchema<typeof appDataSchema>();
+  const { t } = useLocale();
@@
-      <TextField
-        name="Tracking ID"
+      <TextField
+        name={t("tracking_id")}
         value={trackingId}
         onChange={(e) => {
           setAppData("trackingId", e.target.value);
         }}
       />

19-27: Align enabled state handling with existing hook

You manage enabled via local state while AppCard also writes enabled via context. Prefer useIsAppEnabled(app) for a single source of truth.

Apply:

+import useIsAppEnabled from "@calcom/app-store/_utils/useIsAppEnabled";
@@
-  const [enabled, setEnabled] = useState(getAppData("enabled"));
+  const { enabled, updateEnabled } = useIsAppEnabled(app);
@@
-      switchOnClick={(e) => {
-        if (!e) {
-          setEnabled(false);
-        } else {
-          setEnabled(true);
-        }
-      }}
+      switchOnClick={(e) => updateEnabled(e)}
packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx (2)

295-297: Localize user‑visible strings

  • showToast("Field already exists", …)
  • Section title "Send no show attendee data to event object"
  • Label "Field name to check (must be checkbox data type)"

Wrap with t() and add corresponding keys.

Apply:

-                    showToast("Field already exists", "error");
+                    showToast(t("field_already_exists"), "error");
@@
-          <Section.SubSectionHeader
-            icon="calendar"
-            title="Send no show attendee data to event object"
+          <Section.SubSectionHeader
+            icon="calendar"
+            title={t("send_no_show_attendee_data_to_event_object")}
@@
-                Field name to check (must be checkbox data type)
+                {t("field_name_to_check_checkbox")}

Also applies to: 460-477


367-367: Minor: fix id typo

"book-directly-witha-attendee-owner" → "book-directly-with-attendee-owner".

-                  id="book-directly-witha-attendee-owner"
+                  id="book-directly-with-attendee-owner"
packages/app-store/posthog/components/EventTypeAppCardInterface.tsx (1)

30-49: Localize labels/placeholders and fix casing

Use t() for "Tracking ID", "API host", and placeholders. Prefer "API host URL".

Apply:

+import { useLocale } from "@calcom/lib/hooks/useLocale";
@@
-  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();
+  const { t } = useLocale();
@@
-        <TextField
+        <TextField
           required
           disabled={disabled}
-          name="Tracking ID"
+          name={t("tracking_id")}
           value={trackingId}
-          placeholder="Enter your Tracking ID"
+          placeholder={t("enter_your_tracking_id")}
           onChange={(e) => {
             setAppData("TRACKING_ID", e.target.value);
           }}
         />
@@
-        <TextField
+        <TextField
           required
           disabled={disabled}
-          name="Api host"
+          name={t("api_host")}
           value={apiHost}
-          placeholder="Enter your Api host url"
+          placeholder={t("enter_api_host_url")}
           onChange={(e) => {
             setAppData("API_HOST", e.target.value);
           }}
         />
packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx (1)

147-148: Nit: simplify nested map with flatMap

Minor readability improvement.

-          {cardsForAppsWithTeams.map((apps) => apps.map((cards) => cards))}
+          {cardsForAppsWithTeams.flat()}
packages/app-store/plausible/components/EventTypeAppCardInterface.tsx (2)

19-21: Micro: pass handler directly

Slight tidy-up; avoids creating a new closure each render.

-      switchOnClick={(e) => {
-        updateEnabled(e);
-      }}
+      switchOnClick={updateEnabled}

23-23: Avoid falsy trap with teamId

Use nullish coalescing to preserve a valid teamId of 0.

-      teamId={eventType.team?.id || undefined}>
+      teamId={eventType.team?.id ?? undefined}>
📜 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 6e12304 and 5120488.

📒 Files selected for processing (34)
  • .eslintrc.js (1 hunks)
  • packages/app-store/_components/AppCard.tsx (2 hunks)
  • packages/app-store/_components/DynamicComponent.tsx (1 hunks)
  • packages/app-store/_components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/_components/OmniInstallAppButton.tsx (1 hunks)
  • packages/app-store/alby/components/EventTypeAppCardInterface.tsx (2 hunks)
  • packages/app-store/basecamp3/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/btcpayserver/components/EventTypeAppCardInterface.tsx (2 hunks)
  • packages/app-store/closecom/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/fathom/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/ga4/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/giphy/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/gtm/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/hitpay/components/EventTypeAppCardInterface.tsx (2 hunks)
  • packages/app-store/hubspot/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/insihts/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/matomo/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/metapixel/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/mock-payment-app/components/EventTypeAppCardInterface.tsx (2 hunks)
  • packages/app-store/paypal/components/EventTypeAppCardInterface.tsx (2 hunks)
  • packages/app-store/pipedrive-crm/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/plausible/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/posthog/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx (2 hunks)
  • packages/app-store/stripepayment/components/EventTypeAppCardInterface.tsx (2 hunks)
  • packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/twipla/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/types.d.ts (1 hunks)
  • packages/app-store/umami/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/zoho-bigin/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/zohocrm/components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx (6 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.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/app-store/types.d.ts
**/*.{ts,tsx}

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

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/app-store/types.d.ts
  • packages/app-store/_components/DynamicComponent.tsx
  • packages/app-store/mock-payment-app/components/EventTypeAppCardInterface.tsx
  • packages/app-store/stripepayment/components/EventTypeAppCardInterface.tsx
  • packages/app-store/basecamp3/components/EventTypeAppCardInterface.tsx
  • packages/app-store/closecom/components/EventTypeAppCardInterface.tsx
  • packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx
  • packages/app-store/umami/components/EventTypeAppCardInterface.tsx
  • packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx
  • packages/app-store/insihts/components/EventTypeAppCardInterface.tsx
  • packages/app-store/fathom/components/EventTypeAppCardInterface.tsx
  • packages/app-store/zohocrm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/plausible/components/EventTypeAppCardInterface.tsx
  • packages/app-store/paypal/components/EventTypeAppCardInterface.tsx
  • packages/app-store/hubspot/components/EventTypeAppCardInterface.tsx
  • packages/app-store/metapixel/components/EventTypeAppCardInterface.tsx
  • packages/app-store/matomo/components/EventTypeAppCardInterface.tsx
  • packages/app-store/alby/components/EventTypeAppCardInterface.tsx
  • packages/app-store/btcpayserver/components/EventTypeAppCardInterface.tsx
  • packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx
  • packages/app-store/twipla/components/EventTypeAppCardInterface.tsx
  • packages/app-store/pipedrive-crm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/_components/AppCard.tsx
  • packages/app-store/giphy/components/EventTypeAppCardInterface.tsx
  • packages/app-store/ga4/components/EventTypeAppCardInterface.tsx
  • packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx
  • packages/app-store/posthog/components/EventTypeAppCardInterface.tsx
  • packages/app-store/gtm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/hitpay/components/EventTypeAppCardInterface.tsx
  • packages/app-store/zoho-bigin/components/EventTypeAppCardInterface.tsx
  • packages/app-store/_components/OmniInstallAppButton.tsx
  • packages/app-store/_components/EventTypeAppCardInterface.tsx
  • packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx
**/*.{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/app-store/types.d.ts
  • packages/app-store/_components/DynamicComponent.tsx
  • packages/app-store/mock-payment-app/components/EventTypeAppCardInterface.tsx
  • packages/app-store/stripepayment/components/EventTypeAppCardInterface.tsx
  • packages/app-store/basecamp3/components/EventTypeAppCardInterface.tsx
  • packages/app-store/closecom/components/EventTypeAppCardInterface.tsx
  • packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx
  • packages/app-store/umami/components/EventTypeAppCardInterface.tsx
  • packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx
  • packages/app-store/insihts/components/EventTypeAppCardInterface.tsx
  • packages/app-store/fathom/components/EventTypeAppCardInterface.tsx
  • packages/app-store/zohocrm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/plausible/components/EventTypeAppCardInterface.tsx
  • packages/app-store/paypal/components/EventTypeAppCardInterface.tsx
  • packages/app-store/hubspot/components/EventTypeAppCardInterface.tsx
  • packages/app-store/metapixel/components/EventTypeAppCardInterface.tsx
  • packages/app-store/matomo/components/EventTypeAppCardInterface.tsx
  • packages/app-store/alby/components/EventTypeAppCardInterface.tsx
  • packages/app-store/btcpayserver/components/EventTypeAppCardInterface.tsx
  • packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx
  • packages/app-store/twipla/components/EventTypeAppCardInterface.tsx
  • packages/app-store/pipedrive-crm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/_components/AppCard.tsx
  • packages/app-store/giphy/components/EventTypeAppCardInterface.tsx
  • packages/app-store/ga4/components/EventTypeAppCardInterface.tsx
  • packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx
  • packages/app-store/posthog/components/EventTypeAppCardInterface.tsx
  • packages/app-store/gtm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/hitpay/components/EventTypeAppCardInterface.tsx
  • packages/app-store/zoho-bigin/components/EventTypeAppCardInterface.tsx
  • packages/app-store/_components/OmniInstallAppButton.tsx
  • packages/app-store/_components/EventTypeAppCardInterface.tsx
  • packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx
**/*.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/app-store/_components/DynamicComponent.tsx
  • packages/app-store/mock-payment-app/components/EventTypeAppCardInterface.tsx
  • packages/app-store/stripepayment/components/EventTypeAppCardInterface.tsx
  • packages/app-store/basecamp3/components/EventTypeAppCardInterface.tsx
  • packages/app-store/closecom/components/EventTypeAppCardInterface.tsx
  • packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx
  • packages/app-store/umami/components/EventTypeAppCardInterface.tsx
  • packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx
  • packages/app-store/insihts/components/EventTypeAppCardInterface.tsx
  • packages/app-store/fathom/components/EventTypeAppCardInterface.tsx
  • packages/app-store/zohocrm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/plausible/components/EventTypeAppCardInterface.tsx
  • packages/app-store/paypal/components/EventTypeAppCardInterface.tsx
  • packages/app-store/hubspot/components/EventTypeAppCardInterface.tsx
  • packages/app-store/metapixel/components/EventTypeAppCardInterface.tsx
  • packages/app-store/matomo/components/EventTypeAppCardInterface.tsx
  • packages/app-store/alby/components/EventTypeAppCardInterface.tsx
  • packages/app-store/btcpayserver/components/EventTypeAppCardInterface.tsx
  • packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx
  • packages/app-store/twipla/components/EventTypeAppCardInterface.tsx
  • packages/app-store/pipedrive-crm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/_components/AppCard.tsx
  • packages/app-store/giphy/components/EventTypeAppCardInterface.tsx
  • packages/app-store/ga4/components/EventTypeAppCardInterface.tsx
  • packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx
  • packages/app-store/posthog/components/EventTypeAppCardInterface.tsx
  • packages/app-store/gtm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/hitpay/components/EventTypeAppCardInterface.tsx
  • packages/app-store/zoho-bigin/components/EventTypeAppCardInterface.tsx
  • packages/app-store/_components/OmniInstallAppButton.tsx
  • packages/app-store/_components/EventTypeAppCardInterface.tsx
  • packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx
🧠 Learnings (1)
📚 Learning: 2025-09-12T07:15:58.030Z
Learnt from: hbjORbj
PR: calcom/cal.com#23475
File: packages/features/credentials/handleDeleteCredential.ts:5-10
Timestamp: 2025-09-12T07:15:58.030Z
Learning: When EventTypeAppMetadataSchema is used only in z.infer<typeof EventTypeAppMetadataSchema> type annotations or type casts, it can be imported as a type-only import since this usage is purely at the TypeScript type level and doesn't require the runtime value.

Applied to files:

  • packages/app-store/types.d.ts
  • packages/app-store/basecamp3/components/EventTypeAppCardInterface.tsx
  • packages/app-store/closecom/components/EventTypeAppCardInterface.tsx
  • packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx
  • packages/app-store/umami/components/EventTypeAppCardInterface.tsx
  • packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx
  • packages/app-store/insihts/components/EventTypeAppCardInterface.tsx
  • packages/app-store/fathom/components/EventTypeAppCardInterface.tsx
  • packages/app-store/zohocrm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/plausible/components/EventTypeAppCardInterface.tsx
  • packages/app-store/metapixel/components/EventTypeAppCardInterface.tsx
  • packages/app-store/matomo/components/EventTypeAppCardInterface.tsx
  • packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx
  • packages/app-store/twipla/components/EventTypeAppCardInterface.tsx
  • packages/app-store/giphy/components/EventTypeAppCardInterface.tsx
  • packages/app-store/ga4/components/EventTypeAppCardInterface.tsx
  • packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx
  • packages/app-store/posthog/components/EventTypeAppCardInterface.tsx
  • packages/app-store/gtm/components/EventTypeAppCardInterface.tsx
  • packages/app-store/zoho-bigin/components/EventTypeAppCardInterface.tsx
🧬 Code graph analysis (25)
packages/app-store/mock-payment-app/components/EventTypeAppCardInterface.tsx (2)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/basecamp3/components/EventTypeAppCardInterface.tsx (2)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/closecom/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/umami/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx (2)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/insihts/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/fathom/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/zohocrm/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/plausible/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/hubspot/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/metapixel/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/matomo/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/twipla/components/EventTypeAppCardInterface.tsx (2)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/pipedrive-crm/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/_components/AppCard.tsx (1)
packages/app-store/types.d.ts (1)
  • AppCardApp (25-27)
packages/app-store/giphy/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/ga4/components/EventTypeAppCardInterface.tsx (2)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/posthog/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/gtm/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/zoho-bigin/components/EventTypeAppCardInterface.tsx (3)
packages/app-store/_components/EventTypeAppCardInterface.tsx (1)
  • EventTypeAppCard (14-38)
packages/app-store/types.d.ts (1)
  • EventTypeAppCardComponent (88-88)
packages/app-store/_components/AppCard.tsx (1)
  • AppCard (16-149)
packages/app-store/_components/EventTypeAppCardInterface.tsx (2)
packages/app-store/_components/DynamicComponent.tsx (1)
  • DynamicComponent (2-21)
packages/app-store/apps.browser.generated.tsx (1)
  • EventTypeAddonMap (22-54)
packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx (1)
packages/trpc/react/trpc.ts (1)
  • trpc (54-138)
🔇 Additional comments (32)
.eslintrc.js (1)

26-26: Confirm no remaining tRPC imports in packages/app-store. Ran ripgrep for '@calcom/trpc' and '@trpc/' under packages/app-store — no matches found.

packages/app-store/matomo/components/EventTypeAppCardInterface.tsx (2)

9-18: Good: onAppInstallSuccess is correctly plumbed to AppCard

Forwarding the callback here matches the updated public API.


27-38: data-testid prop casing — OK
TextField accepts a camelCase dataTestid prop and maps it to the DOM data-testid; EventTypeAppCard's dataTestid usage is correct (packages/ui/components/form/inputs/TextField.tsx).

packages/app-store/hubspot/components/EventTypeAppCardInterface.tsx (1)

8-16: LGTM: prop added and forwarded

onAppInstallSuccess is correctly added to the signature and passed to AppCard.

packages/app-store/_components/EventTypeAppCardInterface.tsx (1)

19-20: LGTM: public API extended and forwarded properly

onAppInstallSuccess added to props, destructured, and forwarded to DynamicComponent.

Also applies to: 25-26, 33-34

packages/app-store/metapixel/components/EventTypeAppCardInterface.tsx (1)

9-20: LGTM: parity with other EventType cards

Signature update and forwarding look consistent.

packages/app-store/types.d.ts (1)

68-69: Resolved — EventTypeAppCardInterface implementations forward onAppInstallSuccess

Verified: every EventTypeAppCardInterface in packages/app-store/*/components (and packages/app-store/_components/EventTypeAppCardInterface.tsx) accepts and forwards onAppInstallSuccess to . AppCard usages in packages/features/apps and apps/web import a different AppCard and are unaffected. No changes required.

packages/app-store/ga4/components/EventTypeAppCardInterface.tsx (1)

9-13: onAppInstallSuccess correctly added and forwarded — LGTM

The prop is wired into the component API and passed to AppCard as required.

Also applies to: 19-20

packages/app-store/twipla/components/EventTypeAppCardInterface.tsx (1)

9-9: onAppInstallSuccess propagation — looks good

Signature updated and forwarded to AppCard.

Also applies to: 16-17

packages/app-store/qr_code/components/EventTypeAppCardInterface.tsx (1)

9-9: onAppInstallSuccess propagation — looks good

Signature updated and forwarded to AppCard.

Also applies to: 16-17

packages/app-store/fathom/components/EventTypeAppCardInterface.tsx (1)

9-9: onAppInstallSuccess propagation — looks good

Signature updated and forwarded to AppCard.

Also applies to: 15-16

packages/app-store/insihts/components/EventTypeAppCardInterface.tsx (1)

8-12: onAppInstallSuccess propagation — looks good

Signature updated and forwarded to AppCard.

Also applies to: 19-21

packages/app-store/mock-payment-app/components/EventTypeAppCardInterface.tsx (1)

23-23: onAppInstallSuccess propagation — looks good

Wired through to AppCard.

Also applies to: 54-55

packages/app-store/zohocrm/components/EventTypeAppCardInterface.tsx (1)

8-12: onAppInstallSuccess propagation — looks good

Signature updated and forwarded to AppCard; returnTo wiring consistent.

Also applies to: 19-21

packages/app-store/basecamp3/components/EventTypeAppCardInterface.tsx (1)

9-13: onAppInstallSuccess propagation — looks good

Signature updated and forwarded to AppCard.

Also applies to: 19-20

packages/app-store/gtm/components/EventTypeAppCardInterface.tsx (1)

9-16: Prop passthrough looks correct

onAppInstallSuccess is correctly added to the signature and forwarded to AppCard. Type-only import usage for appDataSchema is also correct.

packages/app-store/stripepayment/components/EventTypeAppCardInterface.tsx (1)

15-20: Wiring is consistent

onAppInstallSuccess is added and forwarded correctly; returnTo and other props unchanged.

Also applies to: 31-32

packages/app-store/btcpayserver/components/EventTypeAppCardInterface.tsx (1)

16-21: Wiring is correct

onAppInstallSuccess is accepted and forwarded to AppCard.

Also applies to: 31-32

packages/app-store/pipedrive-crm/components/EventTypeAppCardInterface.tsx (1)

8-12: Looks good

Signature update and prop forwarding are consistent with the shared types.

Also applies to: 15-16, 19-19

packages/app-store/closecom/components/EventTypeAppCardInterface.tsx (1)

9-13: Good prop surface update

onAppInstallSuccess is correctly added and passed to AppCard.

Also applies to: 19-21

packages/app-store/alby/components/EventTypeAppCardInterface.tsx (1)

15-20: Prop added and forwarded correctly

onAppInstallSuccess is wired through to AppCard.

Also applies to: 35-37

packages/app-store/templates/event-type-app-card/components/EventTypeAppCardInterface.tsx (1)

9-13: Template wiring LGTM

onAppInstallSuccess added and forwarded; aligns with the new AppCard API.

Also applies to: 20-20

packages/app-store/hitpay/components/EventTypeAppCardInterface.tsx (1)

15-20: Solid passthrough

onAppInstallSuccess added and passed to AppCard as expected.

Also applies to: 31-32

packages/app-store/templates/booking-pages-tag/components/EventTypeAppCardInterface.tsx (1)

10-10: Good: callback threaded correctly

onAppInstallSuccess is added to the component signature and forwarded to AppCard. Looks consistent with the new contract.

Also applies to: 17-17

packages/app-store/giphy/components/EventTypeAppCardInterface.tsx (1)

10-14: LGTM: onAppInstallSuccess correctly added and forwarded

Signature and AppCard prop are updated consistently.

Also applies to: 22-22

packages/app-store/salesforce/components/EventTypeAppCardInterface.tsx (1)

23-23: LGTM: callback wiring

onAppInstallSuccess added and passed into AppCard; matches the shared AppCard API.

Also applies to: 98-99

packages/app-store/posthog/components/EventTypeAppCardInterface.tsx (1)

9-13: LGTM: onAppInstallSuccess threading

Signature and AppCard prop look correct.

Also applies to: 21-21

packages/app-store/zoho-bigin/components/EventTypeAppCardInterface.tsx (1)

8-12: LGTM: callback added and forwarded

Signature and AppCard prop are consistent with the shared API.

Also applies to: 19-19

packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx (1)

28-29: LGTM: cache invalidation callback wired through

utils.useUtils + handleAppInstallSuccess and forwarding onAppInstallSuccess across all cards is consistent and readable.

Also applies to: 46-53, 71-72, 96-97, 162-163, 196-197

packages/app-store/_components/AppCard.tsx (1)

28-32: API change: onAppInstallSuccess now required

Ensure every <AppCard ...> usage includes onAppInstallSuccess={...}; otherwise TypeScript/CI will fail. Automated verification returned no conclusive results — manual repo check required.

Location: packages/app-store/_components/AppCard.tsx (lines 28–32; also 117–118).

packages/app-store/plausible/components/EventTypeAppCardInterface.tsx (2)

6-6: Good: type-only schema import

Using import type { appDataSchema } keeps this module free of runtime deps; aligns with prior learning on schema-only usage.


1-4: No tRPC client usage found in the imported modules

Scanned packages/app-store for "trpc", "createTRPC", "createTRPCReact", and "trpc." and inspected:

  • packages/app-store/EventTypeAppContext.tsx
  • packages/app-store/_components/AppCard.tsx
  • packages/app-store/_utils/useIsAppEnabled.ts
  • packages/app-store/types.d.ts

No matches found.

Comment on lines +9 to 17
const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({ app, eventType, onAppInstallSuccess }) {
const { getAppData, setAppData, disabled } = useAppContextWithSchema<typeof appDataSchema>();

const { enabled, updateEnabled } = useIsAppEnabled(app);

return (
<AppCard
onAppInstallSuccess={onAppInstallSuccess}
hideSettingsIcon
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Prop added and correctly forwarded

Adding and passing onAppInstallSuccess to AppCard is correct and matches the updated contract.

Verify all call sites provide the new required prop:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Checking all <EventTypeAppCard …> usages for onAppInstallSuccess…"
files=$(rg -n --glob '!**/node_modules/**' -l '<EventTypeAppCard\b')
for f in $files; do
  if ! rg -n 'onAppInstallSuccess\s*=' "$f" >/dev/null; then
    echo "Missing onAppInstallSuccess in: $f"
  fi
done || true

Length of output: 214


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching for JSX usages of EventTypeAppCard (including hidden/unignored files)..."
files=$(rg -n --hidden -uu -S -l '<EventTypeAppCard\b' || true)

if [[ -z "$files" ]]; then
  echo "No JSX tag usages found. Searching for any references to EventTypeAppCard..."
  files=$(rg -n --hidden -uu -S -l '\bEventTypeAppCard\b' || true)
fi

if [[ -z "$files" ]]; then
  echo "No files reference EventTypeAppCard."
  exit 0
fi

echo "Found references in the following files:"
printf '%s\n' "$files"

echo
missing=0
echo "Checking each file for an explicit onAppInstallSuccess prop..."
while IFS= read -r f; do
  if rg -n --hidden -uu -S 'onAppInstallSuccess\s*=' "$f" >/dev/null 2>&1; then
    echo "OK: $f"
  else
    echo "Missing onAppInstallSuccess in: $f"
    missing=$((missing+1))
  fi
done <<< "$files"

echo
echo "Summary: total files referencing EventTypeAppCard: $(echo "$files" | wc -l | tr -d ' ')"
echo "Files missing explicit onAppInstallSuccess: $missing"

Length of output: 783


Add onAppInstallSuccess to these EventTypeAppCard call sites

  • packages/platform/atoms/event-types/wrappers/EventPaymentsTabPlatformWrapper.tsx
  • packages/app-store/_components/eventTypeAppCardInterface.test.tsx

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

Caution

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

⚠️ Outside diff range comments (4)
packages/app-store/_components/eventTypeAppCardInterface.test.tsx (4)

51-64: Fix: you’re calling the mocks before render; pass function refs instead.

Using getAppData: getAppDataMock() and setAppData: setAppDataMock() executes the mocks immediately and makes the assertions trivially pass. Pass the functions, not their return values.

Apply this diff:

-        value={{
-          getAppData: getAppDataMock(),
-          setAppData: setAppDataMock(),
-        }}
+        value={{
+          getAppData: getAppDataMock,
+          setAppData: setAppDataMock,
+        }}

41-46: React FCs receive a single props arg; drop the extra {} in call assertions.

DynamicComponent (a function component) is invoked with props only. Expecting a second argument is brittle and may fail.

Apply this diff in both places:

-    expect(DynamicComponent).toHaveBeenCalledWith(
-      expect.objectContaining({
-        slug: mockProps.app.slug,
-      }),
-      {}
-    );
+    expect(DynamicComponent).toHaveBeenCalledWith(
+      expect.objectContaining({
+        slug: mockProps.app.slug,
+      })
+    );
-    expect(DynamicComponent).toHaveBeenCalledWith(
-      expect.objectContaining({
-        slug: "stripepayment",
-      }),
-      {}
-    );
+    expect(DynamicComponent).toHaveBeenCalledWith(
+      expect.objectContaining({
+        slug: "stripepayment",
+      })
+    );

Also applies to: 77-82


3-3: Use Vitest types; throw to trigger the error boundary; scope to one call.

Avoid jest.Mock in a Vitest test and return-vs-throw confusion.

Apply this diff:

-import { vi } from "vitest";
+import { vi, type Mock } from "vitest";
-    (DynamicComponent as jest.Mock).mockImplementation(() => {
-      return Error("Mocked error from DynamicComponent");
-    });
+    (DynamicComponent as Mock).mockImplementationOnce(() => {
+      throw new Error("Mocked error from DynamicComponent");
+    });

Also applies to: 88-90


16-18: Reset mock implementations between tests.

vi.clearAllMocks() doesn’t reset implementations. Use vi.resetAllMocks() for isolation.

Apply this diff:

-afterEach(() => {
-  vi.clearAllMocks();
-});
+afterEach(() => {
+  vi.resetAllMocks();
+});
🧹 Nitpick comments (3)
packages/app-store/_components/eventTypeAppCardInterface.test.tsx (3)

33-33: Add an assertion that onAppInstallSuccess is forwarded.

You add the prop but don’t verify it’s passed to DynamicComponent.

Append a test like:

+  test("Forwards onAppInstallSuccess to DynamicComponent", () => {
+    render(<EventTypeAppCard {...mockProps} />);
+    expect(DynamicComponent).toHaveBeenCalledWith(
+      expect.objectContaining({
+        onAppInstallSuccess: mockProps.onAppInstallSuccess,
+      })
+    );
+  });

22-35: Avoid as any; type mockProps precisely.

Use satisfies Partial<ComponentProps<typeof EventTypeAppCard>> to keep type‑safety without over‑specifying.

Apply this diff:

+import type { ComponentProps } from "react";
@@
-  onAppInstallSuccess: vi.fn(),
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-} as any;
+  onAppInstallSuccess: vi.fn(),
+} satisfies Partial<ComponentProps<typeof EventTypeAppCard>>;

93-94: Reduce brittleness of i18n‑dependent assertion.

Asserting on a hardcoded English message is fragile. Prefer a role/testid or a stable container around the boundary.

Example:

// In component: <div data-testid="app-error-boundary">...</div>
// In test:
expect(screen.getByTestId("app-error-boundary")).toBeInTheDocument();
📜 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 5120488 and 2e38851.

📒 Files selected for processing (3)
  • .eslintrc.js (1 hunks)
  • packages/app-store/_components/EventTypeAppCardInterface.tsx (1 hunks)
  • packages/app-store/_components/eventTypeAppCardInterface.test.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/app-store/_components/EventTypeAppCardInterface.tsx
  • .eslintrc.js
🧰 Additional context used
📓 Path-based instructions (3)
**/*.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/app-store/_components/eventTypeAppCardInterface.test.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/app-store/_components/eventTypeAppCardInterface.test.tsx
**/*.{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/app-store/_components/eventTypeAppCardInterface.test.tsx
🔇 Additional comments (1)
packages/app-store/_components/eventTypeAppCardInterface.test.tsx (1)

66-85: LGTM: stripe → stripepayment slug mapping test.

Covers the critical alias behavior.

@hbjORbj hbjORbj merged commit 76bba1c into main Sep 14, 2025
88 of 92 checks passed
@hbjORbj hbjORbj deleted the refactor/circular-dep-between-appstore-trpc branch September 14, 2025 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app-store area: app store, apps, calendar integrations, google calendar, outlook, lark, apple calendar core area: core, team members only foundation ready-for-e2e 💻 refactor size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants