0a7402b327
study_memo_cards 추출 파이프라인 + 버전키 폴러 + needs_review 컬럼. 운영 SR 코드(session_finalize/quiz_selection) 무수정.
- migrations 287~298: study_memo_cards/_evidence/_jobs/_progress(P1 휴면)·study_reminders·study_topics.focused_at·study_questions needs_review 3컬럼. dedup PARTIAL UNIQUE(deleted_at IS NULL).
- 워커: in-process RAG gather → MLX {cards} → 카드 가드(정량=evidence 원문 등장·cue/cloze 누출·dedup) → supersede 구버전 retire → append. 별 consumer 로 기존 study_queue 격리.
- 폴러 study_card_enqueue: 버전키 NOT EXISTS(source_version) 멱등 + ai_explanation_generated_at NOT NULL 가드 + per-poll LIMIT(thundering-herd).
- 검증: 실 prod 스키마 덤프 위 12 마이그 적용 OK + dedup/supersede/active-unique 기능 7/7 PASS + 정규화 util 15/15.
plan: PKM plans/2026-06-05-study-memo-card-p1-plan.html
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
11 lines
597 B
SQL
11 lines
597 B
SQL
-- 288_study_memo_cards_dedup_uq.sql
|
|
-- dedup_hash 중복 카드 차단의 최종 방어선 (구조로 강제).
|
|
-- append_card 의 ON CONFLICT (dedup_hash) DO NOTHING 이 매칭할 UNIQUE 제약 — 필수.
|
|
-- PARTIAL (WHERE deleted_at IS NULL): supersede 로 retire 된 구버전 카드가
|
|
-- 같은 dedup_hash 의 새 추출을 막지 않도록 살아있는 카드만 유일성 강제.
|
|
-- dedup_hash = sha256(source_question_id | format | normalize(정답토큰)).
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_study_memo_cards_dedup
|
|
ON study_memo_cards (dedup_hash)
|
|
WHERE deleted_at IS NULL;
|