Отчёт №2 — Таблица доступов и план переписывания прав
Документ подготовлен после согласования отчёта №1. Содержит: большую таблицу доступов (раздел × подраздел × роль), рекомендуемые шаблоны прав, пошаговый план переписывания логики прав и чек-лист файлов для правок.
1. Большая таблица доступов
Уровни: — нет доступа, Ч чтение, Р редактирование, С только своё. По умолчанию для роли везде, где раздел доступен, используется Р (редактирование).
1.1 Сводка (dashboard)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Стратегические цели |
Р |
Р |
— |
Р |
Р |
Р |
Р |
| Панель «Производство» |
Р |
Р |
Р¹ |
Р |
Р |
Р |
Р |
| Панель «PR и клиентский опыт» |
Р |
Р |
— |
Р |
Р |
Р |
Р |
| Панель «Финансы» |
Р |
Р |
— |
Р |
Р |
Р |
Р |
| Панель «Развитие» |
Р |
Р |
— |
Р |
Р |
Р |
Р |
| Панель «Юр. отдел» |
Р |
Р |
— |
Р |
Р |
Р |
Р |
| Панель «Кадры» |
Р |
Р |
— |
Р |
Р |
Р |
Р |
| Мои задачи |
Р |
Р |
— |
Р |
Р |
Р |
Р |
| Новости компании |
Р |
Р |
— |
Р |
Р |
Р |
Р |
1.2 Участки (objects)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Обзор участков |
Р |
Р |
Р* |
Р |
Р |
— |
— |
| Дома |
Р |
Р |
Р* |
Р |
Р |
— |
— |
| Штат участка |
Р |
Р |
Р* |
Р |
Р |
— |
— |
* MASTER: по умолчанию scope = только свой участок (см. п. 1.10).
1.3 Заявки (requests)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Сводка |
Р |
Р |
Р* |
Р |
— |
— |
Р |
| Реестр заявок |
Р |
Р |
Р* |
Р |
— |
— |
Р |
| Контроль |
Р |
Р |
Р* |
Р |
— |
— |
Р |
| Качество |
Р |
Р |
Р* |
Р |
— |
— |
Р |
| Привязки |
Р |
Р |
Р* |
Р |
— |
— |
Р |
| Отключения |
Р |
Р |
Р* |
Р |
— |
— |
Р |
1.4 PR и NPS (pr)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Сводка |
Р |
— |
— |
— |
— |
— |
Р |
| SMM |
Р |
— |
— |
— |
— |
— |
Р |
| Мероприятия |
Р |
— |
Р¹ |
— |
— |
— |
Р |
| Обратная связь |
Р |
— |
— |
— |
— |
— |
Р |
| Отчёты |
Р |
— |
— |
— |
— |
— |
Р |
| Фото работ |
Р |
— |
Р¹ |
— |
— |
— |
Р |
| NPS |
Р |
— |
— |
— |
— |
— |
Р |
| Негатив |
Р |
— |
— |
— |
— |
— |
Р |
1.5 Финансы (finance)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Сводка |
Р |
— |
— |
— |
Р |
— |
— |
| Реестр счетов |
Р |
— |
С¹ |
— |
Р |
— |
— |
| Календарь оплат |
Р |
— |
Р¹ |
— |
Р |
— |
— |
| Отчёты |
Р |
— |
— |
— |
Р |
— |
— |
1.6 Юр. отдел (legal)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Сводка |
Р |
— |
— |
Р |
— |
— |
— |
| Взыскание долгов |
Р |
— |
— |
Р |
— |
— |
— |
| Договоры |
Р |
— |
— |
Р |
— |
— |
— |
| Судебные дела |
Р |
— |
— |
Р |
— |
— |
— |
| Досудебная работа |
Р |
— |
— |
Р |
— |
Р |
— |
| Соответствие |
Р |
— |
— |
Р |
— |
— |
— |
1.7 Развитие (development)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Сводка |
Р |
Р |
— |
— |
— |
— |
— |
| Реестр объектов |
Р |
Р |
— |
— |
— |
— |
— |
| ОСС |
Р |
Р |
— |
— |
— |
— |
— |
| Техаудит |
Р |
Р |
— |
— |
— |
— |
— |
| Маркетинг |
Р |
Р |
— |
— |
— |
— |
— |
1.8 Кадры (hr)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Сводка |
Р |
— |
— |
— |
— |
Р |
— |
| Сотрудники |
Р |
— |
— |
— |
— |
Р |
— |
| Календарь |
Р |
— |
— |
— |
— |
Р |
— |
| Вакансии |
Р |
— |
— |
— |
— |
Р |
— |
| Подбор |
Р |
— |
— |
— |
— |
Р |
— |
| Охрана труда |
Р |
— |
— |
— |
— |
Р |
— |
1.9 Офис (office)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Сводка |
Р |
Р |
— |
— |
Р |
Р |
— |
| Закупки |
Р |
Р |
Р¹ |
— |
Р |
Р |
— |
| Документы |
Р |
Р |
— |
— |
Р |
Р |
— |
| Объекты |
Р |
Р |
— |
— |
Р |
Р |
— |
| Ремонты |
Р |
Р |
Р¹ |
— |
Р |
Р |
— |
| База знаний |
Р |
Р |
— |
— |
Р |
Р |
— |
| Встречи |
Р |
Р |
— |
— |
Р |
Р |
— |
| Новости |
Р |
Р |
— |
— |
Р |
Р |
— |
1.10 Панель управления (admin)
| Подраздел |
DIRECTOR |
ENGINEER |
MASTER |
LAWYER |
FINANCIER |
HR_MANAGER |
PR_MANAGER |
| Все подразделы |
Р |
— |
— |
— |
— |
— |
— |
Только роль DIRECTOR по умолчанию имеет доступ к разделу admin. Остальные роли — нет доступа (при необходимости доступ задаётся кастомными permissions).
1.11 Ограничение по участкам
| Роль |
Ограничение по участкам |
| DIRECTOR |
Все участки |
| ENGINEER |
Все участки |
| MASTER |
Только свой участок (свои назначенные участки) |
| LAWYER |
Все участки |
| FINANCIER |
Все участки |
| HR_MANAGER |
Все участки |
| PR_MANAGER |
Все участки |
Список «своих» участков формируется из employee_districts с fallback на employees.assigned_district_id.
¹ MASTER: доступ по шаблону «Мастер участка (расширенный)» — при назначении шаблона подставляются permissions (в т.ч. dashboard_production, finance_invoices:own, finance_calendar, office_supply, office_repair, pr_events, pr_photos), scope = own_district. Реестр счетов для мастера — уровень «только своё» (С): видны только счета, созданные им (scope=own в API).
2. Шаблоны прав
Рекомендуемые шаблоны для быстрого назначения прав пользователям. Каждый шаблон задаёт permissions (массив ключей раздел/подраздел:уровень), scope и suggested_role.
| Название шаблона |
Разделы и подразделы (уровень) |
Рекомендуемая роль |
Scope |
Назначение |
| Мастер участка |
objects (все подразделы), requests (все подразделы) |
MASTER |
own_district |
Мастер: участки и заявки только по своим участкам. |
| Мастер участка (расширенный) |
objects, requests, dashboard_production, finance_invoices:own, finance_calendar, office_supply, office_repair, pr_events, pr_photos |
MASTER |
own_district |
Мастер: участки, заявки, сводка (производство), реестр счетов (только свои), календарь оплат, закупки ТМЦ, ремонт техники, мероприятия и фото отчёты по своим домам. |
| Гл. инженер |
dashboard, objects, requests, office, development (все подразделы — edit) |
ENGINEER |
all |
Производство, участки, заявки, офис, развитие. |
| Начальник PR |
dashboard, pr, requests (все подразделы — edit) |
PR_MANAGER |
all |
PR и NPS, заявки, сводка. |
| Финансист |
dashboard, finance, office, objects (все подразделы — edit) |
FINANCIER |
all |
Финансы, офис, участки (для отчётности). |
| HR-менеджер |
dashboard, hr, office (все подразделы — edit) |
HR_MANAGER |
all |
Кадры, офис. |
| Юрист |
dashboard, legal, objects, requests (все подразделы — edit) |
LAWYER |
all |
Юр. отдел, участки, заявки. |
| Только чтение (сводка и участки) |
dashboard:read, objects:read (подразделы — read) |
ENGINEER или MASTER |
all / own_district |
Просмотр без редактирования. |
В интерфейсе админки шаблоны отображаются как справочник: при создании/редактировании пользователя можно применить шаблон — подставляются permissions, scope и при необходимости suggested_role. Таблица доступов (раздел × подраздел) остаётся единой; шаблон — это готовый набор строк этой таблицы для выбранной роли и scope.
3. План переписывания прав
3.1 Единый источник прав
- Создать один модуль констант: коды ролей, названия ролей (ROLE_NAMES), список разделов (SECTION_IDS / ALL_SECTION_KEYS), матрица «роль → разделы по умолчанию» (ROLE_ACCESS), матрица «роль → scope по умолчанию» (например ROLE_DEFAULT_SCOPE).
- Варианты реализации: (1) общий файл в репозитории, импортируемый и на фронте (TypeScript), и на бэкенде (через require/импорт JS-версии или общий JSON); (2) генерация из одного JSON/YAML в constants для фронта и в константы для Node. Цель: убрать дублирование ROLE_ACCESS, ROLE_NAMES, SECTION_IDS в App.tsx, Navigation.tsx, server.js, UsersSection.tsx, PermissionsSection.tsx.
- В constants/permissions.ts оставить SECTION_LABELS, SECTION_SUBS, функции canAccessSub, getPermissionLevel, allowedSubsForSection и т.д.; роли и ROLE_ACCESS импортировать из единого источника.
3.2 Изменения в БД
- Миграции при необходимости: структура portal_users (role, permissions, scope) и permission_templates не меняется. При scope=own_district во всех API, где идёт фильтр по участку, единообразно использовать список district_id из employee_districts с fallback на assigned_district_id (см. п. 3.4).
3.3 Фронт
- Заменить все проверки «по роли» на единые функции из общего модуля прав с учётом permissions и scope. Логика уже опирается на allowedSections и userPermissions из /auth/me; нужно убрать локальные константы и импортировать ROLE_ACCESS, ROLE_NAMES (и при необходимости SECTION_IDS) из единого источника.
- Компоненты, использующие allowedSubsForSection, canAccessSub, useSubPermission, оставить без изменения логики; источник констант — общий.
3.4 Бэкенд
- Все API, отдающие данные в зависимости от прав: использовать единую функцию вычисления allowedSections (и при необходимости уровней по подразделам) из констант. Для фильтра по участку при scope=own_district — единая функция: получить разрешённые district_id из employee_districts по employee_id пользователя; если пусто — взять assigned_district_id. Применять этот список в запросах (buildings — фильтр домов по district_id IN (...), при необходимости заявки, отчёты и т.д.).
- В backend/routes/buildings.js заменить текущую логику (только assigned_district_id) на получение списка участков через employee_districts + fallback и фильтр WHERE (data->>'districtId') = ANY($1).
3.5 Админка
- Создание/редактирование пользователей и шаблонов — сохранение в текущем формате (role, permissions, scope); при необходимости расширить под полную матрицу или подсказки по шаблонам. ROLE_NAMES брать из единого источника.
4. Чек-лист файлов для правок
| Файл |
Что менять |
| Единый источник (новый файл) |
Создать модуль с ролями, ROLE_NAMES, ROLE_ACCESS, SECTION_IDS, ROLE_DEFAULT_SCOPE. Вариант: constants/roleAccess.ts (фронт) + использование на бэкенде через копию или общий пакет. |
| constants/permissions.ts |
Импорт SECTION_IDS/ALL_SECTION_KEYS и ролей из единого источника при необходимости; оставить SECTION_LABELS, SECTION_SUBS, все функции. |
| types.ts |
UserRole синхронизировать с единым источником (экспорт типа из источника или дублировать список). |
| App.tsx |
Удалить локальные ROLE_ACCESS, ROLE_NAMES; импорт из единого модуля. |
| components/Navigation.tsx |
Удалить ROLE_ACCESS; импорт из единого модуля. |
| components/admin/UsersSection.tsx |
Удалить ROLE_NAMES; импорт из единого модуля. |
| components/admin/PermissionsSection.tsx |
Удалить ROLE_NAMES; импорт из единого модуля. |
| backend/server.js |
Удалить локальные ROLE_ACCESS, SECTION_IDS; подключать константы из общего модуля (например shared/roleAccess.js или сгенерированный файл). Функцию allowedSectionsFromPermissions оставить, секции брать из констант. |
| backend/routes/buildings.js |
При scope=own_district: получать список district_id из employee_districts по employee_id пользователя; при пустом — [assigned_district_id]. Фильтр домов: WHERE (data->>'districtId') = ANY($1::text[]). |
| Другие API в server.js |
Найти все места фильтра по участку или проверки раздела; подключить единую функцию получения списка участков для scope=own_district. |
| Миграции |
При появлении новых полей или таблиц ролей по умолчанию — добавить миграции. Текущий план миграций не требует. |
После выполнения пунктов чек-листа логика прав будет приведена к единому источнику, дубли убраны, фильтр по участкам для scope=own_district будет учитывать все назначенные участки (employee_districts).