Skip to content

Team joining mode + self-service leave#2086

Merged
dimitri-tombroff merged 4 commits into
swiftfrom
feat/team-joining-mode-2084
Jul 24, 2026
Merged

Team joining mode + self-service leave#2086
dimitri-tombroff merged 4 commits into
swiftfrom
feat/team-joining-mode-2084

Conversation

@Maxime-DARAGON

Copy link
Copy Markdown
Contributor

Summary

  • TEAM-09 — replace Team.is_private with a 4-way joining_mode (open/request_only/invite_only/closed) marketplace model, plus self-service POST /teams/{team_id}/join for open teams. Marketplace discovery becomes unconditional (ReBAC public relation granted to every team); joining_mode only gates membership. Existing teams migrate to request_only, matching prior real-world behavior exactly.
  • AUTHZ-09 — allow any team member to leave a team via the existing DELETE /teams/{team_id}/members/{user_id} endpoint (same-identity bypass of the admin permission check); the last-admin invariant still applies, so a team's sole team_admin cannot leave. Team settings become reachable by every member, scoped per role: plain members get a read-only Members view plus a new "Leave team" action.
  • Two small UI fixes: left inset on the members table's first column, and color-ramp tokens prefixed core- to stop a silent collision with Radix Colors bundled inside @mdxeditor/editor (was corrupting --on-error app-wide once that editor's stylesheet loaded).

Commits

  • feat(TEAM-09): replace team is_private with joining_mode marketplace model
  • feat(AUTHZ-09): allow team members to leave a team
  • fix: inset the first column of the team members table
  • fix: prefix color ramp tokens with core- to avoid third-party collisions

Tracking

Test plan

  • Backend: make code-quality + make test (control-plane-backend) — 501 passed
  • Frontend: make code-quality (tsc/prettier/eslint) + make test — 597 passed
  • Manual: leave-team flow (plain member, elevated role, sole admin blocked) on a live stack

🤖 Generated with Claude Code

Maxime-DARAGON and others added 4 commits July 23, 2026 21:38
…model

Introduces JoiningMode (open/request_only/invite_only/closed) replacing the
former is_private bool, plus self-service POST /teams/{team_id}/join for
OPEN teams. Marketplace visibility is now unconditional for every team
(ReBAC public relation granted to all, backfilled lazily) — joining_mode
gates only membership, never discovery. Existing teams migrate to
request_only, matching the prior mailto-based behavior exactly.

Frontend: TeamSettingsParameters gets a 4-way ButtonGroup (extended with
per-item color override) replacing the private/public Switch; TeamCard's
mailto flow is replaced by joining_mode-driven rendering (instant join,
disabled request button, or a closed/invite-only label).

RFC: FRED-TEAM-CONFIG-RFC.md §5.1.1. Tracking: id-legend.yaml TEAM-09,
issue #2084.
Any team member can now remove themselves from a team via the existing
DELETE /teams/{team_id}/members/{user_id} endpoint (admin permission
check bypassed for same-identity calls) — the last-admin invariant still
applies, so a team's sole team_admin cannot leave. The team-settings
gear icon opens to every member instead of admins only, scoped per
role: plain members get a read-only Members view plus a new "Leave
team" action; elevated roles keep the existing full panel.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The first column's content sat flush against the table's left edge.
Added an opt-in firstColumnInset prop to the shared DataTable (default
off, so its other 3 consumers are unaffected) and enabled it on
TeamSettingsMembersTable.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mdxeditor/editor bundles Radix Colors, which defines its own --red-10
(and other ramp steps) on :root — colliding with ours and silently
corrupting --on-error (and any other token built on a colliding ramp
step) app-wide once that editor's stylesheet loads. Prefixed every ramp
family (indigo, light-blue, light-purple, cold-green, mustard, red,
cold-grey) with core- in color-ramps.css and updated every reference in
colors-semantic-{light,dark}.css and teamColor.ts (the only other
direct consumer).

Also switched --scrim's hue to pure black (rgb(0,0,0)), same opacity.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@dimitri-tombroff
dimitri-tombroff merged commit 26554c6 into swift Jul 24, 2026
63 checks passed
@dimitri-tombroff
dimitri-tombroff deleted the feat/team-joining-mode-2084 branch July 24, 2026 02:30
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.

2 participants