feat(trainer): P2 — умная тренировка, интервальное повторение, итог сессии

- adaptive.js (TrainerAdaptive): nextSkill (in-session повтор → серверный due → прогрессия → удержание), onWrong/onCorrect (очередь повторения), sessionStats
- умная тренировка на странице (тумблер, по умолч. вкл): авто-подбор навыка от простого к сложному, возврат ошибок
- сессия из 10 задач + экран «Итог сессии» (верно/точность/навыки/стоит повторить); неверный ответ авто-показывает решение
- сервер: SR-поля box+due_at на practice_progress (мигр.082, Leitner 0/1/3/7/16/30 дн), listProgress отдаёт box/due_at/due
- смоуки: adaptive 12/12, страница 23/23, practice.test.js 11/11 (+SR box/due); план P2 → DONE

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-25 13:46:29 +03:00
parent 20b8ce2c5b
commit 48a73d9f8e
6 changed files with 281 additions and 29 deletions
@@ -0,0 +1,13 @@
-- ═══════════════════════════════════════════════════════════════
-- 082: SR-поля тренажёра (интервальное повторение по навыкам, Фаза 2).
--
-- К practice_progress добавляем Leitner-«коробку» и срок следующего показа:
-- box — уровень 0..5 (выше = увереннее освоено, реже повторяем).
-- due_at — когда навык снова стоит показать (datetime). NULL = «как можно скорее».
-- На верный ответ box растёт и срок отодвигается; на ошибку box сбрасывается в 0
-- и срок = сейчас (навык всплывёт первым при следующем заходе). Адаптивный
-- подборщик на клиенте показывает «просроченные» навыки (due_at <= now) раньше.
-- ═══════════════════════════════════════════════════════════════
ALTER TABLE practice_progress ADD COLUMN box INTEGER NOT NULL DEFAULT 0;
ALTER TABLE practice_progress ADD COLUMN due_at TEXT;