feat(scripts): import legacy deco admin teams into Studio - #5392
Open
viktormarinho wants to merge 1 commit into
Open
feat(scripts): import legacy deco admin teams into Studio#5392viktormarinho wants to merge 1 commit into
viktormarinho wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
One-shot, idempotent migration script (
apps/api/scripts/import-deco-teams.ts) that replicates every legacy deco.cx admin team that owns at least one site (~434 teams, 742 sites today) into Studio: org, members, and one project agent per site.How (per team)
imports@deco.cx— inserted directly intouser(noaccountrow → not loggable). Owner of imported orgs andinviterIdon invitations.metadata.decoTeamIdmatch (re-runs) → singleorg_sitesowner → same slug + member-email overlap → created via Better Auth (auth.api.createOrganization, soseedOrgDb/reserved-slug/billing hooks all run). Every resolved org getsmetadata.decoTeamIdstamped — the persisted team↔org linkbackfill-org-sites.tsnever had. New orgs are markedorganization_billing.legacy = true(--no-legacyopts out).invitationrows (no email blast; default invite expiry is 48h, too short for users who may show up months later). The pending invite suppresses the personal auto-org on first signup and reuses the existing accept screen. Legacyadmin: true→ roleadmin.githubRepo,siteSlug, realproductionUrl, preview-first layout. WhenDECO_GITHUB_MCP_TOKEN(deco machine account user-to-server grant) is set, it mints a refreshable repo grant viaMINT_REPO_TOKENand creates the repo-scoped child connection in the client org — the managed-assets model applied to GitHub: the client org only ever holds a token scoped to its own repo; renewal happens through the normal OAuth refresh path (github-repo-scope.ts), no broad credential ever lands in a client org. Repos whose owner has no installation visible to the machine account fall back to an unconnectedgithubRepo, completed by the first real user's GitHub OAuth.team-org-mapping.jsonfor the existingbackfill-org-sites.ts --mapping=(org_sites claims + managed file configs).Rollout
Safe to re-run: every step checks existing state first. Teams whose sites are already claimed by >1 Studio org (the two deco-internal teams) are skipped with a warning.
Testing
bunx tsc --noEmit,oxlint,bun run fmtclean.DECO_SUPABASE_URL.--dry-runwith prod env.Follow-up (out of scope)
Web affordance to finish the GitHub connection on an imported project that has
githubRepobut no child connection (today that flow only exists inside the import dialog, which would create a duplicate project).Summary by cubic
Adds a one-shot, idempotent script to import legacy deco.cx admin teams into Studio as orgs with members and one Virtual MCP agent per site, optionally provisioning repo‑scoped GitHub connections via a machine account. It also writes a team→org mapping JSON for the follow-up backfill.
New Features
organization.metadata.decoTeamId(owner isimports@deco.cx; new orgs can be marked legacy billing unless--no-legacy).githubRepo,siteSlug, production URL, and preview‑first layout.DECO_GITHUB_MCP_TOKEN, mints refreshable repo‑scoped tokens and creates a child GitHub connection; otherwise leavesgithubRepounconnected for later user OAuth.team-org-mapping.jsonforscripts/backfill-org-sites.ts --mapping=.... Safe to re-run; skips teams whose sites are owned by multiple orgs.Migration
bun run scripts/import-deco-teams.ts --dry-runbun run scripts/import-deco-teams.ts --teams=<ids>bun run scripts/import-deco-teams.ts [--no-legacy]→ thenbun run scripts/backfill-org-sites.ts --mapping=team-org-mapping.jsonWritten for commit bb9f2bc. Summary will update on new commits.