-- =============================================
-- Education 模块 — 统一幂等表 DDL (PostgreSQL)
-- Ticket: 合并 Answer + Submit 幂等表为统一 education_idempotency
-- Migration: 009
-- Prerequisites: 002-education-practice-session.sql
-- =============================================

-- =============================================
-- Preconditions
-- =============================================
-- Verify table does not already exist:
--   SELECT COUNT(*) FROM information_schema.tables
--     WHERE table_catalog = current_database()
--       AND table_name = 'education_idempotency';
-- Result MUST be 0 before executing this migration.
--
-- NOTE: This table replaces education_answer_idempotency and education_submit_idempotency.
-- Those tables should be dropped after this migration is verified:
--   DROP TABLE IF EXISTS education_answer_idempotency;
--   DROP TABLE IF EXISTS education_submit_idempotency;

-- =============================================
-- 统一幂等表
-- =============================================
-- Purpose: Unified idempotency store for all education write operations.
--   operation field distinguishes: SUBMIT_ANSWER vs SUBMIT_SESSION.
--   Same (tenant, user, operation, idempotency_key) + same request_hash → replay original response.
--   Same key + different request_hash → conflict.
--   PostgreSQL ON CONFLICT DO NOTHING resolves concurrent same-key inserts.
--
-- Indexes:
--   uk_idempotency — per-tenant, per-actor, per-operation uniqueness for idempotency key.
--     Used by: IdempotencyStoreMapper.insertIgnore() ON CONFLICT resolution.
--   idx_tenant_session — covers lookup by session for audit/debug.
--
-- Fields specific to SUBMIT_ANSWER: question_id, selected_answer (nullable for SUBMIT_SESSION).
-- Fields specific to SUBMIT_SESSION: report_id (nullable for SUBMIT_ANSWER).
-- response_json: stores serialized response for replay after timeout/retry.
-- request_hash: SHA-256 of canonical payload for content-based dedup.
CREATE TABLE education_idempotency (
    id               BIGINT       GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    tenant_id        BIGINT       NOT NULL,
    user_id          BIGINT       NOT NULL,
    operation        VARCHAR(32)  NOT NULL,
    idempotency_key  VARCHAR(64)  NOT NULL,
    request_hash     VARCHAR(64)  NOT NULL,
    session_id       BIGINT       NOT NULL,
    question_id      VARCHAR(64)  DEFAULT NULL,
    selected_answer  TEXT         DEFAULT NULL,
    report_id        BIGINT       DEFAULT NULL,
    status           VARCHAR(20)  NOT NULL DEFAULT 'ACCEPTED',
    response_json    TEXT         DEFAULT NULL,
    business_payload JSONB        DEFAULT NULL,
    creator          VARCHAR(64)  DEFAULT '',
    create_time      TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updater          VARCHAR(64)  DEFAULT '',
    update_time      TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted          BOOLEAN      NOT NULL DEFAULT false
);

COMMENT ON TABLE education_idempotency IS '教育-统一幂等记录（合并 answer + submit）';
COMMENT ON COLUMN education_idempotency.id IS '主键';
COMMENT ON COLUMN education_idempotency.tenant_id IS '租户编号';
COMMENT ON COLUMN education_idempotency.user_id IS '用户编号';
COMMENT ON COLUMN education_idempotency.operation IS '操作类型：SUBMIT_ANSWER-答题, SUBMIT_SESSION-交卷';
COMMENT ON COLUMN education_idempotency.idempotency_key IS '客户端幂等键（UUID）';
COMMENT ON COLUMN education_idempotency.request_hash IS '请求载荷 SHA-256 哈希';
COMMENT ON COLUMN education_idempotency.session_id IS '会话 ID';
COMMENT ON COLUMN education_idempotency.question_id IS '题目 ID（SUBMIT_ANSWER）';
COMMENT ON COLUMN education_idempotency.selected_answer IS '学生已选答案（SUBMIT_ANSWER）';
COMMENT ON COLUMN education_idempotency.report_id IS '关联报告 ID（SUBMIT_SESSION）';
COMMENT ON COLUMN education_idempotency.status IS '状态：ACCEPTED-已接受, CONFLICT-冲突';
COMMENT ON COLUMN education_idempotency.response_json IS '首次成功响应 JSON（用于重试重放）';
COMMENT ON COLUMN education_idempotency.business_payload IS '业务扩展载荷（JSONB）';
COMMENT ON COLUMN education_idempotency.creator IS '创建者';
COMMENT ON COLUMN education_idempotency.create_time IS '创建时间';
COMMENT ON COLUMN education_idempotency.updater IS '更新者';
COMMENT ON COLUMN education_idempotency.update_time IS '更新时间';
COMMENT ON COLUMN education_idempotency.deleted IS '是否删除';

CREATE UNIQUE INDEX uk_idempotency ON education_idempotency (tenant_id, user_id, operation, idempotency_key);
CREATE INDEX idx_idempotency_tenant_session ON education_idempotency (tenant_id, session_id);

-- =============================================
-- PracticeSessionDO: add review_fingerprint column
-- =============================================
-- Purpose: Store canonical fingerprint for wrong-question review session idempotency.
--   SHA-256 of comma-joined sorted wrong_question IDs for deterministic comparison.
ALTER TABLE education_practice_session
    ADD COLUMN review_fingerprint VARCHAR(64) DEFAULT NULL;

COMMENT ON COLUMN education_practice_session.review_fingerprint IS '错题复习指纹（SHA-256），用于幂等创建';

-- =============================================
-- Post-migration verification queries
-- =============================================
-- Verify new table exists:
--   \d education_idempotency
-- Verify unique index:
--   SELECT * FROM pg_indexes WHERE tablename = 'education_idempotency';
-- Verify column added:
--   SELECT column_name, data_type FROM information_schema.columns
--    WHERE table_name = 'education_practice_session' AND column_name = 'review_fingerprint';
