-- governance_remediation_dispatch_2026-05-03.sql
-- Wave 2 D: 治理事件修復派遣表
-- 2026-05-03 ogt + Claude Sonnet 4.6（亞太）
--
-- 用途：
--   將 5 種治理事件（trust_drift / knowledge_degradation / llm_hallucination /
--   execution_blast_radius / governance_slo_data_gap）接到修復執行器。
--   每個事件同一時間最多 1 筆活躍 dispatch（partial unique index）。
--   失敗重試採 INSERT 新 row（保留完整審計痕跡），舊 row 永久保留 failed。
--
-- 依賴（必須先存在）：
--   - ai_governance_events（governance_event_id FK）
--   - playbooks（playbook_id FK）
--   - incidents（incident_id FK）
--   - approval_records（approval_id FK）
--
-- 回滾路徑：
--   DROP TABLE IF EXISTS governance_remediation_dispatch;
--   DROP TYPE  IF EXISTS governance_event_type;
--   DROP TYPE  IF EXISTS governance_dispatch_status;
-- ---------------------------------------------------------------------------

-- Step 1: 建立 ENUM 類型（create_type=False 的 ORM 需要 migration 預先建立）
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_type WHERE typname = 'governance_event_type'
    ) THEN
        CREATE TYPE governance_event_type AS ENUM (
            'trust_drift',
            'knowledge_degradation',
            'llm_hallucination',
            'execution_blast_radius',
            'governance_slo_data_gap'
        );
    END IF;
END
$$;

DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_type WHERE typname = 'governance_dispatch_status'
    ) THEN
        CREATE TYPE governance_dispatch_status AS ENUM (
            'pending',
            'dispatched',
            'executing',
            'succeeded',
            'failed',
            'skipped',
            'cancelled'
        );
    END IF;
END
$$;

-- Step 2: 建立主表
CREATE TABLE IF NOT EXISTS governance_remediation_dispatch (
    id                  VARCHAR(36)                 NOT NULL PRIMARY KEY,
    governance_event_id VARCHAR(36)                 NOT NULL
                            REFERENCES ai_governance_events(id) ON DELETE RESTRICT,
    event_type          governance_event_type       NOT NULL,
    dispatch_status     governance_dispatch_status  NOT NULL DEFAULT 'pending',
    playbook_id         VARCHAR(36)
                            REFERENCES playbooks(playbook_id) ON DELETE SET NULL,
    incident_id         VARCHAR(30)
                            REFERENCES incidents(incident_id) ON DELETE SET NULL,
    approval_id         VARCHAR(36)
                            REFERENCES approval_records(id) ON DELETE SET NULL,
    decision_context    JSONB                       NOT NULL DEFAULT '{}',
    executor_type       VARCHAR(80)                 NOT NULL,
    attempt_count       INTEGER                     NOT NULL DEFAULT 0,
    max_attempts        INTEGER                     NOT NULL DEFAULT 3,
    last_error          TEXT,
    dispatched_at       TIMESTAMPTZ                 NOT NULL DEFAULT NOW(),
    started_at          TIMESTAMPTZ,
    completed_at        TIMESTAMPTZ,
    created_by          VARCHAR(100)                DEFAULT 'governance_dispatcher',

    CONSTRAINT ck_grd_attempts
        CHECK (attempt_count >= 0 AND attempt_count <= max_attempts),
    CONSTRAINT ck_grd_max_attempts_positive
        CHECK (max_attempts > 0)
);

COMMENT ON TABLE governance_remediation_dispatch IS
    'Wave 2 D: 治理事件修復派遣記錄（失敗重試採 INSERT 新 row 審計策略）';

-- Step 3: 一般索引
CREATE INDEX IF NOT EXISTS ix_grd_status_dispatched
    ON governance_remediation_dispatch (dispatch_status, dispatched_at);

CREATE INDEX IF NOT EXISTS ix_grd_event_status
    ON governance_remediation_dispatch (governance_event_id, dispatch_status);

CREATE INDEX IF NOT EXISTS ix_grd_playbook_id
    ON governance_remediation_dispatch (playbook_id);

CREATE INDEX IF NOT EXISTS ix_grd_event_type_status
    ON governance_remediation_dispatch (event_type, dispatch_status);

CREATE INDEX IF NOT EXISTS ix_grd_governance_event_id
    ON governance_remediation_dispatch (governance_event_id);

-- Step 4: Partial unique index（同 event_id 不可同時有 2 筆活躍 dispatch）
-- 注意：ORM 層 __table_args__ 無法宣告 partial unique，此為唯一來源
CREATE UNIQUE INDEX IF NOT EXISTS ux_grd_one_active_per_event
    ON governance_remediation_dispatch (governance_event_id)
    WHERE dispatch_status IN ('pending', 'dispatched', 'executing');

-- Step 5: 權限授予（對齊 adr094 模式）
GRANT SELECT, INSERT, UPDATE ON governance_remediation_dispatch TO awoooi;

COMMENT ON INDEX ux_grd_one_active_per_event IS
    'Partial unique: 同一治理事件同一時間最多 1 筆活躍 dispatch（pending/dispatched/executing）';
