feat(api): Add OSS org-creation path and EE-shaped signup flow#4673
feat(api): Add OSS org-creation path and EE-shaped signup flow#4673jp-agenta wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR consolidates organization and membership management across OSS and EE by introducing a unified membership table schema (organization_members, workspace_members, project_members), refactoring shared organization creation and lifecycle helpers into OSS implementations, unifying account provisioning logic, and removing OSS-specific multi-organization restrictions. EE re-exports the OSS implementations where applicable. ChangesMembership and Organization Management Consolidation
🎯 4 (Complex) | ⏱️ ~75 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Railway Preview Environment
|
042bffd to
c4da60a
Compare
c4da60a to
8492cc4
Compare
9437bd2 to
339c787
Compare
8492cc4 to
83c2f59
Compare
774c502 to
548913d
Compare
83c2f59 to
bc9a071
Compare
Moves the org-creation core (org + owner membership + default workspace/ project + seeded defaults) into shared OSS code (oss commoners + db_manager); EE commoners slims to subscription/entitlement wrappers over it. OSS signup converges on the EE flow: personal org per allowed user, no first-user bootstrap, no invite-only gate. Mounts create/update/delete/transfer organization endpoints in OSS, lifts the admin-API multi-org block, and writes membership rows on invitation accept.
Adds acceptance tests for the OSS create/rename/transfer/delete organization endpoints and unit tests for can_create_organization. Lifts the leftover is_ee gates on the simple membership-create endpoints — they wrap the graph path, which already creates memberships in both editions.
bc9a071 to
2135ed8
Compare
Context
OSS has no way to mint a second organization: signup hard-codes a first-user bootstrap of one singleton org (slug
oss-default), later users must hold an invitation to that org, andPOST /organizations/exists only in EE. This PR is sequencing step 2 of the convergence plan (docs/designs/oss-ee-convergence/assessment-a-oss-multi-org.md): give OSS the same org-creation path and signup semantics as EE.Changes
The org-creation core moves into shared OSS code. New
oss/src/services/commoners.pyholdscan_create_organization(theAGENTA_ACCESS_ALLOWED_OWNER_EMAILScheck, moved verbatim from EE), the creation core (org row + owner membership + default workspace + default project + seeded testsets/evaluators/environments),create_organization_for_signup,create_organization_for_user, and an OSScreate_accountsthat mirrors the EE flow minus billing, demos, and marketing emails. EE'scommoners.pynow wraps the shared core with subscription provisioning and entitlement checks; its duplicated creation code indb_manager_ee.pyis deleted, and the membership writers (add_user_to_organization/workspace/project,add_user_to_workspace_and_org),transfer_organization_ownership,count_organizations_by_owner, anddelete_organizationmove to OSSdb_managerwith re-exports in place.Signup: the OSS branch of
_create_account(first-user bootstrap, invite-only check for everyone else) collapses to the samecreate_accounts(payload)call EE makes. Behavior change: a fresh signup now gets a personal org when the allowlist permits, instead of joining the singleton; users not allowed to create an org sign in org-less and join via invitation. Accepting an invitation now writes org/workspace/project membership rows (before, OSS only flipped the invitation'susedflag).Endpoints: OSS mounts
POST /organizations/,PUT/PATCH /organizations/{id},DELETE /organizations/{id}, andPOST /organizations/{id}/transfer/{new_owner_id}with plain owner checks (no RBAC/entitlements). They register only whenis_ee()is false, since the OSS router is mounted first and would otherwise shadow EE's gated versions.Admin API: the
OssMultiOrgNotSupportedErrorblock is gone; OSS accepts explicit org/workspace/project/memberships like EE, and membership rows are written through the shared models (the EE-onlyadmin_managerindirection is gone).Removed from OSS
db_manager:is_first_user_signup,get_or_bootstrap_oss_organization,setup_oss_organization_for_first_user,_assign_user_to_organization_oss,create_accounts,check_if_user_invitation_exists, and theINSERT ... ON CONFLICT (slug)singleton branch ofcreate_organization(slugs now stay NULL at creation, matching EE).Tests / notes
New acceptance suite
oss/tests/pytest/acceptance/accounts/test_organizations.py: create, list, rename, empty-update 400, delete, ownership transfer (and transfer-to-non-member rejection) through the new endpoints with an ApiKey-authed account.New unit tests for
can_create_organization(unit/services/test_commoners.py).Follow-up commit also lifts the leftover
is_eegates on the simple membership-create admin endpoints; they wrap the graph path this PR already ungated.ruff formatandruff checkpass; all touched files compile.get_default_workspace_id_oss()loses itsoss-defaultslug filter (it would break fresh deployments whose first org has no slug) but still picks the oldest workspace; the full membership-aware resolution of its callers is sequencing step 4.The remaining
OSS_SINGLETON_ORG_SLUGguards in the admin delete paths (refuse to delete the legacy singleton org/workspace) are left in place; they protect migrated deployments and go away with the step-4 sweep.Release note for operators: upgrading flips OSS from invite-only to open signup. Set
AGENTA_ACCESS_ALLOWED_OWNER_EMAILS/AGENTA_ACCESS_ALLOWED_DOMAINS(or block lists) before upgrading to keep a closed instance (access vars are enforced by the step-3 PR).What to QA
AGENTA_ACCESS_ALLOWED_OWNER_EMAILS=you@x.com: a different email can still sign up but gets no org; inviting them to a project and accepting works and grants access (membership rows now exist).POST /organizations/, rename it, transfer it to a member, delete it (deleting your last org is refused).🤖 Generated with Claude Code