merge: SimForge (конструктор + улучшения + тумблер + руководство) в quantik-game

This commit is contained in:
Maxim Dolgolyov
2026-06-13 16:32:30 +03:00
6 changed files with 154 additions and 10 deletions
+1 -1
View File
@@ -525,7 +525,7 @@ function getFeatures(_req, res) {
function updateFeatures(req, res) {
const allowed = ['crossword', 'hangman', 'pet', 'red_book', 'collection',
'flashcards', 'knowledge_map', 'board', 'biochem', 'live_quiz', 'classroom',
'gamification', 'assistant'];
'gamification', 'assistant', 'sim_builder'];
const updates = req.body;
const stmt = db.prepare("INSERT OR REPLACE INTO app_settings (key, value) VALUES (?, ?)");
const getOld = db.prepare("SELECT value FROM app_settings WHERE key = ?");
+13 -7
View File
@@ -6,29 +6,35 @@
const express = require('express');
const router = express.Router();
const { authMiddleware, requireRole } = require('../middleware/auth');
const { requireFeature } = require('../middleware/features');
const c = require('../controllers/customSimController');
router.use(authMiddleware);
// «Конструктор симуляций» можно отключить в админке (feature_sim_builder_enabled).
// Чтение/проигрывание уже сохранённых симуляций остаётся доступным; гейтим только
// авторинг — создание/правку/удаление/раздачу/клон/связи.
const gate = requireFeature('sim_builder');
router.get('/', c.list);
// @public-by-design: router-level authMiddleware (above) + ownership/published check in handler
router.get('/:id', c.get);
// @public-by-design: router-level authMiddleware (above) + ownership/published check in handler
router.get('/:id/related', c.related);
router.post('/', requireRole('teacher', 'admin'), c.create);
router.post('/', gate, requireRole('teacher', 'admin'), c.create);
// @public-by-design: router-level authMiddleware (above) + per-row ownership check in handler
router.put('/:id', requireRole('teacher', 'admin'), c.update);
router.put('/:id', gate, requireRole('teacher', 'admin'), c.update);
// @public-by-design: router-level authMiddleware (above) + per-row ownership check in handler
router.delete('/:id', requireRole('teacher', 'admin'), c.remove);
router.delete('/:id', gate, requireRole('teacher', 'admin'), c.remove);
// Фаза 6 — раздача классу / клон / курикулумные связи. Мутации — inline
// requireRole(teacher,admin) + per-row ownership в хендлере.
router.post('/:id/share', requireRole('teacher', 'admin'), c.share);
router.post('/:id/clone', requireRole('teacher', 'admin'), c.clone);
router.post('/:id/share', gate, requireRole('teacher', 'admin'), c.share);
router.post('/:id/clone', gate, requireRole('teacher', 'admin'), c.clone);
// @public-by-design: router-level authMiddleware (above) + per-row ownership check in handler
router.post('/:id/links', requireRole('teacher', 'admin'), c.addLink);
router.post('/:id/links', gate, requireRole('teacher', 'admin'), c.addLink);
// @public-by-design: router-level authMiddleware (above) + per-row ownership check in handler
router.delete('/:id/links/:linkId', requireRole('teacher', 'admin'), c.removeLink);
router.delete('/:id/links/:linkId', gate, requireRole('teacher', 'admin'), c.removeLink);
module.exports = router;