Skip to content

feat: add Move Team to Organization admin migration page#25067

Merged
hariombalhara merged 27 commits intomainfrom
devin/1762853442-restore-move-team-to-org-endpoint
Mar 19, 2026
Merged

feat: add Move Team to Organization admin migration page#25067
hariombalhara merged 27 commits intomainfrom
devin/1762853442-restore-move-team-to-org-endpoint

Conversation

@hariombalhara
Copy link
Member

@hariombalhara hariombalhara commented Nov 11, 2025

What does this PR do?

Adds an admin-only "Move Team to Organization" migration page under Settings → Admin → Migrations. This provides a UI for instance admins to move an existing standalone team into an organization.

Key changes:

  • Admin page at /settings/admin/migrations/move-team-to-org with a form to enter Team ID, new slug, and target Org ID
  • tRPC handler (moveTeamToOrg.handler.ts) that delegates to the existing createTeamsHandler by impersonating the org owner
  • Slug conflict handling — intercepts Prisma P2002 unique constraint errors via instanceof Prisma.PrismaClientKnownRequestError in moveTeam() and surfaces a user-friendly CONFLICT error using an i18n key
  • Test for the slug conflict scenario in createTeams.handler.test.ts
  • Settings sidebar updated with a new "Migrations" nav item under the Admin section
  • i18n strings added for all UI labels and messages
  • PII removal — log statements use only user/org IDs, no emails

Link to Devin run: https://app.devin.ai/sessions/d313feb45bcd45949d0e49914ed99419
Requested by: bot_apk (apk@cognition.ai)
Original author: @hariombalhara


Updates since last revision

  • i18n for slug conflict error: Changed the hardcoded English error message (Slug "xyz" is already in use within this organization) to an i18n key slug_already_in_use_in_org, addressing this review comment. Updated the unit test accordingly.
  • Narrowed P2002 catch scope: Separated the try-catch for prisma.team.update from creditService.moveCreditsFromTeamToOrg so that a P2002 from the credit service is not misattributed as a slug conflict. Each now has its own try-catch with appropriate error logging. Addresses this review comment.

Important Review Points

Human Review Checklist — please verify these:

  1. Security-sensitive impersonation pattern: The handler constructs a context with { user: { id: orgOwner.id, organizationId: targetOrgId } } and passes it to createTeamsHandler. Is this the correct and safe way to perform admin actions on behalf of the org owner?
  2. Org owner lookup: Uses org.members[0].user from organizationRepository.adminFindById to get the first OWNER-role member. Verify this reliably returns the actual org owner.
  3. Prisma import in handler: createTeams.handler.ts changed import type { Prisma } to a runtime import { Prisma } from @calcom/prisma/client to support the instanceof check. This is a known deviation from the "no @calcom/prisma/client in handlers" guideline — confirm this tradeoff is acceptable.
  4. Credit service error propagation: After separating the try-catch blocks, creditService.moveCreditsFromTeamToOrg errors are logged and re-thrown as raw errors (not wrapped in TRPCError). Verify this is acceptable — the team update will have already succeeded at this point.
  5. Removed dbRemoveTeamFromOrg from playwright/lib/orgMigration.ts — verify nothing else depends on this function (hariombalhara confirmed it was unused).
  6. Formatting changes in SettingsLayoutAppDirClient.tsx are auto-formatter output — review alongside the actual nav item addition to ensure no unintended changes.

How should this be tested?

Prerequisites:

  • Admin user account
  • Existing organization with an owner
  • Existing standalone team (not already in an org)

Happy path:

  1. Log in as admin → navigate to /settings/admin/migrations/move-team-to-org
  2. Enter Team ID, new slug, and Target Organization ID → click "Move Team to Org"
  3. Verify: team's parentId is updated, members are invited to the org, redirect is created, success message is displayed

Slug conflict:

  • Try moving a team with a slug that already exists in the target organization
  • Expected: translated error message for slug_already_in_use_in_org

Edge cases:

  • Try moving a team that's already in an org → should get cannot_move_subteam_already_in_org error
  • Try with a non-existent team ID → should get team_not_found error
  • Try with a non-existent org ID → should get organization_not_found error

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • N/A — No documentation changes required (admin-only endpoint)
  • I confirm automated tests are in place that prove my fix is effective or that my feature works

- Add moveTeamToOrg and removeTeamFromOrg functions to orgMigration.ts
- Restore API endpoint at /api/orgMigration/moveTeamToOrg
- Restore admin UI page at /settings/admin/orgMigrations/moveTeamToOrg
- Add helper functions for team redirect management
- Support moving team members along with the team

This endpoint allows admins to migrate teams to organizations after org creation,
which is needed as a temporary solution until proper org admin permissions are implemented.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

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

