From 35842277ead893833169a1230f1e3e8b07cd486c Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 17 Sep 2025 13:15:19 +0200 Subject: [PATCH 01/73] chore: cleanup test data --- .../oauth-client-users.controller.e2e-spec.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/api/v2/src/modules/oauth-clients/controllers/oauth-client-users/oauth-client-users.controller.e2e-spec.ts b/apps/api/v2/src/modules/oauth-clients/controllers/oauth-client-users/oauth-client-users.controller.e2e-spec.ts index 825fadef422ea7..c251d93ac7bb79 100644 --- a/apps/api/v2/src/modules/oauth-clients/controllers/oauth-client-users/oauth-client-users.controller.e2e-spec.ts +++ b/apps/api/v2/src/modules/oauth-clients/controllers/oauth-client-users/oauth-client-users.controller.e2e-spec.ts @@ -719,6 +719,11 @@ describe("OAuth Client Users Endpoints", () => { } catch (e) { // User might have been deleted by the test } + try { + await userRepositoryFixture.delete(postResponseDataTwo.user.id); + } catch (e) { + // User might have been deleted by the test + } try { await userRepositoryFixture.delete(platformAdmin.id); } catch (e) { From d3b544d518dce3f7708d40b89946c70570384e31 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 17 Sep 2025 13:17:37 +0200 Subject: [PATCH 02/73] feat: e2e env file --- packages/platform/examples/base/.env.e2e.example | 9 +++++++++ packages/platform/examples/base/.gitignore | 1 + 2 files changed, 10 insertions(+) create mode 100644 packages/platform/examples/base/.env.e2e.example diff --git a/packages/platform/examples/base/.env.e2e.example b/packages/platform/examples/base/.env.e2e.example new file mode 100644 index 00000000000000..c8e33a34e4601c --- /dev/null +++ b/packages/platform/examples/base/.env.e2e.example @@ -0,0 +1,9 @@ +NEXT_PUBLIC_X_CAL_ID= +X_CAL_SECRET_KEY= +NEXT_PUBLIC_CALCOM_API_URL= +VITE_BOOKER_EMBED_OAUTH_CLIENT_ID= +VITE_BOOKER_EMBED_API_URL= +ORGANIZATION_ID= +ATOMS_E2E_APPLE_ID= +ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE= +NEXT_PUBLIC_IS_E2E="1" diff --git a/packages/platform/examples/base/.gitignore b/packages/platform/examples/base/.gitignore index 9184ed87223ae8..0a92d640efab1e 100644 --- a/packages/platform/examples/base/.gitignore +++ b/packages/platform/examples/base/.gitignore @@ -27,6 +27,7 @@ yarn-error.log* # local env files .env*.local +!.env.e2e.example # vercel .vercel From fb0f9675e498fbf0a51ac35dc8449aee8b91704a Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 17 Sep 2025 13:19:12 +0200 Subject: [PATCH 03/73] feat: e2e examples app prisma client --- packages/platform/examples/base/src/lib/prismaClient.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/platform/examples/base/src/lib/prismaClient.ts b/packages/platform/examples/base/src/lib/prismaClient.ts index 526f0420a369e1..db7e267d1a250e 100644 --- a/packages/platform/examples/base/src/lib/prismaClient.ts +++ b/packages/platform/examples/base/src/lib/prismaClient.ts @@ -1,7 +1,8 @@ -// prisma client of example app -// using local prisma db, not related to the cal.com monorepo prisma client -// eslint-disable-next-line -import { PrismaClient } from "@prisma/client"; +const isE2E = process.env.NEXT_PUBLIC_IS_E2E === "1"; + +const { PrismaClient } = isE2E + ? require("../../node_modules/.prisma/test-client") + : require("@prisma/client"); const prismaClientSingleton = () => { return new PrismaClient(); From 05207461bff782bc96d7cbd44fbf1886d8dbb71f Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 17 Sep 2025 13:20:06 +0200 Subject: [PATCH 04/73] fix: managed user setup from example app on any port --- .../platform/examples/base/src/pages/api/managed-user.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index ee6013ac3bcbfc..935f2cd9958d3e 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -28,7 +28,6 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar "Content-Type": "application/json", // eslint-disable-next-line turbo/no-undeclared-env-vars [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - origin: "http://localhost:4321", }, body: JSON.stringify({ email, @@ -152,7 +151,6 @@ async function createTeam(orgId: number, name: string) { [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", // eslint-disable-next-line turbo/no-undeclared-env-vars [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", - origin: "http://localhost:4321", }, body: JSON.stringify({ name, @@ -177,7 +175,6 @@ async function createOrgTeamMembershipMember(orgId: number, teamId: number, user [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", // eslint-disable-next-line turbo/no-undeclared-env-vars [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", - origin: "http://localhost:4321", }, body: JSON.stringify({ userId, @@ -200,7 +197,6 @@ async function createOrgMembershipAdmin(orgId: number, userId: number) { [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", // eslint-disable-next-line turbo/no-undeclared-env-vars [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", - origin: "http://localhost:4321", }, body: JSON.stringify({ userId, @@ -223,7 +219,6 @@ async function createCollectiveEventType(orgId: number, teamId: number, userIds: [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", // eslint-disable-next-line turbo/no-undeclared-env-vars [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", - origin: "http://localhost:4321", }, body: JSON.stringify({ lengthInMinutes: 60, @@ -248,7 +243,6 @@ async function createRoundRobinEventType(orgId: number, teamId: number, userIds: [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", // eslint-disable-next-line turbo/no-undeclared-env-vars [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", - origin: "http://localhost:4321", }, body: JSON.stringify({ lengthInMinutes: 60, From 3f5fffc596537936d876061bda4cec74e0128fb9 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 17 Sep 2025 13:20:57 +0200 Subject: [PATCH 05/73] chore: reduce flaky e2e tests by refreshing page --- .../availability-settings-atom/availability-settings-atom.e2e.ts | 1 + .../platform/examples/base/tests/booker-atom/booker-atom.e2e.ts | 1 + .../examples/base/tests/connect-atoms/apple-connect.e2e.ts | 1 + .../base/tests/create-event-type-atom/create-event-type.e2e.ts | 1 + .../create-team-event-type-atom/create-team-event-type.e2e.ts | 1 + 5 files changed, 5 insertions(+) diff --git a/packages/platform/examples/base/tests/availability-settings-atom/availability-settings-atom.e2e.ts b/packages/platform/examples/base/tests/availability-settings-atom/availability-settings-atom.e2e.ts index 70bc6fda8e88a4..7298dfb7b03a14 100644 --- a/packages/platform/examples/base/tests/availability-settings-atom/availability-settings-atom.e2e.ts +++ b/packages/platform/examples/base/tests/availability-settings-atom/availability-settings-atom.e2e.ts @@ -10,6 +10,7 @@ async function selectOption(page: Page, optionNumber: number) { test("availability page loads with all components", async ({ page }) => { await page.goto("/availability"); + await page.reload(); await expect(page).toHaveURL("/availability"); diff --git a/packages/platform/examples/base/tests/booker-atom/booker-atom.e2e.ts b/packages/platform/examples/base/tests/booker-atom/booker-atom.e2e.ts index 4a342f4b10a3cc..401fb05e50ff21 100644 --- a/packages/platform/examples/base/tests/booker-atom/booker-atom.e2e.ts +++ b/packages/platform/examples/base/tests/booker-atom/booker-atom.e2e.ts @@ -10,6 +10,7 @@ async function selectOption(page: Page, optionNumber: number) { test("tweak availability using AvailabilitySettings Atom", async ({ page }) => { await page.goto("/booking"); + await page.reload(); await expect(page).toHaveURL("/booking"); diff --git a/packages/platform/examples/base/tests/connect-atoms/apple-connect.e2e.ts b/packages/platform/examples/base/tests/connect-atoms/apple-connect.e2e.ts index eed8380b0330ec..6e9e67e29a23d8 100644 --- a/packages/platform/examples/base/tests/connect-atoms/apple-connect.e2e.ts +++ b/packages/platform/examples/base/tests/connect-atoms/apple-connect.e2e.ts @@ -5,6 +5,7 @@ test("connect calendar using the apple connect atom", async ({ page }) => { const appSpecificPassword = process.env.ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE; await page.goto("/"); + await page.reload(); await expect(page.locator("body")).toBeVisible(); diff --git a/packages/platform/examples/base/tests/create-event-type-atom/create-event-type.e2e.ts b/packages/platform/examples/base/tests/create-event-type-atom/create-event-type.e2e.ts index d0094357553fab..9c2fb7632604ce 100644 --- a/packages/platform/examples/base/tests/create-event-type-atom/create-event-type.e2e.ts +++ b/packages/platform/examples/base/tests/create-event-type-atom/create-event-type.e2e.ts @@ -4,6 +4,7 @@ import { generateRandomText } from "../../src/lib/generateRandomText"; test("create event type using CreateEventTypeAtom", async ({ page }) => { await page.goto("/"); + await page.reload(); await page.goto("/event-types"); diff --git a/packages/platform/examples/base/tests/create-team-event-type-atom/create-team-event-type.e2e.ts b/packages/platform/examples/base/tests/create-team-event-type-atom/create-team-event-type.e2e.ts index 85b4bc9cbe8341..651b5ea49694fa 100644 --- a/packages/platform/examples/base/tests/create-team-event-type-atom/create-team-event-type.e2e.ts +++ b/packages/platform/examples/base/tests/create-team-event-type-atom/create-team-event-type.e2e.ts @@ -4,6 +4,7 @@ import { generateRandomText } from "../../src/lib/generateRandomText"; test("create team event using CreateTeamEventTypeAtom", async ({ page }) => { await page.goto("/"); + await page.reload(); await page.goto("/event-types"); From d7e484a447bff8b7d09e5cff6060cec4c01903be Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 17 Sep 2025 13:28:22 +0200 Subject: [PATCH 06/73] feat: e2e enable new env.e2e and data cleanup --- .../platform/examples/base/global-teardown.ts | 111 ++++++++++++++++++ packages/platform/examples/base/package.json | 5 +- .../examples/base/playwright.config.ts | 7 +- .../examples/base/prisma/schema.test.prisma | 19 +++ turbo.json | 5 +- 5 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 packages/platform/examples/base/global-teardown.ts create mode 100644 packages/platform/examples/base/prisma/schema.test.prisma diff --git a/packages/platform/examples/base/global-teardown.ts b/packages/platform/examples/base/global-teardown.ts new file mode 100644 index 00000000000000..00afaa21012f17 --- /dev/null +++ b/packages/platform/examples/base/global-teardown.ts @@ -0,0 +1,111 @@ +import { execSync } from "child_process"; +import dotenv from "dotenv"; +import path from "path"; + +dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); +async function globalTeardown() { + console.log("Cleaning up managed users..."); + try { + const oauthClientId = process.env.NEXT_PUBLIC_X_CAL_ID; + const secretKey = process.env.X_CAL_SECRET_KEY; + const apiUrl = process.env.NEXT_PUBLIC_CALCOM_API_URL; + if (!oauthClientId || !secretKey || !apiUrl) { + console.log("Missing environment variables, skipping managed user cleanup"); + return; + } + const getManagedUsersResponse = await fetch(`${apiUrl}/oauth-clients/${oauthClientId}/users`, { + method: "GET", + headers: { + "Content-Type": "application/json", + "x-cal-secret-key": secretKey, + "x-cal-client-id": oauthClientId, + }, + }); + if (getManagedUsersResponse.ok) { + const managedUsersData = await getManagedUsersResponse.json(); + const users = managedUsersData.data || []; + for (const user of users) { + try { + const deleteResponse = await fetch(`${apiUrl}/oauth-clients/${oauthClientId}/users/${user.id}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + "x-cal-secret-key": secretKey, + "x-cal-client-id": oauthClientId, + }, + }); + if (deleteResponse.ok) { + console.log(`Deleted managed user: ${user.email}`); + } else { + console.error(`Failed to delete user ${user.email}:`, await deleteResponse.text()); + } + } catch (error) { + console.error(`Error deleting user ${user.email}:`, error); + } + } + } else { + console.error("Failed to fetch managed users:", await getManagedUsersResponse.text()); + } + const getOAuthClientResponse = await fetch(`${apiUrl}/oauth-clients/${oauthClientId}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + "x-cal-secret-key": secretKey, + "x-cal-client-id": oauthClientId, + }, + }); + if (getOAuthClientResponse.ok) { + const oauthClientData = await getOAuthClientResponse.json(); + const organizationId = oauthClientData.data?.organizationId; + if (organizationId) { + console.log(`Found organizationId: ${organizationId}`); + const getTeamsResponse = await fetch(`${apiUrl}/organizations/${organizationId}/teams`, { + method: "GET", + headers: { + "Content-Type": "application/json", + "x-cal-secret-key": secretKey, + "x-cal-client-id": oauthClientId, + }, + }); + if (getTeamsResponse.ok) { + const teamsData = await getTeamsResponse.json(); + const teams = teamsData.data || []; + for (const team of teams) { + try { + const deleteTeamResponse = await fetch( + `${apiUrl}/organizations/${organizationId}/teams/${team.id}`, + { + method: "DELETE", + headers: { + "Content-Type": "application/json", + "x-cal-secret-key": secretKey, + "x-cal-client-id": oauthClientId, + }, + } + ); + if (deleteTeamResponse.ok) { + console.log(`Deleted team: ${team.name}`); + } else { + console.error(`Failed to delete team ${team.name}:`, await deleteTeamResponse.text()); + } + } catch (error) { + console.error(`Error deleting team ${team.name}:`, error); + } + } + } else { + console.error("Failed to fetch teams:", await getTeamsResponse.text()); + } + } else { + console.log("No organizationId found in OAuth client"); + } + } else { + console.error("Failed to fetch OAuth client:", await getOAuthClientResponse.text()); + } + console.log("Cleaning up test database..."); + execSync("rm -f prisma/test.db", { stdio: "inherit" }); + console.log("Test database cleaned up successfully"); + } catch (error) { + console.error("Failed to clean up:", error); + } +} +export default globalTeardown; diff --git a/packages/platform/examples/base/package.json b/packages/platform/examples/base/package.json index d761c05f05c83b..b25b2b2b453c6a 100644 --- a/packages/platform/examples/base/package.json +++ b/packages/platform/examples/base/package.json @@ -9,7 +9,10 @@ "start": "next start", "lint": "next lint", "test:e2e": "playwright test", - "test:e2e:ui": "playwright test --ui" + "test:e2e:ui": "playwright test --ui", + "db:push:test": "prisma db push --schema=prisma/schema.test.prisma", + "db:generate:test": "prisma generate --schema=prisma/schema.test.prisma", + "db:reset:test": "rm -f prisma/test.db && yarn db:push:test" }, "dependencies": { "@calcom/atoms": "*", diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index d77d9e71361d81..735e8fed5441bd 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -2,9 +2,7 @@ import { defineConfig, devices } from "@playwright/test"; import dotenv from "dotenv"; import path from "path"; -const envPath = process.env.CI ? path.resolve(__dirname, ".env") : path.resolve(__dirname, ".env.local"); - -dotenv.config({ path: envPath }); +dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; @@ -17,6 +15,7 @@ export default defineConfig({ workers: process.env.CI ? 1 : undefined, timeout: DEFAULT_TEST_TIMEOUT, fullyParallel: false, + globalTeardown: require.resolve("./global-teardown"), reporter: [ ["list"], ["html", { outputFolder: "./test-results/reports/playwright-html-report", open: "never" }], @@ -45,7 +44,7 @@ export default defineConfig({ webServer: { command: process.env.CI ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && rm -f prisma/dev.db && yarn prisma db push && NEXT_PUBLIC_IS_E2E=1 NODE_ENV=test NEXT_PUBLIC_X_CAL_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID}" X_CAL_SECRET_KEY="${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET}" NEXT_PUBLIC_CALCOM_API_URL="${process.env.ATOMS_E2E_API_URL}" VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED}" VITE_BOOKER_EMBED_API_URL="${process.env.ATOMS_E2E_API_URL}" ORGANIZATION_ID=${process.env.ATOMS_E2E_ORG_ID} yarn dev:e2e` - : `rm -f prisma/dev.db && yarn prisma db push && yarn dev:e2e`, + : `yarn db:generate:test && yarn db:reset:test && yarn dev:e2e`, url: "http://localhost:4322", timeout: 600_000, reuseExistingServer: !process.env.CI, diff --git a/packages/platform/examples/base/prisma/schema.test.prisma b/packages/platform/examples/base/prisma/schema.test.prisma new file mode 100644 index 00000000000000..04752bcfb00c82 --- /dev/null +++ b/packages/platform/examples/base/prisma/schema.test.prisma @@ -0,0 +1,19 @@ +generator testClient { + provider = "prisma-client-js" + output = "../node_modules/.prisma/test-client" +} +datasource testDb { + provider = "sqlite" + url = "file:./test.db" +} +model User { + id Int @id @default(autoincrement()) + email String @unique(map: "TestUser_email_key") + name String? + calcomUserId Int? @unique(map: "TestUser_calcomUserId_key") + calcomUsername String? @unique(map: "TestUser_calcomUsername_key") + refreshToken String? @unique(map: "TestUser_refreshToken_key") + accessToken String? @unique(map: "TestUser_accessToken_key") + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) +} \ No newline at end of file diff --git a/turbo.json b/turbo.json index 5ab7c99b3983a1..369a74462376b0 100644 --- a/turbo.json +++ b/turbo.json @@ -279,7 +279,10 @@ "ATOMS_E2E_APPLE_ID", "ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE", "INTERCOM_API_TOKEN", - "NEXT_PUBLIC_INTERCOM_APP_ID" + "NEXT_PUBLIC_INTERCOM_APP_ID", + "NEXT_PUBLIC_X_CAL_ID", + "X_CAL_SECRET_KEY", + "NEXT_PUBLIC_CALCOM_API_URL" ], "tasks": { "@calcom/prisma#build": { From 4629e6e935c033160ae00b5bdbb561a726c3e2f4 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 17 Sep 2025 13:35:25 +0200 Subject: [PATCH 07/73] feat: e2e oauth client in a seed --- scripts/seed.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scripts/seed.ts b/scripts/seed.ts index d60e1a19f17022..e6a5a1af459e7f 100644 --- a/scripts/seed.ts +++ b/scripts/seed.ts @@ -186,7 +186,7 @@ async function createPlatformAndSetupUser({ await prisma.platformOAuthClient.create({ data: { - name: "Acme", + name: "examples-app", redirectUris: ["http://localhost:4321"], permissions: 1023, areEmailsEnabled: true, @@ -196,6 +196,19 @@ async function createPlatformAndSetupUser({ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiQWNtZSAiLCJwZXJtaXNzaW9ucyI6MTAyMywicmVkaXJlY3RVcmlzIjpbImh0dHA6Ly9sb2NhbGhvc3Q6NDMyMSJdLCJib29raW5nUmVkaXJlY3RVcmkiOiIiLCJib29raW5nQ2FuY2VsUmVkaXJlY3RVcmkiOiIiLCJib29raW5nUmVzY2hlZHVsZVJlZGlyZWN0VXJpIjoiIiwiYXJlRW1haWxzRW5hYmxlZCI6dHJ1ZSwiaWF0IjoxNzE5NTk1ODA4fQ.L5_jSS14fcKLCD_9_DAOgtGd6lUSZlU5CEpCPaPt41I", }, }); + + await prisma.platformOAuthClient.create({ + data: { + name: "examples-app-e2e", + redirectUris: ["http://localhost:4322"], + permissions: 1023, + areEmailsEnabled: true, + organizationId: team.id, + id: "e2e8k9m3n0004p2q1r5s6t7u8", + secret: + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZXhhbXBsZXMtYXBwLWUyZSIsInBlcm1pc3Npb25zIjoxMDIzLCJyZWRpcmVjdFVyaXMiOlsiaHR0cDovL2xvY2FsaG9zdDo0MzIyIl0sImJvb2tpbmdSZWRpcmVjdFVyaSI6IiIsImJvb2tpbmdDYW5jZWxSZWRpcmVjdFVyaSI6IiIsImJvb2tpbmdSZXNjaGVkdWxlUmVkaXJlY3RVcmkiOiIiLCJhcmVFbWFpbHNFbmFibGVkIjp0cnVlLCJpYXQiOjE3MjYwNDMyNTl9.kL8mN9pQ5rS7tU8vW0xY1zA2bC4dE6fG8hI0jK1lM3n", + }, + }); console.log(`\t👤 Added '${teamInput.name}' membership for '${username}' with role '${membershipRole}'`); } } From 6cca42a4755d0381da99891b4d2f2c5ad16849ee Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 17 Sep 2025 16:16:39 +0200 Subject: [PATCH 08/73] feat: run atoms e2e in CI with local v2 --- .github/workflows/e2e-atoms.yml | 74 ++++++++++++++++++++++++++++++++- apps/api/v2/package.json | 2 +- packages/prisma/schema.prisma | 7 ++-- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index f6b347dbaa395f..1dc7f32b79bf5c 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -7,7 +7,27 @@ permissions: contents: read env: - NODE_OPTIONS: --max-old-space-size=8096 + ## api v2 env + ALLOWED_HOSTNAMES: ${{ vars.CI_ALLOWED_HOSTNAMES }} + API_KEY_PREFIX: ${{ secrets.CI_API_KEY_PREFIX }} + API_PORT: ${{ vars.CI_API_V2_PORT }} + CALCOM_LICENSE_KEY: ${{ secrets.CI_CALCOM_LICENSE_KEY }} + DAILY_API_KEY: ${{ secrets.CI_DAILY_API_KEY }} + DATABASE_READ_URL: ${{ secrets.CI_DATABASE_URL }} + DATABASE_WRITE_URL: ${{ secrets.CI_DATABASE_URL }} + GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }} + IS_E2E: true + NEXTAUTH_SECRET: ${{ secrets.CI_NEXTAUTH_SECRET }} + NEXTAUTH_URL: ${{ secrets.CI_NEXTAUTH_URL }} + REDIS_URL: "redis://localhost:6379" + LINGO_DOT_DEV_API_KEY: ${{ secrets.CI_LINGO_DOT_DEV_API_KEY }} + STRIPE_PRIVATE_KEY: ${{ secrets.CI_STRIPE_PRIVATE_KEY }} + STRIPE_API_KEY: ${{ secrets.CI_STRIPE_PRIVATE_KEY }} + STRIPE_CLIENT_ID: ${{ secrets.CI_STRIPE_CLIENT_ID }} + STRIPE_WEBHOOK_SECRET: ${{ secrets.CI_STRIPE_WEBHOOK_SECRET }} + SLOTS_CACHE_TTL: ${{ secrets.CI_SLOTS_CACHE_TTL }} + + ## atoms e2e examples app env ATOMS_E2E_OAUTH_CLIENT_ID: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID }} ATOMS_E2E_OAUTH_CLIENT_SECRET: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_SECRET }} ATOMS_E2E_API_URL: ${{ secrets.ATOMS_E2E_API_URL }} @@ -15,14 +35,46 @@ env: ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED }} ATOMS_E2E_APPLE_ID: ${{ secrets.ATOMS_E2E_APPLE_ID }} ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE: ${{ secrets.ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE }} + + ## env variables needed for both api v2 and examples app DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }} DATABASE_URL: ${{ secrets.CI_DATABASE_URL }} + NODE_OPTIONS: --max-old-space-size=29000 jobs: e2e-atoms: timeout-minutes: 15 name: E2E Atoms - runs-on: buildjet-4vcpu-ubuntu-2204 + runs-on: buildjet-16vcpu-ubuntu-2204 + services: + postgres: + image: postgres:13 + credentials: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: calendso + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + redis: + image: redis:latest + credentials: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - uses: docker/login-action@v3 with: @@ -31,10 +83,28 @@ jobs: - uses: actions/checkout@v4 - uses: ./.github/actions/dangerous-git-checkout - uses: ./.github/actions/yarn-install + - uses: ./.github/actions/cache-db - uses: ./.github/actions/yarn-playwright-install + - name: Start API v2 + working-directory: apps/api/v2 + run: | + yarn dev:no-docker & + API_PID=$! + echo "API_PID=$API_PID" >> $GITHUB_ENV + + # Wait for API to be ready + echo "Waiting for API v2 to be ready on port ${{ vars.CI_API_V2_PORT }}..." + timeout 60 bash -c 'until curl -f http://localhost:${{ vars.CI_API_V2_PORT }}/health > /dev/null 2>&1; do sleep 2; done' + echo "API v2 is ready!" - name: Run E2E Atoms Tests working-directory: packages/platform/examples/base run: yarn test:e2e + - name: Stop API v2 + if: always() + run: | + if [ ! -z "$API_PID" ]; then + kill $API_PID || true + fi - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() diff --git a/apps/api/v2/package.json b/apps/api/v2/package.json index b3f7156e196ea5..0bb3c8a9e1808a 100644 --- a/apps/api/v2/package.json +++ b/apps/api/v2/package.json @@ -16,7 +16,7 @@ "_dev:build:watch:enums": "yarn workspace @calcom/platform-enums build:watch", "_dev:build:watch:utils": "yarn workspace @calcom/platform-utils build:watch", "_dev:build:watch:types": "yarn workspace @calcom/platform-types build:watch", - "dev:build": "yarn workspace @calcom/platform-constants build && yarn workspace @calcom/platform-enums build && yarn workspace @calcom/platform-utils build && yarn workspace @calcom/platform-types build", + "dev:build": "yarn workspace @calcom/platform-constants build && yarn workspace @calcom/platform-enums build && yarn workspace @calcom/platform-utils build && yarn workspace @calcom/platform-types build && yarn workspace @calcom/platform-libraries build", "dev": "yarn dev:build && ts-node scripts/docker-start.ts && yarn copy-swagger-module && yarn start --watch", "dev:no-docker": "yarn dev:build && yarn copy-swagger-module && yarn start --watch", "start:debug": "nest start --debug --watch", diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 0ea9c358a758bb..ed53bd03ba5fdc 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -1885,9 +1885,10 @@ model PlatformOAuthClient { bookingRedirectUri String? bookingCancelRedirectUri String? bookingRescheduleRedirectUri String? - areEmailsEnabled Boolean @default(false) - areDefaultEventTypesEnabled Boolean @default(true) - areCalendarEventsEnabled Boolean @default(true) + + areEmailsEnabled Boolean @default(false) + areDefaultEventTypesEnabled Boolean @default(true) + areCalendarEventsEnabled Boolean @default(true) createdAt DateTime @default(now()) } From 58e470d0ba7b5be46baed216358e0a7a018488ea Mon Sep 17 00:00:00 2001 From: supalarry Date: Tue, 23 Sep 2025 11:30:31 +0200 Subject: [PATCH 09/73] refactor: load e2e env only locally --- packages/platform/examples/base/playwright.config.ts | 4 +++- turbo.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 735e8fed5441bd..4cc455cda5cf10 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -2,7 +2,9 @@ import { defineConfig, devices } from "@playwright/test"; import dotenv from "dotenv"; import path from "path"; -dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); +if (!process.env.CI) { + dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); +} const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; diff --git a/turbo.json b/turbo.json index d4cdd477bce3c3..a76babde1c9a95 100644 --- a/turbo.json +++ b/turbo.json @@ -282,7 +282,7 @@ "NEXT_PUBLIC_INTERCOM_APP_ID", "NEXT_PUBLIC_X_CAL_ID", "X_CAL_SECRET_KEY", - "NEXT_PUBLIC_CALCOM_API_URL" + "NEXT_PUBLIC_CALCOM_API_URL", "_CAL_INTERNAL_PAST_BOOKING_RESCHEDULE_CHANGE_TEAM_IDS" ], "tasks": { From 32bc7c63c12578abd5f10faca5683c4b40fc8654 Mon Sep 17 00:00:00 2001 From: supalarry Date: Tue, 23 Sep 2025 11:36:03 +0200 Subject: [PATCH 10/73] chore: reset test db in CI and ignore test db --- packages/platform/examples/base/.gitignore | 1 + packages/platform/examples/base/playwright.config.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/platform/examples/base/.gitignore b/packages/platform/examples/base/.gitignore index 0a92d640efab1e..b8065cc21e666c 100644 --- a/packages/platform/examples/base/.gitignore +++ b/packages/platform/examples/base/.gitignore @@ -37,6 +37,7 @@ yarn-error.log* next-env.d.ts .yarn dev.db +test.db # playwright test-results diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 4cc455cda5cf10..3df8b473e130b9 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -45,7 +45,7 @@ export default defineConfig({ ], webServer: { command: process.env.CI - ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && rm -f prisma/dev.db && yarn prisma db push && NEXT_PUBLIC_IS_E2E=1 NODE_ENV=test NEXT_PUBLIC_X_CAL_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID}" X_CAL_SECRET_KEY="${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET}" NEXT_PUBLIC_CALCOM_API_URL="${process.env.ATOMS_E2E_API_URL}" VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED}" VITE_BOOKER_EMBED_API_URL="${process.env.ATOMS_E2E_API_URL}" ORGANIZATION_ID=${process.env.ATOMS_E2E_ORG_ID} yarn dev:e2e` + ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && rm -f prisma/test.db && yarn db:generate:test && yarn db:reset:test && NEXT_PUBLIC_IS_E2E=1 NODE_ENV=test NEXT_PUBLIC_X_CAL_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID}" X_CAL_SECRET_KEY="${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET}" NEXT_PUBLIC_CALCOM_API_URL="${process.env.ATOMS_E2E_API_URL}" VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED}" VITE_BOOKER_EMBED_API_URL="${process.env.ATOMS_E2E_API_URL}" ORGANIZATION_ID=${process.env.ATOMS_E2E_ORG_ID} yarn dev:e2e` : `yarn db:generate:test && yarn db:reset:test && yarn dev:e2e`, url: "http://localhost:4322", timeout: 600_000, From d24c4da7fab0af1ea71d12d24307d591dd626ede Mon Sep 17 00:00:00 2001 From: supalarry Date: Tue, 23 Sep 2025 12:22:34 +0200 Subject: [PATCH 11/73] refactor: remove unneeded cleanup --- packages/platform/examples/base/playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 3df8b473e130b9..1ea978ec2816b2 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -45,7 +45,7 @@ export default defineConfig({ ], webServer: { command: process.env.CI - ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && rm -f prisma/test.db && yarn db:generate:test && yarn db:reset:test && NEXT_PUBLIC_IS_E2E=1 NODE_ENV=test NEXT_PUBLIC_X_CAL_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID}" X_CAL_SECRET_KEY="${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET}" NEXT_PUBLIC_CALCOM_API_URL="${process.env.ATOMS_E2E_API_URL}" VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED}" VITE_BOOKER_EMBED_API_URL="${process.env.ATOMS_E2E_API_URL}" ORGANIZATION_ID=${process.env.ATOMS_E2E_ORG_ID} yarn dev:e2e` + ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && yarn db:generate:test && yarn db:reset:test && NEXT_PUBLIC_IS_E2E=1 NODE_ENV=test NEXT_PUBLIC_X_CAL_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID}" X_CAL_SECRET_KEY="${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET}" NEXT_PUBLIC_CALCOM_API_URL="${process.env.ATOMS_E2E_API_URL}" VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED}" VITE_BOOKER_EMBED_API_URL="${process.env.ATOMS_E2E_API_URL}" ORGANIZATION_ID=${process.env.ATOMS_E2E_ORG_ID} yarn dev:e2e` : `yarn db:generate:test && yarn db:reset:test && yarn dev:e2e`, url: "http://localhost:4322", timeout: 600_000, From d23dfaac0f3032ca3681d5e4eb5056b0ec4a6ff6 Mon Sep 17 00:00:00 2001 From: supalarry Date: Tue, 23 Sep 2025 12:34:23 +0200 Subject: [PATCH 12/73] refactor: db cleanup in finally statement --- packages/platform/examples/base/global-teardown.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/platform/examples/base/global-teardown.ts b/packages/platform/examples/base/global-teardown.ts index 00afaa21012f17..535cc2e080502d 100644 --- a/packages/platform/examples/base/global-teardown.ts +++ b/packages/platform/examples/base/global-teardown.ts @@ -1,5 +1,5 @@ -import { execSync } from "child_process"; import dotenv from "dotenv"; +import fs from "fs"; import path from "path"; dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); @@ -101,11 +101,13 @@ async function globalTeardown() { } else { console.error("Failed to fetch OAuth client:", await getOAuthClientResponse.text()); } - console.log("Cleaning up test database..."); - execSync("rm -f prisma/test.db", { stdio: "inherit" }); - console.log("Test database cleaned up successfully"); } catch (error) { console.error("Failed to clean up:", error); + } finally { + console.log("Cleaning up test database..."); + const testDbPath = path.resolve(__dirname, "prisma", "test.db"); + fs.rmSync(testDbPath, { force: true }); + console.log("Test database cleaned up successfully"); } } export default globalTeardown; From 1c06815b1bae182d7f325e41b9eacb0e48848825 Mon Sep 17 00:00:00 2001 From: supalarry Date: Tue, 23 Sep 2025 12:43:55 +0200 Subject: [PATCH 13/73] refactor: use webserv.env instead of inline env --- .../platform/examples/base/playwright.config.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 1ea978ec2816b2..02379d328602c6 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -45,10 +45,24 @@ export default defineConfig({ ], webServer: { command: process.env.CI - ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && yarn db:generate:test && yarn db:reset:test && NEXT_PUBLIC_IS_E2E=1 NODE_ENV=test NEXT_PUBLIC_X_CAL_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID}" X_CAL_SECRET_KEY="${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET}" NEXT_PUBLIC_CALCOM_API_URL="${process.env.ATOMS_E2E_API_URL}" VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED}" VITE_BOOKER_EMBED_API_URL="${process.env.ATOMS_E2E_API_URL}" ORGANIZATION_ID=${process.env.ATOMS_E2E_ORG_ID} yarn dev:e2e` + ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && yarn db:generate:test && yarn db:reset:test && yarn dev:e2e` : `yarn db:generate:test && yarn db:reset:test && yarn dev:e2e`, url: "http://localhost:4322", timeout: 600_000, reuseExistingServer: !process.env.CI, + ...(process.env.CI + ? { + env: { + NEXT_PUBLIC_IS_E2E: "1", + NODE_ENV: "test", + NEXT_PUBLIC_X_CAL_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID ?? "", + X_CAL_SECRET_KEY: process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET ?? "", + NEXT_PUBLIC_CALCOM_API_URL: process.env.ATOMS_E2E_API_URL ?? "", + VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED ?? "", + VITE_BOOKER_EMBED_API_URL: process.env.ATOMS_E2E_API_URL ?? "", + ORGANIZATION_ID: String(process.env.ATOMS_E2E_ORG_ID ?? ""), + }, + } + : {}), }, }); From c3cf330fbfa94cb75d736be2c647dded9d24ab9a Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 24 Sep 2025 15:26:12 +0200 Subject: [PATCH 14/73] chore: temporarily dont run atoms on e2e label --- .github/workflows/all-checks.yml | 8 +------- .github/workflows/e2e-atoms.yml | 10 +++++++++- .github/workflows/pr.yml | 10 +--------- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/.github/workflows/all-checks.yml b/.github/workflows/all-checks.yml index 34ab40d3f6e50c..8d033f754c6949 100644 --- a/.github/workflows/all-checks.yml +++ b/.github/workflows/all-checks.yml @@ -74,14 +74,8 @@ jobs: uses: ./.github/workflows/e2e-embed-react.yml secrets: inherit - e2e-atoms: - name: Tests - needs: [lint, build, build-atoms, build-api-v2] - uses: ./.github/workflows/e2e-atoms.yml - secrets: inherit - required: - needs: [lint, type-check, unit-test, integration-test, build, build-api-v1, build-api-v2, e2e, e2e-embed, e2e-embed-react, e2e-app-store, e2e-atoms] + needs: [lint, type-check, unit-test, integration-test, build, build-api-v1, build-api-v2, e2e, e2e-embed, e2e-embed-react, e2e-app-store] if: always() runs-on: buildjet-2vcpu-ubuntu-2204 steps: diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index 1dc7f32b79bf5c..c81c60688b99d1 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -1,7 +1,15 @@ name: E2E Atoms on: - workflow_call: + pull_request: + branches: + - main + paths: + - 'packages/platform/atoms/**' + - 'packages/platform/examples/base/**' + - 'apps/api/v2/**' + - '.github/workflows/atoms-e2e.yml' + permissions: actions: write contents: read diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 98d4b316800e0b..8527205a00e67d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -195,13 +195,6 @@ jobs: uses: ./.github/workflows/e2e-embed-react.yml secrets: inherit - e2e-atoms: - name: Tests - needs: [changes, check-label, build, build-atoms, build-api-v2] - if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }} - uses: ./.github/workflows/e2e-atoms.yml - secrets: inherit - analyze: name: Analyze Build needs: [build] @@ -211,7 +204,7 @@ jobs: merge-reports: name: Merge reports if: ${{ !cancelled() && needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }} - needs: [changes, check-label, e2e, e2e-embed, e2e-embed-react, e2e-app-store, e2e-atoms] + needs: [changes, check-label, e2e, e2e-embed, e2e-embed-react, e2e-app-store] uses: ./.github/workflows/merge-reports.yml secrets: inherit @@ -256,7 +249,6 @@ jobs: e2e-embed, e2e-embed-react, e2e-app-store, - e2e-atoms, ] if: always() runs-on: buildjet-2vcpu-ubuntu-2204 From 57eb4b01a855040ed5db10b839e12a13e60cf2e7 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 24 Sep 2025 15:46:12 +0200 Subject: [PATCH 15/73] fix: self trigger path --- .github/workflows/e2e-atoms.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index c81c60688b99d1..7ad4a94acb976a 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -8,7 +8,7 @@ on: - 'packages/platform/atoms/**' - 'packages/platform/examples/base/**' - 'apps/api/v2/**' - - '.github/workflows/atoms-e2e.yml' + - '.github/workflows/e2e-atoms.yml' permissions: actions: write From 5321633b16de073f0e39a91bc782f9df8410af01 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 24 Sep 2025 16:03:45 +0200 Subject: [PATCH 16/73] fix: increase timeout --- .github/workflows/e2e-atoms.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index 7ad4a94acb976a..ba6ffed32ab36f 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -102,7 +102,7 @@ jobs: # Wait for API to be ready echo "Waiting for API v2 to be ready on port ${{ vars.CI_API_V2_PORT }}..." - timeout 60 bash -c 'until curl -f http://localhost:${{ vars.CI_API_V2_PORT }}/health > /dev/null 2>&1; do sleep 2; done' + timeout 300 bash -c 'until curl -f http://localhost:${{ vars.CI_API_V2_PORT }}/health > /dev/null 2>&1; do sleep 2; done' echo "API v2 is ready!" - name: Run E2E Atoms Tests working-directory: packages/platform/examples/base From 3302ae8d67e8014f2d0a32ac1d96acda6529ac3e Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 24 Sep 2025 16:21:56 +0200 Subject: [PATCH 17/73] chore: add vapid env keys to workflow --- .github/workflows/e2e-atoms.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index ba6ffed32ab36f..f485f16c0d4659 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -34,6 +34,8 @@ env: STRIPE_CLIENT_ID: ${{ secrets.CI_STRIPE_CLIENT_ID }} STRIPE_WEBHOOK_SECRET: ${{ secrets.CI_STRIPE_WEBHOOK_SECRET }} SLOTS_CACHE_TTL: ${{ secrets.CI_SLOTS_CACHE_TTL }} + NEXT_PUBLIC_VAPID_PUBLIC_KEY: ${{ secrets.NEXT_PUBLIC_VAPID_PUBLIC_KEY }} + VAPID_PRIVATE_KEY: ${{ secrets.VAPID_PRIVATE_KEY }} ## atoms e2e examples app env ATOMS_E2E_OAUTH_CLIENT_ID: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID }} From 6ea0bdaccd24247aac1773f338502d9b0fab2bb7 Mon Sep 17 00:00:00 2001 From: "cal.com" Date: Wed, 24 Sep 2025 20:46:36 +0300 Subject: [PATCH 18/73] chore: add CI_JWT_SECRET to e2e atoms --- .github/workflows/e2e-api-v2.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e-api-v2.yml b/.github/workflows/e2e-api-v2.yml index 4806dcc7ff42ff..8bb2f9b7dffadc 100644 --- a/.github/workflows/e2e-api-v2.yml +++ b/.github/workflows/e2e-api-v2.yml @@ -23,6 +23,7 @@ env: STRIPE_CLIENT_ID: ${{ secrets.CI_STRIPE_CLIENT_ID }} STRIPE_WEBHOOK_SECRET: ${{ secrets.CI_STRIPE_WEBHOOK_SECRET }} SLOTS_CACHE_TTL: ${{ secrets.CI_SLOTS_CACHE_TTL }} + JWT_SECRET: ${{ secrets.CI_JWT_SECRET }} jobs: e2e: timeout-minutes: 20 From cf1177e061b6b919b6d294de1500095d9c18f294 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 25 Sep 2025 07:26:40 +0200 Subject: [PATCH 19/73] chore: add NODE_ENV env --- .github/workflows/e2e-api-v2.yml | 1 + .github/workflows/e2e-atoms.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/e2e-api-v2.yml b/.github/workflows/e2e-api-v2.yml index 8bb2f9b7dffadc..1b5feb6f75a8f3 100644 --- a/.github/workflows/e2e-api-v2.yml +++ b/.github/workflows/e2e-api-v2.yml @@ -24,6 +24,7 @@ env: STRIPE_WEBHOOK_SECRET: ${{ secrets.CI_STRIPE_WEBHOOK_SECRET }} SLOTS_CACHE_TTL: ${{ secrets.CI_SLOTS_CACHE_TTL }} JWT_SECRET: ${{ secrets.CI_JWT_SECRET }} + NODE_ENV: ${{ vars.CI_NODE_ENV }} jobs: e2e: timeout-minutes: 20 diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index f485f16c0d4659..1a460d658f4c4e 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -36,6 +36,8 @@ env: SLOTS_CACHE_TTL: ${{ secrets.CI_SLOTS_CACHE_TTL }} NEXT_PUBLIC_VAPID_PUBLIC_KEY: ${{ secrets.NEXT_PUBLIC_VAPID_PUBLIC_KEY }} VAPID_PRIVATE_KEY: ${{ secrets.VAPID_PRIVATE_KEY }} + JWT_SECRET: ${{ secrets.CI_JWT_SECRET }} + NODE_ENV: ${{ vars.CI_NODE_ENV }} ## atoms e2e examples app env ATOMS_E2E_OAUTH_CLIENT_ID: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID }} From b3f33b27420afe62ccb58f7aa03c169616d49347 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 25 Sep 2025 07:42:00 +0200 Subject: [PATCH 20/73] fix: only run atoms e2e on main repo --- .github/workflows/e2e-atoms.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index 1a460d658f4c4e..0546b91b111fef 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -55,6 +55,7 @@ env: jobs: e2e-atoms: + if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} timeout-minutes: 15 name: E2E Atoms runs-on: buildjet-16vcpu-ubuntu-2204 From 045520200ac70a12e902b9b61574d55cc37df1e7 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 25 Sep 2025 11:16:46 +0200 Subject: [PATCH 21/73] fix: merge conflict --- turbo.json | 1 - 1 file changed, 1 deletion(-) diff --git a/turbo.json b/turbo.json index 73668caa695876..b0a98146065237 100644 --- a/turbo.json +++ b/turbo.json @@ -284,7 +284,6 @@ "NEXT_PUBLIC_X_CAL_ID", "X_CAL_SECRET_KEY", "NEXT_PUBLIC_CALCOM_API_URL", - "_CAL_INTERNAL_PAST_BOOKING_RESCHEDULE_CHANGE_TEAM_IDS" "_CAL_INTERNAL_PAST_BOOKING_RESCHEDULE_CHANGE_TEAM_IDS", "ENTERPRISE_SLUGS", "PLATFORM_ENTERPRISE_SLUGS" From 54ff08fc59ee7b651e24ce9583cdd78fe1080153 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 25 Sep 2025 13:06:18 +0200 Subject: [PATCH 22/73] debug: add logs to check env variables --- .../platform/examples/base/playwright.config.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 02379d328602c6..b5e4d28568b31b 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -11,6 +11,22 @@ const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; const headless = !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS; +// Debug logging for environment variables in CI +if (process.env.CI) { + console.log("=== E2E Environment Variables Debug ==="); + console.log(`NEXT_PUBLIC_IS_E2E: "1"`); + console.log(`NODE_ENV: "test"`); + console.log(`NEXT_PUBLIC_X_CAL_ID: "${process.env.ATOMS_E2E_OAUTH_CLIENT_ID ?? ""}"`); + console.log(`X_CAL_SECRET_KEY: "${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET ?? ""}"`); + console.log(`NEXT_PUBLIC_CALCOM_API_URL: "${process.env.ATOMS_E2E_API_URL ?? ""}"`); + console.log( + `VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: "${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED ?? ""}"` + ); + console.log(`VITE_BOOKER_EMBED_API_URL: "${process.env.ATOMS_E2E_API_URL ?? ""}"`); + console.log(`ORGANIZATION_ID: "${String(process.env.ATOMS_E2E_ORG_ID ?? "")}"`); + console.log("=== End Environment Variables Debug ==="); +} + export default defineConfig({ forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, From edb6ca8e14fd241bee9e867418d9a133a758735d Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 25 Sep 2025 13:19:37 +0200 Subject: [PATCH 23/73] Revert "debug: add logs to check env variables" This reverts commit 54ff08fc59ee7b651e24ce9583cdd78fe1080153. --- .../platform/examples/base/playwright.config.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index b5e4d28568b31b..02379d328602c6 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -11,22 +11,6 @@ const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; const headless = !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS; -// Debug logging for environment variables in CI -if (process.env.CI) { - console.log("=== E2E Environment Variables Debug ==="); - console.log(`NEXT_PUBLIC_IS_E2E: "1"`); - console.log(`NODE_ENV: "test"`); - console.log(`NEXT_PUBLIC_X_CAL_ID: "${process.env.ATOMS_E2E_OAUTH_CLIENT_ID ?? ""}"`); - console.log(`X_CAL_SECRET_KEY: "${process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET ?? ""}"`); - console.log(`NEXT_PUBLIC_CALCOM_API_URL: "${process.env.ATOMS_E2E_API_URL ?? ""}"`); - console.log( - `VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: "${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED ?? ""}"` - ); - console.log(`VITE_BOOKER_EMBED_API_URL: "${process.env.ATOMS_E2E_API_URL ?? ""}"`); - console.log(`ORGANIZATION_ID: "${String(process.env.ATOMS_E2E_ORG_ID ?? "")}"`); - console.log("=== End Environment Variables Debug ==="); -} - export default defineConfig({ forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, From 28b8487777f2cbd22c3f69def589e308c640b7cb Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 10:46:39 +0200 Subject: [PATCH 24/73] try to make it work --- packages/platform/examples/base/.env.e2e.ci | 10 +++++++ .../examples/base/playwright.config.ts | 30 ++++++++++--------- 2 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 packages/platform/examples/base/.env.e2e.ci diff --git a/packages/platform/examples/base/.env.e2e.ci b/packages/platform/examples/base/.env.e2e.ci new file mode 100644 index 00000000000000..40784300c363fe --- /dev/null +++ b/packages/platform/examples/base/.env.e2e.ci @@ -0,0 +1,10 @@ +NEXT_PUBLIC_X_CAL_ID="e2e8k9m3n0004p2q1r5s6t7u8" +X_CAL_SECRET_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZXhhbXBsZXMtYXBwLWUyZSIsInBlcm1pc3Npb25zIjoxMDIzLCJyZWRpcmVjdFVyaXMiOlsiaHR0cDovL2xvY2FsaG9zdDo0MzIyIl0sImJvb2tpbmdSZWRpcmVjdFVyaSI6IiIsImJvb2tpbmdDYW5jZWxSZWRpcmVjdFVyaSI6IiIsImJvb2tpbmdSZXNjaGVkdWxlUmVkaXJlY3RVcmkiOiIiLCJhcmVFbWFpbHNFbmFibGVkIjp0cnVlLCJpYXQiOjE3MjYwNDMyNTl9.kL8mN9pQ5rS7tU8vW0xY1zA2bC4dE6fG8hI0jK1lM3n" +NEXT_PUBLIC_CALCOM_API_URL="http://localhost:5555/api/v2" +VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="clywuonwt0001regwyzy6subr" +VITE_BOOKER_EMBED_API_URL="http://localhost:5555/api/v2" +ORGANIZATION_ID=1 +ATOMS_E2E_APPLE_ID="test@gmail.com" +ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE="test" +NEXT_PUBLIC_IS_E2E="1" +NODE_ENV="test" \ No newline at end of file diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 02379d328602c6..bb51a7be00d135 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -4,6 +4,8 @@ import path from "path"; if (!process.env.CI) { dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); +} else { + dotenv.config({ path: path.resolve(__dirname, ".env.e2e.ci") }); } const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; @@ -50,19 +52,19 @@ export default defineConfig({ url: "http://localhost:4322", timeout: 600_000, reuseExistingServer: !process.env.CI, - ...(process.env.CI - ? { - env: { - NEXT_PUBLIC_IS_E2E: "1", - NODE_ENV: "test", - NEXT_PUBLIC_X_CAL_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID ?? "", - X_CAL_SECRET_KEY: process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET ?? "", - NEXT_PUBLIC_CALCOM_API_URL: process.env.ATOMS_E2E_API_URL ?? "", - VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED ?? "", - VITE_BOOKER_EMBED_API_URL: process.env.ATOMS_E2E_API_URL ?? "", - ORGANIZATION_ID: String(process.env.ATOMS_E2E_ORG_ID ?? ""), - }, - } - : {}), + // ...(process.env.CI + // ? { + // env: { + // NEXT_PUBLIC_IS_E2E: "1", + // NODE_ENV: "test", + // NEXT_PUBLIC_X_CAL_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID ?? "", + // X_CAL_SECRET_KEY: process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET ?? "", + // NEXT_PUBLIC_CALCOM_API_URL: process.env.ATOMS_E2E_API_URL ?? "", + // VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED ?? "", + // VITE_BOOKER_EMBED_API_URL: process.env.ATOMS_E2E_API_URL ?? "", + // ORGANIZATION_ID: String(process.env.ATOMS_E2E_ORG_ID ?? ""), + // }, + // } + // : {}), }, }); From 4aa6f96e7e0e75572c011070a388ef1c60823b33 Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 13:57:42 +0200 Subject: [PATCH 25/73] Revert "try to make it work" This reverts commit 28b8487777f2cbd22c3f69def589e308c640b7cb. --- packages/platform/examples/base/.env.e2e.ci | 10 ------- .../examples/base/playwright.config.ts | 30 +++++++++---------- 2 files changed, 14 insertions(+), 26 deletions(-) delete mode 100644 packages/platform/examples/base/.env.e2e.ci diff --git a/packages/platform/examples/base/.env.e2e.ci b/packages/platform/examples/base/.env.e2e.ci deleted file mode 100644 index 40784300c363fe..00000000000000 --- a/packages/platform/examples/base/.env.e2e.ci +++ /dev/null @@ -1,10 +0,0 @@ -NEXT_PUBLIC_X_CAL_ID="e2e8k9m3n0004p2q1r5s6t7u8" -X_CAL_SECRET_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZXhhbXBsZXMtYXBwLWUyZSIsInBlcm1pc3Npb25zIjoxMDIzLCJyZWRpcmVjdFVyaXMiOlsiaHR0cDovL2xvY2FsaG9zdDo0MzIyIl0sImJvb2tpbmdSZWRpcmVjdFVyaSI6IiIsImJvb2tpbmdDYW5jZWxSZWRpcmVjdFVyaSI6IiIsImJvb2tpbmdSZXNjaGVkdWxlUmVkaXJlY3RVcmkiOiIiLCJhcmVFbWFpbHNFbmFibGVkIjp0cnVlLCJpYXQiOjE3MjYwNDMyNTl9.kL8mN9pQ5rS7tU8vW0xY1zA2bC4dE6fG8hI0jK1lM3n" -NEXT_PUBLIC_CALCOM_API_URL="http://localhost:5555/api/v2" -VITE_BOOKER_EMBED_OAUTH_CLIENT_ID="clywuonwt0001regwyzy6subr" -VITE_BOOKER_EMBED_API_URL="http://localhost:5555/api/v2" -ORGANIZATION_ID=1 -ATOMS_E2E_APPLE_ID="test@gmail.com" -ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE="test" -NEXT_PUBLIC_IS_E2E="1" -NODE_ENV="test" \ No newline at end of file diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index bb51a7be00d135..02379d328602c6 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -4,8 +4,6 @@ import path from "path"; if (!process.env.CI) { dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); -} else { - dotenv.config({ path: path.resolve(__dirname, ".env.e2e.ci") }); } const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; @@ -52,19 +50,19 @@ export default defineConfig({ url: "http://localhost:4322", timeout: 600_000, reuseExistingServer: !process.env.CI, - // ...(process.env.CI - // ? { - // env: { - // NEXT_PUBLIC_IS_E2E: "1", - // NODE_ENV: "test", - // NEXT_PUBLIC_X_CAL_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID ?? "", - // X_CAL_SECRET_KEY: process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET ?? "", - // NEXT_PUBLIC_CALCOM_API_URL: process.env.ATOMS_E2E_API_URL ?? "", - // VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED ?? "", - // VITE_BOOKER_EMBED_API_URL: process.env.ATOMS_E2E_API_URL ?? "", - // ORGANIZATION_ID: String(process.env.ATOMS_E2E_ORG_ID ?? ""), - // }, - // } - // : {}), + ...(process.env.CI + ? { + env: { + NEXT_PUBLIC_IS_E2E: "1", + NODE_ENV: "test", + NEXT_PUBLIC_X_CAL_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID ?? "", + X_CAL_SECRET_KEY: process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET ?? "", + NEXT_PUBLIC_CALCOM_API_URL: process.env.ATOMS_E2E_API_URL ?? "", + VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED ?? "", + VITE_BOOKER_EMBED_API_URL: process.env.ATOMS_E2E_API_URL ?? "", + ORGANIZATION_ID: String(process.env.ATOMS_E2E_ORG_ID ?? ""), + }, + } + : {}), }, }); From 346be391679b87096e5ffa4ccb908dff081cea9b Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 13:59:11 +0200 Subject: [PATCH 26/73] upload atoms dist for inspection --- .github/workflows/e2e-atoms.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index 0546b91b111fef..423c2864c04f86 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -112,6 +112,15 @@ jobs: - name: Run E2E Atoms Tests working-directory: packages/platform/examples/base run: yarn test:e2e + - name: Upload Atoms dist (entire folder) + uses: actions/upload-artifact@v4 + if: always() + with: + name: atoms-dist-${{ github.sha }} + path: packages/platform/atoms/dist + retention-days: 7 + if-no-files-found: warn + - name: Stop API v2 if: always() run: | From ccfd52e2a3de1ff06835342d91c53a8aa504c14a Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 15:09:17 +0200 Subject: [PATCH 27/73] experiment: set random url instead of empty --- packages/features/shell/useBottomNavItems.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/features/shell/useBottomNavItems.ts b/packages/features/shell/useBottomNavItems.ts index 4bbbf5c3402394..b4bf592cdad619 100644 --- a/packages/features/shell/useBottomNavItems.ts +++ b/packages/features/shell/useBottomNavItems.ts @@ -38,7 +38,7 @@ export function useBottomNavItems({ isTrial ? { name: "skip_trial", - href: "", + href: publicPageUrl, isLoading: skipTeamTrialsMutation.isPending, icon: "clock", onClick: (e: { preventDefault: () => void }) => { @@ -55,7 +55,7 @@ export function useBottomNavItems({ }, { name: "copy_public_page_link", - href: "", + href: publicPageUrl, onClick: (e: { preventDefault: () => void }) => { e.preventDefault(); navigator.clipboard.writeText(publicPageUrl); From e202aa7c88eb45156aa8f80a74e147e5f034758b Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 15:35:09 +0200 Subject: [PATCH 28/73] Revert "experiment: set random url instead of empty" This reverts commit ccfd52e2a3de1ff06835342d91c53a8aa504c14a. --- packages/features/shell/useBottomNavItems.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/features/shell/useBottomNavItems.ts b/packages/features/shell/useBottomNavItems.ts index b4bf592cdad619..4bbbf5c3402394 100644 --- a/packages/features/shell/useBottomNavItems.ts +++ b/packages/features/shell/useBottomNavItems.ts @@ -38,7 +38,7 @@ export function useBottomNavItems({ isTrial ? { name: "skip_trial", - href: publicPageUrl, + href: "", isLoading: skipTeamTrialsMutation.isPending, icon: "clock", onClick: (e: { preventDefault: () => void }) => { @@ -55,7 +55,7 @@ export function useBottomNavItems({ }, { name: "copy_public_page_link", - href: publicPageUrl, + href: "", onClick: (e: { preventDefault: () => void }) => { e.preventDefault(); navigator.clipboard.writeText(publicPageUrl); From aad1c0c964c8aa4d322ee96ad78ddc7b2ad59137 Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 15:41:41 +0200 Subject: [PATCH 29/73] try fix --- packages/features/shell/useBottomNavItems.ts | 76 ++++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/features/shell/useBottomNavItems.ts b/packages/features/shell/useBottomNavItems.ts index 4bbbf5c3402394..e452b860d860f4 100644 --- a/packages/features/shell/useBottomNavItems.ts +++ b/packages/features/shell/useBottomNavItems.ts @@ -1,11 +1,11 @@ import type { User as UserAuth } from "next-auth"; import { IS_DUB_REFERRALS_ENABLED } from "@calcom/lib/constants"; -import { useHasActiveTeamPlanAsOwner } from "@calcom/lib/hooks/useHasPaidPlan"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { trpc } from "@calcom/trpc/react"; -import { showToast } from "@calcom/ui/components/toast"; +// import { useHasActiveTeamPlanAsOwner } from "@calcom/lib/hooks/useHasPaidPlan"; +// import { useLocale } from "@calcom/lib/hooks/useLocale"; +// import { trpc } from "@calcom/trpc/react"; +// import { showToast } from "@calcom/ui/components/toast"; import { type NavigationItemType } from "./navigation/NavigationItem"; type BottomNavItemsProps = { @@ -19,50 +19,50 @@ export function useBottomNavItems({ isAdmin, user, }: BottomNavItemsProps): NavigationItemType[] { - const { t } = useLocale(); - const { isTrial } = useHasActiveTeamPlanAsOwner(); - const utils = trpc.useUtils(); + // const { t } = useLocale(); + // const { isTrial } = useHasActiveTeamPlanAsOwner(); + // const utils = trpc.useUtils(); - const skipTeamTrialsMutation = trpc.viewer.teams.skipTeamTrials.useMutation({ - onSuccess: () => { - utils.viewer.teams.hasActiveTeamPlan.invalidate(); - showToast(t("team_trials_skipped_successfully"), "success"); - }, - onError: () => { - showToast(t("something_went_wrong"), "error"); - }, - }); + // const skipTeamTrialsMutation = trpc.viewer.teams.skipTeamTrials.useMutation({ + // onSuccess: () => { + // utils.viewer.teams.hasActiveTeamPlan.invalidate(); + // showToast(t("team_trials_skipped_successfully"), "success"); + // }, + // onError: () => { + // showToast(t("something_went_wrong"), "error"); + // }, + // }); return [ // Render above to prevent layout shift as much as possible - isTrial - ? { - name: "skip_trial", - href: "", - isLoading: skipTeamTrialsMutation.isPending, - icon: "clock", - onClick: (e: { preventDefault: () => void }) => { - e.preventDefault(); - skipTeamTrialsMutation.mutate({}); - }, - } - : null, + // isTrial + // ? { + // name: "skip_trial", + // href: "", + // isLoading: skipTeamTrialsMutation.isPending, + // icon: "clock", + // onClick: (e: { preventDefault: () => void }) => { + // e.preventDefault(); + // skipTeamTrialsMutation.mutate({}); + // }, + // } + // : null, { name: "view_public_page", href: publicPageUrl, icon: "external-link", target: "__blank", }, - { - name: "copy_public_page_link", - href: "", - onClick: (e: { preventDefault: () => void }) => { - e.preventDefault(); - navigator.clipboard.writeText(publicPageUrl); - showToast(t("link_copied"), "success"); - }, - icon: "copy", - }, + // { + // name: "copy_public_page_link", + // href: "", + // onClick: (e: { preventDefault: () => void }) => { + // e.preventDefault(); + // navigator.clipboard.writeText(publicPageUrl); + // showToast(t("link_copied"), "success"); + // }, + // icon: "copy", + // }, IS_DUB_REFERRALS_ENABLED ? { name: "referral_text", From 2e9d0b3a747dd1f04db201460abbbcbd10dd335c Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 15:43:06 +0200 Subject: [PATCH 30/73] Revert "try fix" This reverts commit aad1c0c964c8aa4d322ee96ad78ddc7b2ad59137. --- packages/features/shell/useBottomNavItems.ts | 76 ++++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/features/shell/useBottomNavItems.ts b/packages/features/shell/useBottomNavItems.ts index e452b860d860f4..4bbbf5c3402394 100644 --- a/packages/features/shell/useBottomNavItems.ts +++ b/packages/features/shell/useBottomNavItems.ts @@ -1,11 +1,11 @@ import type { User as UserAuth } from "next-auth"; import { IS_DUB_REFERRALS_ENABLED } from "@calcom/lib/constants"; +import { useHasActiveTeamPlanAsOwner } from "@calcom/lib/hooks/useHasPaidPlan"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; +import { trpc } from "@calcom/trpc/react"; +import { showToast } from "@calcom/ui/components/toast"; -// import { useHasActiveTeamPlanAsOwner } from "@calcom/lib/hooks/useHasPaidPlan"; -// import { useLocale } from "@calcom/lib/hooks/useLocale"; -// import { trpc } from "@calcom/trpc/react"; -// import { showToast } from "@calcom/ui/components/toast"; import { type NavigationItemType } from "./navigation/NavigationItem"; type BottomNavItemsProps = { @@ -19,50 +19,50 @@ export function useBottomNavItems({ isAdmin, user, }: BottomNavItemsProps): NavigationItemType[] { - // const { t } = useLocale(); - // const { isTrial } = useHasActiveTeamPlanAsOwner(); - // const utils = trpc.useUtils(); + const { t } = useLocale(); + const { isTrial } = useHasActiveTeamPlanAsOwner(); + const utils = trpc.useUtils(); - // const skipTeamTrialsMutation = trpc.viewer.teams.skipTeamTrials.useMutation({ - // onSuccess: () => { - // utils.viewer.teams.hasActiveTeamPlan.invalidate(); - // showToast(t("team_trials_skipped_successfully"), "success"); - // }, - // onError: () => { - // showToast(t("something_went_wrong"), "error"); - // }, - // }); + const skipTeamTrialsMutation = trpc.viewer.teams.skipTeamTrials.useMutation({ + onSuccess: () => { + utils.viewer.teams.hasActiveTeamPlan.invalidate(); + showToast(t("team_trials_skipped_successfully"), "success"); + }, + onError: () => { + showToast(t("something_went_wrong"), "error"); + }, + }); return [ // Render above to prevent layout shift as much as possible - // isTrial - // ? { - // name: "skip_trial", - // href: "", - // isLoading: skipTeamTrialsMutation.isPending, - // icon: "clock", - // onClick: (e: { preventDefault: () => void }) => { - // e.preventDefault(); - // skipTeamTrialsMutation.mutate({}); - // }, - // } - // : null, + isTrial + ? { + name: "skip_trial", + href: "", + isLoading: skipTeamTrialsMutation.isPending, + icon: "clock", + onClick: (e: { preventDefault: () => void }) => { + e.preventDefault(); + skipTeamTrialsMutation.mutate({}); + }, + } + : null, { name: "view_public_page", href: publicPageUrl, icon: "external-link", target: "__blank", }, - // { - // name: "copy_public_page_link", - // href: "", - // onClick: (e: { preventDefault: () => void }) => { - // e.preventDefault(); - // navigator.clipboard.writeText(publicPageUrl); - // showToast(t("link_copied"), "success"); - // }, - // icon: "copy", - // }, + { + name: "copy_public_page_link", + href: "", + onClick: (e: { preventDefault: () => void }) => { + e.preventDefault(); + navigator.clipboard.writeText(publicPageUrl); + showToast(t("link_copied"), "success"); + }, + icon: "copy", + }, IS_DUB_REFERRALS_ENABLED ? { name: "referral_text", From 642ccb82bd8b7b8ea0c3a5626aeab91a9325e5b3 Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 15:48:36 +0200 Subject: [PATCH 31/73] try fix --- packages/features/shell/SideBar.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/features/shell/SideBar.tsx b/packages/features/shell/SideBar.tsx index 46eb75661d58ae..38ac745b10819a 100644 --- a/packages/features/shell/SideBar.tsx +++ b/packages/features/shell/SideBar.tsx @@ -6,7 +6,6 @@ import { usePathname } from "next/navigation"; import { IS_VISUAL_REGRESSION_TESTING, ENABLE_PROFILE_SWITCHER } from "@calcom/lib/constants"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; -import { getBookerBaseUrlSync } from "@calcom/lib/getBookerUrl/client"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { UserPermissionRole } from "@calcom/prisma/enums"; import classNames from "@calcom/ui/classNames"; @@ -57,7 +56,7 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { const isPlatformPages = pathname?.startsWith("/settings/platform"); const isAdmin = session.data?.user.role === UserPermissionRole.ADMIN; - const publicPageUrl = `${getBookerBaseUrlSync(user?.org?.slug ?? null)}/${user?.orgAwareUsername}`; + const publicPageUrl = "https://app.cal.com/"; const bottomNavItems = useBottomNavItems({ publicPageUrl, From cf2dc403de7273f373fe4399343df96e43d55a54 Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 15:58:03 +0200 Subject: [PATCH 32/73] Revert "try fix" This reverts commit 642ccb82bd8b7b8ea0c3a5626aeab91a9325e5b3. --- packages/features/shell/SideBar.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/features/shell/SideBar.tsx b/packages/features/shell/SideBar.tsx index 38ac745b10819a..46eb75661d58ae 100644 --- a/packages/features/shell/SideBar.tsx +++ b/packages/features/shell/SideBar.tsx @@ -6,6 +6,7 @@ import { usePathname } from "next/navigation"; import { IS_VISUAL_REGRESSION_TESTING, ENABLE_PROFILE_SWITCHER } from "@calcom/lib/constants"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; +import { getBookerBaseUrlSync } from "@calcom/lib/getBookerUrl/client"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { UserPermissionRole } from "@calcom/prisma/enums"; import classNames from "@calcom/ui/classNames"; @@ -56,7 +57,7 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { const isPlatformPages = pathname?.startsWith("/settings/platform"); const isAdmin = session.data?.user.role === UserPermissionRole.ADMIN; - const publicPageUrl = "https://app.cal.com/"; + const publicPageUrl = `${getBookerBaseUrlSync(user?.org?.slug ?? null)}/${user?.orgAwareUsername}`; const bottomNavItems = useBottomNavItems({ publicPageUrl, From a82b84516903604391da570dfba92e0266302833 Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 15:58:20 +0200 Subject: [PATCH 33/73] try fix --- packages/features/shell/SideBar.tsx | 3 +-- packages/features/shell/useBottomNavItems.ts | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/features/shell/SideBar.tsx b/packages/features/shell/SideBar.tsx index 46eb75661d58ae..38ac745b10819a 100644 --- a/packages/features/shell/SideBar.tsx +++ b/packages/features/shell/SideBar.tsx @@ -6,7 +6,6 @@ import { usePathname } from "next/navigation"; import { IS_VISUAL_REGRESSION_TESTING, ENABLE_PROFILE_SWITCHER } from "@calcom/lib/constants"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; -import { getBookerBaseUrlSync } from "@calcom/lib/getBookerUrl/client"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { UserPermissionRole } from "@calcom/prisma/enums"; import classNames from "@calcom/ui/classNames"; @@ -57,7 +56,7 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { const isPlatformPages = pathname?.startsWith("/settings/platform"); const isAdmin = session.data?.user.role === UserPermissionRole.ADMIN; - const publicPageUrl = `${getBookerBaseUrlSync(user?.org?.slug ?? null)}/${user?.orgAwareUsername}`; + const publicPageUrl = "https://app.cal.com/"; const bottomNavItems = useBottomNavItems({ publicPageUrl, diff --git a/packages/features/shell/useBottomNavItems.ts b/packages/features/shell/useBottomNavItems.ts index 4bbbf5c3402394..b4bf592cdad619 100644 --- a/packages/features/shell/useBottomNavItems.ts +++ b/packages/features/shell/useBottomNavItems.ts @@ -38,7 +38,7 @@ export function useBottomNavItems({ isTrial ? { name: "skip_trial", - href: "", + href: publicPageUrl, isLoading: skipTeamTrialsMutation.isPending, icon: "clock", onClick: (e: { preventDefault: () => void }) => { @@ -55,7 +55,7 @@ export function useBottomNavItems({ }, { name: "copy_public_page_link", - href: "", + href: publicPageUrl, onClick: (e: { preventDefault: () => void }) => { e.preventDefault(); navigator.clipboard.writeText(publicPageUrl); From f14758e1af67ad3a9c14d71843328bc667ea54bf Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 16:06:05 +0200 Subject: [PATCH 34/73] Revert "try fix" This reverts commit a82b84516903604391da570dfba92e0266302833. --- packages/features/shell/SideBar.tsx | 3 ++- packages/features/shell/useBottomNavItems.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/features/shell/SideBar.tsx b/packages/features/shell/SideBar.tsx index 38ac745b10819a..46eb75661d58ae 100644 --- a/packages/features/shell/SideBar.tsx +++ b/packages/features/shell/SideBar.tsx @@ -6,6 +6,7 @@ import { usePathname } from "next/navigation"; import { IS_VISUAL_REGRESSION_TESTING, ENABLE_PROFILE_SWITCHER } from "@calcom/lib/constants"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; +import { getBookerBaseUrlSync } from "@calcom/lib/getBookerUrl/client"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { UserPermissionRole } from "@calcom/prisma/enums"; import classNames from "@calcom/ui/classNames"; @@ -56,7 +57,7 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { const isPlatformPages = pathname?.startsWith("/settings/platform"); const isAdmin = session.data?.user.role === UserPermissionRole.ADMIN; - const publicPageUrl = "https://app.cal.com/"; + const publicPageUrl = `${getBookerBaseUrlSync(user?.org?.slug ?? null)}/${user?.orgAwareUsername}`; const bottomNavItems = useBottomNavItems({ publicPageUrl, diff --git a/packages/features/shell/useBottomNavItems.ts b/packages/features/shell/useBottomNavItems.ts index b4bf592cdad619..4bbbf5c3402394 100644 --- a/packages/features/shell/useBottomNavItems.ts +++ b/packages/features/shell/useBottomNavItems.ts @@ -38,7 +38,7 @@ export function useBottomNavItems({ isTrial ? { name: "skip_trial", - href: publicPageUrl, + href: "", isLoading: skipTeamTrialsMutation.isPending, icon: "clock", onClick: (e: { preventDefault: () => void }) => { @@ -55,7 +55,7 @@ export function useBottomNavItems({ }, { name: "copy_public_page_link", - href: publicPageUrl, + href: "", onClick: (e: { preventDefault: () => void }) => { e.preventDefault(); navigator.clipboard.writeText(publicPageUrl); From 494ea2ac7ebfd2f59b841e9b3fca9bdd3091c2e0 Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 16:09:13 +0200 Subject: [PATCH 35/73] try chatgpt fix --- packages/features/shell/SideBar.tsx | 22 +++++-- packages/features/shell/useBottomNavItems.ts | 69 ++++++++++++++------ 2 files changed, 66 insertions(+), 25 deletions(-) diff --git a/packages/features/shell/SideBar.tsx b/packages/features/shell/SideBar.tsx index 46eb75661d58ae..6420929d6814b0 100644 --- a/packages/features/shell/SideBar.tsx +++ b/packages/features/shell/SideBar.tsx @@ -42,14 +42,22 @@ export type SideBarProps = { export function SideBarContainer({ bannersHeight, isPlatformUser = false }: SideBarContainerProps) { const { status, data } = useSession(); - - // Make sure that Sidebar is rendered optimistically so that a refresh of pages when logged in have SideBar from the beginning. - // This improves the experience of refresh on app store pages(when logged in) which are SSG. - // Though when logged out, app store pages would temporarily show SideBar until session status is confirmed. if (status !== "loading" && status !== "authenticated") return null; return ; } +// Build a safe public page URL (absolute or empty if not resolvable). +const buildPublicPageUrl = (user?: UserAuth | null): string => { + const base = + getBookerBaseUrlSync(user?.org?.slug ?? null) || + process.env.NEXT_PUBLIC_WEBAPP_URL || + process.env.NEXTAUTH_URL || + ""; + const username = user?.orgAwareUsername; + if (!base || !username) return ""; + return `${String(base).replace(/\/+$/, "")}/${username}`; +}; + export function SideBar({ bannersHeight, user }: SideBarProps) { const session = useSession(); const { t, isLocaleReady } = useLocale(); @@ -57,7 +65,7 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { const isPlatformPages = pathname?.startsWith("/settings/platform"); const isAdmin = session.data?.user.role === UserPermissionRole.ADMIN; - const publicPageUrl = `${getBookerBaseUrlSync(user?.org?.slug ?? null)}/${user?.orgAwareUsername}`; + const publicPageUrl = buildPublicPageUrl(user); const bottomNavItems = useBottomNavItems({ publicPageUrl, @@ -134,10 +142,12 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { + {/* logo icon for tablet */} + @@ -150,7 +160,7 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { { + if (!u) return undefined; + const base = process.env.NEXTAUTH_URL || process.env.NEXT_PUBLIC_WEBAPP_URL || "http://localhost:3000"; + try { + return new URL(u, base).toString(); + } catch { + return undefined; + } +}; + export function useBottomNavItems({ publicPageUrl, isAdmin, @@ -33,12 +45,18 @@ export function useBottomNavItems({ }, }); + const safePublicHref = withBase(publicPageUrl); + const safeReferHref = withBase("/refer"); + const safeImpersonationHref = withBase("/settings/admin/impersonation"); + const safeSettingsHref = withBase( + user?.org ? "/settings/organizations/profile" : "/settings/my-account/profile" + ); + return [ - // Render above to prevent layout shift as much as possible + // Action-only (no href) isTrial ? { name: "skip_trial", - href: "", isLoading: skipTeamTrialsMutation.isPending, icon: "clock", onClick: (e: { preventDefault: () => void }) => { @@ -47,40 +65,53 @@ export function useBottomNavItems({ }, } : null, - { - name: "view_public_page", - href: publicPageUrl, - icon: "external-link", - target: "__blank", - }, + + // External public page link, only if we have a resolvable absolute URL + safePublicHref + ? { + name: "view_public_page", + href: safePublicHref, + icon: "external-link", + target: "_blank", + } + : null, + + // Action-only (no href) { name: "copy_public_page_link", - href: "", + icon: "copy", onClick: (e: { preventDefault: () => void }) => { e.preventDefault(); - navigator.clipboard.writeText(publicPageUrl); - showToast(t("link_copied"), "success"); + // Prefer resolved; fall back to raw input if clipboard is allowed + const toCopy = safePublicHref ?? publicPageUrl ?? ""; + if (typeof navigator !== "undefined" && navigator.clipboard?.writeText && toCopy) { + navigator.clipboard.writeText(toCopy); + showToast(t("link_copied"), "success"); + } else { + showToast(t("something_went_wrong"), "error"); + } }, - icon: "copy", }, + IS_DUB_REFERRALS_ENABLED - ? { + ? safeReferHref && { name: "referral_text", - href: "/refer", + href: safeReferHref, icon: "gift", } : null, isAdmin - ? { + ? safeImpersonationHref && { name: "impersonation", - href: "/settings/admin/impersonation", + href: safeImpersonationHref, icon: "lock", } : null, - { + + safeSettingsHref && { name: "settings", - href: user?.org ? `/settings/organizations/profile` : "/settings/my-account/profile", + href: safeSettingsHref, icon: "settings", }, ].filter(Boolean) as NavigationItemType[]; From c2cb435f97118440c68f5a3e2d386bcd2420e082 Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 3 Oct 2025 16:22:43 +0200 Subject: [PATCH 36/73] try chatgpt fix pt 2 --- packages/features/shell/SideBar.tsx | 71 +++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/packages/features/shell/SideBar.tsx b/packages/features/shell/SideBar.tsx index 6420929d6814b0..a316661f48ce57 100644 --- a/packages/features/shell/SideBar.tsx +++ b/packages/features/shell/SideBar.tsx @@ -42,11 +42,13 @@ export type SideBarProps = { export function SideBarContainer({ bannersHeight, isPlatformUser = false }: SideBarContainerProps) { const { status, data } = useSession(); + + // Render nothing once we know the user isn't authenticated. if (status !== "loading" && status !== "authenticated") return null; return ; } -// Build a safe public page URL (absolute or empty if not resolvable). +// Build a safe absolute public page URL, or empty string if we can't. const buildPublicPageUrl = (user?: UserAuth | null): string => { const base = getBookerBaseUrlSync(user?.org?.slug ?? null) || @@ -156,21 +158,13 @@ export function SideBar({ bannersHeight, user }: SideBarProps) {
- {bottomNavItems.map((item, index) => ( - - + + {bottomNavItems.map((item, index) => { + const isActionOnly = !item.href; + const isInternal = !!item.href && item.href.startsWith("/"); + + const content = ( + <> {!!item.icon && ( )} - - - ))} + + ); + + const commonClassName = classNames( + "text-left", + "[&[aria-current='page']]:bg-emphasis text-default justify-right group flex items-center rounded-md px-2 py-1.5 text-sm font-medium transition", + "[&[aria-current='page']]:text-emphasis mt-0.5 w-full text-sm", + isLocaleReady ? "hover:bg-emphasis hover:text-emphasis" : "", + index === 0 && "mt-3" + ); + + return ( + + {isActionOnly ? ( + + ) : isInternal ? ( + + {content} + + ) : ( + + {content} + + )} + + ); + })} + {!IS_VISUAL_REGRESSION_TESTING && } )} From 9ee899c81d4c0b677b5dd2f7eece0e9e320df35c Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 10:30:53 +0100 Subject: [PATCH 37/73] revert: useBottomNavItems.ts --- packages/features/shell/useBottomNavItems.ts | 75 +++++++------------- 1 file changed, 24 insertions(+), 51 deletions(-) diff --git a/packages/features/shell/useBottomNavItems.ts b/packages/features/shell/useBottomNavItems.ts index 6c2ba18a93d3a0..cc1fe754a87ca5 100644 --- a/packages/features/shell/useBottomNavItems.ts +++ b/packages/features/shell/useBottomNavItems.ts @@ -1,7 +1,8 @@ import type { User as UserAuth } from "next-auth"; +import posthog from "posthog-js"; +import { useHasActiveTeamPlanAsOwner } from "@calcom/features/billing/hooks/useHasPaidPlan"; import { IS_DUB_REFERRALS_ENABLED } from "@calcom/lib/constants"; -import { useHasActiveTeamPlanAsOwner } from "@calcom/lib/hooks/useHasPaidPlan"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import { showToast } from "@calcom/ui/components/toast"; @@ -9,23 +10,11 @@ import { showToast } from "@calcom/ui/components/toast"; import { type NavigationItemType } from "./navigation/NavigationItem"; type BottomNavItemsProps = { - publicPageUrl: string; // can be empty/relative; we’ll normalize + publicPageUrl: string; isAdmin: boolean; user: UserAuth | null | undefined; }; -// Resolve any href (absolute or relative) to an absolute URL for SSR safety. -// Returns undefined if it can’t be resolved. -const withBase = (u?: string): string | undefined => { - if (!u) return undefined; - const base = process.env.NEXTAUTH_URL || process.env.NEXT_PUBLIC_WEBAPP_URL || "http://localhost:3000"; - try { - return new URL(u, base).toString(); - } catch { - return undefined; - } -}; - export function useBottomNavItems({ publicPageUrl, isAdmin, @@ -45,18 +34,12 @@ export function useBottomNavItems({ }, }); - const safePublicHref = withBase(publicPageUrl); - const safeReferHref = withBase("/refer"); - const safeImpersonationHref = withBase("/settings/admin/impersonation"); - const safeSettingsHref = withBase( - user?.org ? "/settings/organizations/profile" : "/settings/my-account/profile" - ); - return [ - // Action-only (no href) + // Render above to prevent layout shift as much as possible isTrial ? { name: "skip_trial", + href: "", isLoading: skipTeamTrialsMutation.isPending, icon: "clock", onClick: (e: { preventDefault: () => void }) => { @@ -65,53 +48,43 @@ export function useBottomNavItems({ }, } : null, - - // External public page link, only if we have a resolvable absolute URL - safePublicHref - ? { - name: "view_public_page", - href: safePublicHref, - icon: "external-link", - target: "_blank", - } - : null, - - // Action-only (no href) + { + name: "view_public_page", + href: publicPageUrl, + icon: "external-link", + target: "__blank", + }, { name: "copy_public_page_link", - icon: "copy", + href: "", onClick: (e: { preventDefault: () => void }) => { e.preventDefault(); - // Prefer resolved; fall back to raw input if clipboard is allowed - const toCopy = safePublicHref ?? publicPageUrl ?? ""; - if (typeof navigator !== "undefined" && navigator.clipboard?.writeText && toCopy) { - navigator.clipboard.writeText(toCopy); - showToast(t("link_copied"), "success"); - } else { - showToast(t("something_went_wrong"), "error"); - } + navigator.clipboard.writeText(publicPageUrl); + showToast(t("link_copied"), "success"); }, + icon: "copy", }, - IS_DUB_REFERRALS_ENABLED - ? safeReferHref && { + ? { name: "referral_text", - href: safeReferHref, + href: "/refer", icon: "gift", + onClick: () => { + posthog.capture("refer_and_earn_clicked"); + }, } : null, isAdmin - ? safeImpersonationHref && { + ? { name: "impersonation", - href: safeImpersonationHref, + href: "/settings/admin/impersonation", icon: "lock", } : null, - - safeSettingsHref && { + { name: "settings", - href: safeSettingsHref, + href: user?.org ? `/settings/organizations/profile` : "/settings/my-account/profile", icon: "settings", }, ].filter(Boolean) as NavigationItemType[]; From 8aec94b225af4efb52664f6c4358418ae8d731fd Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 10:40:26 +0100 Subject: [PATCH 38/73] seed e2e client --- scripts/seed.ts | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/scripts/seed.ts b/scripts/seed.ts index 27584c538d29f5..a6b6b747d38ec3 100644 --- a/scripts/seed.ts +++ b/scripts/seed.ts @@ -184,19 +184,34 @@ async function createPlatformAndSetupUser({ }, }); - const clientId = process.env.SEED_PLATFORM_OAUTH_CLIENT_ID; - const secret = process.env.SEED_PLATFORM_OAUTH_CLIENT_SECRET; - - if (clientId && secret) { + const exampleAppClientId = process.env.SEED_PLATFORM_OAUTH_CLIENT_ID; + const exampleAppClientSecret = process.env.SEED_PLATFORM_OAUTH_CLIENT_SECRET; + if (exampleAppClientId && exampleAppClientSecret) { await prisma.platformOAuthClient.create({ data: { - name: "Acme", + name: "examples-app", redirectUris: ["http://localhost:4321"], permissions: 1023, areEmailsEnabled: true, organizationId: team.id, - id: clientId, - secret, + id: exampleAppClientId, + secret: exampleAppClientSecret, + }, + }); + } + + const exampleAppClientIdE2e = process.env.SEED_PLATFORM_OAUTH_CLIENT_ID_E2E; + const exampleAppClientSecretE2e = process.env.SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E; + if (exampleAppClientIdE2e && exampleAppClientSecretE2e) { + await prisma.platformOAuthClient.create({ + data: { + name: "examples-app-e2e", + redirectUris: ["http://localhost:4322"], + permissions: 1023, + areEmailsEnabled: true, + organizationId: team.id, + id: exampleAppClientIdE2e, + secret: exampleAppClientSecretE2e, }, }); } From 08d8c4b8c70fb166f2f0443b9f119480b0dffff4 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 10:46:39 +0100 Subject: [PATCH 39/73] example e2e env --- packages/platform/examples/base/.env.e2e.example | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/platform/examples/base/.env.e2e.example b/packages/platform/examples/base/.env.e2e.example index c8e33a34e4601c..a427c43e08e93f 100644 --- a/packages/platform/examples/base/.env.e2e.example +++ b/packages/platform/examples/base/.env.e2e.example @@ -7,3 +7,4 @@ ORGANIZATION_ID= ATOMS_E2E_APPLE_ID= ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE= NEXT_PUBLIC_IS_E2E="1" +NODE_ENV="test" From 1fbd3d3f5bc94de164fc693481a433ecff464a2b Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 11:38:59 +0100 Subject: [PATCH 40/73] rename env ci variables --- .../platform/examples/base/playwright.config.ts | 13 +++++++------ turbo.json | 5 +++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 02379d328602c6..9c1e5ce8acd7cd 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -55,12 +55,13 @@ export default defineConfig({ env: { NEXT_PUBLIC_IS_E2E: "1", NODE_ENV: "test", - NEXT_PUBLIC_X_CAL_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID ?? "", - X_CAL_SECRET_KEY: process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET ?? "", - NEXT_PUBLIC_CALCOM_API_URL: process.env.ATOMS_E2E_API_URL ?? "", - VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED ?? "", - VITE_BOOKER_EMBED_API_URL: process.env.ATOMS_E2E_API_URL ?? "", - ORGANIZATION_ID: String(process.env.ATOMS_E2E_ORG_ID ?? ""), + NEXT_PUBLIC_X_CAL_ID: process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ?? "", + X_CAL_SECRET_KEY: process.env.ATOMS_E2E_OAUTH_CLIENT_SECRET_2025_12 ?? "", + NEXT_PUBLIC_CALCOM_API_URL: process.env.ATOMS_E2E_API_URL_2025_12 ?? "", + VITE_BOOKER_EMBED_OAUTH_CLIENT_ID: + process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED_2025_12 ?? "", + VITE_BOOKER_EMBED_API_URL: process.env.ATOMS_E2E_API_URL_2025_12 ?? "", + ORGANIZATION_ID: String(process.env.ATOMS_E2E_ORG_ID_2025_12 ?? ""), }, } : {}), diff --git a/turbo.json b/turbo.json index 3f7b08c1ccf6db..b08fd6a9c0ddba 100644 --- a/turbo.json +++ b/turbo.json @@ -10,6 +10,11 @@ "ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED", "ATOMS_E2E_OAUTH_CLIENT_SECRET", "ATOMS_E2E_ORG_ID", + "ATOMS_E2E_API_URL_2025_12", + "ATOMS_E2E_OAUTH_CLIENT_ID_2025_12", + "ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED_2025_12", + "ATOMS_E2E_OAUTH_CLIENT_SECRET_2025_12", + "ATOMS_E2E_ORG_ID_2025_12", "BASECAMP3_CLIENT_ID", "BASECAMP3_CLIENT_SECRET", "BASECAMP3_USER_AGENT", From 9e916235d56f08c8563a85b3a5b1071c7513ed3c Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 12:28:20 +0100 Subject: [PATCH 41/73] dont log managed test user email --- packages/platform/examples/base/global-teardown.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/platform/examples/base/global-teardown.ts b/packages/platform/examples/base/global-teardown.ts index 535cc2e080502d..96f66ac788ead2 100644 --- a/packages/platform/examples/base/global-teardown.ts +++ b/packages/platform/examples/base/global-teardown.ts @@ -35,12 +35,12 @@ async function globalTeardown() { }, }); if (deleteResponse.ok) { - console.log(`Deleted managed user: ${user.email}`); + console.log(`Deleted managed user: with id = ${user.id}`); } else { - console.error(`Failed to delete user ${user.email}:`, await deleteResponse.text()); + console.error(`Failed to delete user with id = ${user.id}:`, await deleteResponse.text()); } } catch (error) { - console.error(`Error deleting user ${user.email}:`, error); + console.error(`Error deleting user with id = ${user.id}:`, error); } } } else { From cbf24ca4e2faff5d74f4f80b799caa352b9d34f9 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 12:32:20 +0100 Subject: [PATCH 42/73] refactor: updatedAt for test schema --- packages/platform/examples/base/prisma/schema.test.prisma | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/examples/base/prisma/schema.test.prisma b/packages/platform/examples/base/prisma/schema.test.prisma index 04752bcfb00c82..83cf030bd46052 100644 --- a/packages/platform/examples/base/prisma/schema.test.prisma +++ b/packages/platform/examples/base/prisma/schema.test.prisma @@ -15,5 +15,5 @@ model User { refreshToken String? @unique(map: "TestUser_refreshToken_key") accessToken String? @unique(map: "TestUser_accessToken_key") createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) + updatedAt DateTime @updatedAt } \ No newline at end of file From 77086cf45e0192c21c6e1303d1e67f1d1b488384 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 12:40:17 +0100 Subject: [PATCH 43/73] fix: onclick sidebar item --- packages/features/shell/SideBar.tsx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/features/shell/SideBar.tsx b/packages/features/shell/SideBar.tsx index 8616235edf3371..f9bf1fd9881eca 100644 --- a/packages/features/shell/SideBar.tsx +++ b/packages/features/shell/SideBar.tsx @@ -122,19 +122,13 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { color="minimal" onClick={() => window.history.back()} className="todesktop:block hover:text-emphasis text-subtle group hidden text-sm font-medium"> - + {!!user?.org && (
@@ -207,7 +201,11 @@ export function SideBar({ bannersHeight, user }: SideBarProps) { {content} ) : isInternal ? ( - + {content} ) : ( From 62438e4ceebaff9e81d0d403cdf96c7d3a5ef2dc Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 12:51:18 +0100 Subject: [PATCH 44/73] retrigger db setup in ci --- packages/prisma/schema.prisma | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 2446305bf286bf..9a8c878d658978 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -1977,10 +1977,10 @@ model PlatformOAuthClient { bookingRedirectUri String? bookingCancelRedirectUri String? bookingRescheduleRedirectUri String? + areEmailsEnabled Boolean @default(false) + areDefaultEventTypesEnabled Boolean @default(true) - areEmailsEnabled Boolean @default(false) - areDefaultEventTypesEnabled Boolean @default(true) - areCalendarEventsEnabled Boolean @default(true) + areCalendarEventsEnabled Boolean @default(true) createdAt DateTime @default(now()) } From 6a416da94842f4ef16b4888fba174f21b24d0fcc Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 13:50:30 +0100 Subject: [PATCH 45/73] fix: e2e workflow env --- .github/workflows/e2e-atoms.yml | 26 +++++++++---------- .../examples/base/playwright.config.ts | 3 +++ turbo.json | 2 ++ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index 423c2864c04f86..be5eefb3bf0a2e 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -5,10 +5,10 @@ on: branches: - main paths: - - 'packages/platform/atoms/**' - - 'packages/platform/examples/base/**' - - 'apps/api/v2/**' - - '.github/workflows/e2e-atoms.yml' + - "packages/platform/atoms/**" + - "packages/platform/examples/base/**" + - "apps/api/v2/**" + - ".github/workflows/e2e-atoms.yml" permissions: actions: write @@ -40,14 +40,14 @@ env: NODE_ENV: ${{ vars.CI_NODE_ENV }} ## atoms e2e examples app env - ATOMS_E2E_OAUTH_CLIENT_ID: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID }} - ATOMS_E2E_OAUTH_CLIENT_SECRET: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_SECRET }} - ATOMS_E2E_API_URL: ${{ secrets.ATOMS_E2E_API_URL }} - ATOMS_E2E_ORG_ID: ${{ secrets.ATOMS_E2E_ORG_ID }} - ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED }} - ATOMS_E2E_APPLE_ID: ${{ secrets.ATOMS_E2E_APPLE_ID }} - ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE: ${{ secrets.ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE }} - + ATOMS_E2E_OAUTH_CLIENT_ID_2025_12: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 }} + ATOMS_E2E_OAUTH_CLIENT_SECRET_2025_12: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_SECRET_2025_12 }} + ATOMS_E2E_API_URL_2025_12: ${{ secrets.ATOMS_E2E_API_URL_2025_12 }} + ATOMS_E2E_ORG_ID_2025_12: ${{ secrets.ATOMS_E2E_ORG_ID_2025_12 }} + ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED_2025_12: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED_2025_12 }} + ATOMS_E2E_APPLE_ID_2025_12: ${{ secrets.ATOMS_E2E_APPLE_ID_2025_12 }} + ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE_2025_12: ${{ secrets.ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE_2025_12 }} + ## env variables needed for both api v2 and examples app DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }} DATABASE_URL: ${{ secrets.CI_DATABASE_URL }} @@ -104,7 +104,7 @@ jobs: yarn dev:no-docker & API_PID=$! echo "API_PID=$API_PID" >> $GITHUB_ENV - + # Wait for API to be ready echo "Waiting for API v2 to be ready on port ${{ vars.CI_API_V2_PORT }}..." timeout 300 bash -c 'until curl -f http://localhost:${{ vars.CI_API_V2_PORT }}/health > /dev/null 2>&1; do sleep 2; done' diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 9c1e5ce8acd7cd..fe2272d5604319 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -62,6 +62,9 @@ export default defineConfig({ process.env.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED_2025_12 ?? "", VITE_BOOKER_EMBED_API_URL: process.env.ATOMS_E2E_API_URL_2025_12 ?? "", ORGANIZATION_ID: String(process.env.ATOMS_E2E_ORG_ID_2025_12 ?? ""), + ATOMS_E2E_APPLE_ID: process.env.ATOMS_E2E_APPLE_ID_2025_12 ?? "", + ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE: + process.env.ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE_2025_12 ?? "", }, } : {}), diff --git a/turbo.json b/turbo.json index b08fd6a9c0ddba..19ff99248edc5b 100644 --- a/turbo.json +++ b/turbo.json @@ -14,6 +14,8 @@ "ATOMS_E2E_OAUTH_CLIENT_ID_2025_12", "ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED_2025_12", "ATOMS_E2E_OAUTH_CLIENT_SECRET_2025_12", + "ATOMS_E2E_APPLE_ID_2025_12", + "ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE_2025_12", "ATOMS_E2E_ORG_ID_2025_12", "BASECAMP3_CLIENT_ID", "BASECAMP3_CLIENT_SECRET", From 5829d263364c846d4ecb55d3e620b2b15ce0fcba Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 15:15:56 +0100 Subject: [PATCH 46/73] retrigger e2e --- packages/prisma/schema.prisma | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 9a8c878d658978..afcfd1ae73a7b3 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -1974,13 +1974,13 @@ model PlatformOAuthClient { authorizationTokens PlatformAuthorizationToken[] webhook Webhook[] - bookingRedirectUri String? + bookingRedirectUri String? + bookingCancelRedirectUri String? bookingRescheduleRedirectUri String? areEmailsEnabled Boolean @default(false) areDefaultEventTypesEnabled Boolean @default(true) - - areCalendarEventsEnabled Boolean @default(true) + areCalendarEventsEnabled Boolean @default(true) createdAt DateTime @default(now()) } From e1ce5adcb3c94d9426ed9162f16be91a034b1050 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 15:30:33 +0100 Subject: [PATCH 47/73] chore: check CI env value --- packages/platform/examples/base/playwright.config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index fe2272d5604319..94a0a53515dadc 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -2,6 +2,8 @@ import { defineConfig, devices } from "@playwright/test"; import dotenv from "dotenv"; import path from "path"; +console.log("asap the value of process.env.CI", process.env.CI); + if (!process.env.CI) { dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); } From 5d71101188f21932ce3f6011bb49a831f8b5740c Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 15:44:07 +0100 Subject: [PATCH 48/73] debug --- packages/platform/examples/base/playwright.config.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 94a0a53515dadc..9bc012702019b3 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -2,12 +2,20 @@ import { defineConfig, devices } from "@playwright/test"; import dotenv from "dotenv"; import path from "path"; -console.log("asap the value of process.env.CI", process.env.CI); +console.log( + `1 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, + process.env.NEXT_PUBLIC_X_CAL_ID +); if (!process.env.CI) { dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); } +console.log( + `2 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, + process.env.NEXT_PUBLIC_X_CAL_ID +); + const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; From d567be0284dd8d388cf3900458f5126dcb320d82 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 16:26:10 +0100 Subject: [PATCH 49/73] try to debug e2e --- .../examples/base/playwright.config.ts | 8 ++++ .../base/src/pages/api/managed-user.ts | 47 +++++++++++-------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 9bc012702019b3..429c8dbba11ff4 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -6,6 +6,10 @@ console.log( `1 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, process.env.NEXT_PUBLIC_X_CAL_ID ); +console.log( + `2 asap ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, + process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 +); if (!process.env.CI) { dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); @@ -15,6 +19,10 @@ console.log( `2 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, process.env.NEXT_PUBLIC_X_CAL_ID ); +console.log( + `2 asap ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, + process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 +); const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index 935f2cd9958d3e..4d9f295dafe41c 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -19,14 +19,23 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar }, }); + console.log( + `4 wiz NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, + process.env.NEXT_PUBLIC_X_CAL_ID + ); + console.log( + `4 wiz ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, + process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 + ); + const managedUserResponse = await fetch( - // eslint-disable-next-line turbo/no-undeclared-env-vars + `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/oauth-clients/${process.env.NEXT_PUBLIC_X_CAL_ID}/users`, { method: "POST", headers: { "Content-Type": "application/json", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", }, body: JSON.stringify({ @@ -141,15 +150,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< async function createTeam(orgId: number, name: string) { const response = await fetch( - // eslint-disable-next-line turbo/no-undeclared-env-vars + `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/teams`, { method: "POST", headers: { "Content-Type": "application/json", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -165,15 +174,15 @@ async function createTeam(orgId: number, name: string) { async function createOrgTeamMembershipMember(orgId: number, teamId: number, userId: number) { await fetch( - // eslint-disable-next-line turbo/no-undeclared-env-vars + `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/teams/${teamId}/memberships`, { method: "POST", headers: { "Content-Type": "application/json", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -187,15 +196,15 @@ async function createOrgTeamMembershipMember(orgId: number, teamId: number, user async function createOrgMembershipAdmin(orgId: number, userId: number) { await fetch( - // eslint-disable-next-line turbo/no-undeclared-env-vars + `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/memberships`, { method: "POST", headers: { "Content-Type": "application/json", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -209,15 +218,15 @@ async function createOrgMembershipAdmin(orgId: number, userId: number) { async function createCollectiveEventType(orgId: number, teamId: number, userIds: number[]) { await fetch( - // eslint-disable-next-line turbo/no-undeclared-env-vars + `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/teams/${teamId}/event-types`, { method: "POST", headers: { "Content-Type": "application/json", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -233,15 +242,15 @@ async function createCollectiveEventType(orgId: number, teamId: number, userIds: async function createRoundRobinEventType(orgId: number, teamId: number, userIds: number[]) { await fetch( - // eslint-disable-next-line turbo/no-undeclared-env-vars + `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/teams/${teamId}/event-types`, { method: "POST", headers: { "Content-Type": "application/json", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - // eslint-disable-next-line turbo/no-undeclared-env-vars + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -261,13 +270,13 @@ async function createDefaultSchedule(accessToken: string) { const isDefault = true; const response = await fetch( - // eslint-disable-next-line turbo/no-undeclared-env-vars + `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/schedules`, { method: "POST", headers: { "Content-Type": "application/json", - // eslint-disable-next-line turbo/no-undeclared-env-vars + Authorization: `Bearer ${accessToken}`, }, body: JSON.stringify({ From e8de71d8f154f9a72fe643fa5b818d9a38f734f3 Mon Sep 17 00:00:00 2001 From: supalarry Date: Wed, 3 Dec 2025 17:05:15 +0100 Subject: [PATCH 50/73] try to debug e2e --- .../base/src/pages/api/managed-user.ts | 105 ++++++++---------- 1 file changed, 46 insertions(+), 59 deletions(-) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index 4d9f295dafe41c..2acbc1aeb1da3f 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -19,23 +19,13 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar }, }); - console.log( - `4 wiz NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, - process.env.NEXT_PUBLIC_X_CAL_ID - ); - console.log( - `4 wiz ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, - process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 - ); - const managedUserResponse = await fetch( - `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/oauth-clients/${process.env.NEXT_PUBLIC_X_CAL_ID}/users`, { method: "POST", headers: { "Content-Type": "application/json", - + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", }, body: JSON.stringify({ @@ -82,6 +72,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< }); } + console.log( + `4 wiz NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, + process.env.NEXT_PUBLIC_X_CAL_ID + ); + console.log( + `4 wiz ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, + process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 + ); + const managedUserResponseOne = await createUserWithDefaultSchedule( emailOne, "Keith", @@ -150,15 +149,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< async function createTeam(orgId: number, name: string) { const response = await fetch( - `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/teams`, { method: "POST", headers: { "Content-Type": "application/json", - + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -174,15 +172,14 @@ async function createTeam(orgId: number, name: string) { async function createOrgTeamMembershipMember(orgId: number, teamId: number, userId: number) { await fetch( - `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/teams/${teamId}/memberships`, { method: "POST", headers: { "Content-Type": "application/json", - + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -195,38 +192,33 @@ async function createOrgTeamMembershipMember(orgId: number, teamId: number, user } async function createOrgMembershipAdmin(orgId: number, userId: number) { - await fetch( - - `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/memberships`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - - [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - - [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", - }, - body: JSON.stringify({ - userId, - accepted: true, - role: "ADMIN", - }), - } - ); + await fetch(`${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/memberships`, { + method: "POST", + headers: { + "Content-Type": "application/json", + + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", + + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", + }, + body: JSON.stringify({ + userId, + accepted: true, + role: "ADMIN", + }), + }); } async function createCollectiveEventType(orgId: number, teamId: number, userIds: number[]) { await fetch( - `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/teams/${teamId}/event-types`, { method: "POST", headers: { "Content-Type": "application/json", - + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -242,15 +234,14 @@ async function createCollectiveEventType(orgId: number, teamId: number, userIds: async function createRoundRobinEventType(orgId: number, teamId: number, userIds: number[]) { await fetch( - `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/organizations/${orgId}/teams/${teamId}/event-types`, { method: "POST", headers: { "Content-Type": "application/json", - + [X_CAL_SECRET_KEY]: process.env.X_CAL_SECRET_KEY ?? "", - + [X_CAL_CLIENT_ID]: process.env.NEXT_PUBLIC_X_CAL_ID ?? "", }, body: JSON.stringify({ @@ -269,23 +260,19 @@ async function createDefaultSchedule(accessToken: string) { const timeZone = "Europe/London"; const isDefault = true; - const response = await fetch( - - `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/schedules`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - - Authorization: `Bearer ${accessToken}`, - }, - body: JSON.stringify({ - name, - timeZone, - isDefault, - }), - } - ); + const response = await fetch(`${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/schedules`, { + method: "POST", + headers: { + "Content-Type": "application/json", + + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ + name, + timeZone, + isDefault, + }), + }); const schedule = await response.json(); return schedule; From cba482a9c7f744bafb6ddd7e4921d341f92ea051 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 09:14:33 +0100 Subject: [PATCH 51/73] try to fix key constraint --- packages/platform/examples/base/package.json | 3 ++- .../examples/base/playwright.config.ts | 20 +------------------ 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/packages/platform/examples/base/package.json b/packages/platform/examples/base/package.json index 13c49a3656d4be..8ea04d22300d97 100644 --- a/packages/platform/examples/base/package.json +++ b/packages/platform/examples/base/package.json @@ -12,7 +12,8 @@ "test:e2e:ui": "playwright test --ui", "db:push:test": "prisma db push --schema=prisma/schema.test.prisma", "db:generate:test": "prisma generate --schema=prisma/schema.test.prisma", - "db:reset:test": "rm -f prisma/test.db && yarn db:push:test" + "db:reset:test": "rm -f prisma/test.db && yarn db:push:test", + "db:reset:remove": "echo 'Removing test database file...' && rm -f prisma/test.db" }, "dependencies": { "@calcom/atoms": "workspace:*", diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 429c8dbba11ff4..c9580bca848ef1 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -2,28 +2,10 @@ import { defineConfig, devices } from "@playwright/test"; import dotenv from "dotenv"; import path from "path"; -console.log( - `1 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, - process.env.NEXT_PUBLIC_X_CAL_ID -); -console.log( - `2 asap ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, - process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 -); - if (!process.env.CI) { dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); } -console.log( - `2 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, - process.env.NEXT_PUBLIC_X_CAL_ID -); -console.log( - `2 asap ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, - process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 -); - const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; @@ -63,7 +45,7 @@ export default defineConfig({ ], webServer: { command: process.env.CI - ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && yarn db:generate:test && yarn db:reset:test && yarn dev:e2e` + ? `yarn db:reset:remove &&yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && yarn db:generate:test && yarn db:reset:test && yarn dev:e2e` : `yarn db:generate:test && yarn db:reset:test && yarn dev:e2e`, url: "http://localhost:4322", timeout: 600_000, From 4f2ffbfcb4e573a7a2798fffa0b5089df373af89 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 09:31:01 +0100 Subject: [PATCH 52/73] Revert "try to fix key constraint" This reverts commit cba482a9c7f744bafb6ddd7e4921d341f92ea051. --- packages/platform/examples/base/package.json | 3 +-- .../examples/base/playwright.config.ts | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/platform/examples/base/package.json b/packages/platform/examples/base/package.json index 8ea04d22300d97..13c49a3656d4be 100644 --- a/packages/platform/examples/base/package.json +++ b/packages/platform/examples/base/package.json @@ -12,8 +12,7 @@ "test:e2e:ui": "playwright test --ui", "db:push:test": "prisma db push --schema=prisma/schema.test.prisma", "db:generate:test": "prisma generate --schema=prisma/schema.test.prisma", - "db:reset:test": "rm -f prisma/test.db && yarn db:push:test", - "db:reset:remove": "echo 'Removing test database file...' && rm -f prisma/test.db" + "db:reset:test": "rm -f prisma/test.db && yarn db:push:test" }, "dependencies": { "@calcom/atoms": "workspace:*", diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index c9580bca848ef1..429c8dbba11ff4 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -2,10 +2,28 @@ import { defineConfig, devices } from "@playwright/test"; import dotenv from "dotenv"; import path from "path"; +console.log( + `1 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, + process.env.NEXT_PUBLIC_X_CAL_ID +); +console.log( + `2 asap ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, + process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 +); + if (!process.env.CI) { dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); } +console.log( + `2 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, + process.env.NEXT_PUBLIC_X_CAL_ID +); +console.log( + `2 asap ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, + process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 +); + const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; @@ -45,7 +63,7 @@ export default defineConfig({ ], webServer: { command: process.env.CI - ? `yarn db:reset:remove &&yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && yarn db:generate:test && yarn db:reset:test && yarn dev:e2e` + ? `yarn workspace @calcom/atoms dev-on && yarn workspace @calcom/atoms build && yarn db:generate:test && yarn db:reset:test && yarn dev:e2e` : `yarn db:generate:test && yarn db:reset:test && yarn dev:e2e`, url: "http://localhost:4322", timeout: 600_000, From 6a70eb1f89a8f8b3d3ee182c822afc245b45af0c Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 09:41:06 +0100 Subject: [PATCH 53/73] try to debug --- .../services/oauth-clients-users.service.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts b/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts index 27aaec6758cde7..233ec746b1e32a 100644 --- a/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts +++ b/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts @@ -83,6 +83,14 @@ export class OAuthClientUsersService { const { accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt } = await this.tokensRepository.createOAuthTokens(oAuthClientId, user.id); + console.log("asap first 15 characters of access token:"); + accessToken + .slice(0, 15) + .split("") + .forEach((char, index) => { + console.log(`[${index}]: ${char}`); + }); + if (oAuthClient.areDefaultEventTypesEnabled) { await this.eventTypesService.createUserDefaultEventTypes(user.id); } @@ -95,7 +103,7 @@ export class OAuthClientUsersService { try { this.logger.log(`Setting default calendars in db for user with id ${user.id}`); await this.calendarsService.getCalendars(user.id); - } catch (err) { + } catch { this.logger.error(`Could not get calendars of new managed user with id ${user.id}`); } From 26c20eebeb26741ee1bbdad0234cc8bbd4b804d1 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 09:51:06 +0100 Subject: [PATCH 54/73] Revert "try to debug" This reverts commit 6a70eb1f89a8f8b3d3ee182c822afc245b45af0c. --- .../services/oauth-clients-users.service.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts b/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts index 233ec746b1e32a..27aaec6758cde7 100644 --- a/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts +++ b/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts @@ -83,14 +83,6 @@ export class OAuthClientUsersService { const { accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt } = await this.tokensRepository.createOAuthTokens(oAuthClientId, user.id); - console.log("asap first 15 characters of access token:"); - accessToken - .slice(0, 15) - .split("") - .forEach((char, index) => { - console.log(`[${index}]: ${char}`); - }); - if (oAuthClient.areDefaultEventTypesEnabled) { await this.eventTypesService.createUserDefaultEventTypes(user.id); } @@ -103,7 +95,7 @@ export class OAuthClientUsersService { try { this.logger.log(`Setting default calendars in db for user with id ${user.id}`); await this.calendarsService.getCalendars(user.id); - } catch { + } catch (err) { this.logger.error(`Could not get calendars of new managed user with id ${user.id}`); } From 31408d55a3100eab3313a6cddf7bbda74e40d7c4 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 09:51:39 +0100 Subject: [PATCH 55/73] delete logs --- .../examples/base/playwright.config.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 429c8dbba11ff4..fe2272d5604319 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -2,28 +2,10 @@ import { defineConfig, devices } from "@playwright/test"; import dotenv from "dotenv"; import path from "path"; -console.log( - `1 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, - process.env.NEXT_PUBLIC_X_CAL_ID -); -console.log( - `2 asap ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, - process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 -); - if (!process.env.CI) { dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); } -console.log( - `2 asap NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, - process.env.NEXT_PUBLIC_X_CAL_ID -); -console.log( - `2 asap ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, - process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 -); - const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; From f20ee84f261b2bff8ef74218459b15685dd26e76 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 09:53:12 +0100 Subject: [PATCH 56/73] remove mapping --- .../platform/examples/base/prisma/schema.test.prisma | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/platform/examples/base/prisma/schema.test.prisma b/packages/platform/examples/base/prisma/schema.test.prisma index 83cf030bd46052..f6fdeb9e8c7896 100644 --- a/packages/platform/examples/base/prisma/schema.test.prisma +++ b/packages/platform/examples/base/prisma/schema.test.prisma @@ -8,12 +8,12 @@ datasource testDb { } model User { id Int @id @default(autoincrement()) - email String @unique(map: "TestUser_email_key") + email String @unique name String? - calcomUserId Int? @unique(map: "TestUser_calcomUserId_key") - calcomUsername String? @unique(map: "TestUser_calcomUsername_key") - refreshToken String? @unique(map: "TestUser_refreshToken_key") - accessToken String? @unique(map: "TestUser_accessToken_key") + calcomUserId Int? @unique + calcomUsername String? @unique + refreshToken String? @unique + accessToken String? @unique createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } \ No newline at end of file From 93adc3f5a5ee879a6b7a4b1c6585237dbfba51bb Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 09:54:16 +0100 Subject: [PATCH 57/73] have 1 worker --- packages/platform/examples/base/playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index fe2272d5604319..8c399d646f2465 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -14,7 +14,7 @@ const headless = !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS; export default defineConfig({ forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, - workers: process.env.CI ? 1 : undefined, + workers: 1, timeout: DEFAULT_TEST_TIMEOUT, fullyParallel: false, globalTeardown: require.resolve("./global-teardown"), From d04256a1c9abb5473167717d5ad6d3e20a6bbbef Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 10:02:27 +0100 Subject: [PATCH 58/73] revert thos - trying to debug --- .../examples/base/src/pages/api/managed-user.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index 2acbc1aeb1da3f..eae0a1a6e2aeed 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -38,6 +38,13 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar const managedUserResponseBody = await managedUserResponse.json(); + const debugExistingUsers = await prisma.user.findMany(); + if (debugExistingUsers.length > 0) { + throw new Error( + `asap User with calcomUserId ${JSON.stringify(debugExistingUsers, null, 2)} already exists` + ); + } + await prisma.user.update({ data: { refreshToken: (managedUserResponseBody.data?.refreshToken as string) ?? "", @@ -72,15 +79,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< }); } - console.log( - `4 wiz NEXT_PUBLIC_X_CAL_ID ${process.env.NEXT_PUBLIC_X_CAL_ID}`, - process.env.NEXT_PUBLIC_X_CAL_ID - ); - console.log( - `4 wiz ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 ${process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12}`, - process.env.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 - ); - const managedUserResponseOne = await createUserWithDefaultSchedule( emailOne, "Keith", From 356b3bec65ff703c3d208b76d2d5c6b299ee0e71 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 10:14:41 +0100 Subject: [PATCH 59/73] debug --- .../examples/base/src/pages/api/managed-user.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index eae0a1a6e2aeed..f4c7c332ba21a7 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -38,10 +38,16 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar const managedUserResponseBody = await managedUserResponse.json(); - const debugExistingUsers = await prisma.user.findMany(); + const debugExistingUsers = await prisma.user.findMany({ + where: { accessToken: managedUserResponseBody.data?.accessToken }, + }); if (debugExistingUsers.length > 0) { throw new Error( - `asap User with calcomUserId ${JSON.stringify(debugExistingUsers, null, 2)} already exists` + `asap User with accessToken ${JSON.stringify( + debugExistingUsers, + null, + 2 + )} already exists so cant create new one: ${JSON.stringify(managedUserResponseBody.data, null, 2)}` ); } From bddd60a2e0fa7be6350355d4ea0a35f84ddcbc28 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 10:41:24 +0100 Subject: [PATCH 60/73] debug --- .../examples/base/src/pages/api/managed-user.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index f4c7c332ba21a7..fbee14e08ff24a 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -37,6 +37,16 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar ); const managedUserResponseBody = await managedUserResponse.json(); + const shouldThrow = true; + if (shouldThrow) { + throw new Error( + `asap managedUserResponseBody and has access token: ${JSON.stringify( + managedUserResponseBody.data, + null, + 2 + )}` + ); + } const debugExistingUsers = await prisma.user.findMany({ where: { accessToken: managedUserResponseBody.data?.accessToken }, From 92bf962a054d34f5da21319e6416619d1ebe4c71 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 10:56:48 +0100 Subject: [PATCH 61/73] debug --- .../examples/base/src/pages/api/managed-user.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index fbee14e08ff24a..2167590ac01463 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -40,11 +40,14 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar const shouldThrow = true; if (shouldThrow) { throw new Error( - `asap managedUserResponseBody and has access token: ${JSON.stringify( - managedUserResponseBody.data, - null, - 2 - )}` + JSON.stringify({ + email: email, + calcomUserId: managedUserResponseBody.data?.user.id, + calcomUsername: managedUserResponseBody.data?.user.username, + refreshToken: managedUserResponseBody.data?.refreshToken, + accessToken: managedUserResponseBody.data?.accessToken, + testkey: "asd", + }) ); } From c1c5b3a4a2fc94fd089028145ebcd92d01e3b5c3 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 11:11:39 +0100 Subject: [PATCH 62/73] revert thos - trying to debug --- .../platform/examples/base/src/pages/api/managed-user.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index 2167590ac01463..52b3beb5d7db6a 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -42,10 +42,10 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar throw new Error( JSON.stringify({ email: email, - calcomUserId: managedUserResponseBody.data?.user.id, - calcomUsername: managedUserResponseBody.data?.user.username, - refreshToken: managedUserResponseBody.data?.refreshToken, - accessToken: managedUserResponseBody.data?.accessToken, + calcomUserId: managedUserResponseBody.data?.user.id || "not-defined", + calcomUsername: managedUserResponseBody.data?.user.username || "not-defined", + refreshToken: managedUserResponseBody.data?.refreshToken || "not-defined", + accessToken: managedUserResponseBody.data?.accessToken || "not-defined", testkey: "asd", }) ); From d1960bb622c34015bdbce17e83547095be8abdf0 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 11:40:24 +0100 Subject: [PATCH 63/73] debug --- .../examples/base/src/pages/api/managed-user.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index 52b3beb5d7db6a..7288fa9373016f 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -19,6 +19,17 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar }, }); + throw new Error( + JSON.stringify( + { + NEXT_PUBLIC_CALCOM_API_URL: process.env.NEXT_PUBLIC_CALCOM_API_URL, + NEXT_PUBLIC_X_CAL_ID: process.env.NEXT_PUBLIC_X_CAL_ID, + NEXT_PUBLIC_X_CAL_ID_SHORT: process.env.NEXT_PUBLIC_X_CAL_ID?.substr(0, 5), + }, + null, + 2 + ) + ); const managedUserResponse = await fetch( `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/oauth-clients/${process.env.NEXT_PUBLIC_X_CAL_ID}/users`, { From 619c592ba4c59000b5143680cd5a818af20be154 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 12:02:00 +0100 Subject: [PATCH 64/73] try running e2e without dotenv --- .../examples/base/playwright.config.ts | 11 +-- .../base/src/pages/api/managed-user.ts | 74 +++++++++---------- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 8c399d646f2465..583903a24cf171 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -1,10 +1,11 @@ import { defineConfig, devices } from "@playwright/test"; -import dotenv from "dotenv"; -import path from "path"; -if (!process.env.CI) { - dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); -} +// import dotenv from "dotenv"; +// import path from "path"; + +// if (!process.env.CI) { +// dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); +// } const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index 7288fa9373016f..49d2ddaf313b4f 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -19,17 +19,17 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar }, }); - throw new Error( - JSON.stringify( - { - NEXT_PUBLIC_CALCOM_API_URL: process.env.NEXT_PUBLIC_CALCOM_API_URL, - NEXT_PUBLIC_X_CAL_ID: process.env.NEXT_PUBLIC_X_CAL_ID, - NEXT_PUBLIC_X_CAL_ID_SHORT: process.env.NEXT_PUBLIC_X_CAL_ID?.substr(0, 5), - }, - null, - 2 - ) - ); + // throw new Error( + // JSON.stringify( + // { + // NEXT_PUBLIC_CALCOM_API_URL: process.env.NEXT_PUBLIC_CALCOM_API_URL, + // NEXT_PUBLIC_X_CAL_ID: process.env.NEXT_PUBLIC_X_CAL_ID, + // NEXT_PUBLIC_X_CAL_ID_SHORT: process.env.NEXT_PUBLIC_X_CAL_ID?.substr(0, 5), + // }, + // null, + // 2 + // ) + // ); const managedUserResponse = await fetch( `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/oauth-clients/${process.env.NEXT_PUBLIC_X_CAL_ID}/users`, { @@ -48,32 +48,32 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar ); const managedUserResponseBody = await managedUserResponse.json(); - const shouldThrow = true; - if (shouldThrow) { - throw new Error( - JSON.stringify({ - email: email, - calcomUserId: managedUserResponseBody.data?.user.id || "not-defined", - calcomUsername: managedUserResponseBody.data?.user.username || "not-defined", - refreshToken: managedUserResponseBody.data?.refreshToken || "not-defined", - accessToken: managedUserResponseBody.data?.accessToken || "not-defined", - testkey: "asd", - }) - ); - } - - const debugExistingUsers = await prisma.user.findMany({ - where: { accessToken: managedUserResponseBody.data?.accessToken }, - }); - if (debugExistingUsers.length > 0) { - throw new Error( - `asap User with accessToken ${JSON.stringify( - debugExistingUsers, - null, - 2 - )} already exists so cant create new one: ${JSON.stringify(managedUserResponseBody.data, null, 2)}` - ); - } + // const shouldThrow = true; + // if (shouldThrow) { + // throw new Error( + // JSON.stringify({ + // email: email, + // calcomUserId: managedUserResponseBody.data?.user.id || "not-defined", + // calcomUsername: managedUserResponseBody.data?.user.username || "not-defined", + // refreshToken: managedUserResponseBody.data?.refreshToken || "not-defined", + // accessToken: managedUserResponseBody.data?.accessToken || "not-defined", + // testkey: "asd", + // }) + // ); + // } + + // const debugExistingUsers = await prisma.user.findMany({ + // where: { accessToken: managedUserResponseBody.data?.accessToken }, + // }); + // if (debugExistingUsers.length > 0) { + // throw new Error( + // `asap User with accessToken ${JSON.stringify( + // debugExistingUsers, + // null, + // 2 + // )} already exists so cant create new one: ${JSON.stringify(managedUserResponseBody.data, null, 2)}` + // ); + // } await prisma.user.update({ data: { From 411ff39da3898568148b7ca555b52d26b691ffd5 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 12:13:59 +0100 Subject: [PATCH 65/73] uncomment --- packages/platform/examples/base/playwright.config.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/platform/examples/base/playwright.config.ts b/packages/platform/examples/base/playwright.config.ts index 583903a24cf171..8c399d646f2465 100644 --- a/packages/platform/examples/base/playwright.config.ts +++ b/packages/platform/examples/base/playwright.config.ts @@ -1,11 +1,10 @@ import { defineConfig, devices } from "@playwright/test"; +import dotenv from "dotenv"; +import path from "path"; -// import dotenv from "dotenv"; -// import path from "path"; - -// if (!process.env.CI) { -// dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); -// } +if (!process.env.CI) { + dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); +} const DEFAULT_EXPECT_TIMEOUT = process.env.CI ? 30000 : 120000; const DEFAULT_TEST_TIMEOUT = process.env.CI ? 60000 : 240000; From 617e483c2879cbffd5c7a06d49930b27f7bb589a Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 12:25:45 +0100 Subject: [PATCH 66/73] debug --- .../base/src/pages/api/managed-user.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index 49d2ddaf313b4f..1ecc69e0a07b6c 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -48,6 +48,24 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar ); const managedUserResponseBody = await managedUserResponse.json(); + + if (!managedUserResponse.ok) { + throw new Error( + `Failed to create managed user: ${managedUserResponse.status} ${ + managedUserResponse.statusText + }\n${JSON.stringify(managedUserResponseBody, null, 2)}` + ); + } + + if (!managedUserResponseBody.data?.accessToken) { + throw new Error( + `Managed user API returned success but no accessToken:\n${JSON.stringify( + managedUserResponseBody, + null, + 2 + )}` + ); + } // const shouldThrow = true; // if (shouldThrow) { // throw new Error( From 2d58c36c81f908d77ac3d6a1af8c4f6144685cdb Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 12:43:28 +0100 Subject: [PATCH 67/73] fix: seeding db --- .github/workflows/e2e-api-v2.yml | 5 ++ .github/workflows/e2e-atoms.yml | 6 +++ .../base/src/pages/api/managed-user.ts | 47 ------------------- scripts/seed.ts | 6 +++ 4 files changed, 17 insertions(+), 47 deletions(-) diff --git a/.github/workflows/e2e-api-v2.yml b/.github/workflows/e2e-api-v2.yml index 254d6c90858351..96c88b748e650c 100644 --- a/.github/workflows/e2e-api-v2.yml +++ b/.github/workflows/e2e-api-v2.yml @@ -27,6 +27,11 @@ env: VAPID_PRIVATE_KEY: ${{ secrets.VAPID_PRIVATE_KEY }} JWT_SECRET: ${{ secrets.CI_JWT_SECRET }} NODE_ENV: ${{ vars.CI_NODE_ENV }} + ## seed script env variables + SEED_PLATFORM_OAUTH_CLIENT_ID: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_ID }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_SECRET }} + SEED_PLATFORM_OAUTH_CLIENT_ID_E2E: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_ID_E2E }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E }} jobs: e2e: timeout-minutes: 20 diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index be5eefb3bf0a2e..de1e32f4d3a370 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -53,6 +53,12 @@ env: DATABASE_URL: ${{ secrets.CI_DATABASE_URL }} NODE_OPTIONS: --max-old-space-size=29000 + ## seed script env variables + SEED_PLATFORM_OAUTH_CLIENT_ID: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_ID }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_SECRET }} + SEED_PLATFORM_OAUTH_CLIENT_ID_E2E: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_ID_E2E }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E }} + jobs: e2e-atoms: if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} diff --git a/packages/platform/examples/base/src/pages/api/managed-user.ts b/packages/platform/examples/base/src/pages/api/managed-user.ts index 1ecc69e0a07b6c..ac32d86f2e2a84 100644 --- a/packages/platform/examples/base/src/pages/api/managed-user.ts +++ b/packages/platform/examples/base/src/pages/api/managed-user.ts @@ -19,17 +19,6 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar }, }); - // throw new Error( - // JSON.stringify( - // { - // NEXT_PUBLIC_CALCOM_API_URL: process.env.NEXT_PUBLIC_CALCOM_API_URL, - // NEXT_PUBLIC_X_CAL_ID: process.env.NEXT_PUBLIC_X_CAL_ID, - // NEXT_PUBLIC_X_CAL_ID_SHORT: process.env.NEXT_PUBLIC_X_CAL_ID?.substr(0, 5), - // }, - // null, - // 2 - // ) - // ); const managedUserResponse = await fetch( `${process.env.NEXT_PUBLIC_CALCOM_API_URL ?? ""}/oauth-clients/${process.env.NEXT_PUBLIC_X_CAL_ID}/users`, { @@ -57,42 +46,6 @@ async function createUserWithDefaultSchedule(email: string, name: string, avatar ); } - if (!managedUserResponseBody.data?.accessToken) { - throw new Error( - `Managed user API returned success but no accessToken:\n${JSON.stringify( - managedUserResponseBody, - null, - 2 - )}` - ); - } - // const shouldThrow = true; - // if (shouldThrow) { - // throw new Error( - // JSON.stringify({ - // email: email, - // calcomUserId: managedUserResponseBody.data?.user.id || "not-defined", - // calcomUsername: managedUserResponseBody.data?.user.username || "not-defined", - // refreshToken: managedUserResponseBody.data?.refreshToken || "not-defined", - // accessToken: managedUserResponseBody.data?.accessToken || "not-defined", - // testkey: "asd", - // }) - // ); - // } - - // const debugExistingUsers = await prisma.user.findMany({ - // where: { accessToken: managedUserResponseBody.data?.accessToken }, - // }); - // if (debugExistingUsers.length > 0) { - // throw new Error( - // `asap User with accessToken ${JSON.stringify( - // debugExistingUsers, - // null, - // 2 - // )} already exists so cant create new one: ${JSON.stringify(managedUserResponseBody.data, null, 2)}` - // ); - // } - await prisma.user.update({ data: { refreshToken: (managedUserResponseBody.data?.refreshToken as string) ?? "", diff --git a/scripts/seed.ts b/scripts/seed.ts index a6b6b747d38ec3..13f7c9b20da891 100644 --- a/scripts/seed.ts +++ b/scripts/seed.ts @@ -198,6 +198,8 @@ async function createPlatformAndSetupUser({ secret: exampleAppClientSecret, }, }); + } else { + console.log("⚠️ No example app client id and secret found, skipping example app client creation"); } const exampleAppClientIdE2e = process.env.SEED_PLATFORM_OAUTH_CLIENT_ID_E2E; @@ -214,6 +216,10 @@ async function createPlatformAndSetupUser({ secret: exampleAppClientSecretE2e, }, }); + } else { + console.log( + "⚠️ No example app e2e client id and secret found, skipping example app e2e client creation" + ); } console.log(`\t👤 Added '${teamInput.name}' membership for '${username}' with role '${membershipRole}'`); } From a16661b47a67f519a7c1563478aaba58766e27dd Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 12:52:59 +0100 Subject: [PATCH 68/73] retrigger db setup --- packages/prisma/schema.prisma | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index afcfd1ae73a7b3..70b913b515d09f 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -1978,9 +1978,10 @@ model PlatformOAuthClient { bookingCancelRedirectUri String? bookingRescheduleRedirectUri String? - areEmailsEnabled Boolean @default(false) - areDefaultEventTypesEnabled Boolean @default(true) - areCalendarEventsEnabled Boolean @default(true) + + areEmailsEnabled Boolean @default(false) + areDefaultEventTypesEnabled Boolean @default(true) + areCalendarEventsEnabled Boolean @default(true) createdAt DateTime @default(now()) } From 22e68ae1e52b32f8f5ca6d122c20b8550e6c984c Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 14:13:51 +0100 Subject: [PATCH 69/73] fix: db seed env --- .github/actions/cache-db/action.yml | 13 +++++++++++++ .github/workflows/e2e-api-v2.yml | 5 +++++ .github/workflows/e2e-atoms.yml | 5 +++++ 3 files changed, 23 insertions(+) diff --git a/.github/actions/cache-db/action.yml b/.github/actions/cache-db/action.yml index 32b9b0c083bda3..84308b518863ab 100644 --- a/.github/actions/cache-db/action.yml +++ b/.github/actions/cache-db/action.yml @@ -7,6 +7,14 @@ inputs: path: required: false default: "backups/backup.sql" + SEED_PLATFORM_OAUTH_CLIENT_ID: + required: false + SEED_PLATFORM_OAUTH_CLIENT_SECRET: + required: false + SEED_PLATFORM_OAUTH_CLIENT_ID_E2E: + required: false + SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E: + required: false runs: using: "composite" steps: @@ -29,6 +37,11 @@ runs: - run: yarn db-seed if: steps.cache-db.outputs.cache-hit != 'true' shell: bash + env: + SEED_PLATFORM_OAUTH_CLIENT_ID: ${{ inputs.SEED_PLATFORM_OAUTH_CLIENT_ID }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET: ${{ inputs.SEED_PLATFORM_OAUTH_CLIENT_SECRET }} + SEED_PLATFORM_OAUTH_CLIENT_ID_E2E: ${{ inputs.SEED_PLATFORM_OAUTH_CLIENT_ID_E2E }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E: ${{ inputs.SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E }} - name: Postgres Dump Backup if: steps.cache-db.outputs.cache-hit != 'true' uses: tj-actions/pg-dump@v2.3 diff --git a/.github/workflows/e2e-api-v2.yml b/.github/workflows/e2e-api-v2.yml index 96c88b748e650c..5b22c617ac1680 100644 --- a/.github/workflows/e2e-api-v2.yml +++ b/.github/workflows/e2e-api-v2.yml @@ -77,6 +77,11 @@ jobs: - uses: ./.github/actions/dangerous-git-checkout - uses: ./.github/actions/yarn-install - uses: ./.github/actions/cache-db + with: + SEED_PLATFORM_OAUTH_CLIENT_ID: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_ID }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_SECRET }} + SEED_PLATFORM_OAUTH_CLIENT_ID_E2E: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_ID_E2E }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E }} - name: Generate Swagger working-directory: apps/api/v2 diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index de1e32f4d3a370..8e521292e40374 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -103,6 +103,11 @@ jobs: - uses: ./.github/actions/dangerous-git-checkout - uses: ./.github/actions/yarn-install - uses: ./.github/actions/cache-db + with: + SEED_PLATFORM_OAUTH_CLIENT_ID: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_ID }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_SECRET }} + SEED_PLATFORM_OAUTH_CLIENT_ID_E2E: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_ID_E2E }} + SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E: ${{ secrets.SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E }} - uses: ./.github/actions/yarn-playwright-install - name: Start API v2 working-directory: apps/api/v2 From aeacaa10f6ea3d8b99ebf5cb2bc10fb0516463ad Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 14:26:07 +0100 Subject: [PATCH 70/73] retrigger db seed --- packages/prisma/schema.prisma | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 70b913b515d09f..88fdc80275cee7 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -1972,16 +1972,17 @@ model PlatformOAuthClient { accessTokens AccessToken[] refreshToken RefreshToken[] authorizationTokens PlatformAuthorizationToken[] - webhook Webhook[] + + webhook Webhook[] bookingRedirectUri String? - bookingCancelRedirectUri String? - bookingRescheduleRedirectUri String? + bookingCancelRedirectUri String? - areEmailsEnabled Boolean @default(false) - areDefaultEventTypesEnabled Boolean @default(true) - areCalendarEventsEnabled Boolean @default(true) + bookingRescheduleRedirectUri String? + areEmailsEnabled Boolean @default(false) + areDefaultEventTypesEnabled Boolean @default(true) + areCalendarEventsEnabled Boolean @default(true) createdAt DateTime @default(now()) } From 38d31b9523e88dc92080d4f5e4de9676258d5332 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 14:50:52 +0100 Subject: [PATCH 71/73] add seed e2e env to turob.json --- turbo.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/turbo.json b/turbo.json index 19ff99248edc5b..8f294e40bc39f4 100644 --- a/turbo.json +++ b/turbo.json @@ -301,7 +301,9 @@ "GOOGLE_ADS_ENABLED", "LINKEDIN_ADS_ENABLED", "SEED_PLATFORM_OAUTH_CLIENT_ID", - "SEED_PLATFORM_OAUTH_CLIENT_SECRET" + "SEED_PLATFORM_OAUTH_CLIENT_SECRET", + "SEED_PLATFORM_OAUTH_CLIENT_ID_E2E", + "SEED_PLATFORM_OAUTH_CLIENT_SECRET_E2E" ], "tasks": { "@calcom/web#copy-app-store-static": { From ca8bab061f5841f215d181b852e983914a7cb5e5 Mon Sep 17 00:00:00 2001 From: supalarry Date: Thu, 4 Dec 2025 15:18:47 +0100 Subject: [PATCH 72/73] teardown env --- .github/workflows/e2e-atoms.yml | 6 ++++++ packages/platform/examples/base/global-teardown.ts | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e-atoms.yml b/.github/workflows/e2e-atoms.yml index 8e521292e40374..f5a6a8b353418f 100644 --- a/.github/workflows/e2e-atoms.yml +++ b/.github/workflows/e2e-atoms.yml @@ -25,6 +25,7 @@ env: DATABASE_WRITE_URL: ${{ secrets.CI_DATABASE_URL }} GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }} IS_E2E: true + CI: true NEXTAUTH_SECRET: ${{ secrets.CI_NEXTAUTH_SECRET }} NEXTAUTH_URL: ${{ secrets.CI_NEXTAUTH_URL }} REDIS_URL: "redis://localhost:6379" @@ -48,6 +49,11 @@ env: ATOMS_E2E_APPLE_ID_2025_12: ${{ secrets.ATOMS_E2E_APPLE_ID_2025_12 }} ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE_2025_12: ${{ secrets.ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE_2025_12 }} + ## atoms e2e examples app env aliases for playwright + NEXT_PUBLIC_X_CAL_ID: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID_2025_12 }} + X_CAL_SECRET_KEY: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_SECRET_2025_12 }} + NEXT_PUBLIC_CALCOM_API_URL: ${{ secrets.ATOMS_E2E_API_URL_2025_12 }} + ## env variables needed for both api v2 and examples app DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }} DATABASE_URL: ${{ secrets.CI_DATABASE_URL }} diff --git a/packages/platform/examples/base/global-teardown.ts b/packages/platform/examples/base/global-teardown.ts index 96f66ac788ead2..53be4c31738d5b 100644 --- a/packages/platform/examples/base/global-teardown.ts +++ b/packages/platform/examples/base/global-teardown.ts @@ -2,7 +2,9 @@ import dotenv from "dotenv"; import fs from "fs"; import path from "path"; -dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); +if (!process.env.CI) { + dotenv.config({ path: path.resolve(__dirname, ".env.e2e") }); +} async function globalTeardown() { console.log("Cleaning up managed users..."); try { From 9643a535a3515e3839035628948d45030b360a7c Mon Sep 17 00:00:00 2001 From: supalarry Date: Fri, 5 Dec 2025 13:17:54 +0100 Subject: [PATCH 73/73] refactor: remove unused type --- packages/trpc/server/routers/viewer/slots/_router.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/trpc/server/routers/viewer/slots/_router.tsx b/packages/trpc/server/routers/viewer/slots/_router.tsx index c99b7af3b21ae9..96a556e64dd342 100644 --- a/packages/trpc/server/routers/viewer/slots/_router.tsx +++ b/packages/trpc/server/routers/viewer/slots/_router.tsx @@ -7,12 +7,6 @@ import { ZRemoveSelectedSlotInputSchema } from "./removeSelectedSlot.schema"; import { ZReserveSlotInputSchema } from "./reserveSlot.schema"; import { ZGetScheduleInputSchema } from "./types"; -type SlotsRouterHandlerCache = { - getSchedule?: typeof import("./getSchedule.handler").getScheduleHandler; - reserveSlot?: typeof import("./reserveSlot.handler").reserveSlotHandler; - isAvailable?: typeof import("./isAvailable.handler").isAvailableHandler; -}; - /** This should be called getAvailableSlots */ export const slotsRouter = router({ getSchedule: publicProcedure.input(ZGetScheduleInputSchema).query(async ({ input, ctx }) => {