-- ================================================================
-- 补丁迁移：覆盖 db push 创建的 6 张表 + 3 列
-- 所有语句使用 IF NOT EXISTS 保证幂等（多次执行不报错）
-- 日期：2026-02-27
-- ================================================================

-- ============ iit_schema: 4 张新表 + 1 列 + 1 索引 ============

-- 1. IIT 字段元数据表（REDCap 字段定义缓存）
CREATE TABLE IF NOT EXISTS "iit_schema"."field_metadata" (
    "id" TEXT NOT NULL,
    "project_id" TEXT NOT NULL,
    "field_name" TEXT NOT NULL,
    "field_label" TEXT NOT NULL,
    "field_type" TEXT NOT NULL,
    "form_name" TEXT NOT NULL,
    "section_header" TEXT,
    "validation" TEXT,
    "validation_min" TEXT,
    "validation_max" TEXT,
    "choices" TEXT,
    "required" BOOLEAN NOT NULL DEFAULT false,
    "branching" TEXT,
    "alias" TEXT,
    "rule_source" TEXT,
    "synced_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT "field_metadata_pkey" PRIMARY KEY ("id")
);

CREATE UNIQUE INDEX IF NOT EXISTS "unique_iit_field_metadata"
  ON "iit_schema"."field_metadata"("project_id", "field_name");
CREATE INDEX IF NOT EXISTS "idx_iit_field_metadata_project"
  ON "iit_schema"."field_metadata"("project_id");
CREATE INDEX IF NOT EXISTS "idx_iit_field_metadata_form"
  ON "iit_schema"."field_metadata"("project_id", "form_name");

-- 2. IIT 质控日志表
CREATE TABLE IF NOT EXISTS "iit_schema"."qc_logs" (
    "id" TEXT NOT NULL,
    "project_id" TEXT NOT NULL,
    "record_id" TEXT NOT NULL,
    "event_id" TEXT,
    "qc_type" TEXT NOT NULL,
    "form_name" TEXT,
    "status" TEXT NOT NULL,
    "issues" JSONB NOT NULL DEFAULT '[]',
    "rules_evaluated" INTEGER NOT NULL DEFAULT 0,
    "rules_skipped" INTEGER NOT NULL DEFAULT 0,
    "rules_passed" INTEGER NOT NULL DEFAULT 0,
    "rules_failed" INTEGER NOT NULL DEFAULT 0,
    "rule_version" TEXT NOT NULL,
    "inclusion_passed" BOOLEAN,
    "exclusion_passed" BOOLEAN,
    "triggered_by" TEXT NOT NULL,
    "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT "qc_logs_pkey" PRIMARY KEY ("id")
);

CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_record_time"
  ON "iit_schema"."qc_logs"("project_id", "record_id", "created_at");
CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_status_time"
  ON "iit_schema"."qc_logs"("project_id", "status", "created_at");
CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_type_time"
  ON "iit_schema"."qc_logs"("project_id", "qc_type", "created_at");

-- 3. IIT 受试者记录汇总表
CREATE TABLE IF NOT EXISTS "iit_schema"."record_summary" (
    "id" TEXT NOT NULL,
    "project_id" TEXT NOT NULL,
    "record_id" TEXT NOT NULL,
    "enrolled_at" TIMESTAMP(3),
    "enrolled_by" TEXT,
    "last_updated_at" TIMESTAMP(3) NOT NULL,
    "last_updated_by" TEXT,
    "last_form_name" TEXT,
    "form_status" JSONB NOT NULL DEFAULT '{}',
    "total_forms" INTEGER NOT NULL DEFAULT 0,
    "completed_forms" INTEGER NOT NULL DEFAULT 0,
    "completion_rate" DOUBLE PRECISION NOT NULL DEFAULT 0,
    "latest_qc_status" TEXT,
    "latest_qc_at" TIMESTAMP(3),
    "update_count" INTEGER NOT NULL DEFAULT 0,
    "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updated_at" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "record_summary_pkey" PRIMARY KEY ("id")
);

CREATE UNIQUE INDEX IF NOT EXISTS "unique_iit_record_summary"
  ON "iit_schema"."record_summary"("project_id", "record_id");
CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_enrolled"
  ON "iit_schema"."record_summary"("project_id", "enrolled_at");
CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_qc_status"
  ON "iit_schema"."record_summary"("project_id", "latest_qc_status");
CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_completion"
  ON "iit_schema"."record_summary"("project_id", "completion_rate");

-- 4. IIT 项目级质控统计汇总表
CREATE TABLE IF NOT EXISTS "iit_schema"."qc_project_stats" (
    "id" TEXT NOT NULL,
    "project_id" TEXT NOT NULL,
    "total_records" INTEGER NOT NULL DEFAULT 0,
    "passed_records" INTEGER NOT NULL DEFAULT 0,
    "failed_records" INTEGER NOT NULL DEFAULT 0,
    "warning_records" INTEGER NOT NULL DEFAULT 0,
    "inclusion_met" INTEGER NOT NULL DEFAULT 0,
    "exclusion_met" INTEGER NOT NULL DEFAULT 0,
    "avg_completion_rate" DOUBLE PRECISION NOT NULL DEFAULT 0,
    "updated_at" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "qc_project_stats_pkey" PRIMARY KEY ("id")
);

CREATE UNIQUE INDEX IF NOT EXISTS "qc_project_stats_project_id_key"
  ON "iit_schema"."qc_project_stats"("project_id");

