-- 164_study_sessions.sql -- iPad 손글씨 학습 세션 + 모바일 암기노트/퀴즈 — Phase 1 MVP (1/10) -- plan: ~/.claude/plans/scalable-chasing-stonebraker.md -- -- asyncpg prepared statement 는 single-command 만 허용. -- 원래 한 파일이던 학습 세션 스키마를 10개로 분리: -- 164: CREATE TABLE study_sessions -- 165~169: study_sessions 인덱스 5개 -- 170: CREATE TABLE study_session_assets -- 171~173: study_session_assets 인덱스 3개 -- -- 자격증(certification) + 어학(language) 두 도메인을 모두 받는 일반 학습 세션. -- iPad write / 모바일 review / 모바일 quiz 가 같은 데이터를 공유. -- -- 핵심 원칙: -- - study_type 으로 도메인 분기. metadata jsonb 가 도메인별 자유 메타. -- - 단일 *_document_id 컬럼 금지. 모든 미디어 연결은 study_session_assets. -- - documents 본체는 절대 삭제하지 않음 (assets 만 cascade). -- - Phase 1 미사용 필드 (review_state / quiz / ocr / ai_summary / prompt) 는 NULL 허용, -- 자동 로직은 Phase 2~4 별도 PR 에서 활성. CREATE TABLE IF NOT EXISTS study_sessions ( id BIGSERIAL PRIMARY KEY, user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE, study_type VARCHAR(30) NOT NULL DEFAULT 'certification', certification VARCHAR(120), language_code VARCHAR(20), learning_level VARCHAR(80), subject VARCHAR(120), topic VARCHAR(200), source_text TEXT, source_page INTEGER, mode VARCHAR(30) NOT NULL DEFAULT 'copy', prompt_question TEXT, expected_answer TEXT, metadata JSONB, target_count INTEGER, repetition_count INTEGER NOT NULL DEFAULT 0, strokes_json JSONB, canvas_width INTEGER, canvas_height INTEGER, schema_version INTEGER NOT NULL DEFAULT 1, ocr_text TEXT, user_corrected_text TEXT, ai_summary TEXT, review_state VARCHAR(20), next_review_at TIMESTAMPTZ, last_quiz_at TIMESTAMPTZ, correct_count INTEGER NOT NULL DEFAULT 0, incorrect_count INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() );