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
+12 -2
View File
@@ -53,9 +53,19 @@ UI: выбор темы (вкладки) → навыки (чипы) с бейд
- **Acceptance:** ≥3 темы × ≥3 навыка, у каждого generateBatch(50) даёт 50 разных корректных
задач; solvability-смоук на сетке параметров.
## Phase 2 — Адаптивность и интервальное повторение
## Phase 2 — Адаптивность и интервальное повторение — DONE
**Цель:** вести ученика, а не давать случайное.
**Сделано:** `frontend/js/trainer/adaptive.js` (`window.TrainerAdaptive`, чистая логика) —
`nextSkill` (приоритет: in-session повтор → серверный due → прогрессия → удержание по
box), `onWrong/onCorrect` (in-session очередь повторения), `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).
**Цель (исходная):** вести ученика, а не давать случайное.
- Диагностика на входе (по 1–2 задачи на навык) → стартовый уровень.
- Подбор следующего навыка по мастерству (escalate при серии, откат при ошибках).