5aa2dd1a4b
Phase C, Stage C-1 (ветка feature/custom-roles): таблица roles (name, label, base_roles JSON, is_builtin) + засев встроенных. auth.effectiveRoles(role) — кастомная роль наследует base_roles (какие встроенные гейты проходит); встроенные — быстрый путь без БД. requireRole() теперь проверяет пересечение allowed с effectiveRoles → 111 существующих гейтов не задеты (встроенные ведут себя как прежде). Дизайн: PHASE_C_DESIGN.md. Тест effectiveRoles 5/5; полный backend pass. ВАЖНО (обнаружено): users.role в канон-схеме имеет CHECK (admin/teacher/student/ free_student), безопасно пересобрать users (FK от многих таблиц, миграции в txn) нельзя → присвоение кастомной роли пользователю пойдёт через users.custom_role (C-2). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>