Роли — Карточка
Три режима одного экрана: просмотр, создание, редактирование.
Источники
- Бизнес: Роли
- BR: BR 1.4.3, BR 1.4.4
- API: User Service API
(Обновлено в BR 1.4.4)
Enum
admin_franchise/admin_franchisee/manager/cashierудалён. В матрицах доступа — колонки «Владелец франшизы / Владелец партнёра / Обычный сотрудник» (через scope + permissions). Карточка обычной роли работает только с обычными ролями: скрытые роли владельцев партнёров управляются через карточку ЮЛ (Юр. лица — Карточка § Права).
Общий layout (все режимы)
Шапка карточки:
- Breadcrumb: «Роли» → «{name или “Новая роль”}»
- Заголовок — название роли (в edit/new — пустой placeholder «Название роли»)
- Справа — бейдж «Системная роль» если
is_system=true - Кнопки (в зависимости от режима — см. ниже)
Табы под шапкой:
- Общее
- Разделы Бэк-офиса
- Функции POS
- Зарплата
Переключение вкладок не меняет URL (состояние в компоненте). Default tab — «Общее».
Вкладка 1: Общее
| Поле | Режим | Тип | Обязательно | Описание |
|---|---|---|---|---|
| Название роли | view: readonly / edit, new: text input | string | Да | max 100 символов |
| Описание | view: readonly (или «—») / edit, new: textarea | string | Нет | Короткое описание для чего эта роль |
| Системная | view: readonly (чекбокс-иконка) / edit, new: скрыто | bool | — | Задаётся системой при seed, редактируется только админом БД |
Информационный блок (только view):
- «Сотрудников с этой ролью: N» — ссылка ведёт на
/employees?role_id={id} - «Создана: DD.MM.YYYY» / «Изменена: DD.MM.YYYY»
Вкладка 2: Разделы Бэк-офиса
Таблица: 17 разделов × {Read, Edit} — чекбоксы (15 разделов с обеими галочками, 2 только Read). Источник лейблов — GET /api/v1/admin/roles/permission-catalog (секция backoffice).
Layout таблицы
| Раздел | Чтение | Редактирование |
|---|---|---|
| Меню | ☐ | ☐ |
| Прейскуранты | ☐ | ☐ |
| Техкарты | ☐ | ☐ |
| Ингредиенты | ☐ | ☐ |
| Стоп-листы | ☐ | ☐ |
| Склад | ☐ | ☐ |
| Торговые точки | ☐ | ☐ |
| Юридические лица | ☐ | ☐ |
| Сотрудники | ☐ | ☐ |
| Роли | ☐ | ☐ |
| Расписание смен | ☐ | ☐ |
| Учёт рабочего времени | ☐ | ☐ |
| Зарплата | ☐ | ☐ |
| Дашборд | ☐ | (нет, колонка disabled) |
| Отчёты | ☐ | (нет, колонка disabled) |
| Заказы | ☐ | ☐ |
| Настройки | ☐ | ☐ |
Правила
- Edit implies Read: при включении чекбокса в колонке «Редактирование» автоматически включается соответствующий «Чтение» (визуально, без запроса). При снятии «Чтение» — снимается и «Редактирование».
- Разделы без Edit (
dashboard,reports): колонка «Редактирование» пустая/disabled с tooltip «Редактирование не поддерживается». - В шапке таблицы — две вспомогательные ссылки «Выбрать всё» / «Снять всё» (для ускорения настройки).
View-режим
Всё то же, но чекбоксы disabled. Галочки там, где granted=true.
Вкладка 3: Функции POS
Список 14 операций с чекбоксами on/off. Источник лейблов — permission-catalog.pos.
Layout
| Операция | Флаг |
|---|---|
| Доступ к POS | ☐ |
| Открытие смены | ☐ |
| Закрытие смены (Z-отчёт) | ☐ |
| Создание заказов | ☐ |
| Редактирование заказа | ☐ |
| Применение скидок | ☐ |
| Внесение наличных | ☐ |
| Изъятие наличных | ☐ |
| Инкассация | ☐ |
| Возврат средств | ☐ |
| Аннулирование заказа | ☐ |
| Аннулирование позиции | ☐ |
| Изменение цены (товары с открытой ценой) | ☐ |
| Изменение настроек кассы | ☐ |
Вспомогательные «Выбрать всё» / «Снять всё» — также.
(Deferred — BR 1.4.3)
Лимиты Min/Max на отдельных операциях (например, «не более 5000₽ за изъятие») — в MVP не реализуются. См. Роли § Deferred.
Вкладка 4: Зарплата
Блок формулы зарплаты для роли. Одна формула на роль на всю франшизу.
Поля
| Поле | Тип | Показывается когда |
|---|---|---|
| Тип формулы | Select: «Без формулы» / «Почасовая» / «Оклад» / «Смешанная» | Всегда |
| Почасовая ставка, ₽ | Number | Тип = Почасовая или Смешанная |
| Оклад за месяц, ₽ | Number | Тип = Оклад или Смешанная |
| Ставка за переработку, ₽/час | Number | Тип = Смешанная |
| Норма часов, мес | Number (default 160) | Тип = Смешанная |
Выбор «Без формулы» → все поля скрыты. Зарплата сотрудников с этой ролью не будет рассчитываться, если нет индивидуальной формулы.
Подпись внизу блока: «Эта формула применяется ко всем сотрудникам с этой ролью, если у них нет индивидуальной формулы. Смотри Платёжные ведомости.»
(Deferred — BR 1.4.3)
Различные ставки по ТТ — в MVP не реализуются. Подробнее — Роли § Deferred.
View-режим
Компактный вид:
- Если формула задана: «Почасовая, 500 ₽/час» или «Оклад, 60 000 ₽/мес» и т.п.
- Если не задана: «Без формулы для этой роли»
Кнопки и действия
Режим просмотра (/roles/:id)
(Обновлено в BR 1.4.4 — без enum)
| Кнопка | Видимость |
|---|---|
| Редактировать | Владелец франшизы, и не системная (для системной — только редактирование вкладки «Общее») |
| Удалить | Владелец франшизы, не системная, employee_count == 0 |
| Назад | Всегда, возврат к /roles |
Кто может CRUD ролей
| Действие | Владелец франшизы | Владелец партнёра | Обычный сотрудник |
|---|---|---|---|
| Просмотр карточки | Все обычные роли | Только роли своих сотрудников (фильтр на бэке) | Если есть roles.read |
| Создание / редактирование | Да | Нет (scope) | roles.edit (обычно не выдаётся) |
| Удаление | Да | Нет | roles.edit |
Режим создания / редактирования
| Кнопка | Действие |
|---|---|
| Сохранить | POST / PATCH запрос |
| Отмена | Возврат на предыдущую страницу (с подтверждением если есть несохранённые изменения) |
Валидация и ошибки
Клиент
- Название обязательно, max 100
- Описание — max 500
- Edit implies Read — авто, без ошибок
- Формула: если
type != "Без формулы", соответствующие числовые поля обязательны и > 0
Сервер
| Code | HTTP | Где показывать |
|---|---|---|
NAME_DUPLICATE | 409 | Под полем «Название»: «Роль с таким названием уже есть» |
UNKNOWN_PERMISSION_KEY | 400 | Общий toast «Некорректный ключ прав — обновите страницу и повторите» |
SYSTEM_ROLE_PROTECTED | 422 | Toast «Нельзя изменять права системной роли» |
ROLE_NOT_FOUND | 404 | Страница «Роль не найдена» + кнопка «К списку» |
VALIDATION_ERROR | 400 | Под соответствующим полем |
Удаление роли
Сценарий 1: employee_count == 0
- Клик «Удалить» → модалка: «Удалить роль “{name}“? Она перенесётся в архив и её можно будет восстановить.»
- Подтверждение → DELETE → toast «Роль перенесена в архив» → redirect на
/roles
Сценарий 2: ROLE_IN_USE (409)
- DELETE возвращает 409 со списком
employee_id[]вdetails - Модалка меняется на предупреждение: «Эта роль назначена {N} сотрудникам. Снимите роль со всех сотрудников перед удалением.»
- Кнопки: «Открыть список сотрудников» (→
/employees?role_id={id}) / «Отмена»
Системная роль «Администратор»
(Обновлено в BR 1.4.4 §5.1 — выдаётся владельцу франшизы и владельцу партнёра в режиме «Полный доступ»)
Системная роль автосоздаётся при bootstrap франшизы. Полный набор permissions включая pos.access. Выдаётся:
- Владельцу франшизы — при bootstrap
- Владельцу партнёра — если в карточке ЮЛ выбран режим «Полный доступ» (см. Юр. лица — Карточка § Права)
Режим просмотра:
- Все вкладки видны
- Чекбоксы Back-office и POS отмечены полностью, но disabled
- На каждой вкладке кроме «Общее» — информер (блок): «ℹ️ Это системная роль. Права зафиксированы и не могут быть изменены.»
Режим редактирования:
- Вкладка «Общее»: можно менять только название и описание
- Остальные вкладки disabled с тем же информером
- Попытка сохранить с изменёнными permissions →
SYSTEM_ROLE_PROTECTED(теоретически, UI это предотвращает)
Удаление системной роли недоступно: кнопка «Удалить» скрыта.
Скрытые роли владельцев партнёров
(Введено в BR 1.4.4 §5.2)
Если для владельца партнёра выбран режим «Настроенные права», для него создаётся скрытая персональная роль (owner_legal_entity_id != NULL).
Где НЕ отображаются:
- В списке
/admin/roles— фильтрowner_legal_entity_id IS NULLна бэке (default) - В Select ролей при создании/редактировании обычного сотрудника
- В фильтре «Permissions-роль» в списке сотрудников
Где управляются:
- Только через карточку ЮЛ партнёра, вкладка «Права» — см. Юр. лица — Карточка § Права
- Карточка
/roles/:idдля скрытой роли — недоступна (404 при прямом URL); либо открывается с информером «Эта роль управляется через карточку ЮЛ» + ссылкой на ЮЛ
Минимум permissions (форсится UI и бэком):
pos.access,stores.read,employees.read— чекбоксы заблокированы (нельзя снять)
Состояния
| Состояние | Что показываем |
|---|---|
| Загрузка | Skeleton для табов и полей |
| Роль не найдена (404) | Страница «Роль не найдена» + кнопка «К списку ролей» |
| Загрузка permission-catalog | Inline-spinner внутри вкладок Back-office/POS |
| Несохранённые изменения | При уходе: «У вас есть несохранённые изменения. Покинуть страницу?» |
Переходы
| Откуда | Куда | Триггер |
|---|---|---|
| Список ролей | Карточка просмотра | Клик по строке |
| Карточка | Редактирование | Кнопка «Редактировать» |
| Карточка | Список сотрудников с фильтром | Клик по employee_count > 0 или по ссылке в модалке удаления |
| Создание | Просмотр новой роли | После успешного POST |