사용자가 며칠 안 들어오면 due_today 가 누적되어 학습 페이스 압박. Phase 1
plan 위험 항목 처리. 자동 batch 대신 사용자 명시 액션으로 통제권 보장.
Backend:
- POST /study-topics/{tid}/review-queue/redistribute — overdue 를 round-robin
분산. days_offset = i % spread_days + 1 (오늘 + 1~7일). 같은 날 안에서도
i*7분 spread 로 시간 분산. review_stage 는 보존 (재배치만, stage 리셋 X).
body { spread_days: 1~14, default 7 }. 응답 { redistributed_count, spread_days }.
- GET /review-queue?tab=due_today 응답에 overdue_count: int 옵션 필드 — UI 가
경고 + [정리] 노출 판단. due_at < today 0시 (UTC) + stage<4 카운트.
Frontend (review-queue):
- due_today 탭에서 overdue_count>0 시 노란 banner — "정체 N건" + [정리] 버튼.
- 정리 클릭 → confirm → POST → toast (N건을 7일에 분산) → 카운트/목록 reload.
- 다른 탭에서는 banner 미노출 (backend 가 overdue_count=0 응답).
Plan: ~/.claude/plans/crispy-petting-dijkstra.md (Phase 2-F)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
vision (풀이 → 확인 → 학습 → 복습 → 다음 풀이 가중치) 의 데이터 계층.
데이터 모델 (migrations 222~225):
- study_question_progress 테이블 — user × topic × question 단위 현재 상태 캐시
- 마지막 시도: last_outcome, last_attempted_at, last_attempt_id
- 검토 상태: last_reviewed_at
- 복습 큐: due_at, review_stage
- 패턴 분류 (derived): pattern_state, pattern_updated_at, pattern_window_attempts
- 3 partial idx (due / topic_pattern / pending_review) — 탭별 빠른 조회
패턴 분류 (services/study/learning_pattern.py):
- 7 분류: unattempted/unsure/chronic_wrong/regressed/recovered/stable/unstable
- 윈도우 = 최근 3회 + 과거 correct/wrong 존재 여부
- chronic_wrong > regressed > recovered 우선순위 (보수적 학습)
- 가드: wrong 1회만으로 regressed 안 됨 (이전 correct 이력 필요)
- stable 은 3 연속 correct 부터
세션 종료 집계 (services/study/session_finalize.py):
- attempts append-only 원본 보존, progress upsert 만
- 마지막 attempt 직후 finalize hook 자동 발동
- finalize 는 last_* + pattern_state 만 갱신, due_at 미진입 문제는 NULL 유지
- 이미 due_at 박힌 문제는 finalize 가 stage 갱신 (correct → +1 / wrong → 리셋)
API (api/study_question_progress.py):
- POST /study-topics/{tid}/questions/{qid}/review-complete
→ last_reviewed_at + (wrong/unsure 인 경우만) due_at 최초 부여
- GET /study-topics/{tid}/review-queue?tab=due_today|pending_review|chronic|regressed|mastered
→ 5 탭 paginated 조회
→ pending_review 는 last_reviewed_at < last_attempted_at 까지 포함 (이전 확인완료 후 다시 wrong 잡힘)
Phase 1-E (풀이 선별 알고리즘) 은 후속 commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>