Skip to content

feat(web,api,auth): people-tab pending invites + member management (#275)#278

Merged
Zach Dunn (zachdunn) merged 11 commits into
mainfrom
claude/people-tab-member-mgmt-275
Jul 20, 2026
Merged

feat(web,api,auth): people-tab pending invites + member management (#275)#278
Zach Dunn (zachdunn) merged 11 commits into
mainfrom
claude/people-tab-member-mgmt-275

Conversation

@zachdunn

@zachdunn Zach Dunn (zachdunn) commented Jul 20, 2026

Copy link
Copy Markdown
Member

Closes #275. Follow-up to #274, which added a read-only member list to the workspace people tab. This adds pending-invite listing with revoke, and member management (remove, change role) — all admin/owner-gated, on the user-facing /account/workspaces/:name/people surface only.

Permission matrix

Enforced in the auth worker (it owns the member/invitation tables); the /me API layer only coarse-gates (adminWorkspaceOr403 = admin|owner) and passes actorUserId.

Action Owner Admin
Remove a member
Remove an admin ❌ 403
Remove / modify an owner ❌ protected ❌ protected
Promote memberadmin / demote adminmember ❌ 403
Act on yourself ❌ 400 ❌ 400
Revoke a pending invite

The owner is immutable and unremovable (exactly one, set at provision), so "the last owner is never removed/demoted" holds without a counting query. The #260 last-admin guard protects the global admin() plugin, not org members, so this ships its own protections. Role changes are limited to admin↔member; owner is never a role-change source or target.

What's in it, per layer

  • Auth worker (apps/auth/src/internal-routes.ts) — 3 new internal routes (DELETE …/invites/:id, DELETE …/members/:memberId, PATCH …/members/:memberId), each enforcing the matrix via a shared actorRole helper. Direct drizzle, errorJson shape.
  • API (apps/api) — org-workspaces helpers (invitesForOrg/revokeInvite/removeMember/updateMemberRole) mapping auth errors to @uploads/errors, plus 4 adminWorkspaceOr403+allowWrite-gated /me routes. The members list now exposes the opaque member.id only to admin/owner callers — regular members keep today's sanitized payload with no handle.
  • Web (apps/web) — api-client calls, escaped render helpers (renderInvitesHtml + per-row controls in renderMembersHtml), and people-tab wiring: a Pending-invites section with revoke, and per-member role select + remove, suppressed on owner rows and your own row. confirm() on destructive actions; server is the real gate.

Management targets member.id, never the global userId.

Testing

  • Full repo suite 1672/1672 (137 files); @uploads/api + @uploads/auth types clean; @uploads/web typecheck 0 errors/0 warnings; oxfmt clean.
  • TDD per task (auth authz-matrix incl. owner/self protection; api route gating + id-exposure-by-role + helper error mapping; web status mapping + owner/self row exclusions).
  • Deferred: live populated-view browser verification needs the full 3-server stack + a seeded session/members/invite (same precedent as feat(web,api): tabbed workspace view with connected-work rail + folder-aware file listing #268). The logic is covered by the suite above plus per-layer and whole-branch review.

Notes

  • No changeset@uploads/auth, @uploads/api, @uploads/web are all on the changeset ignore list (Workers-deployed); a changeset would be release poison.
  • Spec + plan committed under docs/superpowers/.
  • Deferred Minors (non-blocking, from review): a few test-coverage nits (cross-org invite test, idempotent-write assertion, XSS-payload regression test) and a DRY gate-pair in me.ts. Can fold into a follow-up.

Summary by CodeRabbit

  • New Features
    • Added pending invite management, including viewing and revoking invites.
    • Added member management controls for authorized workspace administrators and owners.
    • Administrators can remove eligible members; owners can update member roles.
    • Added safeguards preventing self-removal, owner changes, and unauthorized actions.
    • Improved the People tab with role controls, removal actions, invite status, and confirmation feedback.
  • Bug Fixes
    • Improved handling and display of permission, validation, missing-resource, and service errors.

@zachdunn

Copy link
Copy Markdown
Member Author

CodeRabbit (@coderabbitai) review

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 20, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
uploads-web f9bdbd1 Commit Preview URL

Branch Preview URL
Jul 20 2026, 12:48 AM

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0dcfd344-8585-447e-a83c-30ea30376f96

📥 Commits

Reviewing files that changed from the base of the PR and between a001695 and f9bdbd1.

📒 Files selected for processing (14)
  • apps/api/src/org-workspaces.test.ts
  • apps/api/src/org-workspaces.ts
  • apps/api/src/routes/me.test.ts
  • apps/api/src/routes/me.ts
  • apps/auth/src/internal-routes.test.ts
  • apps/auth/src/internal-routes.ts
  • apps/web/src/lib/api-client.test.ts
  • apps/web/src/lib/api-client.ts
  • apps/web/src/lib/workspace-ui.test.ts
  • apps/web/src/lib/workspace-ui.ts
  • apps/web/src/pages/account/workspaces/[name]/people.astro
  • apps/web/src/styles/account-content.css
  • docs/superpowers/plans/2026-07-19-people-tab-member-management.md
  • docs/superpowers/specs/2026-07-19-people-tab-member-management-design.md

📝 Walkthrough

Walkthrough

Pending invite listing and revocation, member removal, and role updates now span auth routes, API helpers, /me routes, web client functions, and People tab controls with role-based authorization and tests.

Changes

Auth management

Layer / File(s) Summary
Internal authorization and mutations
apps/auth/src/internal-routes.ts, apps/auth/src/internal-routes.test.ts
Adds invite revocation, member removal, and role-update endpoints with owner/admin checks, self and owner protections, validation, and idempotent updates.

API management

Layer / File(s) Summary
Workspace helpers and routes
apps/api/src/org-workspaces.ts, apps/api/src/routes/me.ts
Adds invite/member helper functions, mapped errors, admin-gated /me endpoints, and conditional member ID exposure.
API validation coverage and design docs
apps/api/src/*.test.ts, docs/superpowers/specs/*
Tests API behavior and documents the permission model, endpoint contracts, and response shapes.

Web client contracts

Layer / File(s) Summary
Invite and member API client
apps/web/src/lib/api-client.ts, apps/web/src/lib/api-client.test.ts
Adds invite and member-management types and authenticated operations, including response and status normalization.

People tab controls

Layer / File(s) Summary
Rendering and interactions
apps/web/src/lib/workspace-ui.ts, apps/web/src/pages/account/workspaces/[name]/people.astro, apps/web/src/styles/account-content.css, apps/web/src/lib/*.test.ts
Adds pending-invite rendering, conditional member controls, revoke/remove/role-change handlers, reloads, alerts, and related styling and tests.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PeopleTab
  participant MeRoutes
  participant OrgWorkspaceHelpers
  participant AuthInternalRoutes
  PeopleTab->>MeRoutes: authenticated invite or member request
  MeRoutes->>OrgWorkspaceHelpers: invoke workspace operation
  OrgWorkspaceHelpers->>AuthInternalRoutes: internal organization request
  AuthInternalRoutes-->>OrgWorkspaceHelpers: result or status error
  OrgWorkspaceHelpers-->>MeRoutes: mapped result
  MeRoutes-->>PeopleTab: workspace response
Loading

Possibly related PRs

Suggested labels: coderabbit:review

Poem

I’m a rabbit with buttons to click,
Revoking invites with one tiny flick.
Members can shift, roles can grow,
Owners stay safe wherever they go.
The People tab now hops in a row!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/people-tab-member-mgmt-275

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
uploads-auth 9a5abf6 Commit Preview URL

Branch Preview URL
Jul 20 2026, 12:41 AM

… queries

/simplify pass on #275:
- extract loadTargetMember() in internal-routes.ts (was duplicated verbatim
  across the remove-member and change-role routes; removes drift risk on the
  self/owner-protection ordering)
- Promise.all the independent target/invite + actorRole lookups in the three
  mutating internal routes (one fewer sequential D1 round-trip per request;
  check ordering and response codes unchanged)
- drop the redundant `ok` param from manageResultFor (derivable from status)

No behavior change. auth 52/52, web api-client 32/32, full suite 1672/1672.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@zachdunn
Zach Dunn (zachdunn) merged commit 491b5eb into main Jul 20, 2026
2 of 3 checks passed
@zachdunn
Zach Dunn (zachdunn) deleted the claude/people-tab-member-mgmt-275 branch July 20, 2026 01:25
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.

People tab: pending invites + member management

1 participant