Summary
Implement a super admin endpoint that batch-updates user roles. This is the second step of the "Set Admin" flow — after searching users by email, the super admin confirms and submits role changes (e.g., promoting hackers to admins).
Endpoint
PATCH /v1/superadmin/users/role
Auth: Requires super_admin role (behind RequireRoleMiddleware(store.RoleSuperAdmin))
Request Payload
{
"user_ids": ["uuid1", "uuid2"],
"role": "admin"
}
Validation
user_ids is required, must contain 1–50 entries
- Each
user_id must be a valid UUID
role is required, must be one of: "hacker", "admin" (NOT "super_admin" — reject with 400)
- The caller's own user ID must NOT be in the
user_ids list (prevent self-demotion/lockout — reject with 400)
- All user IDs must exist in the database, otherwise reject the entire request with 400
Response
200 OK
{
"data": {
"updated": [
{ "id": "uuid1", "email": "alice@utdallas.edu", "role": "admin" },
{ "id": "uuid2", "email": "bob@utdallas.edu", "role": "admin" }
]
}
}
400 Bad Request — invalid payload, self-inclusion, super_admin role attempted, or user IDs not found
403 Forbidden — caller is not a super admin
Implementation Details
Files to modify/create
| File |
Change |
internal/store/storage.go |
Add BatchUpdateRole(ctx context.Context, userIDs []string, role UserRole) ([]User, error) to the Users interface |
internal/store/users.go |
Implement BatchUpdateRole using UPDATE users SET role = $1 WHERE id = ANY($2) RETURNING id, email, role |
cmd/api/users.go |
Add batchUpdateUserRoleHandler (same file created in the search endpoint task) |
cmd/api/api.go |
Register r.Patch("/users/role", app.batchUpdateUserRoleHandler) under the super admin route group |
Store query
UPDATE users
SET role = $1
WHERE id = ANY($2)
RETURNING id, email, role
Handler logic
- Parse and validate request body
- Check that caller's user ID is not in the
user_ids list
- Check that
role is not super_admin
- Call
store.Users.BatchUpdateRole(ctx, userIDs, role)
- Verify the number of returned rows matches the input count (if not, some IDs didn't exist — return 400)
- Return updated users
Depends on
- Batch search users by email endpoint (for the
users.go handler file and store interface additions)
Labels
enhancement, good first issue
Summary
Implement a super admin endpoint that batch-updates user roles. This is the second step of the "Set Admin" flow — after searching users by email, the super admin confirms and submits role changes (e.g., promoting hackers to admins).
Endpoint
Auth: Requires
super_adminrole (behindRequireRoleMiddleware(store.RoleSuperAdmin))Request Payload
{ "user_ids": ["uuid1", "uuid2"], "role": "admin" }Validation
user_idsis required, must contain 1–50 entriesuser_idmust be a valid UUIDroleis required, must be one of:"hacker","admin"(NOT"super_admin"— reject with 400)user_idslist (prevent self-demotion/lockout — reject with 400)Response
200 OK
{ "data": { "updated": [ { "id": "uuid1", "email": "alice@utdallas.edu", "role": "admin" }, { "id": "uuid2", "email": "bob@utdallas.edu", "role": "admin" } ] } }400 Bad Request — invalid payload, self-inclusion,
super_adminrole attempted, or user IDs not found403 Forbidden — caller is not a super admin
Implementation Details
Files to modify/create
internal/store/storage.goBatchUpdateRole(ctx context.Context, userIDs []string, role UserRole) ([]User, error)to theUsersinterfaceinternal/store/users.goBatchUpdateRoleusingUPDATE users SET role = $1 WHERE id = ANY($2) RETURNING id, email, rolecmd/api/users.gobatchUpdateUserRoleHandler(same file created in the search endpoint task)cmd/api/api.gor.Patch("/users/role", app.batchUpdateUserRoleHandler)under the super admin route groupStore query
Handler logic
user_idslistroleis notsuper_adminstore.Users.BatchUpdateRole(ctx, userIDs, role)Depends on
users.gohandler file and store interface additions)Labels
enhancement, good first issue