BEGIN;

-- ============================================================================
-- Rule Domain Tenant Phase 1
-- 目标：
--   1. 为规则域核心表补 tenant_code / scope_type / 运行结果快照字段
--   2. 为运行时 TENANT -> PROVINCIAL -> PUBLIC 解析建立物理载体
--   3. 将历史全局规则资产默认回填到 PROVINCIAL，而不是 PUBLIC
-- 说明：
--   - 本阶段只做补列、建索引、基础回填
--   - 不强制 NOT NULL
--   - 不删除旧 region / 全局兼容逻辑
-- ============================================================================

-- --------------------------------------------------------------------------
-- 1. leaudit_rule_sets
-- --------------------------------------------------------------------------
ALTER TABLE public.leaudit_rule_sets
    ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64),
    ADD COLUMN IF NOT EXISTS scope_type VARCHAR(32) DEFAULT 'PROVINCIAL',
    ADD COLUMN IF NOT EXISTS source_rule_set_id BIGINT,
    ADD COLUMN IF NOT EXISTS tenant_name_snapshot VARCHAR(255);

COMMENT ON COLUMN public.leaudit_rule_sets.tenant_code IS '规则集所属租户编码';
COMMENT ON COLUMN public.leaudit_rule_sets.scope_type IS '规则集作用域: TENANT / PROVINCIAL / PUBLIC';
COMMENT ON COLUMN public.leaudit_rule_sets.source_rule_set_id IS '派生规则集来源 rule_set_id';
COMMENT ON COLUMN public.leaudit_rule_sets.tenant_name_snapshot IS '规则集所属租户名称快照';

CREATE INDEX IF NOT EXISTS idx_leaudit_rule_sets_tenant_code
    ON public.leaudit_rule_sets(tenant_code)
    WHERE deleted_at IS NULL;

CREATE INDEX IF NOT EXISTS idx_leaudit_rule_sets_scope_type
    ON public.leaudit_rule_sets(scope_type)
    WHERE deleted_at IS NULL;

-- --------------------------------------------------------------------------
-- 2. leaudit_rule_versions
-- --------------------------------------------------------------------------
ALTER TABLE public.leaudit_rule_versions
    ADD COLUMN IF NOT EXISTS tenant_code_snapshot VARCHAR(64),
    ADD COLUMN IF NOT EXISTS scope_type_snapshot VARCHAR(32),
    ADD COLUMN IF NOT EXISTS source_version_id BIGINT;

COMMENT ON COLUMN public.leaudit_rule_versions.tenant_code_snapshot IS '规则版本所属租户编码快照';
COMMENT ON COLUMN public.leaudit_rule_versions.scope_type_snapshot IS '规则版本作用域快照';
COMMENT ON COLUMN public.leaudit_rule_versions.source_version_id IS '派生版本来源 version_id';

CREATE INDEX IF NOT EXISTS idx_leaudit_rule_versions_tenant_code_snapshot
    ON public.leaudit_rule_versions(tenant_code_snapshot);

-- --------------------------------------------------------------------------
-- 3. leaudit_rule_group_bindings
-- --------------------------------------------------------------------------
ALTER TABLE public.leaudit_rule_group_bindings
    ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64),
    ADD COLUMN IF NOT EXISTS scope_type VARCHAR(32) DEFAULT 'PROVINCIAL',
    ADD COLUMN IF NOT EXISTS tenant_name_snapshot VARCHAR(255);

COMMENT ON COLUMN public.leaudit_rule_group_bindings.tenant_code IS '业务组绑定所属租户编码';
COMMENT ON COLUMN public.leaudit_rule_group_bindings.scope_type IS '业务组绑定作用域: TENANT / PROVINCIAL / PUBLIC';
COMMENT ON COLUMN public.leaudit_rule_group_bindings.tenant_name_snapshot IS '业务组绑定所属租户名称快照';

CREATE INDEX IF NOT EXISTS idx_leaudit_rule_group_bindings_group_tenant
    ON public.leaudit_rule_group_bindings(group_id, tenant_code)
    WHERE deleted_at IS NULL;

