a6ff965d80
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7.5 KiB
7.5 KiB
PLAN — Переработка ролевых прав (Role Permissions Rework)
Составлен 2026-06-03 (Opus) по итогам разбора. Цель — сделать модель ролевых прав корректной (зависимости), прозрачной (история, линт), гибкой (группы, пресеты, кастомные роли) и убрать болезненный сайд-эффект (массовый разлогин при смене права).
Факты по текущему коду (проверено):
backend/src/permissions/registry.js— 23 ключа, роли teacher/student (+free_student зеркалит student); поляrole/roles/default/label/desc/requireConfirmOff.- Резолв:
requirePermission(middleware/auth.js:46) читает живьём из БД: user_permissions → role_permissions → дефолт реестра.authMiddlewareкаждый запрос перечитывает роль из БД.- Таблицы
role_permissions(role,permission,enabled),user_permissions(user_id,permission,enabled).permissionsController.js: GET /api/permissions, POST (role-level), GET /me, GET/POST /users/:id, DELETE reset. На каждое изменение —token_version++(role-level → у ВСЕХ юзеров роли; user-level → у одного).- UI:
frontend/js/admin/sections/permissions.js(тумблеры по ролям) +user-detail.js(оверрайды).
Phase A — Быстрые победы (низкий риск)
- A1. Зависимости между правами (
requires). Полеrequires:[...]в реестре (questions.delete→questions.manage;templates.public→templates.manage;courses.interactive→courses.manage;simulations.quiz→simulations.access). Enforce вrequirePermission(effective = own AND все requires). Учесть в/meи/users/:id(effective с учётом requires). UI: каскад (родитель off → дочерние серые/выключены). Тест. - A2. Гигиена реестра + ясные метки. Тест-линт: каждый ключ из
requirePermission/perm(...)в коде есть в реестре; предупреждать о неиспользуемых ключах. Меткиtheory.access/simulations.accessпереформулировать как «… доступен роли» (видимость конкретного — по классам в content_access). - A3. История изменений прав в UI. Аудит уже пишется (
permission.set/permission.user_set/permission.user_reset). ЭндпоинтGET /api/permissions/log(+ опц. фильтр по роли/пользователю), кнопка «История» на вкладке «Доступ · роли» и в карточке пользователя. Переиспользовать паттерн/api/access/log. - A4. Смягчить
token_version++. Сервер уже применяет права live → массовый разлогин роли при одном тумблере не нужен. Убрать bump на role-level (и/или user-level), вместо этого клиент пере-запрашивает/permissions/meприfocus/навигации. Сохранить немедленный серверный эффект (он и так есть). Аккуратно: проверить, где клиент кэширует права (lab-glue и т. п.).
Phase B — Среднее (управление при масштабе)
- B5. Группы прав (
group). Полеgroupв реестре («Контент»/«Класс»/«Геймификация»/«Профиль»/ «Библиотека») → секции в UI + «вкл/выкл всю группу». - B6. Массовое применение к классу / выбранным ученикам. Через
class_members: выставить право пачке учеников (аналог матрицы/массовых операций content_access). - B7. Пресеты-профили прав. Бандлы («Ограниченный ученик», «Ассистент учителя») — применить к пользователю/классу одним кликом.
- B8. Временные права (
expires_at). Колонка вuser_permissions+ авто-снятие в резолвере/кроне.
Phase C — Крупное / архитектурное
- C9. Кастомные роли. Таблица ролей в БД + наборы дефолтов; реестр остаётся словарём ключей.
Кандидаты: методист/завуч, классрук/куратор, ассистент учителя, родитель (есть
parentAuth). - C10. Делегирование учителю. Часть студенческих прав — учителю в рамках его классов.
- C11. Пер-классовый скоуп прав. Право на уровне класса (свести к модели content_access). Большая работа.
Порядок исполнения
A1 → A2 → A3 → A4 → B5 → B6 → B7 → B8 → C9 → C10 → C11. Phase C — отдельными ветками/планом (архитектура).
Тесты/гочи
- Бэкенд-тесты через
backend/tests/setup.js(харнесс монтирует /api/permissions). Прогонnode --test. - pre-commit гоняет полный backend-набор (baseline 3 Auth + флака «intro» в chemistry8-page под нагрузкой).
- ⛔ эмодзи; коммитить поимённо; fetch перед работой (активны параллельные сессии на master).
Прогресс (2026-06-03)
- A1 зависимости (requires) — commit
9ac2a61 - A2 гигиена реестра (lint) + ясные метки —
b0e385b - A3 история изменений прав (endpoint + UI) —
7d474b4 - A4 убран role-level token_version bump (нет массового разлогина) —
6bd1532 - Фаза A завершена. Далее по порядку: B5 группы прав → B6 массово к классу → B7 пресеты → B8 временные → C9-11.
- Линт A2 подсветил: ряд teacher-прав (students.invite, sessions.reset, results.export, schedule.manage, templates.public, courses.interactive) и theory.access НЕ enforce-ятся через requirePermission — потенциальные гейты для проверки (отдельно).
Прогресс — Phase B (2026-06-03)
- B5 группы прав —
0a24a66 - B6 массово по классу —
b95b639 - B7 пресеты-профили —
8b495f1 - B8 временные права (expires_at, миграция 053) —
a250d15 - Phase A + Phase B ЗАВЕРШЕНЫ. Остаётся Phase C (C9 кастомные роли / C10 делегирование учителю / C11 пер-классовый скоуп) — архитектура, отдельной веткой + обсуждение.