✅ I will automatically:

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

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

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@keithwillcode keithwillcode added core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO labels Nov 11, 2025
- Move moveTeamToOrg and removeTeamFromOrg functions from playwright/lib to lib/orgMigration.ts
- Update API endpoint to import from lib/orgMigration instead of playwright/lib
- Fix redirect URL format: use / instead of /team/
- Fix import path: use ../playwright/lib/orgMigration instead of ./playwright/lib/orgMigration
- Rename unused _dbRemoveTeamFromOrg in playwright file to satisfy linter
- Remove duplicate functions from playwright/lib/orgMigration.ts

This fixes the Vercel deployment failure caused by importing from test-only directories
in production API routes, and corrects the redirect URL format to match the original implementation.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
@vercel
Copy link

vercel bot commented Nov 11, 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 Nov 11, 2025 10:25am
cal-eu Ignored Ignored Nov 11, 2025 10:25am

- Remove custom orgMigration.ts implementation
- Update API endpoint to call existing createTeamsHandler with org owner impersonation
- Remove moveMembers option from UI (always moves members by design)
- Fix Vercel deployment by removing playwright import from production code
- Use OrganizationRepository.adminFindById to fetch org owner

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

This PR has been marked as stale due to inactivity. If you're still working on it or need any help, please let us know or update the PR to keep it active.

@github-actions
Copy link
Contributor

This PR has been marked as stale due to inactivity. If you're still working on it or need any help, please let us know or update the PR to keep it active.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

No Conflicts Detected

This PR does not have any merge conflicts with the base branch. The devin-conflict-resolution label has been removed.

If you believe this PR should have conflicts, please check the PR status and try again.

hariombalhara and others added 2 commits February 5, 2026 15:59
- Move admin page from pages/settings/admin/orgMigrations to app/(use-page-wrapper)/settings/(admin-layout)/admin/orgMigrations
- Convert API route from pages/api/orgMigration/moveTeamToOrg.ts to app/api/orgMigration/moveTeamToOrg/route.ts
- Create client view component in modules/settings/admin/org-migrations/
- Remove old pages directory files and getServerSideProps

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
@devin-ai-integration devin-ai-integration bot changed the title feat: restore moveTeamToOrg admin endpoint for organization migration refactor: migrate moveTeamToOrg admin endpoint to App Router Feb 5, 2026
devin-ai-integration bot and others added 2 commits February 5, 2026 10:49
- Fix @calcom/lib/server to @calcom/lib/server/i18n for getTranslation
- Fix @calcom/ui barrel import to specific component paths

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
cubic-dev-ai[bot]

This comment was marked as resolved.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Devin AI is addressing Cubic AI's review feedback

New feedback has been sent to the existing Devin session.

View Devin Session


✅ Pushed commit a20e566

devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

@hariombalhara hariombalhara force-pushed the devin/1762853442-restore-move-team-to-org-endpoint branch from c34da01 to 1b3df61 Compare February 6, 2026 05:37
@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

E2E results are ready!

@github-actions
Copy link
Contributor

Devin AI is resolving merge conflicts

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

View Devin Session

Devin will:

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

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

…ore-move-team-to-org-endpoint

Co-Authored-By: bot_apk <apk@cognition.ai>
devin-ai-integration[bot]

This comment was marked as resolved.

@github-actions
Copy link
Contributor

Devin AI is completing this stale PR

This PR by @hariombalhara has been marked as stale. A Devin session has been created to complete the remaining work.

View Devin Session


Devin will review the PR, address any feedback, and push updates to complete this PR.

…d English string

Co-Authored-By: bot_apk <apk@cognition.ai>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration bot and others added 2 commits February 27, 2026 11:03
Separates the try-catch for prisma.team.update (slug conflict) from
creditService.moveCreditsFromTeamToOrg to avoid misattributing credit
service P2002 errors as slug conflicts.

Co-Authored-By: bot_apk <apk@cognition.ai>
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
joeauyeung
joeauyeung previously approved these changes Mar 18, 2026
Copy link
Contributor

@joeauyeung joeauyeung left a comment

Choose a reason for hiding this comment

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

Great work @hariombalhara. Reuses currently logic and endpoint is protected by the authedAdminProcedure. Tested manually and working as expected

@hariombalhara hariombalhara enabled auto-merge (squash) March 19, 2026 02:11
…ore-move-team-to-org-endpoint

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 13 additional findings in Devin Review.

Open in Devin Review

@calcom calcom deleted a comment from devin-ai-integration bot Mar 19, 2026
@hariombalhara hariombalhara merged commit dc43eba into main Mar 19, 2026
78 of 80 checks passed
@hariombalhara hariombalhara deleted the devin/1762853442-restore-move-team-to-org-endpoint branch March 19, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core area: core, team members only devin-finish-pr enterprise area: enterprise, audit log, organisation, SAML, SSO ready-for-e2e size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants