Skip to content

Add an endpoint that grants a person access to a project - #336

Merged
anuveyatsu merged 1 commit into
mainfrom
bead/jopacc-members-grant
Sep 25, 2026
Merged

anuveyatsu merged 1 commit into
mainfrom
bead/jopacc-members-grant

Conversation

@anuveyatsu

@anuveyatsu anuveyatsu commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

What

POST /v1/projects/{slug}/members grants a person a role on a project, by email (project.manage). It is additive: unlike PATCH /v1/projects/{slug} (which sets exactly the two accountable owners and would displace one to add a third person), this adds a member without touching the owners — so someone can hold full access alongside the owner and backup.

  • role defaults to project_lead ("full project context and execution within policy", i.e. full access) and is restricted to the project roles (project_lead, backup_operator, contributor, observer); org-level roles are refused.
  • Idempotent via ON CONFLICT DO NOTHING — a repeat grant is a no-op.

Why

Granting access is runtime data, not schema — a person's email is a business record the disclosure guard refuses in the public repo — so it belongs behind an endpoint, mirroring SetProjectOwners and SetProjectCell. The immediate driver: grant a third person full access to the JoPACC project without displacing its owner/backup.

Also

Makes SetProjectOwners' membership sync targeted: it removes only the outgoing owners' project_lead/backup_operator rows rather than every lead, so an additional full-access member granted through this endpoint survives a later owner change instead of being silently revoked.

Surface

Domain method + targeted-delete fix, control-api handler, route-action entry (project.manage), OpenAPI operation, api.addMember client, ManageMembers web control, nil-db validation test.

Command run

```
go build ./... && go vet ./internal/domain/ ./cmd/control-api/ && go test ./internal/domain/ ./cmd/control-api/
```
Output:
```
ok github.com/datopian/openbases/internal/domain 0.436s
ok github.com/datopian/openbases/cmd/control-api 0.640s
```
Web: `tsc --noEmit && vite build` → built in 342ms.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Project administrators can grant access to a project by email without changing its owners. Choose a role—project lead, backup operator, contributor, or observer—or leave it blank to use the project lead role. The result is confirmed on screen.
  • Bug Fixes
    • Changing project owners no longer removes membership access for other project leads.

@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: a909b182-485d-4656-8a7e-b329459c6b47

📥 Commits

Reviewing files that changed from the base of the PR and between 49f5e0e and e6604a0.

📒 Files selected for processing (8)
  • apps/web/src/App.tsx
  • apps/web/src/ProjectAdmin.tsx
  • apps/web/src/api.ts
  • cmd/control-api/projects.go
  • cmd/control-api/routeactions.go
  • internal/apispec/openapi.json
  • internal/domain/repositories.go
  • internal/domain/repositories_test.go
 ________________________________________________________
< Rust's borrow checker and I are on a first-name basis. >
 --------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

❤️ Share

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

POST /v1/projects/{slug}/members grants a member a role (project.manage),
by email. It is additive: unlike the owner PATCH, which sets exactly the two
accountable owners and would displace one to add a third person, this adds a
member without touching the owners -- so someone can hold full access
alongside the owner and backup. role defaults to project_lead ("full project
context and execution within policy", i.e. full access) and is restricted to
the project roles (project_lead, backup_operator, contributor, observer); the
org-level roles are refused. Idempotent via ON CONFLICT DO NOTHING.

Also makes SetProjectOwners' membership sync targeted: it removes only the
outgoing owners' project_lead/backup_operator rows rather than every lead, so
an additional full-access member granted through the new endpoint survives a
later owner change instead of being silently revoked.

Membership is runtime data, not schema, so this is the endpoint that changes
it, mirroring SetProjectOwners and SetProjectCell.

Adds a ManageMembers control to the web admin, the api.addMember client, the
OpenAPI operation, the route-action entry, and a nil-db validation test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@anuveyatsu
anuveyatsu force-pushed the bead/jopacc-members-grant branch from 523bcc6 to e6604a0 Compare September 25, 2026 09:07
@anuveyatsu
anuveyatsu merged commit 11d94e2 into main Sep 25, 2026
11 of 13 checks passed
@anuveyatsu
anuveyatsu deleted the bead/jopacc-members-grant branch September 25, 2026 09:11
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.

1 participant