CREATE INDEX IF NOT EXISTS idx_leaudit_rule_group_bindings_scope_type
    ON public.leaudit_rule_group_bindings(scope_type)
    WHERE deleted_at IS NULL;

-- --------------------------------------------------------------------------
-- 4. leaudit_rule_type_bindings
-- --------------------------------------------------------------------------
ALTER TABLE public.leaudit_rule_type_bindings
    ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64),
    ADD COLUMN IF NOT EXISTS scope_type VARCHAR(32) DEFAULT 'PROVINCIAL';

COMMENT ON COLUMN public.leaudit_rule_type_bindings.tenant_code IS '旧规则类型绑定所属租户编码，仅用于兼容与迁移';
COMMENT ON COLUMN public.leaudit_rule_type_bindings.scope_type IS '旧规则类型绑定作用域，仅用于兼容与迁移';

-- --------------------------------------------------------------------------
-- 5. leaudit_audit_runs
-- --------------------------------------------------------------------------
ALTER TABLE public.leaudit_audit_runs
    ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64),
    ADD COLUMN IF NOT EXISTS tenant_name_snapshot VARCHAR(255),
    ADD COLUMN IF NOT EXISTS scope_type_snapshot VARCHAR(32),
    ADD COLUMN IF NOT EXISTS group_id_snapshot BIGINT,
    ADD COLUMN IF NOT EXISTS rule_binding_id_snapshot BIGINT;

COMMENT ON COLUMN public.leaudit_audit_runs.tenant_code IS '本次运行所属租户编码快照';
COMMENT ON COLUMN public.leaudit_audit_runs.tenant_name_snapshot IS '本次运行所属租户名称快照';
COMMENT ON COLUMN public.leaudit_audit_runs.scope_type_snapshot IS '本次运行命中的规则作用域快照';
COMMENT ON COLUMN public.leaudit_audit_runs.group_id_snapshot IS '本次运行命中的业务组快照';
COMMENT ON COLUMN public.leaudit_audit_runs.rule_binding_id_snapshot IS '本次运行命中的规则绑定快照';

CREATE INDEX IF NOT EXISTS idx_leaudit_audit_runs_tenant_code
    ON public.leaudit_audit_runs(tenant_code, created_at DESC);

-- --------------------------------------------------------------------------
-- 6. leaudit_rule_results
-- --------------------------------------------------------------------------
ALTER TABLE public.leaudit_rule_results
    ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64),
    ADD COLUMN IF NOT EXISTS tenant_name_snapshot VARCHAR(255);

COMMENT ON COLUMN public.leaudit_rule_results.tenant_code IS '规则结果所属租户编码快照';
COMMENT ON COLUMN public.leaudit_rule_results.tenant_name_snapshot IS '规则结果所属租户名称快照';

CREATE INDEX IF NOT EXISTS idx_leaudit_rule_results_tenant_code
    ON public.leaudit_rule_results(tenant_code);

-- --------------------------------------------------------------------------
-- 7. leaudit_run_errors
-- --------------------------------------------------------------------------
ALTER TABLE public.leaudit_run_errors
    ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64),
    ADD COLUMN IF NOT EXISTS tenant_name_snapshot VARCHAR(255);

COMMENT ON COLUMN public.leaudit_run_errors.tenant_code IS '运行错误所属租户编码快照';
COMMENT ON COLUMN public.leaudit_run_errors.tenant_name_snapshot IS '运行错误所属租户名称快照';

CREATE INDEX IF NOT EXISTS idx_leaudit_run_errors_tenant_code
    ON public.leaudit_run_errors(tenant_code);

-- --------------------------------------------------------------------------
-- 8. leaudit_run_metrics
-- --------------------------------------------------------------------------
ALTER TABLE public.leaudit_run_metrics
    ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64);

COMMENT ON COLUMN public.leaudit_run_metrics.tenant_code IS '运行指标所属租户编码快照';

CREATE INDEX IF NOT EXISTS idx_leaudit_run_metrics_tenant_code
    ON public.leaudit_run_metrics(tenant_code);

