Skip to content

Conversation

@hbjORbj
Copy link
Contributor

@hbjORbj hbjORbj commented Jan 3, 2026

What does this PR do?

This is part 2 of the ongoing refactor to restore proper package layering in the monorepo (see PR #25859 for part 1).

Why this change is needed

@calcom/features is intended to be a reusable shared layer, but several UI components inside it were directly using tRPC client hooks (e.g., trpc.viewer.*.useQuery() from @calcom/trpc/react). This couples the shared package to app-specific data-fetching assumptions, increases the risk of circular dependencies, and makes it harder to reuse features cleanly across web/platform/embed contexts.

The intended layering is: the web app can depend on both @calcom/features and @calcom/trpc, but @calcom/features should not depend on tRPC.

What changed

This is a refactor only with no intended user-facing behavior changes. It primarily moves files and updates imports.

Components moved from packages/features/** to apps/web/modules/**:

  • Booker UI and subcomponents (DatePicker, EventMeta, AvailableTimeSlots, BookEventForm, etc.)
  • App store UI components (AllApps, AppCard, AppList, etc.)
  • Event type UI components (EventType, CreateEventTypeForm, HostEditDialogs, etc.)
  • Calendar weekly view components
  • EE components (SSO views, directory sync, users admin pages, video)
  • Insights components and hooks

Import paths updated throughout the web app to use @calcom/web/modules/** and ~/ aliases.

Shared types (like EventTypeAssignedUsers, EventTypeHosts) moved to @calcom/features/eventtypes/lib/types to keep them accessible without circular dependencies.

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • N/A - I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

@hbjORbj hbjORbj requested review from a team as code owners January 3, 2026 16:15
@vercel
Copy link

vercel bot commented Jan 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Review Updated (UTC)
cal Ignored Ignored Jan 5, 2026 3:12pm
cal-companion Ignored Ignored Preview Jan 5, 2026 3:12pm
cal-eu Ignored Ignored Jan 5, 2026 3:12pm

@graphite-app graphite-app bot added foundation core area: core, team members only labels Jan 3, 2026
@hbjORbj hbjORbj changed the title refactor: features to web refactor: Move trpc-dependent components from features to web [2] Jan 3, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

8 issues found across 86 files

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/features/apps/AdminAppsList.tsx">

<violation number="1" location="packages/features/apps/AdminAppsList.tsx:13">
P1: This import introduces a circular dependency. `apps/web` depends on `@calcom/features`, but now `packages/features` imports from `@calcom/web`. Shared packages like `features` should not import from application-level code (`apps/web`). Consider keeping `AppListCard` in `@calcom/features` or moving this entire file to `apps/web/modules` if it needs web-specific components.</violation>
</file>

<file name="packages/platform/atoms/add-members-switch/AddMembersWithSwitchPlatformWrapper.tsx">

<violation number="1" location="packages/platform/atoms/add-members-switch/AddMembersWithSwitchPlatformWrapper.tsx:2">
P1: This import creates a circular dependency. `AddMembersWithSwitch.tsx` in `@calcom/web` imports `AddMembersWithSwitchPlatformWrapper` from `@calcom/atoms`, but now `AddMembersWithSwitchPlatformWrapper` imports back from `@calcom/web`. This can cause undefined exports and runtime initialization issues.

Consider keeping the import from `@calcom/features` (the original path) or restructuring to break the cycle.</violation>
</file>

<file name="packages/features/ee/sso/page/orgs-sso-view.tsx">

<violation number="1" location="packages/features/ee/sso/page/orgs-sso-view.tsx:5">
P1: This import introduces a circular dependency. The `packages/features` package should not import from `@calcom/web` (the web app). Currently there are no such imports in the features package, and `@calcom/web` is not a declared dependency. Consider keeping the SkeletonLoader in `@calcom/features` or moving it to a shared package like `@calcom/ui`.</violation>
</file>

<file name="packages/features/ee/dsync/components/ConfigureDirectorySync.tsx">

<violation number="1" location="packages/features/ee/dsync/components/ConfigureDirectorySync.tsx:3">
P1: Circular dependency risk: `packages/features` should not import from `@calcom/web`. The features package is a shared library consumed by `apps/web`, not the other way around. This import creates a circular dependency path (`web` → `features` → `web`) and `@calcom/web` is not declared as a dependency in `packages/features/package.json`. Consider keeping the SkeletonLoader in the features package or moving this component to web as well.</violation>
</file>

<file name="packages/features/form-builder/FormBuilder.tsx">

<violation number="1" location="packages/features/form-builder/FormBuilder.tsx:10">
P1: This import introduces a circular dependency. `@calcom/web` depends on `@calcom/features`, so importing from `@calcom/web` in `packages/features` creates a cycle (web → features → web). This can cause build failures, runtime errors, or unpredictable behavior.

The `LearnMoreLink` component should remain in a shared package like `@calcom/features` or `@calcom/ui`, not be imported from `apps/web` into a lower-level package.</violation>
</file>

<file name="packages/platform/atoms/event-types/wrappers/CreateEventTypePlatformWrapper.tsx">

<violation number="1" location="packages/platform/atoms/event-types/wrappers/CreateEventTypePlatformWrapper.tsx:3">
P1: This import introduces a circular dependency. The target `CreateEventTypeForm` in `@calcom/web` imports `useIsPlatform` from `@calcom/atoms`, while this file (part of `@calcom/atoms`) is now importing from `@calcom/web`. Consider either keeping the import from `@calcom/features` or restructuring to avoid the circular reference.</violation>
</file>

<file name="packages/features/bookings/components/event-meta/Duration.tsx">

<violation number="1" location="packages/features/bookings/components/event-meta/Duration.tsx:6">
P1: This import introduces a circular dependency. The `packages/features` package is now importing from `@calcom/web`, but `apps/web` depends on `@calcom/features`. Consider moving `useShouldShowArrows` to a shared package like `@calcom/lib` or `@calcom/ui` that both can depend on, rather than importing from `web` into `features`.</violation>
</file>

<file name="packages/platform/atoms/event-types/hooks/useHandleRouteChange.ts">

<violation number="1" location="packages/platform/atoms/event-types/hooks/useHandleRouteChange.ts:7">
P1: This import introduces a dependency from `@calcom/platform/atoms` to `@calcom/web`, which inverts the expected architecture. Platform packages should be standalone and consumed by the web app, not the other way around. Currently, no other platform package imports from `@calcom/web`.

Consider keeping types in a shared location (e.g., `@calcom/features` or a dedicated types package) rather than importing from the web app to avoid potential circular dependencies and maintain proper package boundaries.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@hbjORbj hbjORbj marked this pull request as draft January 3, 2026 16:23
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
…ing, dataUpdatedAt)

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

github-actions bot commented Jan 5, 2026

E2E results are ready!

devin-ai-integration bot and others added 2 commits January 5, 2026 14:58
…llTeamMembers value

- Fixed test wrapper to initialize useState with componentProps.assignAllTeamMembers
  instead of hardcoded false, allowing tests to properly test different states
- Updated test expectations for ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_NOT_APPLICABLE
  state to match actual component behavior (toggle should be present and checked)
- Fixed 'should show Segment when toggled on' test to start with assignAllTeamMembers: false
  to properly test the flow of enabling it
- Added explicit types to satisfy biome lint requirements

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 390 files

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.

@keithwillcode keithwillcode merged commit 404d46c into main Jan 5, 2026
50 checks passed
@keithwillcode keithwillcode deleted the refactor/features-to-web branch January 5, 2026 15:53
Pallava-Joshi pushed a commit to Pallava-Joshi/cal.com that referenced this pull request Jan 7, 2026
…lcom#26420)

* fix

* move event types components to web

* update import paths

* mv apps components

* migrate form builder

* fix

* mv sso

* fix

* mv

* update import paths

* update import paths

* mv

* mv

* mv

* fix

* update Booker

* fix

* fix

* fix

* fix

* mv video

* mv embed components to web

* update import paths

* mv calendar weekly view components

* update import paths

* fix

* fixp

* fix

* fix

* fix

* fix: update FormBuilder imports to use @calcom/features/form-builder

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update broken import paths after file migrations

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: correct import paths for platform atoms and moved components

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: apply CSS type fixes and add missing atoms exports

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: resolve type errors in test files after component migrations

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: resolve remaining type errors in test files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* migrate

* fix: resolve type errors in test and mock files

- Add missing bookingForm, bookerFormErrorRef, instantConnectCooldownMs to Booker.test.tsx bookings prop
- Add all required BookerEvent properties to event.mock.ts
- Add vi import from vitest to all mock files
- Fix date parameter types in packages/dayjs/__mocks__/index.ts
- Add verificationCode and setVerificationCode to test-utils.tsx mock store
- Remove children.type access in Section.tsx mock to fix type error
- Fix lint issues: remove unused React imports, use import type where needed, add return types
- Add biome-ignore comments for pre-existing lint warnings in test files

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* migrate

* migrate

* migrate

* update import paths

* update import paths

* update import paths

* fix

* migrate data table

* migrate data table

* fix

* fix

* fix

* migrate insights components

* migrate insights components

* fix

* mv

* update import paths

* fix

* fix

* fix

* fix

* fix

* fix: resolve type errors in test mocks

- Booker.test.tsx: Add all required UseFormReturn methods to bookingForm mock
- event.mock.ts: Fix entity, subsetOfHosts, instantMeetingParameters, fieldTranslations, image types
- dayjs/__mocks__/index.ts: Use Object.assign for proper typing of mock properties
- Section.tsx: Change 'class' to 'className' in JSX with biome-ignore comment

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing hasDataErrors and dataErrors to bookings.errors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing loadingStates properties to bookings mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing slots properties (setTentativeSelectedTimeslots, tentativeSelectedTimeslots, slotReservationId)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update quickAvailabilityChecks to include utcEndIso and use valid status type

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing bookerForm properties (formName, beforeVerifyEmail, formErrors)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing UseFormReturn properties to bookerForm.bookingForm mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add hasFormErrors and formErrors to bookerForm.formErrors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add hasFormErrors and formErrors to bookerForm.errors mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing isError property to mockEvent

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use complete BookerEvent mock in Booker.test.tsx

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use branded bookingFields type in event mock

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: add missing schedule mock properties (isError, isSuccess, isLoading, dataUpdatedAt)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* revert

* fix

* fix

* fix

* fix build

* fix

* fix

* fix

* fix: correct AddMembersWithSwitch test wrapper to use initial assignAllTeamMembers value

- Fixed test wrapper to initialize useState with componentProps.assignAllTeamMembers
  instead of hardcoded false, allowing tests to properly test different states
- Updated test expectations for ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_NOT_APPLICABLE
  state to match actual component behavior (toggle should be present and checked)
- Fixed 'should show Segment when toggled on' test to start with assignAllTeamMembers: false
  to properly test the flow of enabling it
- Added explicit types to satisfy biome lint requirements

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use JSX.Element instead of React.JSX.Element for type compatibility

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants