Skip to content

feat(web): disable member invites for child organizations#4257

Merged
RSO merged 3 commits into
mainfrom
neat-radar
Jun 25, 2026
Merged

feat(web): disable member invites for child organizations#4257
RSO merged 3 commits into
mainfrom
neat-radar

Conversation

@RSO

@RSO RSO commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Child organizations now manage membership exclusively through their parent organization. This disables the self-serve invite flow for child orgs (orgs where parent_organization_id IS NOT NULL) in both the backend and the UI.

Changes

  • Block sending invitesinviteUserToOrganization rejects child orgs (Child organizations cannot invite members). The organizations.members.invite tRPC handler maps this to PRECONDITION_FAILED with a user-facing message: "Child organizations manage membership through their parent organization."
  • Block accepting invitesacceptOrganizationInvite rejects redeeming any invitation (including pre-existing/legacy ones) into a child org, so no membership can be created that way.
  • Hide the UI — the "Invite Member" button is hidden for child orgs in OrganizationMembersCard (the withMembers query already returns parent_organization_id).

Scope / decisions

  • SSO needs no change. The SSO authority for a domain is always a top-level org (resolveAuthorityForNormalizedDomain treats a child-owned domain as conflicting_child_policy), so SSO auto-join always targets the parent/standalone org — never a child.
  • Left untouched (admin/system override paths): Kilo-admin direct add (admin.addMember), the Stripe seat webhook owner re-add, OSS sponsorship onboarding, and org creation (creator-as-owner; orgs have no parent at creation).

Tests

  • Replaced obsolete child-org invite/accept SSO-inheritance tests with rejection tests in organizations.test.ts.
  • Added a tRPC router test asserting child-org invites return PRECONDITION_FAILED.
  • Verified: web typecheck passes; organizations.test.ts, organization-members-router.test.ts, and organization-subscription-event.test.ts all green.

Child organizations now manage membership through their parent
organization, so direct invites into a child org are no longer allowed.

- inviteUserToOrganization rejects child orgs; members.invite maps this
  to a PRECONDITION_FAILED with a user-facing message
- acceptOrganizationInvite rejects redeeming any (including legacy)
  invitation into a child org
- hide the Invite Member button for child orgs in OrganizationMembersCard
- update tests to encode the new behavior
@RSO RSO marked this pull request as ready for review June 25, 2026 11:49
@kilo-code-bot

kilo-code-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (1 files)
  • apps/web/src/routers/organizations/organization-members-router.ts
Previous Review Summary (commit b826308)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit b826308)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (5 files)
  • apps/web/src/components/organizations/OrganizationMembersCard.tsx
  • apps/web/src/lib/organizations/organizations.test.ts
  • apps/web/src/lib/organizations/organizations.ts
  • apps/web/src/routers/organizations/organization-members-router.test.ts
  • apps/web/src/routers/organizations/organization-members-router.ts

Reviewed by gpt-5.4-20260305 · Input: 37K · Output: 4K · Cached: 180K

Review guidance: REVIEW.md from base branch main

@RSO RSO merged commit 44064a4 into main Jun 25, 2026
20 checks passed
@RSO RSO deleted the neat-radar branch June 25, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants