70 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# users-admin Specification
## Purpose
Администрирование доступа: пользователи, назначение ролей и матрица «роль × право» как данные (`role_permission`), с
аудитом; минимальный экран администратора во фронте.
## Requirements
### Requirement: Пользователи — список, создание, изменение, деактивация
Маршруты `/api/v1/admin/users` (право `USERS_ADMIN`): `GET` — список с ролями и филиалом (поиск по email/ФИО, фильтр
`is_active`, пагинация); `POST` — создание с обязательными `email` (уникален без учёта регистра → 409 `EMAIL_EXISTS`),
`full_name`, `regional_office_id`, необязательными `employee_no`, `business_segment`, `roles` (коды); `PATCH …/{id}` —
`full_name`, `employee_no`, `regional_office_id`, `business_segment`, `is_active`. Удаление MUST NOT предоставляться.
`external_id` через API не задаётся. Каждая мутация пишет `audit_event(USER_CHANGE, section = USERS)`.
#### Scenario: Создание с ролью
- **WHEN** администратор создаёт пользователя с `roles = ["KA_RF"]`
- **THEN** появляются `app_user` и `user_role`, `GET /me` от его имени (dev-токен) возвращает права `KA_RF`
#### Scenario: Email в другом регистре
- **WHEN** создаётся пользователь с email, отличающимся от существующего только регистром
- **THEN** ответ 409 `EMAIL_EXISTS`
### Requirement: Назначение ролей
`PUT /api/v1/admin/users/{id}/roles` (тело: список кодов) SHALL заменять набор ролей пользователя: отсутствующие в наборе
назначения удаляются, новые добавляются; неизвестный или неактивный код роли → 422; пишется `audit_event(USER_ROLE_CHANGE,
before_value = прежний набор, after_value = новый)`. Замена набора ролей MUST NOT оставить систему без активного пользователя с
`USERS_ADMIN` (409 `LAST_ADMIN`): администратор не может снять с себя последнюю роль, дающую `USERS_ADMIN`, если он —
единственный активный обладатель этого права; при наличии другого активного администратора снятие у себя разрешено
(решение №34).
#### Scenario: Замена набора ролей
- **WHEN** у пользователя роли `[KA_RF]`, администратор ставит `[KA_GO, EXPERT]`
- **THEN** `user_role` содержит ровно две новые строки, в аудите `before_value = ["KA_RF"]`, `after_value = ["KA_GO","EXPERT"]`
#### Scenario: Последний администратор
- **WHEN** единственный активный пользователь с `USERS_ADMIN` снимает с себя роль `ADMIN`
- **THEN** ответ 409 `LAST_ADMIN`, роли не изменены
### Requirement: Матрица прав
`GET /api/v1/admin/roles` SHALL отдавать роли с их правами; `GET /api/v1/admin/permissions` — справочник прав (16 кодов, только
чтение; создание прав MUST NOT предоставляться); `PUT /api/v1/admin/roles/{code}/permissions` (тело: список кодов прав) SHALL
заменять набор прав роли и писать `audit_event(ROLE_PERMISSION_CHANGE)` с before/after. Системные роли (`is_system`)
нельзя деактивировать или переименовать; нельзя снять `USERS_ADMIN` с роли, если после этого ни у одного активного
пользователя не останется этого права (409 `LAST_ADMIN`).
#### Scenario: Изменение матрицы
- **WHEN** у роли `EXPERT` добавляется право `EXPORT`
- **THEN** `role_permission` содержит новую строку, пользователь с ролью `EXPERT` при следующем запросе `/me` видит `EXPORT`,
в аудите `ROLE_PERMISSION_CHANGE`
#### Scenario: Снятие USERS_ADMIN с единственной роли
- **WHEN** у роли `ADMIN` (единственной с `USERS_ADMIN` у активных пользователей) убирают `USERS_ADMIN`
- **THEN** ответ 409 `LAST_ADMIN`
### Requirement: Минимальный экран администратора
SPA SHALL содержать маршрут `/admin` (пункт «Система → Пользователи и роли» в боковом меню), доступный при наличии
`USERS_ADMIN` в ответе `/api/v1/me`: таблица пользователей с выбором ролей и формой создания, таблица «роль × право» с
чекбоксами и кнопкой сохранения; запросы идут через общий API-клиент с заголовком `Authorization: Bearer`. В режиме
разработки SHALL быть доступен ввод email для получения dev-токена (`POST /api/v1/dev/token`); в сборке для прода этот
ввод отсутствует.
#### Scenario: Назначение роли через экран
- **WHEN** администратор на `/admin` выбирает пользователю роль `KA_GO` и сохраняет
- **THEN** вызывается `PUT /admin/users/{id}/roles`, таблица показывает новую роль, ошибка API показывается уведомлением
#### Scenario: Нет права
- **WHEN** пользователь без `USERS_ADMIN` открывает `/admin`
- **THEN** страница показывает сообщение об отсутствии доступа и не делает запросов к `/admin/*`