feat(users): admin promote/demote endpoints

POST /users/{id}/promote and /demote set a user's role (admin/user), admin-only
(403 otherwise). Mirrors the verify endpoints: SetRole use case + repo method,
validated role. Unit, admin-flow, and integration tests included.
This commit is contained in:
Efremenko Arhip
2026-07-26 21:14:32 +03:00
parent 49eb662798
commit 9a458ec4ef
13 changed files with 167 additions and 0 deletions
@@ -85,6 +85,27 @@ func (r *UserRepo) SetVerified(ctx context.Context, id uuid.UUID, verified bool)
return nil
}
// SetRole changes a user's role and returns ErrUserNotFound when the id matches
// no row.
func (r *UserRepo) SetRole(ctx context.Context, id uuid.UUID, role domain.Role) error {
sql, args, err := psql.Update("users").
Set("role", string(role)).
Set("updated_at", sq.Expr("now()")).
Where(sq.Eq{"id": id}).
ToSql()
if err != nil {
return err
}
tag, err := conn(ctx, r.pool).Exec(ctx, sql, args...)
if err != nil {
return err
}
if tag.RowsAffected() == 0 {
return usecase.ErrUserNotFound
}
return nil
}
func scanUser(row pgx.Row) (*domain.User, error) {
var (
u domain.User