feat(lab-content-engine): phase 4 - каталог симуляций в БД + API + админка
- Миграция 042_lab_sims.sql: таблица lab_sims (id, cat, title, subject, grade,
sort_order, enabled, featured, tags JSON), сид 40 симуляций в порядке каталога
- backend/src/routes/lab.js: GET /api/lab/sims (мёрж БД + legacy-флаги, auth),
PATCH /api/lab/sims/:id (admin), POST /api/lab/sims/reorder (admin).
enabled зеркалится в legacy sim_disabled_ids -> lab.html без правок фронта
- server.js: монтирование /api/lab
- tests/lab-sims.test.js: 11 тестов (auth/роли/вкл-выкл+зеркало/featured/tags/
валидация/reorder/404), все проходят; +0 к baseline (3 pre-existing)
- admin/sections/sims.js: убран захардкоженный ADMIN_SIMS, каталог из /api/lab/sims,
тумблеры вкл-выкл и «рекомендуемая»; XSS-эскейп, иконки .ic
- plans/: Фаза 4 done + handoff
Независимое ревью: PASS, блокеров нет. route-auth lint: PATCH-роут защищён inline
requireRole('admin'). Миграция применена к живой БД.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
-- 042_lab_sims.sql — Контент-движок лаборатории, Фаза 4.
|
||||
-- Каталог симуляций в БД: метаданные + оверрайды (вкл/выкл, порядок, теги,
|
||||
-- рекомендуемые, курикулумные subject/grade). Источник истины каталога для
|
||||
-- админки и (опционально) для /lab. Превью-SVG остаются в коде (frontend).
|
||||
--
|
||||
-- Совместимость: вкл/выкл также зеркалится в app_settings.sim_disabled_ids
|
||||
-- на уровне API, поэтому существующая логика lab.html не ломается.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS lab_sims (
|
||||
id TEXT PRIMARY KEY, -- id симуляции ('pendulum', ...)
|
||||
cat TEXT NOT NULL, -- math | phys | chem | bio | game
|
||||
title TEXT NOT NULL,
|
||||
subject TEXT, -- курикулум (Фаза 5), напр. 'physics'
|
||||
grade INTEGER, -- класс (Фаза 5)
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
enabled INTEGER NOT NULL DEFAULT 1, -- 0 = скрыта в каталоге
|
||||
featured INTEGER NOT NULL DEFAULT 0, -- 1 = «рекомендуемая»
|
||||
tags TEXT NOT NULL DEFAULT '[]', -- JSON-массив строк
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_lab_sims_sort ON lab_sims (sort_order);
|
||||
|
||||
-- Сид 40 симуляций в текущем порядке каталога /lab (из frontend SIMS).
|
||||
INSERT OR IGNORE INTO lab_sims (id, cat, title, sort_order) VALUES
|
||||
('graph', 'math', 'График функции', 1),
|
||||
('graphtransform', 'math', 'Трансформации графиков', 2),
|
||||
('geometry', 'math', 'Планиметрия', 3),
|
||||
('triangle', 'math', 'Геометрия треугольника', 4),
|
||||
('quadratic', 'math', 'Корни квадратного уравнения', 5),
|
||||
('stereo', 'math', 'Стереометрия 3D', 6),
|
||||
('probability', 'math', 'Теория вероятностей', 7),
|
||||
('trigcircle', 'math', 'Тригонометрическая окружность', 8),
|
||||
('normaldist', 'math', 'Нормальное распределение', 9),
|
||||
('projectile', 'phys', 'Бросок тела', 10),
|
||||
('pendulum', 'phys', 'Маятник', 11),
|
||||
('collision', 'phys', 'Столкновение шаров', 12),
|
||||
('emfield', 'phys', 'Электромагнитные поля', 13),
|
||||
('circuit', 'phys', 'Электрические цепи', 14),
|
||||
('hydrostatics', 'phys', 'Гидростатика', 15),
|
||||
('dynamics', 'phys', 'Динамика', 16),
|
||||
('opticsbench', 'phys', 'Оптическая скамья', 17),
|
||||
('isoprocess', 'phys', 'Изопроцессы', 18),
|
||||
('waves', 'phys', 'Волны и звук', 19),
|
||||
('radioactive', 'phys', 'Радиоактивный распад', 20),
|
||||
('race', 'phys', 'Гонка с задачами', 21),
|
||||
('heatengine', 'phys', 'Тепловые двигатели', 22),
|
||||
('logic', 'phys', 'Логические схемы', 23),
|
||||
('molphys', 'chem', 'Молекулярная физика', 24),
|
||||
('chemistry', 'chem', 'Химические реакции', 25),
|
||||
('equilibrium', 'chem', 'Химическое равновесие', 26),
|
||||
('electrolysis', 'chem', 'Электролиз', 27),
|
||||
('bohratom', 'chem', 'Атом Бора', 28),
|
||||
('orbitals', 'chem', 'Молекулярные орбитали', 29),
|
||||
('titration', 'chem', 'pH и кривая титрования', 30),
|
||||
('chemsandbox', 'chem', 'Химическая песочница', 31),
|
||||
('stoichiometry', 'chem', 'Стехиометрия', 32),
|
||||
('crystal', 'chem', 'Кристаллическая решётка', 33),
|
||||
('qualanalysis', 'chem', 'Качественный анализ', 34),
|
||||
('periodic', 'chem', 'Периодическая таблица', 35),
|
||||
('organic', 'chem', 'Органическая химия', 36),
|
||||
('solutions', 'chem', 'Растворы', 37),
|
||||
('celldivision', 'bio', 'Деление клетки', 38),
|
||||
('photosynthesis', 'bio', 'Фотосинтез и дыхание', 39),
|
||||
('angrybirds', 'game', 'Angry Birds Physics', 40);
|
||||
Reference in New Issue
Block a user