Skip to content

Conversation

SomayChauhan
Copy link
Member

@SomayChauhan SomayChauhan commented Jul 2, 2025

What does this PR do?

This pull request introduces support for installing conferencing applications at the team/organization level.

Benefits

No individual setup required: Users within a team or organization no longer need to connect their personal accounts to Zoom or other conferencing apps.

Shared credentials: Once installed by a team admin, the conferencing app credentials are available for all sub-teams and users within the org.

Users can leverage the shared team/org-installed credentials when creating personal events, as well as sub-team events.

Reduced redundancy: Instead of every user configuring the same app, the admin installs it once and all members can use it seamlessly.

⚠️ needs platform libraries update

  • Fixes #XXXX (GitHub issue number)
  • Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

Mandatory Tasks (DO NOT REMOVE)

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

@SomayChauhan SomayChauhan requested review from a team as code owners July 2, 2025 12:13
Copy link
Contributor

github-actions bot commented Jul 2, 2025

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.

Details:

No release type found in pull request title "Feat/orgs conferencing apps". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@graphite-app graphite-app bot requested a review from a team July 2, 2025 12:14
@keithwillcode keithwillcode added core area: core, team members only platform Anything related to our platform plan labels Jul 2, 2025
@dosubot dosubot bot added the ✨ feature New feature or request label Jul 2, 2025
Copy link

graphite-app bot commented Jul 2, 2025

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (07/02/25)

1 reviewer was added to this PR based on Keith Williams's automation.

Copy link

delve-auditor bot commented Jul 2, 2025

No security or compliance issues detected. Reviewed everything up to b270660.

Security Overview
  • 🔎 Scanned files: 34 changed file(s)
Detected Code Changes
Change Type Relevant files
Enhancement ► atoms.conferencing-apps.controller.ts
    Add Organization Conferencing Apps List Endpoint
► conferencing-atom.service.ts
    Include Team Installed Apps Option
► conferencing.controller.ts
    Add Default Conferencing App with Credential ID
► organizations-conferencing.controller.ts
    Implement Organization Level Conferencing Apps
► organizations-teams-conferencing.controller.ts
    Implement Team Level Conferencing Apps
Refactor ► conferencing.repository.ts
    Update Team Conferencing Apps Query
► conferencing.service.ts
    Refactor Conferencing App Logic
► user.repository.ts
    Add Profile Skip Platform Check Method
Configuration changes ► package.json
    Update Platform Libraries Version

Reply to this PR with @delve-auditor followed by a description of what change you want and we'll auto-submit a change to this PR to implement it.

Copy link
Contributor

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

Choose a reason for hiding this comment

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

cubic found 9 issues across 22 files. Review them in cubic.dev

React with 👍 or 👎 to teach cubic. Tag @cubic-dev-ai to give specific feedback.

@@ -9,13 +9,15 @@ import http from "../../../lib/http";

export const QUERY_KEY = "get-installed-conferencing-apps";

export const useAtomsGetInstalledConferencingApps = (teamId?: number) => {
export const useAtomsGetInstalledConferencingApps = (teamId?: number, orgId?: number) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

The function signature now allows both teamId and orgId, but the logic does not handle the case where both are provided. This could lead to ambiguous or unintended API calls. Consider validating that only one of teamId or orgId is provided at a time.

@@ -61,6 +61,14 @@ export async function getLocationGroupedOptions(
id: userOrTeamId.userId,
},
});

if (user?.organizationId) {
Copy link
Contributor

Choose a reason for hiding this comment

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

When the user belongs to an organization this branch replaces the previous { userId } filter with { teamId: { in: [user.organizationId] } }, causing personal credentials owned by the user to be ignored. As a result users who are part of an org will no longer see their own conferencing credentials in the location selector.

@@ -169,6 +169,21 @@ export class ConferencingController {
const fallbackUrl = decodedCallbackState.onErrorReturnTo || "";
return { url: fallbackUrl };
}
} else if (decodedCallbackState.orgId) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This new branch repeats almost the same logic as the preceding team-level branch (building the same params / headers, performing the same axios call, and handling identical success & error flows). Copy-pasting this block increases maintenance cost and risks future inconsistencies. Extract the shared logic into a reusable helper instead of duplicating it.

Copy link

vercel bot commented Jul 2, 2025

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

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
cal Ignored Ignored Preview Aug 26, 2025 10:50am
cal-eu Ignored Ignored Preview Aug 26, 2025 10:50am

@vercel vercel bot temporarily deployed to Preview – api July 3, 2025 12:27 Inactive
@vercel vercel bot temporarily deployed to Preview – cal July 3, 2025 12:27 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/app-store/server.ts (1)

72-83: Verify the credential filtering logic for organization users.