-- 5. IIT projects 表新增 knowledge_base_id 列
ALTER TABLE "iit_schema"."projects"
  ADD COLUMN IF NOT EXISTS "knowledge_base_id" TEXT;

CREATE INDEX IF NOT EXISTS "idx_iit_project_kb"
  ON "iit_schema"."projects"("knowledge_base_id");

-- ============ ssa_schema: 1 列 + 2 张新表 ============

-- 6a. SSA Session 新增 data_profile 列（Phase 2A）
ALTER TABLE "ssa_schema"."ssa_sessions"
  ADD COLUMN IF NOT EXISTS "data_profile" JSONB;

-- 6. SSA 工作流表
CREATE TABLE IF NOT EXISTS "ssa_schema"."ssa_workflows" (
    "id" TEXT NOT NULL DEFAULT gen_random_uuid()::text,
    "session_id" TEXT NOT NULL,
    "message_id" TEXT,
    "status" VARCHAR NOT NULL DEFAULT 'pending',
    "total_steps" INTEGER NOT NULL,
    "completed_steps" INTEGER NOT NULL DEFAULT 0,
    "workflow_plan" JSONB NOT NULL,
    "reasoning" TEXT,
    "created_at" TIMESTAMP(3) NOT NULL DEFAULT now(),
    "started_at" TIMESTAMP(3),
    "completed_at" TIMESTAMP(3),

    CONSTRAINT "ssa_workflows_pkey" PRIMARY KEY ("id")
);

CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_session"
  ON "ssa_schema"."ssa_workflows"("session_id");
CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_status"
  ON "ssa_schema"."ssa_workflows"("status");

-- 外键：ssa_workflows.session_id → ssa_sessions.id
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.table_constraints
    WHERE constraint_name = 'ssa_workflows_session_id_fkey'
  ) THEN
    ALTER TABLE "ssa_schema"."ssa_workflows"
      ADD CONSTRAINT "ssa_workflows_session_id_fkey"
      FOREIGN KEY ("session_id")
      REFERENCES "ssa_schema"."ssa_sessions"("id")
      ON DELETE CASCADE ON UPDATE CASCADE;
  END IF;
END $$;

-- 7. SSA 工作流步骤表
CREATE TABLE IF NOT EXISTS "ssa_schema"."ssa_workflow_steps" (
    "id" TEXT NOT NULL DEFAULT gen_random_uuid()::text,
    "workflow_id" TEXT NOT NULL,
    "step_order" INTEGER NOT NULL,
    "tool_code" VARCHAR NOT NULL,
    "tool_name" VARCHAR NOT NULL,
    "status" VARCHAR NOT NULL DEFAULT 'pending',
    "input_params" JSONB,
    "guardrail_checks" JSONB,
    "output_result" JSONB,
    "error_info" JSONB,
    "execution_ms" INTEGER,
    "started_at" TIMESTAMP(3),
    "completed_at" TIMESTAMP(3),

    CONSTRAINT "ssa_workflow_steps_pkey" PRIMARY KEY ("id")
);

CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_step_workflow"
  ON "ssa_schema"."ssa_workflow_steps"("workflow_id");
CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_step_status"
  ON "ssa_schema"."ssa_workflow_steps"("status");

-- 外键：ssa_workflow_steps.workflow_id → ssa_workflows.id
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.table_constraints
    WHERE constraint_name = 'ssa_workflow_steps_workflow_id_fkey'
  ) THEN
    ALTER TABLE "ssa_schema"."ssa_workflow_steps"
      ADD CONSTRAINT "ssa_workflow_steps_workflow_id_fkey"
      FOREIGN KEY ("workflow_id")
      REFERENCES "ssa_schema"."ssa_workflows"("id")
      ON DELETE CASCADE ON UPDATE CASCADE;
  END IF;
END $$;

-- ============ rvw_schema: review_tasks 缺失列 ============

-- 8. review_tasks 后续 prisma db push 新增的 8 个列
ALTER TABLE "rvw_schema"."review_tasks"
  ADD COLUMN IF NOT EXISTS "selected_agents" TEXT[] DEFAULT ARRAY['editorial','methodology'];
ALTER TABLE "rvw_schema"."review_tasks"
  ADD COLUMN IF NOT EXISTS "editorial_score" DOUBLE PRECISION;
ALTER TABLE "rvw_schema"."review_tasks"
  ADD COLUMN IF NOT EXISTS "methodology_score" DOUBLE PRECISION;
ALTER TABLE "rvw_schema"."review_tasks"
  ADD COLUMN IF NOT EXISTS "methodology_status" TEXT;
ALTER TABLE "rvw_schema"."review_tasks"
  ADD COLUMN IF NOT EXISTS "pico_extract" JSONB;
ALTER TABLE "rvw_schema"."review_tasks"
  ADD COLUMN IF NOT EXISTS "context_data" JSONB;
ALTER TABLE "rvw_schema"."review_tasks"
  ADD COLUMN IF NOT EXISTS "is_archived" BOOLEAN DEFAULT false;
ALTER TABLE "rvw_schema"."review_tasks"
  ADD COLUMN IF NOT EXISTS "archived_at" TIMESTAMP(3);

CREATE INDEX IF NOT EXISTS "review_tasks_is_archived_idx"
  ON "rvw_schema"."review_tasks"("is_archived");
