feat(sim-builder): фаза 7 — custom-sim на доске онлайн-урока (синхрон параметров классу, аннотации)
This commit is contained in:
@@ -1,6 +1,35 @@
|
||||
# Feature Context: Конструктор симуляций (SimForge)
|
||||
|
||||
## Current State
|
||||
- **ВСЕ ФАЗЫ (0–7) РЕАЛИЗОВАНЫ** (в рабочем дереве, не закоммичено — коммит за оркестратором).
|
||||
Фича «Конструктор симуляций» функционально полна: рантайм+физика, БД+API, билдер, каталог в /lab,
|
||||
раздача/клон/шаблоны/привязка, доска онлайн-урока с синхроном классу.
|
||||
- **Фаза 7 РЕАЛИЗОВАНА** (в рабочем дереве, не закоммичено). Custom-sim на доске онлайн-урока через
|
||||
существующий iframe-конвейер. **Аддитивные** правки трёх файлов; рабочее дерево по ним было ЧИСТЫМ
|
||||
до начала (classroom.html не имел чужих незакоммиченных правок параллельной сессии — проверено git status).
|
||||
- `backend/src/controllers/classroom/sim.js` (+21/-2): `simOpen` принимает `simId='custom:<dbid>'`,
|
||||
валидирует доступ (владелец ИЛИ published ИЛИ admin; иначе 404/403). Встроенный id — прежний regex
|
||||
`^[a-z0-9_-]{1,40}$`. `simState/simMode/simAnnotate/simClose` НЕ тронуты (state-объект уже произвольный).
|
||||
- `frontend/classroom.html` (+31/-4): `_crLoadCustomSims()` (кэш `LS.customSimsList`), `crOpenSimPicker`
|
||||
async с предзагрузкой, `_crRenderSimGrid` мёржит свои+published custom (бейдж «Моя», id `custom:<dbid>`,
|
||||
XSS-escape). Существующий `crPickSim` передаёт id как есть; `onSimOpen` грузит iframe
|
||||
`/lab?embed=1&sim=custom:<id>` (encodeURIComponent безопасен, lab декодирует param).
|
||||
- `frontend/js/labs/lab-glue.js` (+48/-1): `_bridgeCustomSimState(real)` — подключает custom-sim к
|
||||
тому же мосту `sim_state`/`apply_sim_state`, что и встроенные. getState=`{params,running}` /
|
||||
applyState=`setParam`+play/pause поверх SimEngine-инстанса (`real.instance()`). Регистрируется под
|
||||
ключом `_autoSim` (`custom:<dbid>`, т.к. apply у ученика берёт `_simStateRegistry[_autoSim]`),
|
||||
запускает `_startStateEmit`. Вызов в `_registerLazy.open()` после `real.open(ctx)` (только embed).
|
||||
- **Синхрон:** параметры слайдеров + play/pause — полный (demo-режим). Время `t` (фаза анимации)
|
||||
покадрово НЕ синхронится (by design; ученик крутит свой rAF при running). Аннотации/режим — через
|
||||
существующий конвейер без изменений (id-agnostic). Закрытие/смена: `frame.src='about:blank'` сносит
|
||||
весь документ iframe (SimEngine+rAF+слушатели) — утечек нет.
|
||||
- **Доступ:** двойная проверка — `simOpen` на сервере (постановка на доску) + `GET /custom-sims/:id`
|
||||
при загрузке спеки в iframe. Чужой draft → 403 на обоих. На доску только своё или published.
|
||||
- Верификация: `node --check` sim.js / lab-glue.js / извлечённого инлайна classroom.html — OK;
|
||||
эмодзи нет (UTF-8-скан текст-элементов: 0 в js, 11 в classroom.html — все ПРЕ-существующие
|
||||
×/⇒/реакции, не в моих строках); eval/new Function — 0 call-sites; `npm test` 240/248 pass
|
||||
(8 fail = тот же baseline: 3 auth.test + 5 page-тестов без jsdom; обе custom-sims-сьюты зелёные).
|
||||
git status: тронуты только мои 3 файла (+плановые .md); js/api.js НЕ нужен (методы есть с Ф3).
|
||||
- **Фаза 6 РЕАЛИЗОВАНА** (в рабочем дереве, не закоммичено — коммит за оркестратором). Файлы:
|
||||
`backend/src/controllers/customSimController.js` (+share/clone/related/addLink/removeLink, импорт
|
||||
`pushNotif`), `backend/src/routes/customSims.js` (+POST `/:id/share`, POST `/:id/clone`, GET
|
||||
@@ -135,9 +164,15 @@
|
||||
- Reuse > переписывание: сначала смотреть `_fx_motion`, `_graph_panel`, `graph.js`.
|
||||
|
||||
## RESUME STATE
|
||||
- Последний коммит фичи: — (Ф0..Ф6 реализованы, ещё не закоммичены — ждут оркестратора)
|
||||
- Текущая фаза: Phase 6 — Раздача / шаблоны / клон / программа (✅ Implemented, pending commit) →
|
||||
дальше Phase 7 — Доска онлайн-урока (последняя)
|
||||
- Последний коммит фичи: — (Ф0..Ф7 ВСЕ реализованы, ещё не закоммичены — ждут оркестратора)
|
||||
- Текущая фаза: Phase 7 — Доска онлайн-урока (✅ Implemented, pending commit) — ФИНАЛЬНАЯ.
|
||||
Дальше: Final Review (final-reviewer + security review) → коммит всех фаз → merge в master.
|
||||
- **Ф7 файлы (аддитивно, рабочее дерево по ним было чистым до правок):**
|
||||
`backend/src/controllers/classroom/sim.js` (simOpen принимает `custom:<dbid>` + access-check
|
||||
own|published|admin), `frontend/classroom.html` (пикер: свои+published custom через `_crLoadCustomSims`/
|
||||
`_crRenderSimGrid`; id `custom:<dbid>`), `frontend/js/labs/lab-glue.js` (`_bridgeCustomSimState` —
|
||||
мост sim_state/apply_sim_state для custom-sim поверх SimEngine; вызов в `_registerLazy.open`).
|
||||
js/api.js НЕ менялся. Синхрон: параметры+play/pause (не время t). Открытие — iframe `/lab?embed=1&sim=custom:<id>`.
|
||||
- Эндпоинты Ф6: share/clone/related/links на `/api/custom-sims/:id/*`; клиент `LS.customSimShare/
|
||||
Clone/Related/AddLink/DelLink`. Раздача = авто-publish + pushNotif (НЕ копия). Связи — lab_sim_links
|
||||
`sim_id='custom:<id>'`. Остаток Ф6: UI-редактор связей в билдере + чипы в каталоге (backend готов).
|
||||
|
||||
Reference in New Issue
Block a user