The current implementation replaces the original { userId } filter with team-based filtering when the user has teams. This could cause personal user credentials to be excluded for organization members, potentially breaking existing functionality.

The past review comment correctly identified this issue: "When the user belongs to an organization this branch replaces the previous { userId } filter with { teamId: { in: [user.organizationId] } }, causing personal credentials owned by the user to be ignored."

Run this script to verify the credential filtering behavior:

#!/bin/bash
# Description: Verify that personal user credentials are still accessible when user has teams.
# Expected: Personal credentials should remain accessible alongside team credentials.

# Search for similar patterns in the codebase to understand intended behavior
ast-grep --pattern $'{ 
  OR: [
    {
      teamId: {
        in: $$$
      }
    },
    $$$
  ]
}'

# Check if there are other places where user credentials are fetched
rg -A 10 -B 5 "userId.*OR.*teamId" --type ts
🧹 Nitpick comments (2)
packages/app-store/server.ts (2)

134-137: Improve readability of the credential mapping.

The destructuring assignment in the map function could be clearer by extracting the mapping logic to a separate variable or using more descriptive intermediate steps.

Apply this diff to improve readability:

-      for (const { teamName, credentialId } of app.credentials.map((credential) => ({
-        teamName: credential.team?.name,
-        credentialId: credential.id,
-      }))) {
+      const credentialMappings = app.credentials.map((credential) => ({
+        teamName: credential.team?.name,
+        credentialId: credential.id,
+      }));
+      
+      for (const { teamName, credentialId } of credentialMappings) {

147-150: Remove commented deduplication logic or provide explanation.

The commented deduplication code suggests this was intentionally disabled, but without context it's unclear if this is temporary or permanent. This could lead to duplicate options in the UI.

Either remove the commented code if it's no longer needed, or add a comment explaining why deduplication was disabled:

-          // const existingOption = apps[groupByCategory].find((o) => o.value === option.value);
-          // if (!existingOption) {
           apps[groupByCategory] = [...apps[groupByCategory], option];
-          // }

Or add an explanatory comment:

+          // Deduplication disabled to support multiple credentials per app
           // const existingOption = apps[groupByCategory].find((o) => o.value === option.value);
           // if (!existingOption) {
           apps[groupByCategory] = [...apps[groupByCategory], option];
           // }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0cc40e and eaae740.

📒 Files selected for processing (2)
  • packages/app-store/server.ts (2 hunks)
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/app-store/server.ts
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)

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

Files:

  • packages/app-store/server.ts
🧬 Code Graph Analysis (1)
packages/app-store/server.ts (1)
scripts/prepare-local-for-delegation-credentials-testing.js (1)
  • user (15-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Atoms E2E Tests

Comment on lines +63 to 70
include: {
teams: {
select: {
teamId: true,
},
},
},
});
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Include only necessary fields to optimize query performance.

The query includes the entire teams relationship when only teamId is needed. Following the coding guidelines for Prisma queries, use select instead of include to fetch only required data.

Apply this diff to optimize the query:

-      include: {
-        teams: {
-          select: {
-            teamId: true,
-          },
-        },
-      },
+      select: {
+        id: true,
+        teams: {
+          select: {
+            teamId: true,
+          },
+        },
+      },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
include: {
teams: {
select: {
teamId: true,
},
},
},
});
select: {
id: true,
teams: {
select: {
teamId: true,
},
},
},
});
🤖 Prompt for AI Agents
In packages/app-store/server.ts around lines 63 to 70, the Prisma query
currently uses include to load the entire teams relation though only teamId is
needed; replace the include with a select for the teams relation (teams: {
select: { teamId: true } }) so only teamId is fetched, and preserve any other
top-level selected fields in the query to avoid loading unnecessary data.

...(app.credential
? { credentialId: app.credential.id, teamName: app.credential.team?.name ?? null }
: {}),
...(app.credential ? { credentialId: credentialId, teamName: teamName ?? null } : {}),
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix conditional logic for credential properties.

The condition app.credential doesn't match the loop structure that iterates over app.credentials (plural). This could cause credential-specific properties to be incorrectly applied.

Apply this diff to fix the conditional logic:

-          ...(app.credential ? { credentialId: credentialId, teamName: teamName ?? null } : {}),
+          ...(credentialId ? { credentialId: credentialId, teamName: teamName ?? null } : {}),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
...(app.credential ? { credentialId: credentialId, teamName: teamName ?? null } : {}),
...(credentialId ? { credentialId: credentialId, teamName: teamName ?? null } : {}),
🤖 Prompt for AI Agents
In packages/app-store/server.ts around line 144, the spread uses app.credential
(singular) which doesn't match the surrounding loop over app.credentials;
replace that conditional with a check for app.credentials existing/non-empty
(for example app.credentials?.length > 0) so the credentialId and teamName
properties are only applied when the app has credentials, e.g. change
...(app.credential ? { credentialId: credentialId, teamName: teamName ?? null }
: {}) to use ...(app.credentials?.length > 0 ? { credentialId, teamName:
teamName ?? null } : {}) so the logic aligns with the plural credentials
structure.

