Skip to content

refactor: reorganize platform packages with /src folders and fix cyclic dependencies#26143

Closed
volnei wants to merge 49 commits intomainfrom
devin/platform-packages-reorganization-1766487758
Closed

refactor: reorganize platform packages with /src folders and fix cyclic dependencies#26143
volnei wants to merge 49 commits intomainfrom
devin/platform-packages-reorganization-1766487758

Conversation

@volnei
Copy link
Contributor

@volnei volnei commented Dec 23, 2025

What does this PR do?

This PR reorganizes the 5 platform packages (constants, enums, types, utils, libraries) to follow a consistent /src folder structure, fixes cyclic dependencies, modernizes TypeScript configuration, and cleans up unnecessary tsconfig path mappings.

Why is this better than before?

1. Consistent Package Structure

Before: Source files were scattered at the root level of each package, mixed with config files.
After: All source files are organized under /src folders, providing a clear separation between source code and configuration.

2. Fixed Cyclic Dependencies

Before: There was a cyclic dependency chain: enums → types → constants → enums caused by PLATFORM_PERMISSION type being in the types package but needed by enums.
After: Moved PLATFORM_PERMISSION to constants package, breaking the cycle. The dependency chain is now linear: enums → constants, types → constants.

3. Modern TypeScript Target

Before: Packages used target: "ES5", generating unnecessarily verbose JavaScript with polyfills for features that all modern runtimes support natively.
After: Upgraded to target: "ES2021", producing cleaner, more efficient output that takes advantage of modern JavaScript features.

4. Cleaner tsconfig in API v2

Before: apps/api/v2/tsconfig.json had 17+ explicit path mappings for platform packages, creating maintenance overhead and potential for drift.
After: Removed all platform package paths. TypeScript now resolves these through node_modules using proper exports and typesVersions configuration. Only @calcom/prisma/client and @calcom/prisma/enums path aliases are retained (needed for runtime resolution in the NestJS build).

5. Proper Package Exports

Before: Some packages lacked proper exports field in package.json, making deep imports unreliable.
After: Added proper exports and typesVersions fields to support both modern and legacy module resolution, enabling reliable deep imports like @calcom/platform-constants/permissions.

6. Fixed Pre-existing Bugs

  • The stricter TypeScript configuration exposed a missing traceContext property in the API v2 bookings service that was introduced in PR feat: dist tracing 4 #25574 but never caught. Fixed with inline TraceContext creation using node:crypto randomUUID() (since @calcom/lib is TypeScript-only and can't be resolved at runtime in the NestJS build).
  • Fixed stale Booker hook import paths in atoms package (components/hooks/hooks/) after hooks were moved in refactor: move Booker hooks from packages/features to apps/web/modules #27343.

Updates since last revision

CI Fixes — Round 3 (February 2026)

  1. apps/web/package.json: Added @calcom/platform-libraries as a dependency — the atoms booker types.ts imports from it, so the web app build needs it declared.
  2. API v2 postbuild — prisma/enums CJS shim: The postbuild script now also creates dist/packages/prisma/enums/index.js by transforming the TypeScript source with sed to CommonJS format (export constexports., strips as const and export type lines). This is needed because @calcom/prisma/enums path aliases were removed, so the NestJS compiled output needs a resolvable module at the expected path.
  3. API v2 tsconfig.json: Restored @calcom/prisma/enums path alias — required alongside the CJS shim for both compile-time and runtime resolution.

CI Fixes — Round 2 (February 2026)

  1. turbo.json: Added @calcom/platform-libraries#build to type-check dependencies — the libraries package types live in dist/, so it must be built before type checking.
  2. Atoms Booker import paths: Fixed BookerPlatformWrapper.tsx imports from @calcom/features/bookings/Booker/components/hooks/ to @calcom/features/bookings/Booker/hooks/ — the hooks were relocated in refactor: move Booker hooks from packages/features to apps/web/modules #27343 but atoms imports were never updated.
  3. API v2 tracing fix: Replaced import { distributedTracing } from "@calcom/lib/tracing/factory" with inline TraceContext objects using randomUUID() from node:crypto. The @calcom/lib package has no build step, so it can't be require()d at runtime in the compiled NestJS output.

