Files
Learn_System/plans/permissions-rework/PHASE_C_DESIGN.md
T

63 lines
6.8 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.
# Phase C — кастомные роли / делегирование / пер-классовый скоуп (дизайн)
> Составлен 2026-06-03 (Opus). Это **архитектурная** фаза — отдельная ветка + согласование модели
> ДО реализации. Здесь — факты по коду и развилка, чтобы выбрать подход.
## Факты (проверено по коду/БД)
- `users.role``TEXT NOT NULL DEFAULT 'student'`, **без CHECK** → новое значение роли можно хранить
без пересборки таблицы. В ходу: admin, student, teacher (free_student зеркалит student в коде).
- `role_permissions.role`**CHECK `IN ('teacher','student','free_student')`** → конфиг дефолтов для
новой роли требует миграции-пересборки (SQLite не ALTER-ит CHECK).
- **`requireRole('...')` — 111 вызовов в 24 файлах**, строки ролей захардкожены. Любая новая роль не
пройдёт ни один такой гейт, пока её явно не добавить в нужные списки.
- `registry.byRole()` строит UI только для teacher/student; `requirePermission` читает права live из БД
(user → role → дефолт реестра) — это уже гибко и НЕ зависит от requireRole.
## Суть проблемы
«Способности» выражены двумя разными механизмами: грубый **requireRole** (кто вообще в разделе) +
тонкий **requirePermission** (конкретное действие). Кастомные роли упираются в requireRole: он не
дата-управляемый.
## Варианты (по возрастанию объёма/риска)
### Вариант 1 — Узкий слой: роль «Родитель» (read-only) ★ минимум риска
Уже есть инфраструктура `parentAuth` + `parent_links` (отдельный токен, привязка к ученику). Доделать
родительский доступ как «роль» для просмотра прогресса/оценок ребёнка — без вторжения в requireRole
(родитель ходит через `parentAuth`, не через `requireRole`). Объём: малый. Польза: конкретная и частая.
### Вариант 2 — Курируемые доп-роли (например «методист/завуч», «классрук», «ассистент») ★ среднее
- Миграция: расширить CHECK `role_permissions.role` (пересборка) на новые роли + засеять их дефолты.
- `registry`: добавить роли в `roles[]` нужных ключей + `byRole` для UI.
- **requireRole точечно**: добавить новую роль в те из 111 вызовов, где она должна иметь доступ
(например «методист» = доступ к аналитике/вопросам, но не к админ-настройкам).
- UI вкладки «Доступ · роли»: секции для новых ролей.
Объём: средний (зависит от числа гейтов на роль). Риск: средний (точечные правки auth).
### Вариант 3 — Полностью произвольные роли (admin создаёт роли в UI) ★ крупное, рискованное
Нужен **слой capabilities**: заменить `requireRole` на проверку способностей роли (данные в БД), т.е.
переписать ~111 точек на `requireCapability(...)` + UI конструктора ролей + резолвер. Это недели работы
и затрагивает аутентификацию целиком. Делать только при реальной потребности в произвольных ролях.
## C10 / C11 (отдельные подпункты)
- **C10 делегирование учителю** — дать учителю менять часть студенческих прав *в рамках его классов*.
Технически = пер-классовый скоуп (C11) + расширение прав `/class/:id/bulk` на учителя-владельца.
- **C11 пер-классовый скоуп прав** — правило права на уровне класса (как content_access). Резолвер
начинает учитывать ещё один слой (class-override между user и role). Средне-крупно.
## Рекомендация
Начать с **Варианта 1 (роль «Родитель», read-only)** — конкретная польза, минимум риска, не трогает
requireRole. Затем, если нужно, **Вариант 2** для одной конкретной роли (скажем «методист»). Вариант 3
и C11 — только под явный запрос (большой рефактор аутентификации).
> Реализация — на ветке `feature/custom-roles`. Сначала выбрать вариант/конкретную роль.
## Прогресс Phase C (2026-06-03, ветка feature/custom-roles)
- [x] C-1 фундамент: таблица roles + effectiveRoles (наследование гейтов) — миграция 054
- [x] C-2 назначение: users.custom_role + updateRole + authMiddleware — миграция 055
- [x] C-3 пер-ролевые права: релакс CHECK role_permissions + isEnabled(customRole, фолбэк база) — миграция 056
- [x] C-4a API ролей: /api/roles CRUD + засев из базы + setPermission для кастомных
- [x] C-4b UI: конструктор ролей во вкладке «Доступ · роли» + выпадающий список ролей у пользователя
- PHASE C (произвольные кастомные роли) ЗАВЕРШЕНА на ветке. Тесты: custom-roles 8/8, roles-api 5/5, permissions 17/17, full backend в рамках baseline.
- Влить в master после ревью/проверки в браузере (на ветке: перезапустить сервер → код ветки). Миграции 054-056 уже в общей БД (обратносовместимы с master).
- C-10 (делегирование учителю) и C-11 (пер-классовый скоуп прав) из исходного дизайна — НЕ делались (был выбран вариант «произвольные роли»).