Problem
The seven /teams handlers (backend/internal/handler/team_handler.go, lines 61-67, 109-115, 151-157, 204-210, 259-265, 296-302, 362-368) repeat an in-handler admin check that reads the global users.role_id (currentUser.Role.Name != "admin"). #807 removed the same pattern from /users.
Today that check is never reached. The handlers look the caller up with claims.ID, which is the JWT id, not the user id (claims.Sub). So every /teams call answers 404 "User not found" before the role is read. RequireRole("admin") already guards the routes (cmd/server/main.go, --- Team Management ---). No frontend code calls /teams.
Removing the check would switch on a feature nobody has reviewed for tenant isolation. AddTeamMember in particular takes a userId from the path and does not visibly check that user's membership in the caller's tenant. So the check was left in place in #807, and this issue decides what happens next.
Acceptance criteria
- Decide whether
/teams is kept. If it is not, remove the routes and handlers, and remove them from docs/openapi.yaml if they are listed there.
- If kept: no handler reads
users.role_id. Authorization is the route guard or the membership role, and the caller is resolved from claims.Sub.
- If kept:
AddTeamMember refuses a user who is not an active member of the caller's tenant, and answers 404 for them exactly as it does for an unknown id.
- CLAUDE.md rule 4 tests:
Success, NotFound (foreign or unknown) and Unauthorized (non-admin gets 403).
Definition of Done
grep -n 'Role.Name != "admin"' backend/internal/handler/ returns nothing, and the tests for criteria 3-4 pass.
Found while working #807.
Problem
The seven
/teamshandlers (backend/internal/handler/team_handler.go, lines 61-67, 109-115, 151-157, 204-210, 259-265, 296-302, 362-368) repeat an in-handler admin check that reads the globalusers.role_id(currentUser.Role.Name != "admin"). #807 removed the same pattern from/users.Today that check is never reached. The handlers look the caller up with
claims.ID, which is the JWT id, not the user id (claims.Sub). So every/teamscall answers 404 "User not found" before the role is read.RequireRole("admin")already guards the routes (cmd/server/main.go,--- Team Management ---). No frontend code calls/teams.Removing the check would switch on a feature nobody has reviewed for tenant isolation.
AddTeamMemberin particular takes auserIdfrom the path and does not visibly check that user's membership in the caller's tenant. So the check was left in place in #807, and this issue decides what happens next.Acceptance criteria
/teamsis kept. If it is not, remove the routes and handlers, and remove them fromdocs/openapi.yamlif they are listed there.users.role_id. Authorization is the route guard or the membership role, and the caller is resolved fromclaims.Sub.AddTeamMemberrefuses a user who is not an active member of the caller's tenant, and answers 404 for them exactly as it does for an unknown id.Success,NotFound(foreign or unknown) andUnauthorized(non-admin gets 403).Definition of Done
grep -n 'Role.Name != "admin"' backend/internal/handler/returns nothing, and the tests for criteria 3-4 pass.Found while working #807.