Files
Learn_System/backend/src/db/migrations/074_flashcard_learning_steps.sql
T
Maxim Dolgolyov 5c01a5c7ed feat(flashcards): learning-steps SR — повторный показ «Снова» в сессии, лимит новых карт/день
Tier-1 апгрейд интервального повторения:
- schedule() с состояниями learning/relearning/review вместо плоского sm2():
  новая карта проходит шаги [1,10] мин, «Снова» возвращает на шаг 0 (минуты),
  «Знаю» продвигает шаг → выпуск (1д), «Легко» выпускает сразу (4д); зрелая
  «Снова» = lapse → relearning (ef−0.2, ×0.5).
- study-сессия: динамическая очередь — недоученная карта (graduated=false)
  возвращается через 3 карты и показывается снова в той же сессии.
- лимит новых карт/день (decks.new_per_day, деф.20) в getStudySession и бейдже.
- превью кнопок fcPreview() показывает минуты/дни, зеркало серверной логики.
- миграция 074: state/learning_step/lapses/created_at + new_per_day + индексы.
- тесты SRS 9/9 (шаги, lapse, лимит новых).

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

32 lines
2.5 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- 074_flashcard_learning_steps.sql
-- Tier-1 апгрейд интервального повторения: настоящие learning-steps (под-дневные
-- интервалы), повторный показ «Снова» в той же сессии и лимит новых карт в день.
--
-- flashcard_reviews получает состояние карточки:
-- state — 'review' (зрелая, день-интервалы SM-2) | 'learning' (новая в шагах)
-- | 'relearning' (зрелая после провала, снова в шагах).
-- Старые строки = 'review' (они уже были выпущены старым алгоритмом).
-- learning_step — индекс текущего шага обучения (0..N).
-- lapses — сколько раз зрелая карта проваливалась (для статистики).
-- created_at — когда карта впервые введена в оборот (для лимита новых/день).
-- Старым строкам ставим '' (date('')=NULL → не считаются «введёнными
-- сегодня»); новые строки контроллер заполняет datetime('now').
-- ВАЖНО: под-дневные интервалы живут в due_at (TEXT datetime с минутами), поэтому
-- interval_days остаётся INTEGER — менять тип не нужно.
--
-- flashcard_decks.new_per_day — сколько новых карт колоды показывать за день (деф. 20).
--
-- Примечание: ALTER TABLE ADD COLUMN в SQLite запрещает выражение-default
-- (datetime('now')), поэтому created_at = '' и проставляется кодом на INSERT.
ALTER TABLE flashcard_reviews ADD COLUMN state TEXT NOT NULL DEFAULT 'review';
ALTER TABLE flashcard_reviews ADD COLUMN learning_step INTEGER NOT NULL DEFAULT 0;
ALTER TABLE flashcard_reviews ADD COLUMN lapses INTEGER NOT NULL DEFAULT 0;
ALTER TABLE flashcard_reviews ADD COLUMN created_at TEXT NOT NULL DEFAULT '';
ALTER TABLE flashcard_decks ADD COLUMN new_per_day INTEGER NOT NULL DEFAULT 20;
-- Индексы под горячие пути (getCards / getStudySession / listDecks-подсчёты).
CREATE INDEX IF NOT EXISTS idx_fc_cards_deck ON flashcard_cards(deck_id);
CREATE INDEX IF NOT EXISTS idx_fc_reviews_card ON flashcard_reviews(card_id);