Files
Learn_System/backend/src/db/migrations/081_practice_progress.sql
T
Maxim Dolgolyov c370eaa803 feat(trainer): ИИ-тренажёр — генераторы задач + SimExpr-верификатор, прогресс, фича-флаг
- движок _trainer_engine.js: instantiate/generateBatch/verifyRoot/checkStudentAnswer/exprToLatex
- 5 генераторов уравнений 7 класса (generators.js), приём «корень-вперёд» → целые ответы
- страница /trainer: KaTeX-рендер, чипы-темы, мгновенная проверка, подсказка/решение, авто-выбор навыка
- прогресс practice_progress (мигр.081) + /api/practice/progress|attempt + LS.practiceProgressList/Submit
- фича-флаг trainer: тумблер в админке (Модули), requireFeature, FEATURE_HREFS (скрытие сайдбара+редирект), MODULE_CATALOG
- fix: подключён Lucide CDN на странице (иначе иконки сайдбара пустые)
- тесты practice.test.js (10/10); план развития plans/ai-trainer/PLAN.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:11:47 +03:00

32 lines
2.4 KiB
SQL

-- ═══════════════════════════════════════════════════════════════
-- 081: Practice progress (ИИ-тренажёр, Фаза 0).
--
-- Прогресс ученика по НАВЫКАМ тренажёра. Навык = skill генератора
-- (напр. 'linear-basic'); задачи генерируются на клиенте детерминированно
-- и проверяются подстановкой — сервер хранит лишь агрегаты результата.
--
-- На каждую попытку клиент шлёт { skill, correct }. Сервер делает upsert:
-- solved — всего верных ответов
-- attempts — всего попыток (верных и нет)
-- cur_streak — текущая серия верных подряд (обнуляется ошибкой)
-- best_streak — лучшая серия
-- mastered — 1, как только cur_streak достиг порога (липкое)
-- UNIQUE(user_id, skill) — одна строка на пару ученик-навык.
-- user_id ON DELETE CASCADE — прогресс удаляется вместе с учеником.
-- ═══════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS practice_progress (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
skill TEXT NOT NULL, -- идентификатор навыка генератора
solved INTEGER NOT NULL DEFAULT 0, -- всего верных ответов
attempts INTEGER NOT NULL DEFAULT 0, -- всего попыток
cur_streak INTEGER NOT NULL DEFAULT 0, -- текущая серия верных подряд
best_streak INTEGER NOT NULL DEFAULT 0, -- лучшая серия
mastered INTEGER NOT NULL DEFAULT 0, -- 1, когда серия достигала порога
updated_at TEXT DEFAULT (datetime('now')),
UNIQUE (user_id, skill)
);
CREATE INDEX IF NOT EXISTS idx_practice_progress_user ON practice_progress (user_id);