feat(access): Фаза 1a — видимость симуляций по классам (добавочная модель)
Миграция 051: расширяет content_access.content_type на 'course'/'sim' (пересборка таблицы — SQLite не умеет ALTER CHECK) + мост «открыть все включённые симуляции всем существующим классам» → текущее поведение не меняется. GET /api/lab/sims теперь фильтрует список для НЕпривилегированных по allowedRefs(uid,'sim'); admin/ teacher видят все. Ролевой simulations.access остаётся «модуль вкл.» (добавочно). Тесты: lab-access (4/4, allowlist+класс+личное), lab-sims переведён на admin для проверки полного каталога (видимость ученика — в lab-access). /api/lab в харнессе. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
-- 051_content_access_types.sql
|
||||
-- Расширяем content_access.content_type на 'course' и 'sim' (добавочная модель
|
||||
-- видимости контента по классам/ученикам — см. plans/access-redesign/PLAN.md).
|
||||
--
|
||||
-- SQLite не поддерживает ALTER TABLE ... DROP/ALTER CONSTRAINT, поэтому
|
||||
-- пересобираем таблицу с расширенным CHECK, сохраняя данные, UNIQUE и индексы.
|
||||
-- Затем мост: открываем все ВКЛЮЧЁННЫЕ симуляции всем существующим классам
|
||||
-- (как миграция 040 сделала для учебников) — текущее поведение не меняется.
|
||||
--
|
||||
-- В этой миграции wired только тип 'sim' (фильтр в /api/lab/sims). Тип 'course'
|
||||
-- уже разрешён CHECK-ом на будущее, но мост/гейт курсов добавим отдельным шагом
|
||||
-- (у курсов своя логика публикации и class_courses).
|
||||
|
||||
CREATE TABLE content_access_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
content_type TEXT NOT NULL CHECK (content_type IN ('textbook','exam','course','sim')),
|
||||
content_ref TEXT NOT NULL,
|
||||
scope TEXT NOT NULL CHECK (scope IN ('class','student')),
|
||||
target_id INTEGER NOT NULL,
|
||||
allow INTEGER NOT NULL DEFAULT 1 CHECK (allow IN (0,1)),
|
||||
created_by INTEGER REFERENCES users(id),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE (content_type, content_ref, scope, target_id)
|
||||
);
|
||||
|
||||
INSERT INTO content_access_new (id, content_type, content_ref, scope, target_id, allow, created_by, created_at)
|
||||
SELECT id, content_type, content_ref, scope, target_id, allow, created_by, created_at
|
||||
FROM content_access;
|
||||
|
||||
DROP TABLE content_access;
|
||||
ALTER TABLE content_access_new RENAME TO content_access;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_content_access_lookup ON content_access (content_type, content_ref);
|
||||
CREATE INDEX IF NOT EXISTS idx_content_access_target ON content_access (content_type, scope, target_id);
|
||||
|
||||
-- Мост: все включённые симуляции — всем существующим классам (allowlist-переход).
|
||||
INSERT OR IGNORE INTO content_access (content_type, content_ref, scope, target_id, allow)
|
||||
SELECT 'sim', s.id, 'class', c.id, 1
|
||||
FROM lab_sims s CROSS JOIN classes c
|
||||
WHERE s.enabled = 1;
|
||||
Reference in New Issue
Block a user