Files
Learn_System/plans/permissions-rework/PLAN.md
T
Maxim Dolgolyov 9ac2a612e0 feat(permissions): A1 — зависимости между правами (requires) + план переработки
registry: поле requires (questions.delete→manage, templates.public→manage,
courses.interactive→manage, simulations.quiz→access), проброшено в byRole.
auth.requirePermission: вынесен isEnabled(); право = own AND все requires
(дочернее не работает без родителя). /me и /users/🆔 effective с учётом
requires + requires в ответе. UI permissions.js: каскад — дочернее с
невыполненной зависимостью неактивно (тумблер заблокирован + «Требует: …»).
Тест зависимости. План: plans/permissions-rework/PLAN.md. Backend 216 pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 14:10:20 +03:00

6.1 KiB
Raw Blame History

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.deletequestions.manage; templates.publictemplates.manage; courses.interactivecourses.manage; simulations.quizsimulations.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).