Copy link
Contributor

@hbjORbj hbjORbj left a comment

Choose a reason for hiding this comment

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

Lots of CI actions are failing.

@github-actions github-actions bot marked this pull request as draft August 13, 2025 08:15
Copy link
Member Author

Choose a reason for hiding this comment

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

api endpoint to list all the conferencing apps for in the conferencing atom for an org

@@ -18,6 +18,7 @@ export class ConferencingAtomsService {
input: {
variant: "conferencing",
onlyInstalled: true,
includeTeamInstalledApps: true,
Copy link
Member Author

Choose a reason for hiding this comment

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

Display the installed team or organizational conferencing apps in the conferencing atom when viewed at the user level.

@@ -169,6 +172,21 @@ export class ConferencingController {
const fallbackUrl = decodedCallbackState.onErrorReturnTo || "";
return { url: fallbackUrl };
}
} else if (decodedCallbackState.orgId) {
const apiUrl = this.config.get("api.url");
const url = `${apiUrl}/organizations/${decodedCallbackState.orgId}/conferencing/${app}/oauth/callback`;
Copy link
Member Author

Choose a reason for hiding this comment

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

similar to this #20540 (comment)

@@ -216,6 +236,32 @@ export class ConferencingController {
return { status: SUCCESS_STATUS };
}

@Post("/:app/default/:credentialId")
Copy link
Member Author

Choose a reason for hiding this comment

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

Setting a default app now requires us to include the credentialId, as previously we only had one instance of an app. but now with the introduction of multiple instances at the org, team, and user levels, we need to specify the credentialId to identify which app we're referring to.

if (!CONFERENCING_APPS.includes(appSlug)) {
throw new BadRequestException("Invalid app, available apps are: ", CONFERENCING_APPS.join(", "));
}
const credentials = await getUsersCredentialsIncludeServiceAccountKey(user);
const credentials = await getUsersAndTeamsCredentialsIncludeServiceAccountKey(user);
Copy link
Member Author

Choose a reason for hiding this comment

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

added a new function that will also include the credentials for the teams and organizations the user is a part of.

@@ -112,12 +123,17 @@ export class ConferencingService {
});
}

