-- =============================================
-- Education 模块 — 练习会话与题目快照 DDL
-- Ticket #6: 练习会话创建、题目快照、恢复与状态机
-- Migration: 002
-- Prerequisites: 000-education-schema.sql (database creation)
--                001-education-tenant-seed.sql (tenant seed data)
-- =============================================

-- =============================================
-- Preconditions
-- =============================================
-- This migration MUST fail if either table already exists (no IF NOT EXISTS).
-- Operator is expected to verify:
--   SELECT COUNT(*) FROM information_schema.tables
--     WHERE table_schema = DATABASE()
--       AND table_name IN ('education_practice_session', 'education_practice_question');
-- Result MUST be 0 before executing this migration.

-- =============================================
-- 练习会话表
-- =============================================
-- Indexes:
--   uk_tenant_client_session — per-tenant uniqueness for clientSessionId idempotency.
--     Used by: selectByTenantAndClientSessionId (idempotent create check),
--     DuplicateKeyException catch for concurrent-create race resolution.
--   idx_tenant_user_status — covers getCurrentSession (latest ACTIVE by tenant+user)
--     and ownership queries. Column order: (tenant_id, user_id, status) so the
--     index supports both filtering by tenant+user and tenant+user+status.
-- Lock impact: INSERT acquires next-key lock on uk_tenant_client_session unique key;
--     concurrent inserts with same (tenant_id, client_session_id) serialize naturally.
--     No additional table-level locks required.
CREATE TABLE `education_practice_session` (
    `id`               BIGINT       NOT NULL AUTO_INCREMENT COMMENT '会话主键',
    `tenant_id`        BIGINT       NOT NULL              COMMENT '租户编号',
    `user_id`          BIGINT       NOT NULL              COMMENT 'Member 用户编号',
    `client_session_id` VARCHAR(36) NOT NULL              COMMENT '客户端生成的会话标识（UUID），用于幂等创建',
    `status`           VARCHAR(20)  NOT NULL DEFAULT 'ACTIVE'
        COMMENT '会话状态：ACTIVE-进行中, SUBMITTED-已提交, EXPIRED-已过期, CANCELLED-已取消',
    `question_count`   INT          NOT NULL DEFAULT 0    COMMENT '题目总数',
    `collection_id`    VARCHAR(64)  DEFAULT NULL           COMMENT '源题集 ID',
    `node_id`          VARCHAR(64)  DEFAULT NULL           COMMENT '源目录节点 ID',
    `type`             VARCHAR(32)  DEFAULT NULL           COMMENT '筛选题型',
    `difficulty`       VARCHAR(32)  DEFAULT NULL           COMMENT '筛选难度',
    `version`          INT          NOT NULL DEFAULT 0    COMMENT '乐观锁版本号',
    `creator`          VARCHAR(64)  DEFAULT ''            COMMENT '创建者',
    `create_time`      DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `updater`          VARCHAR(64)  DEFAULT ''            COMMENT '更新者',
    `update_time`      DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    `deleted`          BIT(1)       NOT NULL DEFAULT b'0' COMMENT '是否删除',
    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_tenant_client_session` (`tenant_id`, `client_session_id`),
    KEY `idx_tenant_user_status` (`tenant_id`, `user_id`, `status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='教育-练习会话';

-- =============================================
-- 练习会话题目快照表
-- =============================================
-- Indexes:
--   uk_session_sequence — per-session uniqueness for question sequence numbers.
--     Used by: insertBatch to ensure no duplicate sequences within a session.
--   idx_session_id — covers selectBySessionIdOrderBySequence (load all questions
--     for a session, ordered by sequence). Also used by cascade delete lookups.
-- Lock impact: INSERT acquires gap locks within session_id range on uk_session_sequence;
--     concurrent inserts into different sessions are independent.
-- Options column: JSON data type stores only label, content, order — never isCorrect.
--     Application layer (optionsToSafeJson) strips correctness before storage.
CREATE TABLE `education_practice_question` (
    `id`               BIGINT       NOT NULL AUTO_INCREMENT COMMENT '主键',
    `tenant_id`        BIGINT       NOT NULL              COMMENT '租户编号',
    `session_id`       BIGINT       NOT NULL              COMMENT '会话 ID',
    `sequence`         INT          NOT NULL              COMMENT '题目序号（1-based，服务端固定）',
    `question_id`      VARCHAR(64)  NOT NULL              COMMENT '原始题目 ID',
    `content_version`  VARCHAR(64)  NOT NULL DEFAULT ''   COMMENT '快照时的题目内容版本',
    `stem`             TEXT         NOT NULL              COMMENT '题干快照',
    `type`             VARCHAR(32)  NOT NULL              COMMENT '题型快照',
    `difficulty`       VARCHAR(32)  DEFAULT NULL           COMMENT '难度快照',
    `options`          JSON         NOT NULL              COMMENT '选项快照 JSON（不含 isCorrect）',
    `selected_answer`  TEXT         DEFAULT NULL           COMMENT '学生已选答案',
    `is_answered`      BIT(1)       NOT NULL DEFAULT b'0' COMMENT '是否已作答',
    `creator`          VARCHAR(64)  DEFAULT ''            COMMENT '创建者',
    `create_time`      DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `updater`          VARCHAR(64)  DEFAULT ''            COMMENT '更新者',
    `update_time`      DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    `deleted`          BIT(1)       NOT NULL DEFAULT b'0' COMMENT '是否删除',
    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_session_sequence` (`session_id`, `sequence`),
    KEY `idx_session_id` (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='教育-练习会话题目快照';

-- =============================================
-- Post-migration verification queries
-- =============================================
-- Verify tables exist with correct structure:
--   SHOW CREATE TABLE education_practice_session;
--   SHOW CREATE TABLE education_practice_question;
-- Verify unique keys are enforced:
--   SHOW INDEX FROM education_practice_session WHERE Key_name = 'uk_tenant_client_session';
--   SHOW INDEX FROM education_practice_question WHERE Key_name = 'uk_session_sequence';
-- Verify no orphan data (should be 0 after fresh migration):
--   SELECT COUNT(*) FROM education_practice_session;
--   SELECT COUNT(*) FROM education_practice_question;