-- --------------------------------------------------------------------------
-- 9. 历史资产默认回填到 PROVINCIAL
-- --------------------------------------------------------------------------
UPDATE public.leaudit_rule_sets
SET tenant_code = COALESCE(NULLIF(BTRIM(tenant_code), ''), 'PROVINCIAL'),
    scope_type = COALESCE(NULLIF(BTRIM(scope_type), ''), 'PROVINCIAL')
WHERE deleted_at IS NULL;

-- 兼容历史唯一约束 (rule_type, region)：租户私有规则集必须使用租户编码作为 legacy region，
-- 否则会与省级默认 region=default 冲突。
UPDATE public.leaudit_rule_sets
SET region = tenant_code
WHERE deleted_at IS NULL
  AND scope_type = 'TENANT'
  AND tenant_code IS NOT NULL
  AND BTRIM(tenant_code) <> ''
  AND region = 'default';

UPDATE public.leaudit_rule_versions rv
SET tenant_code_snapshot = COALESCE(
        NULLIF(BTRIM(rv.tenant_code_snapshot), ''),
        NULLIF(BTRIM(rs.tenant_code), ''),
        'PROVINCIAL'
    ),
    scope_type_snapshot = COALESCE(
        NULLIF(BTRIM(rv.scope_type_snapshot), ''),
        NULLIF(BTRIM(rs.scope_type), ''),
        'PROVINCIAL'
    )
FROM public.leaudit_rule_sets rs
WHERE rv.rule_set_id = rs.id;

UPDATE public.leaudit_rule_group_bindings rgb
SET tenant_code = COALESCE(NULLIF(BTRIM(rgb.tenant_code), ''), 'PROVINCIAL'),
    scope_type = COALESCE(NULLIF(BTRIM(rgb.scope_type), ''), 'PROVINCIAL')
WHERE rgb.deleted_at IS NULL;

UPDATE public.leaudit_rule_type_bindings
SET tenant_code = COALESCE(NULLIF(BTRIM(tenant_code), ''), 'PROVINCIAL'),
    scope_type = COALESCE(NULLIF(BTRIM(scope_type), ''), 'PROVINCIAL')
WHERE deleted_at IS NULL;

-- --------------------------------------------------------------------------
-- 10. 运行与结果快照回填
-- --------------------------------------------------------------------------
UPDATE public.leaudit_audit_runs ar
SET tenant_code = COALESCE(
        NULLIF(BTRIM(ar.tenant_code), ''),
        NULLIF(BTRIM(d.tenant_code), ''),
        'PROVINCIAL'
    ),
    scope_type_snapshot = COALESCE(
        NULLIF(BTRIM(ar.scope_type_snapshot), ''),
        'PROVINCIAL'
    ),
    group_id_snapshot = COALESCE(ar.group_id_snapshot, d.group_id)
FROM public.leaudit_documents d
WHERE ar.document_id = d.id;

UPDATE public.leaudit_rule_results rr
SET tenant_code = COALESCE(
        NULLIF(BTRIM(rr.tenant_code), ''),
        NULLIF(BTRIM(ar.tenant_code), ''),
        NULLIF(BTRIM(d.tenant_code), ''),
        'PROVINCIAL'
    )
FROM public.leaudit_audit_runs ar
LEFT JOIN public.leaudit_documents d ON d.id = ar.document_id
WHERE rr.run_id = ar.id;

UPDATE public.leaudit_run_errors re
SET tenant_code = COALESCE(
        NULLIF(BTRIM(re.tenant_code), ''),
        NULLIF(BTRIM(ar.tenant_code), ''),
        NULLIF(BTRIM(d.tenant_code), ''),
        'PROVINCIAL'
    )
FROM public.leaudit_audit_runs ar
LEFT JOIN public.leaudit_documents d ON d.id = ar.document_id
WHERE re.run_id = ar.id;

UPDATE public.leaudit_run_metrics rm
SET tenant_code = COALESCE(
        NULLIF(BTRIM(rm.tenant_code), ''),
        NULLIF(BTRIM(ar.tenant_code), ''),
        NULLIF(BTRIM(d.tenant_code), ''),
        'PROVINCIAL'
    )
FROM public.leaudit_audit_runs ar
LEFT JOIN public.leaudit_documents d ON d.id = ar.document_id
WHERE rm.run_id = ar.id;

COMMIT;
