-- 入口模块菜单模板、多租户可见性、文档归属巡检脚本
-- 用途：
--   1. 检查 entry_module_menu_profile_migration.sql 是否补齐字段、索引、默认值。
--   2. 检查入口模块 features/menu_profile 是否存在非法值或空配置。
--   3. 检查文档 entry_module_id 回填情况和二级分组重复风险。
--   4. 本脚本只查询，不修改数据。
--
-- 推荐执行方式：
-- psql "$DATABASE_URL" -f scripts/创建sql/verify_entry_module_menu_profile.sql

-- =========================================================
-- 1. 必要字段检查
-- =========================================================
SELECT
    table_name,
    column_name,
    data_type,
    is_nullable,
    column_default
FROM information_schema.columns
WHERE table_schema = current_schema()
  AND (
      (table_name = 'leaudit_entry_modules' AND column_name IN ('menu_profile', 'features'))
      OR (table_name = 'leaudit_documents' AND column_name = 'entry_module_id')
  )
ORDER BY table_name, column_name;

-- =========================================================
-- 2. 必要索引检查
-- =========================================================
SELECT
    schemaname,
    tablename,
    indexname,
    indexdef
FROM pg_indexes
WHERE schemaname = current_schema()
  AND indexname IN (
      'idx_leaudit_entry_modules_menu_profile',
      'idx_leaudit_documents_entry_module_id',
      'uq_leaudit_ep_groups_parent_doc_type_active'
  )
ORDER BY indexname;

-- =========================================================
-- 3. 入口模块菜单配置总览
-- =========================================================
SELECT
    em.id,
    em.name,
    em.path,
    em.menu_profile,
    em.features,
    em.is_enabled,
    COALESCE(
        STRING_AGG(emt.tenant_code, ', ' ORDER BY emt.tenant_code)
            FILTER (WHERE emt.is_enabled IS TRUE),
        ''
    ) AS enabled_tenants
FROM leaudit_entry_modules em
LEFT JOIN leaudit_entry_module_tenants emt
  ON emt.entry_module_id = em.id
WHERE em.deleted_at IS NULL
GROUP BY em.id, em.name, em.path, em.menu_profile, em.features, em.is_enabled
ORDER BY em.sort_order, em.id;

-- =========================================================
-- 4. 非法 menu_profile 检查：结果应为空
-- =========================================================
SELECT
    id,
    name,
    path,
    menu_profile
FROM leaudit_entry_modules
WHERE deleted_at IS NULL
  AND menu_profile NOT IN ('document_review', 'contract', 'govdoc', 'cross_checking', 'custom')
ORDER BY id;

-- =========================================================
-- 5. 空 features 检查：结果应为空或只包含刻意关闭菜单的入口
-- =========================================================
SELECT
    id,
    name,
    path,
    menu_profile,
    features
FROM leaudit_entry_modules
WHERE deleted_at IS NULL
  AND (
      features IS NULL
      OR jsonb_typeof(features) <> 'array'
      OR jsonb_array_length(features) = 0
  )
ORDER BY id;

-- =========================================================
-- 6. 非法 feature 编码检查：结果应为空
-- =========================================================
SELECT
    em.id,
    em.name,
    em.menu_profile,
    invalid_feature.feature
FROM leaudit_entry_modules em
CROSS JOIN LATERAL jsonb_array_elements_text(em.features) AS invalid_feature(feature)
WHERE em.deleted_at IS NULL
  AND invalid_feature.feature NOT IN (
      'home',
      'documents',
      'upload',
      'rules',
      'rule_groups',
      'contract_template_search',
      'contract_template_list',
      'govdoc_audits',
      'govdoc_upload',
      'cross_checking',
      'cross_checking_upload',
      'cross_checking_list',
      'usage_stats'
  )
ORDER BY em.id, invalid_feature.feature;

-- =========================================================
-- 7. 文档归属缺失检查
-- =========================================================
SELECT
    COUNT(*) AS documents_without_entry_module
FROM leaudit_documents
WHERE deleted_at IS NULL
  AND entry_module_id IS NULL;

SELECT
    d.id,
    d.normalized_name AS document_name,
    d.type_id,
    dt.name AS document_type_name,
    d.group_id,
    g.name AS group_name,
    d.tenant_code,
    d.created_at
FROM leaudit_documents d
LEFT JOIN leaudit_document_types dt
  ON dt.id = d.type_id
LEFT JOIN leaudit_evaluation_point_groups g
  ON g.id = d.group_id
WHERE d.deleted_at IS NULL
  AND d.entry_module_id IS NULL
ORDER BY d.created_at DESC NULLS LAST, d.id DESC
LIMIT 50;

-- =========================================================
-- 8. 文档 entry_module_id 与分组/文档类型推导不一致检查
-- =========================================================
SELECT
    d.id,
    d.normalized_name AS document_name,
    d.entry_module_id AS document_entry_module_id,
    COALESCE(g.entry_module_id, parent.entry_module_id, dt.entry_module_id) AS resolved_entry_module_id,
    d.type_id,
    d.group_id,
    d.tenant_code
FROM leaudit_documents d
LEFT JOIN leaudit_document_types dt
  ON dt.id = d.type_id
LEFT JOIN leaudit_evaluation_point_groups g
  ON g.id = d.group_id
LEFT JOIN leaudit_evaluation_point_groups parent
  ON parent.id = g.pid
WHERE d.deleted_at IS NULL
  AND d.entry_module_id IS NOT NULL
  AND COALESCE(g.entry_module_id, parent.entry_module_id, dt.entry_module_id) IS NOT NULL
  AND d.entry_module_id <> COALESCE(g.entry_module_id, parent.entry_module_id, dt.entry_module_id)
ORDER BY d.id DESC
LIMIT 100;

-- =========================================================
-- 9. 重复二级分组检查：结果应为空
-- =========================================================
SELECT
    pid,
    document_type_id,
    COUNT(*) AS duplicated_count,
    STRING_AGG(id::text || ':' || name, ' / ' ORDER BY id) AS groups
FROM leaudit_evaluation_point_groups
WHERE deleted_at IS NULL
  AND COALESCE(pid, 0) <> 0
  AND document_type_id IS NOT NULL
GROUP BY pid, document_type_id
HAVING COUNT(*) > 1
ORDER BY duplicated_count DESC, pid, document_type_id;

-- =========================================================
-- 10. 一级分组缺入口模块检查：兼容期允许存在，但新链路应逐步清零
-- =========================================================
SELECT
    id,
    code,
    name,
    document_type_id,
    sort_order,
    is_enabled
FROM leaudit_evaluation_point_groups
WHERE deleted_at IS NULL
  AND COALESCE(pid, 0) = 0
  AND entry_module_id IS NULL
ORDER BY sort_order, id;
