Skip to content

chore: promote dev to main (TypeScript 6.0.3 upgrade) - #58

Merged
JOY (JOY) merged 5 commits into
mainfrom
dev
Sep 2, 2026
Merged

chore: promote dev to main (TypeScript 6.0.3 upgrade)#58
JOY (JOY) merged 5 commits into
mainfrom
dev

Conversation

@JOY

@JOY JOY (JOY) commented Sep 1, 2026

Copy link
Copy Markdown

Summary

  • Upgraded monorepo to TypeScript 6.0.3 across all workspaces (�pps/web, �pps/api/v2, packages/trpc, packages/ui, packages/embeds/, packages/platform/, packages/mcp-server, etc.)
  • Added ignoreDeprecations: 6.0 to root tsconfig base and updated package tsconfigs with explicit rootDir and modern target/lib options.
  • Patched zod-prisma-types with fs.rmSync replacing deprecated fs.rmdirSync.
  • Re-exported PLATFORM_PERMISSION from @calcom/platform-constants resolving circular platform dependencies.
  • Isolated unit test files from production typechecking and verified 0 errors across 114 packages.

Test plan

  • Monorepo turbo type-check: 114/114 packages passed
  • Vitest unit test suite: 8/8 test files, 52/52 tests passed
  • Next.js Turbopack build succeeded with exit code 0

Note

Medium Risk
Wide TypeScript and Prisma generator changes can surface latent type or codegen issues; the health endpoint exposes DB status to unauthenticated callers (standard for probes but worth load-balancer exposure review).

