GET /api/v1/roles — Список ролей компании
Список ролей, доступных в workspace компании актора: собственные роли компании (CompanyId = TenantId)
плюс системные роли платформы (CompanyId = null, IsSystem = true), назначимые её пользователям.
Основа UI «Роли и доступы».
Назначение
Пользователь с правом просмотра ролей видит каталог ролей своей организации с составом permissions и
количеством активных назначений. Owning-контекст — identity (дом полей —
domain/role.md). Feature group — roles.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | identity |
| API area | public |
| Feature group | roles |
| Статус | draft |
| Документ | docs/06-services/identity/api/company-user/list-company-roles.md |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | User (пользователь компании) |
| Auth policy / Permissions | identity.roles.view (дефолт: agent, agency-owner, developer-manager, care-operator) |
| Scope (RBAC) | организация: Active RoleAssignment со scope Platform или Organization(CompanyId) |
| Record-level | не применяется |
| Tenant isolation | TenantId = CompanyId: собственные роли видны только своей компании (CompanyId == TenantId); системные роли платформы (CompanyId == null) видимы всем (permission.md) |
| Audit | none |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/v1/roles |
| Success status | 200 |
| Idempotency header | не применяется |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|---|---|---|---|---|
UserId | identity claims | Guid | Да | Required | — |
CompanyId | identity claims (tenant_id) | Guid | Да | Required | Tenant isolation |
IncludeArchived | query | bool | Нет | default false | — |
IncludeSystem | query | bool | Нет | default true — показывать системные роли платформы | — |
Пейджинг не применяется
Ролей у компании — десятки: UI назначения требует полный список сразу.
Модель ответа GetCompanyRolesQueryResult
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|---|---|---|---|---|
Items | IReadOnlyList<RoleListItemModel> | Да | проекция | — | Роли: сперва компании (по Name), затем системные. |
RoleListItemModel
| Поле | Тип | Обязательность | Источник | Masking | Описание |
|---|---|---|---|---|---|
Id | Guid | Да | RoleDefinition.Id | — | Id роли. |
CompanyId | Guid? | Нет | RoleDefinition.CompanyId | — | null — системная роль платформы. |
Code | string | Да | RoleDefinition.Code | — | Машинный код. |
Name | string | Да | RoleDefinition.Name | — | Название. |
Description | string? | Нет | RoleDefinition.Description | — | Назначение роли. |
IsSystem | bool | Да | RoleDefinition.IsSystem | — | Системная — read-only для компании (INV-R1). |
Status | string (enum RoleStatus) | Да | RoleDefinition.Status | — | Active / Archived. |
PermissionCodes | IReadOnlyList<string> | Да | join RolePermission × PermissionDefinition.Code | — | Состав прав (коды каталога). |
ActiveAssignmentsCount | int | Да | computed: Count Active RoleAssignment по роли в scope компании | — | Сколько пользователей имеют роль. |
Version | long | Да | RoleDefinition.Version | — | Для optimistic-мутаций. |
Алгоритм
- Контекст и доступ. Операцию выполняет пользователь компании; tenant — его компания (
CompanyId); требуется правоidentity.roles.viewв scopeOrganization(CompanyId). Отсутствие claimtenant_id(инвестор) →IDENTITY_COMPANY_NOT_FOUND. - Что читаем. Роли, видимые в workspace: собственные роли компании (
CompanyId = TenantId) и — приIncludeSystem— системные роли платформы (CompanyId = null,IsSystem = true); при!IncludeArchived— толькоActive. Порядок: сперва роли компании (поName), затем системные. Для каждой роли — состав прав; коды прав берутся из in-memory SEED-каталога. Отдельно считается число активных назначений роли в scope компании. - Маппинг. Поле-в-поле по таблице item-модели:
PermissionCodes— коды прав роли,ActiveAssignmentsCount— счётчик назначений (0 при отсутствии). - Результат. Список ролей (
200). Актуальность — read-your-writes; состав прав берётся из SEED-каталога (иммутабелен вне релиза — расхождение исключено).
Диаграмма
Ошибки и failure modes
| Код | HTTP status | Условие | Сообщение | Retry |
|---|---|---|---|---|
ValidationError | 400 | Некорректные query-флаги | Список ошибок | no retry |
IDENTITY_COMPANY_NOT_FOUND | 404 | Claim tenant_id отсутствует (инвестор) | «Компания не найдена» | no retry |
FORBIDDEN | 403 | Нет identity.roles.view | «Недостаточно прав» | no retry |
Совместимость и наблюдаемость
- Новые optional поля item-модели — additive. Неизвестный
RoleStatusу клиента — трактовать как «read-only» (unknown enum handling). - Logs:
CompanyId, счётчик ролей; metrics:identity_roles_list_total{result}; traces: OTel; dashboardidentity-overview; runbook — не применяется.
Acceptance Criteria
- Given пользователь компании с
identity.roles.view, WhenGET /rolesс дефолтами, Then200; в списке —Activeроли компании (поName), затем системные роли платформы; у каждой —PermissionCodesиActiveAssignmentsCount. - Given
IncludeSystem = false, WhenGET /roles, Then в ответе только роли компании (CompanyId = TenantId), системные (CompanyId = null) отсутствуют. - Given
IncludeArchived = trueи есть архивная роль, WhenGET /roles, Then архивная роль присутствует соStatus = Archived. - Given роль назначена трём пользователям (Active), When
GET /roles, Then у этой ролиActiveAssignmentsCount = 3; у роли без назначений —0. - Given у актора нет claim
tenant_id, WhenGET /roles, ThenIDENTITY_COMPANY_NOT_FOUND(404). - Given актор без
identity.roles.view, WhenGET /roles, ThenFORBIDDEN(403). - Given только что создана роль через
create-company-role, When тот же пользователь запрашивает список, Then новая роль присутствует (read-your-writes).
Обратные ссылки
Автоссылки: где используется этот документ.
- API (1): Identity Company-User API — реестр методов и общие правила области
- registries (1): Реестр API-методов PIN