Сотрудники — Карточка
Три режима одного экрана: просмотр, создание, редактирование.
(Переработано в BR 1.4.4)
Enum
employees.roleудалён. Из формы убран dropdown «Менеджер / Кассир» и отдельное поле «Торговая точка». Остался единый блок «Роли» — multi-select permissions-ролей, у каждой свой набор ТТ. Признак «владелец франшизы / партнёра» определяется не ролью, а владением ЮЛ (scope-правила).
Просмотр (/employees/:id)
API: GET /api/v1/employees/{id}
Что видит пользователь
Заголовок — ФИО сотрудника. Рядом — статус (Активен / Деактивирован) и бейдж «Курьер» если флаг установлен.
Если сотрудник является владельцем (определяется на бэке через legal_entities.owner_user_id) — показывается бейдж:
- «Владелец франшизы» — если он
owner_user_idглавного ЮЛ (type=franchise) - «Владелец партнёра» — если он
owner_user_idЮЛtype=franchisee(рядом — название ЮЛ, ссылка на карточку)
(Бейджи «Менеджер / Кассир» убраны вместе с enum BR 1.4.4)
Кнопки в шапке (видимость по scope):
- “Редактировать” → переход в
/employees/{id}/edit - “Деактивировать” (status=active) / “Реактивировать” (status=inactive)
Блоки данных
Основные данные:
| Поле | Значение |
|---|---|
| Имя | first_name |
| Фамилия | last_name |
email | |
| Телефон | phone или ”—“ |
| Статус | ”Активен” / “Деактивирован” |
| Курьер | ”Да” / “Нет” |
Роли и торговые точки: (Обновлено в BR 1.4.4 — нет отдельного поля «Торговая точка»; ТТ показываются per-роль)
- Список permissions-ролей сотрудника (массив
roles[]). Каждая роль — карточка с названием и чипами привязанных ТТ - Скрытая роль владельца партнёра (если есть) отображается как «Собственные права» (без техназвания, см. Роли § Скрытые)
- Для владельца главного ЮЛ — подпись «Доступ ко всей франшизе»
- Для владельца партнёра — подпись «Доступ ко всем ТТ своих ЮЛ»
Создание (/employees/new)
API: POST /api/v1/employees
Доступ: владелец франшизы, владелец партнёра (в своём scope)
Что видит пользователь
Заголовок: “Новый сотрудник”. Форма с полями.
Форма
Основные данные:
| Поле | Тип ввода | Обязательно | Маска/Валидация |
|---|---|---|---|
| Имя | Text input | Да | max 255 |
| Фамилия | Text input | Да | max 255 |
| Text input | Да | email формат | |
| Пароль | Password input | Да | min 6 символов |
| Телефон | Text input | Нет | +7 (XXX) XXX-XX-XX |
| PIN-код | Text input | Нет | ровно 4 цифры |
| Курьер | Checkbox | Нет | Флаг “Может доставлять заказы” |
Блок «Роли» (Переработано в BR 1.4.4 — единый блок без enum)
Repeater: для каждой строки — Select роли + Multi-select ТТ:
| Поле | Тип ввода | Обязательно | Описание |
|---|---|---|---|
| Роль | Select | Нет | Из активных обычных ролей (GET /api/v1/admin/roles?status=active). Скрытые роли владельцев партнёров не отображаются в списке |
| Торговые точки | Multi-select | Нет | Из ТТ, доступных текущему пользователю по его scope |
- Кнопка «+ Добавить роль» — добавляет строку
- Кнопка «🗑 Удалить» в строке — убирает её
- Можно сохранить сотрудника без ролей (пустой массив) и добавить позже на вкладке «Роли и магазины»
Доступные ТТ по scope текущего пользователя:
- Владелец франшизы → любая ТТ франшизы
- Владелец партнёра → только ТТ его ЮЛ
- Обычный сотрудник → обычно не создаёт других (нет permission
employees.edit)
Нет поля «Multi-tenancy роль» и нет отдельного поля «Торговая точка»
(Удалено в BR 1.4.4) — раньше требовалось выбрать одну ТТ для
manager/cashier. Теперь набор ТТ задаётся через ТТ в каждой назначенной роли. Если сотрудник работает на одной ТТ — назначают одну роль с одной ТТ.
Валидация
- На клиенте: email формат, PIN ровно 4 цифры, пароль min 6, обязательные поля
- С сервера:
EMAIL_DUPLICATE— “Сотрудник с таким email уже существует”PIN_DUPLICATE— “PIN-код уже занят на торговой точке [название ТТ]”ROLE_STORE_OUT_OF_SCOPE— “Магазин недоступен в вашем scope” (под полем магазинов соответствующей строки)ROLE_NOT_FOUND— “Выбранная роль не существует или скрыта” (под Select роли)
(Удалено в BR 1.4.4)
Ошибки
ADMIN_ROLE_FORBIDDEN,ROLE_IMMUTABLE,ROLE_ESCALATIONбольше не существуют — enum-роли удалены, формы их не выбирают.
Кнопки
- “Сохранить” — отправить форму
- “Отмена” — возврат на список (с подтверждением если есть несохранённые данные)
После успеха
- Redirect на
/employees/{new_id}(карточка просмотра) - Toast: “Сотрудник создан”
Редактирование (/employees/:id/edit)
API: PATCH /api/v1/employees/{id}
Доступ: владелец франшизы — все сотрудники; владелец партнёра — только своих
Что видит пользователь
Та же форма что при создании, но:
- Поле Пароль — необязательное, placeholder “Оставьте пустым, если не хотите менять”
- Предзаполнены текущие значения
(Изменено в BR 1.4.4)
Поля «Multi-tenancy роль» больше нет — нечего блокировать. Permissions-роли можно свободно менять (добавлять/удалять/менять магазины).
Что нельзя менять через эту форму
- Признак владельца партнёра (управляется через
legal_entities.owner_user_id— карточка ЮЛ) - Скрытую роль владельца партнёра (управляется через карточку ЮЛ → вкладка «Права»)
Владелец партнёра — ограничения scope
- Может редактировать только сотрудников своих ТТ (своего scope)
- При попытке открыть чужого — 403, редирект на список
Кнопки
- “Сохранить” — отправить PATCH
- “Отмена” — возврат на карточку просмотра
После успеха
- Redirect на
/employees/{id}(карточка просмотра) - Toast: “Изменения сохранены”
Состояния
| Состояние | Что показываем |
|---|---|
| Загрузка (просмотр/edit) | Skeleton-блоки вместо полей |
| Сотрудник не найден (404) | “Сотрудник не найден” + кнопка “Вернуться к списку” |
| Ошибка сохранения | Ошибки под полями (validation) или toast (серверная ошибка) |
| Несохранённые изменения | При уходе со страницы: “У вас есть несохранённые изменения. Покинуть страницу?” |
Переходы
| Откуда | Куда | Триггер |
|---|---|---|
| Карточка | Список | Кнопка “Назад” / breadcrumb |
| Карточка | Редактирование | Кнопка “Редактировать” |
| Создание | Карточка | После успешного сохранения |
| Создание | Список | Кнопка “Отмена” |
| Редактирование | Карточка | После сохранения или “Отмена” |
BR 1.4.1 — Карточка с вкладками
Расширение в рамках BR 1.4.1
Карточка сотрудника переходит с плоской формы на 5-табовый layout. Все существующие поля сохраняются на вкладке “Общая информация”.
Вкладки
| # | Вкладка | Содержание | API |
|---|---|---|---|
| 1 | Общая информация | Текущие поля (ФИО, email, телефон, PIN, курьер) | GET /api/v1/employees/{id} |
| 2 | Роли и магазины | Permissions-роли с per-role магазинами + индивидуальная формула зарплаты | GET /api/v1/employees/{id}, GET /api/v1/salary-formulas/employee/{id} |
| 3 | Юридические детали | ИНН, паспорт, водительское удостоверение, СНИЛС | GET /api/v1/employees/{id}/legal-details |
| 4 | Рабочее время | Календарь часов (план/факт) | GET /api/v1/schedules?employee_id={id} |
| 5 | История заказов | Заглушка до Order Service (BR 2.1) | — |
Поведение
- Вкладки рендерятся как горизонтальные табы под заголовком карточки
- Default tab — “Общая информация”
- Переключение вкладок не меняет URL (состояние в компоненте)
- Кнопки “Редактировать”, “Деактивировать/Реактивировать” остаются в шапке (доступны на всех вкладках)
Вкладка “Роли и магазины”
(Переработано в BR 1.4.4 — секция «Multi-tenancy роль» удалена)
Блок «Permissions-роли» (что сотрудник может делать):
Список назначенных роль-объектов (каждая — карточка):
| Элемент | Описание |
|---|---|
| Название роли | Ссылка на /roles/:id. Скрытая роль владельца партнёра отображается как «Собственные права» без ссылки |
| Магазины | Чипы с названиями ТТ где эта роль действует. Если пусто — «Во всех доступных магазинах» |
| Действия | «Изменить магазины» / «Удалить роль у сотрудника» (для скрытой роли «Удалить» недоступно — управляется через карточку ЮЛ) |
Кнопка «Добавить роль» → модалка:
- Select из активных обычных ролей франшизы (
GET /api/v1/admin/roles?status=active); скрытые роли владельцев партнёров недоступны - Multi-select магазинов (из ТТ, доступных сотруднику-редактору по его scope)
- «Сохранить» → PATCH сотрудника с новым массивом
roles
Валидация:
- Нельзя добавить роль, которая уже назначена (показывать её disabled в select)
- Магазины — подмножество ТТ scope текущего пользователя
- Сервер возвращает
ROLE_STORE_OUT_OF_SCOPE→ сообщение под полем магазинов
Блок «Индивидуальная формула зарплаты» (без изменений, из BR 1.4.1)
- Если есть
salary_formulaдля сотрудника — показатьtype+ значения - Кнопка «Изменить формулу» (владельцы) — inline-редактирование или модалка
- Формула индивидуальная → перекрывает любую ролевую
Вкладка “Юридические детали”
- Поля:
inn,passport_series,passport_number,passport_issued_by,passport_issued_date,driver_license,snils - Режим просмотра → кнопка “Редактировать” для inline-edit
- API:
GET /api/v1/employees/{id}/legal-details,PUT /api/v1/employees/{id}/legal-details
Вкладка “Рабочее время”
- Мини-календарь с часами за текущий месяц
- Для каждого дня: плановые часы (из расписания) и фактические (из shift records)
- Итого внизу: сумма план / сумма факт
- Ссылка “Открыть расписание” →
/schedule?employee_id={id}
Вкладка “История заказов”
Заглушка
“История заказов будет доступна после подключения Order Service (BR 2.1)“