async setDefaultConferencingApp(user: UserWithProfile, app: string) {
async setDefaultConferencingApp(user: UserWithProfile, app: string, credentialId?: number) {
Copy link
Member Author

@SomayChauhan SomayChauhan Aug 26, 2025

Choose a reason for hiding this comment

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

similar to #22211 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

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

This controller handles all the conferencing endpoints for organizations

) {}

@Roles("TEAM_ADMIN")
Copy link
Member Author

Choose a reason for hiding this comment

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

removed the endpoint for google-meet as we cannot install gogle-meet on teams/orgs

@@ -328,6 +328,7 @@ export const createdEventSchema = z
const schemaDefaultConferencingApp = z.object({
appSlug: z.string().default("daily-video").optional(),
appLink: z.string().optional(),
credentialId: z.number().optional(),
Copy link
Member Author

Choose a reason for hiding this comment

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

We need to save the credentialId for the default conferencing app. Currently, Zoom can be installed at the team, organization, or user level, so we need to specify which level's credential to save.

}: {
installedApps?: RouterOutputs["viewer"]["apps"]["integrations"]["items"];
}) => {
const baseApps = teamId || orgId ? [ZOOM, OFFICE_365_VIDEO] : [GOOGLE_MEET, ZOOM, OFFICE_365_VIDEO];
Copy link
Member Author

Choose a reason for hiding this comment

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

can't have g-meet on team/orgs

@@ -328,6 +328,7 @@ export const createdEventSchema = z
const schemaDefaultConferencingApp = z.object({
appSlug: z.string().default("daily-video").optional(),
appLink: z.string().optional(),
credentialId: z.number().optional(),
Copy link
Member Author

Choose a reason for hiding this comment

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

We need to save the credentialId for the default conferencing app. Currently, Zoom can be installed at the team, organization, or user level, so we need to specify which level's credential to save.

}: {
installedApps?: RouterOutputs["viewer"]["apps"]["integrations"]["items"];
}) => {
const baseApps = teamId || orgId ? [ZOOM, OFFICE_365_VIDEO] : [GOOGLE_MEET, ZOOM, OFFICE_365_VIDEO];
Copy link
Member Author

Choose a reason for hiding this comment

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

can install google-meet on orgs/teams

apps,
disableBulkUpdateEventTypes = false,
}: ConferencingAppsViewPlatformWrapperProps) => {
const { t } = useLocale();
const queryClient = useQueryClient();
const { toast } = useToast();
const shouldDisableBulkUpdates = !teamId && orgId ? false : disableBulkUpdateEventTypes;
Copy link
Member Author

Choose a reason for hiding this comment

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

disable bulkUpdate event type modal for orgs/teams

Copy link
Member Author

Choose a reason for hiding this comment

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

these changes are for fixing this bug where we select one and we automatically selects the other two

Image

Copy link
Member Author

Choose a reason for hiding this comment

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

Image
Previously, the "invalid credentials" banner would appear on all installed instances of Zoom. Now, it only shows for the instance with invalid credentials.

Copy link
Member Author

Choose a reason for hiding this comment

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

This update includes organization and team-level conferencing apps in the user event types within the location dropdown

Image

@SomayChauhan SomayChauhan marked this pull request as ready for review August 26, 2025 10:50
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.test.ts (1)

77-89: Repeat the DRY + mockResolvedValue refactor in all similar blocks

Apply the same setUserRepoProfile(...) usage to these blocks to remove duplication and ensure async-consistent stubbing.

Also applies to: 162-173, 239-250, 343-355, 666-678

🧹 Nitpick comments (1)
packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.test.ts (1)

22-34: DRY the UserRepository mocking and prefer mockResolvedValue for async semantics

You repeatedly stub enrichUserWithItsProfileSkipPlatformCheck and wire mockImplementation inline. This is verbose and slightly misleading since the repo call is async. Suggest centralizing with a helper and using mockResolvedValue.

  • Benefit: less duplication, clearer intent, easier to tweak across all tests.

Apply this diff to replace the inline stub in this block:

-    const mockEnrichUserWithItsProfileSkipPlatformCheck = vi.fn().mockReturnValue({
-      profile: null,
-    });
-
-    const mockUserRepository = vi.mocked(UserRepository);
-    if (mockUserRepository && typeof mockUserRepository.mockImplementation === "function") {
-      mockUserRepository.mockImplementation(
-        () =>
-          ({
-            enrichUserWithItsProfileSkipPlatformCheck: mockEnrichUserWithItsProfileSkipPlatformCheck,
-          } as any)
-      );
-    }
+    setUserRepoProfile(null);

Add this helper near the top of the file (after the vi.mock(...)):

function setUserRepoProfile(profile: { organizationId?: number } | null) {
  const mockedCtor = vi.mocked(UserRepository);
  if (mockedCtor && typeof mockedCtor.mockImplementation === "function") {
    mockedCtor.mockImplementation(
      () =>
        ({
          enrichUserWithItsProfileSkipPlatformCheck: vi.fn().mockResolvedValue({ profile }),
        } as any)
    );
  }
}

Also consider adding test hygiene:

afterEach(() => {
  vi.clearAllMocks();
});
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between eaae740 and bcab76c.

📒 Files selected for processing (3)
  • packages/app-store/server.ts (2 hunks)
  • packages/features/apps/components/AppList.tsx (4 hunks)
  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.test.ts (12 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/app-store/server.ts
  • packages/features/apps/components/AppList.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

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

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.test.ts
**/*.{ts,tsx}

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

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

Files:

  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.test.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.test.ts
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Production builds / Build Docs
  • GitHub Check: Production builds / Build Web App
  • GitHub Check: Production builds / Build Atoms
  • GitHub Check: Production builds / Build API v2
  • GitHub Check: Production builds / Build API v1
  • GitHub Check: Tests / Unit
  • GitHub Check: Type check / check-types
  • GitHub Check: Linters / lint
🔇 Additional comments (2)
packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.test.ts (2)

12-18: Mocks updated to SkipPlatformCheck API — looks correct

Top-level module mock aligns with the production rename to enrichUserWithItsProfileSkipPlatformCheck. No issues spotted.


343-345: Verified — mock matches repository contract

The repo's enrichUserWithItsProfileSkipPlatformCheck populates a profile containing organizationId (number | null) and an optional nested organization object, so mocking profile: { organizationId: orgId } is valid for tests that only rely on the org id.

Key evidence:

  • packages/lib/server/repository/user.ts — function enrichUserWithItsProfileSkipPlatformCheck (around line 468) and the returned/selected shape includes "organizationId: number | null" (see lines ~579–581).
  • packages/types/UserProfile.d.ts — defines organizationId on Profile (line ~11).

Note: if a test also reads profile.organization or fields on it, add an organization: {...} entry to the mock.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api area: API, enterprise API, access token, OAuth core area: core, team members only ✨ feature New feature or request organizations area: organizations, orgs platform Anything related to our platform plan ready-for-e2e
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants