1
0
forked from wrenn/wrenn

feat: admin grant/revoke from admin panel

Add PUT /v1/admin/users/{id}/admin endpoint and frontend UI for
granting and revoking platform admin status. Uses atomic conditional
SQL (RevokeUserAdmin) to prevent race conditions that could remove
the last admin. Includes idempotency check, audit logging, and
confirmation dialog with self-demotion warning.
This commit is contained in:
2026-05-03 15:24:34 +06:00
parent 4954b19d7c
commit cac6fcd626
8 changed files with 242 additions and 2 deletions

View File

@ -415,6 +415,21 @@ func (q *Queries) ListUsersAdmin(ctx context.Context, arg ListUsersAdminParams)
return items, nil
}
const revokeUserAdmin = `-- name: RevokeUserAdmin :execrows
UPDATE users u SET is_admin = false, updated_at = NOW()
WHERE u.id = $1
AND u.is_admin = true
AND (SELECT COUNT(*) FROM users WHERE is_admin = true AND status != 'deleted') > 1
`
func (q *Queries) RevokeUserAdmin(ctx context.Context, id pgtype.UUID) (int64, error) {
result, err := q.db.Exec(ctx, revokeUserAdmin, id)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const searchUsersByEmailPrefix = `-- name: SearchUsersByEmailPrefix :many
SELECT id, email FROM users WHERE email LIKE $1 || '%' ORDER BY email LIMIT 10
`