Feat v0.9.3 team user roles
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-runners (pull_request) Has been skipped
CI/CD / e2e-smoke (pull_request) Has been skipped
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Successful in 2m49s
CI/CD / test-sqlite (pull_request) Successful in 2m57s
CI/CD / build-and-deploy (pull_request) Successful in 1m19s

Promote team roles to a kernel primitive with many-to-many support.
Users can now hold multiple roles within a team simultaneously.

- Migration 016: team_user_roles table (both dialects)
- 6 new TeamStore methods (AddUserRole, RemoveUserRole, ListUserRoles,
  GetMemberRoles, HasRole, RemoveAllUserRoles)
- RequireRole() middleware with OR semantics and system admin bypass
- 3 new handler endpoints for member role CRUD
- Manifest requires_roles field (advisory for v0.9.3)
- Starlark teams module: get_member_roles(), has_role()
- Team-admin UI: role badge chips + assignment dropdown
- Fixed pre-existing SDK auto-unwrap bug in loadRoles
- 10 new tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-03 15:22:37 +00:00
parent 0cae963480
commit 23dddae0c5
17 changed files with 852 additions and 12 deletions

View File

@@ -2,6 +2,60 @@
All notable changes to Armature are documented here.
## v0.9.3 — Team User Roles
Promotes the team role system from a single-role-per-member model to a
many-to-many relationship, enabling users to hold multiple roles within
a team simultaneously.
**Schema**
- Migration 016: `team_user_roles` table (team_id, user_id, role) with
unique constraint and compound index. Both Postgres and SQLite dialects.
**Store + Models**
- `TeamUserRole` model struct.
- 6 new `TeamStore` methods: `AddUserRole`, `RemoveUserRole`,
`ListUserRoles`, `GetMemberRoles` (union of primary + additional),
`HasRole`, `RemoveAllUserRoles`.
- Implementations for both Postgres and SQLite stores.
**Middleware**
- `RequireRole(teams, roles, stores)` — kernel middleware that checks
whether the user holds at least one of the required roles (OR semantics).
System admin bypass via permissions.
**Handlers**
- `GET /teams/:teamId/members/:memberId/roles` — list full role set.
- `POST /teams/:teamId/members/:memberId/roles` — assign additional role.
- `DELETE /teams/:teamId/members/:memberId/roles/:role` — remove role.
- `RemoveMember` handler now cleans up `team_user_roles` on member removal.
**Manifest**
- `requires_roles` field parsed from package manifests (advisory in v0.9.3;
extensions gate via `teams.has_role()` in Starlark).
**Starlark SDK**
- New `teams` module wired into sandbox runner:
- `teams.get_member_roles(team_id, user_id)` → list of strings.
- `teams.has_role(team_id, user_id, role)` → True/False.
**Admin UI**
- Team-admin members page: removable badge chips for additional roles,
"+ Role" dropdown for assignment.
- Fixed pre-existing SDK auto-unwrap bug in `loadRoles` / `loadMemberRoles`.
**Tests**
- 10 new tests: store CRUD (add, idempotent, has_role, remove, removeAll),
middleware (allowed, denied), manifest parsing (valid, empty, invalid).
## v0.9.2 — Starlark Converter Consolidation + Snapshot Cleanup
Consolidates duplicated Go↔Starlark conversion code and snapshot