chore(quantik-game): полировка по финальному ревью + security-review

Финальное ревью: READY TO MERGE (0 блокеров). Security: SECURE (0 critical).
Применены дешёвые фиксы из ревью:
- validateSpec: блок game{} санитизируется ПОИМЁННО (chapter/subject →
  sanitizeText, order/par_ms/unlockStars → проверка типа, неизвестные ключи
  отбрасываются) — закрыт латентный хранимый XSS (раньше clean.game=spec.game).
- quantik.html: @media (prefers-reduced-motion) делает анимации мгновенными
  (не выключает — иначе forwards-появление узлов оставило бы их скрытыми).
- progress-logic.js: фикс комментария isUnlocked (сумма звёзд по ВСЕМ уровням
  с меньшим глобальным order, а не «той же главы»).
План: Ф6 (лидерборд/гонка) удалена (Amendment 1, решение пользователя);
финальные гейты отмечены; deferred-бэклог зафиксирован.
Затронутые тесты 45/45; lint:routes 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
This commit is contained in:
Maxim Dolgolyov
2026-06-14 17:00:13 +03:00
parent c780b6fd96
commit 69df2f8190
5 changed files with 54 additions and 16 deletions
+23 -7
View File
@@ -64,7 +64,7 @@
- [x] Phase 3: Граф-уровни (движение по f(x)) + зоны-препятствия [domain: fullstack] → [subplan](./phase-3-graph-levels.md)
- [x] Phase 4: Квантовые способности + SR-комнаты [domain: fullstack] → [subplan](./phase-4-quantum-abilities-sr.md)
- [x] Phase 5: Авторинг уровней в sim-builder + раздача классу [domain: fullstack] → [subplan](./phase-5-authoring-sharing.md)
- [ ] Phase 6: Класс-лидерборд / живая гонка (classroom SSE) [domain: fullstack] → [subplan](./phase-6-leaderboard-live.md)
- ~~Phase 6: Класс-лидерборд / живая гонка (classroom SSE)~~ — **REMOVED** (см. Amendment 1) → [subplan](./phase-6-leaderboard-live.md)
## Phase Progress Log
@@ -76,16 +76,32 @@
| Phase 3: Граф-уровни + зоны | fullstack | ✅ Done | ✅ | ✅ | ✅ |
| Phase 4: Квантовые способности + SR | fullstack | ✅ Done | ✅ | ✅ | ✅ |
| Phase 5: Авторинг + раздача | fullstack | ✅ Done | ✅ | ✅ | ✅ |
| Phase 6: Лидерборд / живая гонка | fullstack | ⬜ Not Started | | | |
| ~~Phase 6: Лидерборд / живая гонка~~ | fullstack | ❌ Removed (Amendment 1) | | | |
## MVP boundary
После **Phase 2** игра играбельна и отгружаема: один полный мир физ-уровней с картой,
прогрессом, XP и скинами. Фазы 3–6 — расширение (новые типы уровней, способности,
авторинг, мультиплеер).
## Amendment Log
### Amendment 1 — 2026-06-14
**Type:** Removed phase
**What changed:** Phase 6 (Класс-лидерборд / живая гонка через classroom SSE) убрана из объёма по решению пользователя.
**Why:** Пользователь решил не реализовывать соревновательный слой; переходим к полировке и финальному ревью после Ф5.
**Impact on existing phases:** Нет. Фазы 0–5 самодостаточны и отгружаемы. `game_progress.level_id` (TEXT) уже готов под будущий лидерборд, если фичу вернут. Subplan `phase-6-leaderboard-live.md` сохранён как архив с пометкой REMOVED.
## Final Review
- [ ] Comprehensive code review (final-reviewer)
- [ ] Security review (новые API: прогресс/лидерборд, user-input)
- [ ] `npm test` без новых регрессий (поверх baseline)
- [ ] `npm run lint:routes` baseline 0
- [ ] Merged to `feature/sim-builder`
- [x] Comprehensive code review (final-reviewer) — ✅ READY TO MERGE, 0 блокеров (2026-06-14)
- [x] Security review (новые API/ввод) — ✅ SECURE, 0 critical (2026-06-14)
- [x] Polish-фиксы по ревью применены: game-блок санитизируется (был латентный XSS), prefers-reduced-motion guard, фикс комментария isUnlocked. Тесты 45/45 затронутых, lint 0.
- [x] `npm test` без новых регрессий (8 = baseline: 3 auth + 5 jsdom)
- [x] `npm run lint:routes` baseline 0
- [ ] Merged to `feature/sim-builder` (ожидает одобрения пользователя)
### Deferred / Backlog (не блокеры — из финального ревью)
- `QuantikLevels.ensureCustom` — N+1 `customSimGet` на загрузку /quantik; при росте числа авторённых уровней заменить на bulk-эндпоинт «список game-спек».
- Уровни 3/5/6 (отскок/орбита/манёвр): `fail` — только таймаут, «честная» механика не форсится. Точечно ужесточить `fail`-предикаты (контент-тюнинг).
- `graph-exp-11` капстоун узковат (~36–42/625) — при жалобах на сложность чуть расширить gate.
- Три похожих `starSvg`/`_starIcon` в разных модулях — консолидация не стоит связывания движка с игрой (оставлено).
- Клиентские очки прогресса фальсифицируемы (ожидаемо для single-player). ⚠️ Если когда-нибудь вернут Ф6-лидерборд — валидировать на сервере (replay/подписанные токены).
@@ -1,6 +1,9 @@
# Phase 6: Класс-лидерборд / живая гонка (classroom SSE)
**Status:** ⬜ Not Started
> **REMOVED (Amendment 1, 2026-06-14)** — фаза не реализуется по решению пользователя.
> Архивный subplan. `game_progress.level_id` (TEXT) уже готов под лидерборд, если фичу вернут.
**Status:** ❌ Removed
**Parent plan:** [PLAN.md](./PLAN.md)
**Domain:** fullstack