210 lines
6.3 KiB
SQL
210 lines
6.3 KiB
SQL
-- 入口模块菜单模板、多租户可见性、文档归属巡检脚本
|
|
-- 用途:
|
|
-- 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;
|