Overview
This PR promotes dev → main with a monorepo-wide TypeScript 5.9.3 → 6.0.3 bump, adds ignoreDeprecations: "6.0" on shared tsconfigs, and tightens compiler settings (rootDir, ES2022 targets on embed packages, excluding **/*.test.* from app tsc runs) so type-check stays green across workspaces.

Prisma codegen moves to zod-prisma-types@3.3.11 with a Yarn patch that prefers fs.rmSync over deprecated rmdirSync. PLATFORM_PERMISSION is defined in @calcom/platform-constants and re-exported from @calcom/platform-types to simplify platform package typing.

Operational / product additions: a new GET/HEAD /api/health route reports DB connectivity (200 vs 503) with Vitest coverage; .env.example documents CROVE_BREVO_API_KEY for existing Brevo CRM integration; Playwright specs cover the Crove app switcher, unauthenticated teams/org redirects, and auth expectations on teams/organizations tRPC; docs/TypeScript-7-Migration-Roadmap.md outlines the next compiler upgrade. Turbo post-install caching and Vitest .next exclusion are adjusted for the new toolchain.

Reviewed by Cursor Bugbot for commit 4f814f5. Configure here.

…ons (#57)

Upgrade typescript dependency to 6.0.3 across all monorepo workspaces and root package.json. Add ignoreDeprecations 6.0 compilerOption to tsconfig base and update package-level tsconfigs with rootDir and modern lib targets. Patch zod-prisma-types to use fs.rmSync avoiding deprecated fs.rmdirSync. Re-export PLATFORM_PERMISSION from constants avoiding circular enum/types issue. Update vitest.config.mts and tsconfig exclusions to isolate test files from production typechecking. Verify turbo type-check, Vitest unit tests, and Next.js Turbopack production build.
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 370e905d-18fe-46e1-9336-302e843d5422

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Sep 1, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_47a6b250-9296-49a6-87d3-b65358548b29)

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request upgrades TypeScript to version 6.0.3 across the monorepo, adds a TypeScript 7.0 migration roadmap, applies a patch to zod-prisma-types, and introduces new Playwright E2E tests for the Crove App Switcher and multi-tenant security. Feedback on the new E2E tests highlights critical issues where conditional blocks and weak assertions could allow tests to pass silently, potentially masking authentication bypasses or rendering failures.

Comment on lines +80 to +92
test("tRPC endpoint /api/trpc/viewer.teams.list should require authentication", async ({ request }) => {
const response = await request.get("/api/trpc/viewer/teams.list?batch=1&input=%7B%7D");

// When unauthenticated, tRPC should return UNAUTHORIZED (401) or error in batch response
expect([200, 401, 400]).toContain(response.status());
if (response.status() === 200) {
const json = await response.json();
// In batch tRPC, error is inside payload array
if (Array.isArray(json) && json[0]?.error) {
expect(json[0].error.json.message).toBeDefined();
}
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

This test is designed to verify that the /api/trpc/viewer.teams.list endpoint requires authentication. However, if the endpoint is insecurely exposed and returns a 200 OK status with actual data, the test will silently pass because the assertion expect(json[0].error.json.message).toBeDefined() is wrapped inside a conditional if (Array.isArray(json) && json[0]?.error) block. If there is no error, the block is skipped and the test passes. We must explicitly assert that the response contains an error when a 200 status is returned.

    test("tRPC endpoint /api/trpc/viewer.teams.list should require authentication", async ({ request }) => {
      const response = await request.get("/api/trpc/viewer/teams.list?batch=1&input=%7B%7D");

      // When unauthenticated, tRPC should return UNAUTHORIZED (401) or error in batch response
      expect([200, 401, 400]).toContain(response.status());
      if (response.status() === 200) {
        const json = await response.json();
        expect(Array.isArray(json)).toBe(true);
        expect(json[0]).toHaveProperty("error");
        expect(json[0].error.json.message).toBeDefined();
      }
    });

Comment on lines +94 to +100
test("tRPC endpoint /api/trpc/viewer.organizations.listCurrent should require authentication", async ({
request,
}) => {
const response = await request.get("/api/trpc/viewer/organizations.listCurrent?batch=1&input=%7B%7D");

expect([200, 401, 400]).toContain(response.status());
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

This test only asserts that the response status is one of [200, 401, 400]. If the endpoint is insecurely exposed and returns a 200 OK with the actual organization list, the test will pass without verifying if an error was returned. We must assert that if a 200 status is returned, the body contains a tRPC error indicating that authentication is required.

    test("tRPC endpoint /api/trpc/viewer.organizations.listCurrent should require authentication", async ({
      request,
    }) => {
      const response = await request.get("/api/trpc/viewer/organizations.listCurrent?batch=1&input=%7B%7D");

      expect([200, 401, 400]).toContain(response.status());
      if (response.status() === 200) {
        const json = await response.json();
        expect(Array.isArray(json)).toBe(true);
        expect(json[0]).toHaveProperty("error");
      }
    });

Comment on lines +13 to +36
const appSwitcherTrigger = page.locator('button[title="Crove Ecosystem Apps"]');
const triggerCount = await appSwitcherTrigger.count();
expect(triggerCount).toBeGreaterThanOrEqual(0);

if (triggerCount > 0) {
await appSwitcherTrigger.first().click();

// Check Crove Suite section
const croveSuiteSection = page.getByText("Crove Suite");
await expect(croveSuiteSection).toBeVisible();

// Check key applications listed in the switcher
await expect(page.getByText("Crove Cal")).toBeVisible();
await expect(page.getByText("Crove Post")).toBeVisible();
await expect(page.getByText("Crove Sign")).toBeVisible();
await expect(page.getByText("Crove CRM")).toBeVisible();

// Check DOS Ecosystem section
const dosSection = page.getByText("DOS Ecosystem");
await expect(dosSection).toBeVisible();
await expect(page.getByText("DOS ID")).toBeVisible();
await expect(page.getByText("DOS.Me")).toBeVisible();
await expect(page.getByText("DOS AI")).toBeVisible();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The test currently uses a conditional check if (triggerCount > 0) to decide whether to click the App Switcher and assert its contents. This is a testing anti-pattern because if the App Switcher trigger fails to render (count is 0), the test will silently pass without executing any of the core assertions. E2E tests should be deterministic; if the App Switcher is expected to be present, we should explicitly assert its visibility and fail the test if it is missing.

      const appSwitcherTrigger = page.locator('button[title="Crove Ecosystem Apps"]');
      await expect(appSwitcherTrigger).toBeVisible();
      await appSwitcherTrigger.click();

      // Check Crove Suite section
      const croveSuiteSection = page.getByText("Crove Suite");
      await expect(croveSuiteSection).toBeVisible();

      // Check key applications listed in the switcher
      await expect(page.getByText("Crove Cal")).toBeVisible();
      await expect(page.getByText("Crove Post")).toBeVisible();
      await expect(page.getByText("Crove Sign")).toBeVisible();
      await expect(page.getByText("Crove CRM")).toBeVisible();

      // Check DOS Ecosystem section
      const dosSection = page.getByText("DOS Ecosystem");
      await expect(dosSection).toBeVisible();
      await expect(page.getByText("DOS ID")).toBeVisible();
      await expect(page.getByText("DOS.Me")).toBeVisible();
      await expect(page.getByText("DOS AI")).toBeVisible();

Comment on lines +41 to +55
const appSwitcherTrigger = page.locator('button[title="Crove Ecosystem Apps"]');

if ((await appSwitcherTrigger.count()) > 0) {
await appSwitcherTrigger.first().click();

// Check anchor tags
const postLink = page.locator('a[href="https://post.crove.com"]');
await expect(postLink).toBeAttached();

const signLink = page.locator('a[href="https://sign.crove.com"]');
await expect(signLink).toBeAttached();

const dosMeLink = page.locator('a[href="https://dos.me"]');
await expect(dosMeLink).toBeAttached();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Similar to the previous test, wrapping the assertions in a conditional if ((await appSwitcherTrigger.count()) > 0) block allows the test to pass silently if the trigger button is missing. We should explicitly assert that the trigger is visible and click it to ensure the URL assertions are always executed.

      const appSwitcherTrigger = page.locator('button[title="Crove Ecosystem Apps"]');
      await expect(appSwitcherTrigger).toBeVisible();
      await appSwitcherTrigger.click();

      // Check anchor tags
      const postLink = page.locator('a[href="https://post.crove.com"]');
      await expect(postLink).toBeAttached();

      const signLink = page.locator('a[href="https://sign.crove.com"]');
      await expect(signLink).toBeAttached();

      const dosMeLink = page.locator('a[href="https://dos.me"]');
      await expect(dosMeLink).toBeAttached();

Add /api/health endpoint verifying database connectivity, latency and uptime. Update .env.example with CROVE_BREVO_API_KEY.
@cursor

cursor Bot commented Sep 2, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_4b4eb55d-d3a0-4228-a178-f93c2bdbe495)

…aration

Upgrade target to ES2022 in nextjs.json, react-library.json, platform packages, lib, and testing packages. Verify 114/114 packages pass type-check.
@JOY
JOY (JOY) merged commit f23fc7b into main Sep 2, 2026
37 of 39 checks passed
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.

1 participant