CI Fixes — Round 1 (January 2026)

  1. turbo.json type-check dependencies: Added @calcom/platform-constants#build and @calcom/platform-types#build as dependencies for both type-check and type-check:ci tasks.
  2. Permissions test import path: Updated packages/platform/utils/tests/permissions.test.ts to import from ../src/permissions instead of ../permissions.

Merge with main (January 2026)

Resolved merge conflict in apps/api/v2/package.json:

  • Kept the postbuild script for NestJS Swagger plugin path resolution
  • Updated format script to use biome format --write src test (from main branch's migration from prettier to biome)

Runtime Path Resolution for NestJS Swagger Plugin

Added a postbuild script to apps/api/v2/package.json that handles runtime path resolution for the NestJS Swagger plugin. The plugin generates relative require() paths based on compiled output structure, which don't resolve correctly at runtime. The postbuild script:

  1. Creates dist/packages/prisma/client/index.js - a small CommonJS shim that re-exports from @prisma/client
  2. Creates dist/packages/prisma/enums/index.js - transforms TypeScript enums to CommonJS using sed (removes as const, export type lines, converts export const to exports.)
  3. Creates symlinks for all other packages under dist/packages/ pointing to the repo root
  4. Uses bash -c wrapper for Yarn Berry shell compatibility (Yarn's portable shell doesn't support for loops)

Summary of Changes

Package Reorganization

  • Created /src folders in constants, enums, types, utils, and libraries packages
  • Moved all source files into their respective /src folders
  • Updated index.ts exports to point to new src folder locations
  • Updated tsconfig.json to only include src folder for each package

Dependency & Configuration Fixes

  • Fixed cyclic dependency by moving PLATFORM_PERMISSION type from types to constants
  • Removed unused @calcom/platform-types dependency from utils package
  • Fixed enums package.json types field (was incorrectly pointing to .d.ts.map)
  • Added @calcom/platform-constants, @calcom/platform-libraries, and @calcom/platform-utils to apps/web/package.json
  • Made enums/monorepo.ts an alias of index.ts to avoid divergence

TypeScript Modernization

  • Upgraded target from ES5 to ES2021 for constants, enums, types, and utils packages
  • Added module: "CommonJS" to platform packages for proper runtime resolution
  • Added typesVersions field to constants and types package.json for legacy moduleResolution compatibility
  • Removed 17+ platform package path mappings from apps/api/v2/tsconfig.json (kept only @calcom/prisma/client and @calcom/prisma/enums)

Build System

  • Added platform packages as dependencies for type-check tasks in turbo.json
  • Updated Jest config with moduleNameMapper for platform packages (maps to TypeScript source for ts-jest transpilation)

Bug Fixes

  • Fixed traceContext error in apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts by creating inline TraceContext objects with randomUUID()
  • Fixed atoms package import to use @calcom/platform-constants instead of relative path
  • Fixed permissions test import path after src folder reorganization
  • Fixed Booker hook import paths in atoms after hooks were moved from components/hooks/ to hooks/

Link to Devin run: https://app.devin.ai/sessions/95e45b8887cb4d96a1b91d4f86bd75e1
Conflict resolution & CI fixes: https://app.devin.ai/sessions/7e29ebbaac5749378f10baa546d0f297
Requested by: Volnei Munhoz (volnei@cal.com) (@volnei)

Mandatory Tasks (DO NOT REMOVE)

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

How should this be tested?

  1. Run yarn type-check:ci --force to verify TypeScript compilation
  2. Run yarn lint to verify linting passes
  3. Run TZ=UTC yarn test to verify unit tests pass
  4. Verify that packages depending on platform packages still build correctly
  5. CI should pass Build Web App, Build Atoms, Build API v2, Type check, Lint, and Unit tests

Note: The required check may fail if the ready-for-e2e label is not on the PR - this is expected behavior. The "Check API v2 breaking changes" failure is due to Prisma client not being initialized in the CI environment (infrastructure issue). The E2E API v2 test failure is a flaky test unrelated to these changes.

Human Review Checklist

  • Restored prisma/enums path alias: Verify that restoring @calcom/prisma/enums in apps/api/v2/tsconfig.json is correct — this was initially removed but needed to be added back for runtime resolution alongside the CJS shim
  • prisma/enums CJS transformation: Review the sed transformation in the postbuild script that converts TypeScript enums to CommonJS. This is fragile and will break if the source enum format changes significantly. Consider whether a more robust solution is needed.
  • Inline TraceContext divergence: The inline TraceContext objects using randomUUID() create trace IDs that aren't connected to the distributed tracing system. This is a functional divergence from the original distributedTracing.createTrace(). Confirm this is acceptable or if we need a different approach.
  • turbo.json type-check dependencies: Verify that adding @calcom/platform-libraries#build (in addition to constants and types) is correct for CI type checking
  • Booker hook imports: Confirm the import path fix from components/hooks/ to hooks/ is correct — hooks were moved in refactor: move Booker hooks from packages/features to apps/web/modules #27343 but atoms imports weren't updated
  • postbuild script complexity: Review the entire postbuild script in apps/api/v2/package.json - it creates prisma client and enums shims plus symlinks for runtime path resolution. This is a workaround for NestJS Swagger plugin behavior.
  • Removed tsconfig paths: Confirm TypeScript resolves platform packages through node_modules correctly (except for the two prisma paths)
  • Cyclic dependency fix: Verify the PLATFORM_PERMISSION type move to constants is correct
  • Backward compatibility: Check that types/src/permissions.ts re-exports from constants correctly

…ic dependencies

- Add /src folder to constants, enums, types, utils, and libraries packages
- Move source files into /src folders for each package
- Update index.ts exports to point to new src folder locations
- Update tsconfig.json to only build /src folder for each package
- Add proper exports configuration to package.json for each package
- Fix cyclic dependency by moving PLATFORM_PERMISSION type to constants package
- Remove unused @calcom/platform-types dependency from utils package
- Update vite.config.js for libraries package to use new src folder paths

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

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

✅ I will automatically:

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

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

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
@vercel
Copy link

vercel bot commented Dec 23, 2025

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

4 Skipped Deployments
Project Deployment Review Updated (UTC)
api-v2 Ignored Ignored Preview Jan 13, 2026 7:47am
cal Ignored Ignored Jan 13, 2026 7:47am
cal-companion Ignored Ignored Preview Jan 13, 2026 7:47am
cal-eu Ignored Ignored Jan 13, 2026 7:47am

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
@volnei volnei marked this pull request as ready for review December 23, 2025 11:29
@volnei volnei requested a review from a team as a code owner December 23, 2025 11:29
@graphite-app graphite-app bot added foundation core area: core, team members only labels Dec 23, 2025
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.

1 issue found across 166 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/platform/types/src/slots/slots-2024-09-04/inputs/get-slots-input.pipe.ts">

<violation number="1" location="packages/platform/types/src/slots/slots-2024-09-04/inputs/get-slots-input.pipe.ts:32">
P2: The ESLint disable comment was accidentally removed and replaced with whitespace. The empty constructor is intentional (as documented in the comment above), so the eslint-disable directive should be restored to prevent linting failures.</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

… reorganization

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
devin-ai-integration bot and others added 2 commits December 23, 2025 11:46
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-Authored-By: Volnei Munhoz <volnei.munhoz@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.

1 issue found across 2 files (changes from recent commits).

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/platform/constants/package.json">

<violation number="1" location="packages/platform/constants/package.json:14">
P1: The exports paths may not align with the actual TypeScript build output. Since `tsconfig.json` includes both `index.ts` (at root) and `src/` folder without an explicit `rootDir`, TypeScript computes rootDir as the package root. This means `src/permissions.ts` compiles to `dist/src/permissions.js`, not `dist/permissions.js`.

Either:
1. Add `&quot;rootDir&quot;: &quot;./&quot;` explicitly and update exports to use `./dist/src/...` paths (reverting this change), OR
2. Add `&quot;rootDir&quot;: &quot;./src&quot;` to tsconfig and move `index.ts` into `src/` so all files compile to `dist/` directly</violation>
</file>

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

@@ -4,6 +4,41 @@
"main": "./dist/index.js",
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 5, 2026

Choose a reason for hiding this comment

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

P1: The exports paths may not align with the actual TypeScript build output. Since tsconfig.json includes both index.ts (at root) and src/ folder without an explicit rootDir, TypeScript computes rootDir as the package root. This means src/permissions.ts compiles to dist/src/permissions.js, not dist/permissions.js.

Either:

  1. Add "rootDir": "./" explicitly and update exports to use ./dist/src/... paths (reverting this change), OR
  2. Add "rootDir": "./src" to tsconfig and move index.ts into src/ so all files compile to dist/ directly
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/platform/constants/package.json, line 14:

<comment>The exports paths may not align with the actual TypeScript build output. Since `tsconfig.json` includes both `index.ts` (at root) and `src/` folder without an explicit `rootDir`, TypeScript computes rootDir as the package root. This means `src/permissions.ts` compiles to `dist/src/permissions.js`, not `dist/permissions.js`.

Either:
1. Add `&quot;rootDir&quot;: &quot;./&quot;` explicitly and update exports to use `./dist/src/...` paths (reverting this change), OR
2. Add `&quot;rootDir&quot;: &quot;./src&quot;` to tsconfig and move `index.ts` into `src/` so all files compile to `dist/` directly</comment>

<file context>
@@ -11,31 +11,31 @@
-      &quot;require&quot;: &quot;./dist/src/permissions.js&quot;,
-      &quot;import&quot;: &quot;./dist/src/permissions.js&quot;,
-      &quot;types&quot;: &quot;./dist/src/permissions.d.ts&quot;
+      &quot;require&quot;: &quot;./dist/permissions.js&quot;,
+      &quot;import&quot;: &quot;./dist/permissions.js&quot;,
+      &quot;types&quot;: &quot;./dist/permissions.d.ts&quot;
</file context>

✅ Addressed in 47f06d2

…ipt build output

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
The type-check:ci task was failing because it only depended on @calcom/trpc#build,
but the platform packages (@calcom/platform-constants, @calcom/platform-types) also
need to be built before type checking can work. These packages have exports that
point to their dist/ folders, which don't exist until the packages are built.

This adds @calcom/platform-constants#build and @calcom/platform-types#build as
dependencies for both type-check and type-check:ci tasks in turbo.json.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
@github-actions
Copy link
Contributor

github-actions bot commented Jan 9, 2026

Devin AI is resolving merge conflicts

This PR has merge conflicts with the main branch. A Devin session has been created to automatically resolve them.

View Devin Session

Devin will:

  1. Merge the latest main into this branch
  2. Resolve any conflicts intelligently
  3. Run lint/type checks to ensure validity
  4. Push the resolved changes

If you prefer to resolve conflicts manually, you can close the Devin session and handle it yourself.

…87758

Resolved merge conflicts:
- apps/api/v2/tsconfig.json: Kept simplified paths from PR branch
- packages/platform/libraries/vite.config.js: Combined /src paths with new errors entry
- Moved errors.ts to src/ folder to match PR reorganization pattern
- Accepted new type files (disable-cancelling, disable-rescheduling) in src/ location
- Fixed lint errors in packages/lib/__mocks__/constants.ts (@ts-ignore -> @ts-expect-error)

Co-Authored-By: unknown <>
@github-actions github-actions bot added the ❗️ migrations contains migration files label Jan 9, 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.

40 issues found across 588 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="apps/web/modules/bookings/components/BookEventForm/BookingFields.tsx">

<violation number="1" location="apps/web/modules/bookings/components/BookEventForm/BookingFields.tsx:166">
P1: Calling `setValue` during render can cause infinite re-render loops. Move this logic to a `useEffect` hook that watches `locationResponse` changes.</violation>
</file>

<file name="apps/web/modules/bookings/components/EventMeta.tsx">

<violation number="1" location="apps/web/modules/bookings/components/EventMeta.tsx:145">
P1: `navigator.language` will throw during SSR because `navigator` is not available on the server. Use a browser check or provide a default fallback for SSR.</violation>
</file>

<file name="apps/web/modules/bookings/components/Header.tsx">

<violation number="1" location="apps/web/modules/bookings/components/Header.tsx:198">
P1: Incorrect JSX syntax: using `${t(...)}` instead of `{t(...)}`. The `$` will render as a literal character in the screen reader text.</violation>

<violation number="2" location="apps/web/modules/bookings/components/Header.tsx:208">
P1: Incorrect JSX syntax: using `${t(...)}` instead of `{t(...)}`. The `$` will render as a literal character in the screen reader text.</violation>

<violation number="3" location="apps/web/modules/bookings/components/Header.tsx:218">
P1: Incorrect JSX syntax: using `${t(...)}` instead of `{t(...)}`. The `$` will render as a literal character in the screen reader text.</violation>
</file>

<file name="apps/web/app/api/auth/signup/handlers/calcomSignupHandler.ts">

<violation number="1" location="apps/web/app/api/auth/signup/handlers/calcomSignupHandler.ts:59">
P1: Rule violated: **Avoid Logging Sensitive Information**

User email is being logged directly in debug output. Email addresses are PII and should not be logged. Consider removing the email from the log statement or masking it (e.g., `m***@example.com`).</violation>

<violation number="2" location="apps/web/app/api/auth/signup/handlers/calcomSignupHandler.ts:170">
P2: Use `select` instead of `include` to avoid fetching unnecessary data from `organizationSettings`. Per project guidelines, `include` fetches all fields which can expose sensitive data and impact performance.</violation>

<violation number="3" location="apps/web/app/api/auth/signup/handlers/calcomSignupHandler.ts:289">
P2: Consider awaiting `sendEmailVerification` to properly handle potential errors. Unawaited async calls can result in unhandled promise rejections.</violation>

<violation number="4" location="apps/web/app/api/auth/signup/handlers/calcomSignupHandler.ts:298">
P2: Use the defined logger instead of console.log for consistent logging. The `log` variable is already defined at line 34.</violation>
</file>

<file name="apps/api/v2/src/modules/auth/oauth2/controllers/oauth2.controller.ts">

<violation number="1" location="apps/api/v2/src/modules/auth/oauth2/controllers/oauth2.controller.ts:63">
P1: Rule violated: **Avoid Logging Sensitive Information**

Logging raw error object in OAuth token exchange could expose sensitive credentials (authorization codes, client secrets, PKCE verifiers). Consider logging a sanitized message without the full error object, e.g., `this.logger.error('Token exchange failed', { clientId })`.</violation>

<violation number="2" location="apps/api/v2/src/modules/auth/oauth2/controllers/oauth2.controller.ts:63">
P1: Rule violated: **Avoid Logging Sensitive Information**

Logging raw error object in OAuth token refresh could expose sensitive credentials (refresh tokens, client secrets). Consider logging a sanitized message without the full error object, e.g., `this.logger.error('Token refresh failed', { clientId })`.</violation>

<violation number="3" location="apps/api/v2/src/modules/auth/oauth2/controllers/oauth2.controller.ts:63">
P2: Logging raw error objects in OAuth endpoints may expose sensitive data. Consider logging only the error message or a sanitized version instead of the entire error object.

(Based on your team's feedback about not logging raw error objects as they may expose sensitive data.) [FEEDBACK_USED]</violation>

<violation number="4" location="apps/api/v2/src/modules/auth/oauth2/controllers/oauth2.controller.ts:102">
P1: Potential open redirect vulnerability: If `getClient()` fails (e.g., client not found) or an unexpected error occurs before redirect URI validation in `generateAuthorizationCode`, the code redirects to the user-supplied `body.redirectUri`. Per OAuth2 spec, when the client cannot be verified, you should NOT redirect to the request's redirect URI. Consider validating the client exists and the redirect URI is registered before using it for error redirects, or throw an HTTP error directly for client validation failures.</violation>
</file>

<file name="apps/web/modules/bookings/components/SeatsAvailabilityText.tsx">

<violation number="1" location="apps/web/modules/bookings/components/SeatsAvailabilityText.tsx:32">
P1: Division by zero risk when `totalSeats` is 0. Consider adding a guard or early return to handle this edge case.</violation>
</file>

<file name="apps/web/modules/apps/components/RecentAppsSlider.tsx">

<violation number="1" location="apps/web/modules/apps/components/RecentAppsSlider.tsx:13">
P1: Calling `.sort()` directly on the `items` prop mutates the original array. Props should be treated as immutable in React. Create a copy before sorting to avoid side effects in parent components.</violation>
</file>

<file name="apps/web/modules/bookings/components/DecoyBookingSuccessCard.tsx">

<violation number="1" location="apps/web/modules/bookings/components/DecoyBookingSuccessCard.tsx:37">
P1: The `aria-hidden="true"` attribute on this container hides all booking confirmation content from screen readers, making it inaccessible. This is particularly problematic for a success confirmation that users need to verify. Consider removing `aria-hidden="true"` to allow assistive technologies to announce the booking details.</violation>
</file>

<file name="apps/web/modules/apps/components/PopularAppsSlider.tsx">

<violation number="1" location="apps/web/modules/apps/components/PopularAppsSlider.tsx:13">
P1: Mutating `items` prop with `.sort()` - this modifies the original array passed from the parent. Create a copy first using `[...items].sort(...)` to avoid side effects.</violation>
</file>

<file name="apps/web/modules/bookings/components/DatePicker.tsx">

<violation number="1" location="apps/web/modules/bookings/components/DatePicker.tsx:104">
P1: Calling `moveToNextMonthOnNoAvailability()` directly during render triggers state updates (`setMonth`, `setSelectedDate`, `setDayCount`) which is a React anti-pattern. Side effects should be wrapped in `useEffect` to avoid potential infinite render loops.</violation>
</file>

<file name="apps/web/app/api/auth/signup/handlers/selfHostedHandler.ts">

<violation number="1" location="apps/web/app/api/auth/signup/handlers/selfHostedHandler.ts:64">
P1: Rule violated: **Avoid Logging Sensitive Information**

Logging `userValidation` object exposes PII - it contains `username` and potentially `email` (the existing user's email). Remove sensitive fields from the log or only log the `isValid` boolean.</violation>

<violation number="2" location="apps/web/app/api/auth/signup/handlers/selfHostedHandler.ts:85">
P2: Using `include` with `organizationSettings: true` fetches all columns from the relation. Per project guidelines, prefer `select` to specify only the fields needed. This reduces data exposure risk and improves performance.

If you need specific fields from `organizationSettings`, use:
```typescript
select: {
  organizationSettings: {
    select: { /* only needed fields */ }
  }
}
```</violation>
</file>

<file name=".github/workflows/cubic-devin-review.yml">

<violation number="1" location=".github/workflows/cubic-devin-review.yml:163">
P2: Missing HTTP status code check for API call. Unlike the 'Send message to existing Devin session' step which properly checks the HTTP response code and exits on failure, this step silently continues if the API call fails. Consider adding error handling consistent with lines 118-123.</violation>
</file>

<file name="apps/web/modules/apps/components/AdminAppsList.tsx">

<violation number="1" location="apps/web/modules/apps/components/AdminAppsList.tsx:246">
P2: Using `formMethods.setValue` instead of `field.onChange` from Controller bypasses react-hook-form's proper state management. This can cause issues with dirty state tracking and validation. Destructure and use `field.onChange` directly.</violation>

<violation number="2" location="apps/web/modules/apps/components/AdminAppsList.tsx:326">
P2: Using `app.name` as a React key may cause reconciliation issues if app names aren't unique. Consider using `app.slug` which is designed to be a unique identifier and is already used elsewhere in this file.</violation>
</file>

<file name="apps/web/modules/apps/components/AppListCardPlatformWrapper.tsx">

<violation number="1" location="apps/web/modules/apps/components/AppListCardPlatformWrapper.tsx:5">
P2: Missing validation for `props.logo`. If `logo` is undefined (it's optional in AppListCardProps), this creates `https://app.cal.comundefined`. If it's already an absolute URL, this creates a malformed URL. Prefer an early return to handle edge cases.</violation>
</file>

<file name="apps/web/modules/apps/components/AllApps.tsx">

<violation number="1" location="apps/web/modules/apps/components/AllApps.tsx:35">
P2: Using `ref.current` properties in useEffect dependency array is a React anti-pattern. Refs are mutable and don't trigger re-renders, so changes to `scrollWidth`/`clientWidth` won't re-run this effect. Consider using a ResizeObserver or running the check on window resize instead.</violation>
</file>

<file name="apps/web/modules/apps/components/AppListCard.tsx">

<violation number="1" location="apps/web/modules/apps/components/AppListCard.tsx:13">
P2: `dynamic()` should be called at module scope, not inside the component. This pattern prevents proper preloading and creates a new component type each time `isPlatform` changes. Move both dynamic imports to module level and use conditional rendering instead.</violation>
</file>

<file name="apps/web/modules/apps/components/AppCard.tsx">

<violation number="1" location="apps/web/modules/apps/components/AppCard.tsx:233">
P2: Use `t("template")` for localization instead of the hardcoded string "Template".</violation>
</file>

<file name="apps/web/modules/apps/components/AppSetDefaultLinkDialog.tsx">

<violation number="1" location="apps/web/modules/apps/components/AppSetDefaultLinkDialog.tsx:44">
P2: Empty regex fallback bypasses validation. When `urlRegExp` is undefined, `new RegExp("")` matches everything. Consider throwing an error or using a strict default pattern.</violation>
</file>

<file name="apps/web/modules/bookings/components/AvailableTimes.tsx">

<violation number="1" location="apps/web/modules/bookings/components/AvailableTimes.tsx:247">
P2: Hardcoded "Busy" text should use `t()` for localization. The component already uses `useLocale()` and `t()` for other strings.</violation>

<violation number="2" location="apps/web/modules/bookings/components/AvailableTimes.tsx:271">
P2: Empty `slots` array causes incorrect behavior. `[].every()` returns `true`, so `oooAllDay` would be true for empty arrays, causing an early return that bypasses the "no slots available" UI. Add an early return for empty slots or include a length check.</violation>
</file>

<file name=".github/workflows/devin-conflict-resolver.yml">

<violation number="1" location=".github/workflows/devin-conflict-resolver.yml:96">
P2: The `maintainerCanModify` field is queried in GraphQL but never used. For manually-triggered fork PR conflict resolution, the workflow should verify `maintainerCanModify` is true before creating a Devin session, otherwise Devin won't be able to push the resolved changes. Add a check similar to `stale-pr-devin-completion.yml` which validates `!isFork || maintainerCanModify`.</violation>

<violation number="2" location=".github/workflows/devin-conflict-resolver.yml:315">
P2: Rule violated: **Avoid Logging Sensitive Information**

Logging the full API response `data` object could expose sensitive session information from the Devin API. Consider logging only specific non-sensitive fields like `data.error` or a generic failure message instead of the entire response object.</violation>
</file>

<file name="apps/web/modules/bookings/components/RedirectToInstantMeetingModal.tsx">

<violation number="1" location="apps/web/modules/bookings/components/RedirectToInstantMeetingModal.tsx:52">
P2: The `calculateTimeRemaining` function is used inside this effect but is not in the dependency array. Since it's defined inside the component and captures `expiryTime`, this could cause stale closures. Move the calculation inside the effect to avoid this issue.</violation>
</file>

<file name="apps/web/modules/apps/components/AppList.tsx">

<violation number="1" location="apps/web/modules/apps/components/AppList.tsx:148">
P2: Missing `key` prop on `<ChildAppCard>` components. When rendering lists, React requires unique keys to identify elements. Add a unique key like `key={app.slug}` for the user credential card and `key={team.teamId}` for team cards.</violation>
</file>

<file name="apps/web/modules/bookings/components/Booker.tsx">

<violation number="1" location="apps/web/modules/bookings/components/Booker.tsx:118">
P2: Day.js object is created inside filter loop, causing repeated instantiation for each slot. Per project guidelines about Day.js performance in hot paths, compute `dayjs(selectedDate)` once before the filter to avoid creating new instances on each iteration.</violation>
</file>

<file name="apps/web/modules/bookings/components/LargeCalendar.tsx">

<violation number="1" location="apps/web/modules/bookings/components/LargeCalendar.tsx:48">
P2: This empty `useEffect` doesn't actually force rerenders - it runs after render and does nothing. The comment mentions "overlay events" but the dependency is `displayOverlay`. Since `overlayEvents` comes from Zustand's `useOverlayCalendarStore`, state changes already trigger rerenders automatically. Consider removing this ineffective code or implementing actual re-render logic if truly needed.</violation>
</file>

<file name="apps/web/modules/bookings/components/OverlayCalendar/OverlayCalendarSettingsModal.tsx">

<violation number="1" location="apps/web/modules/bookings/components/OverlayCalendar/OverlayCalendarSettingsModal.tsx:59">
P2: Hardcoded string "Calendar Settings" should use t() for localization to maintain consistency with other localized strings in this component.</violation>
</file>

<file name="apps/web/modules/bookings/components/InstantBooking.tsx">

<violation number="1" location="apps/web/modules/bookings/components/InstantBooking.tsx:40">
P2: Consider extracting the Button component to avoid duplication. The disabled and enabled states render nearly identical buttons, making maintenance error-prone.</violation>
</file>

<file name="apps/web/modules/bookings/components/BookingSuccessCard.tsx">

<violation number="1" location="apps/web/modules/bookings/components/BookingSuccessCard.tsx:86">
P2: Translation key "Host" does not appear to exist in the localization files. Consider using an existing key or adding a new one following the snake_case convention (e.g., `t("host")` after adding the key to common.json).</violation>
</file>

<file name="apps/web/modules/apps/components/DisconnectIntegrationModal.tsx">

<violation number="1" location="apps/web/modules/apps/components/DisconnectIntegrationModal.tsx:38">
P2: When `credentialId` is null, clicking confirm does nothing and the dialog remains open without feedback. Consider adding an early return or guard clause to handle this case gracefully (e.g., close the dialog or disable the confirm button when `credentialId` is null).</violation>
</file>

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

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.

1 issue found across 176 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/platform/constants/package.json">

<violation number="1" location="packages/platform/constants/package.json:8">
P2: The `types` condition should be listed first in each export entry for proper TypeScript type resolution. TypeScript documentation recommends this ordering to ensure types are resolved correctly before other conditions are matched.</violation>
</file>

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

@@ -4,6 +4,41 @@
"main": "./dist/index.js",
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 10, 2026

Choose a reason for hiding this comment

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

P2: The types condition should be listed first in each export entry for proper TypeScript type resolution. TypeScript documentation recommends this ordering to ensure types are resolved correctly before other conditions are matched.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/platform/constants/package.json, line 8:

<comment>The `types` condition should be listed first in each export entry for proper TypeScript type resolution. TypeScript documentation recommends this ordering to ensure types are resolved correctly before other conditions are matched.</comment>

<file context>
@@ -4,6 +4,41 @@
   "types": "./dist/index.d.ts",
   "private": true,
+  "exports": {
+    ".": {
+      "require": "./dist/index.js",
+      "import": "./dist/index.js",
</file context>
Fix with Cubic

@github-actions
Copy link
Contributor

Devin AI is resolving merge conflicts

This PR has merge conflicts with the main branch. A Devin session has been created to automatically resolve them.

View Devin Session

Devin will:

  1. Merge the latest main into this branch
  2. Resolve any conflicts intelligently
  3. Run lint/type checks to ensure validity
  4. Push the resolved changes

If you prefer to resolve conflicts manually, you can close the Devin session and handle it yourself.

@github-actions
Copy link
Contributor

Devin AI is resolving merge conflicts

This PR has merge conflicts with the main branch. A Devin session has been created to automatically resolve them.

View Devin Session

Devin will:

  1. Merge the latest main into this branch
  2. Resolve any conflicts intelligently
  3. Run lint/type checks to ensure validity
  4. Push the resolved changes

If you prefer to resolve conflicts manually, you can close the Devin session and handle it yourself.

@devin-ai-integration
Copy link
Contributor

Merge conflicts have been resolved and pushed. Please remove the devin-conflict-resolution label.

Conflicts resolved:

  • apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts - Added distributedTracing import from PR and BOOKING_REASSIGN_PERMISSION_ERROR constant from main, removed duplicate import block
  • apps/api/v2/tsconfig.json - Kept PR's cleaned-up paths (removed platform package paths per PR intent)
  • packages/platform/constants/index.ts - Used ./src/ paths (PR intent) with alphabetical order from main
  • packages/platform/libraries/vite.config.js - Used ./src/ paths and added new calendars and tasker entries from main
  • packages/platform/types/index.ts - Used ./src/ paths and added normalizeTimezone export from main
  • packages/platform/utils/tests/permissions.test.ts - Kept PR's ../src/permissions import path
  • New files from main (add-attendee.input.ts, normalizeTimezone.ts) were auto-placed in src/ directories
  • New library files from main (calendars.ts, tasker.ts) were moved to src/ directory to match PR's reorganization pattern

devin-ai-integration bot and others added 3 commits February 19, 2026 11:51
…ing changes

- Add @calcom/platform-libraries#build to turbo.json type-check dependencies
- Fix Booker hook import paths from components/hooks/ to hooks/ in atoms
- Replace @calcom/lib/tracing/factory import with inline TraceContext in API v2

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
…ms CJS shim in postbuild

- Add @calcom/platform-libraries to apps/web/package.json for atoms type resolution
- Update postbuild to generate packages/prisma/enums/index.js CJS shim for runtime resolution

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
- Replace node -e with sed to avoid yarn shell parser syntax error
- Restore @calcom/prisma/enums path alias in tsconfig.json

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
@volnei volnei closed this Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants