feat(compliance): add content compliance detection across tenant, ops, and clients
Implements the Revision 8/9 compliance design: tenant + ops backends, ops-web content-safety pages, admin-web editor/publish gate integration, desktop publish block surfacing, and supporting migrations / shared types / config plumbing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
WITH seeded_dictionaries AS (
|
||||
INSERT INTO ops.compliance_dictionaries (
|
||||
code,
|
||||
name,
|
||||
platform_scope,
|
||||
applicable_platforms,
|
||||
default_level,
|
||||
enabled,
|
||||
version,
|
||||
description
|
||||
)
|
||||
VALUES
|
||||
('ad_law_extreme', '广告法极限词', 'all', NULL, 'block', TRUE, 1, '广告法、宣传语场景常见极限表述'),
|
||||
('political_sensitive', '政治敏感词', 'all', NULL, 'block', TRUE, 1, '公开运营口径下的政治敏感表达'),
|
||||
('violence_pornography', '涉黄涉暴通用词', 'all', NULL, 'block', TRUE, 1, '涉黄、涉暴、血腥等通用违规词'),
|
||||
('generic_prohibited', '通用违禁词', 'all', NULL, 'high', TRUE, 1, '赌博、毒品、黑产等通用违禁表达')
|
||||
ON CONFLICT (code) DO NOTHING
|
||||
RETURNING id, code
|
||||
),
|
||||
all_dictionaries AS (
|
||||
SELECT id, code
|
||||
FROM seeded_dictionaries
|
||||
UNION
|
||||
SELECT id, code
|
||||
FROM ops.compliance_dictionaries
|
||||
WHERE code IN ('ad_law_extreme', 'political_sensitive', 'violence_pornography', 'generic_prohibited')
|
||||
),
|
||||
seed_terms(dictionary_code, pattern, level_override, hint, reference_law) AS (
|
||||
VALUES
|
||||
('ad_law_extreme', '国家级', 'block', '广告宣传中避免使用绝对化、最高级表述。', '广告法第九条'),
|
||||
('ad_law_extreme', '最高级', 'block', '广告宣传中避免使用绝对化、最高级表述。', '广告法第九条'),
|
||||
('ad_law_extreme', '最佳', 'block', '广告宣传中避免使用绝对化、最高级表述。', '广告法第九条'),
|
||||
('ad_law_extreme', '最强', 'block', '广告宣传中避免使用绝对化、最高级表述。', '广告法第九条'),
|
||||
('ad_law_extreme', '第一品牌', 'block', '广告宣传中避免使用无法证明的排名表述。', '广告法第九条'),
|
||||
('ad_law_extreme', '顶级', 'block', '广告宣传中避免使用绝对化、最高级表述。', '广告法第九条'),
|
||||
('ad_law_extreme', '全网最低', 'block', '价格比较类结论需要可证明依据。', '广告法第八条'),
|
||||
('ad_law_extreme', '永久有效', 'high', '承诺类表述需确保真实、完整、可履行。', '广告法第四条'),
|
||||
('political_sensitive', '反动', 'block', '涉及政治安全风险,发布前需修改或提交审阅。', NULL),
|
||||
('political_sensitive', '颠覆国家', 'block', '涉及政治安全风险,发布前需修改或提交审阅。', NULL),
|
||||
('political_sensitive', '分裂国家', 'block', '涉及政治安全风险,发布前需修改或提交审阅。', NULL),
|
||||
('political_sensitive', '恐怖主义', 'block', '涉及公共安全风险,发布前需修改或提交审阅。', NULL),
|
||||
('violence_pornography', '色情', 'block', '平台通常禁止涉黄内容或导流表达。', NULL),
|
||||
('violence_pornography', '约炮', 'block', '平台通常禁止涉黄内容或导流表达。', NULL),
|
||||
('violence_pornography', '血腥', 'block', '平台通常限制血腥暴力内容。', NULL),
|
||||
('violence_pornography', '虐杀', 'block', '平台通常限制血腥暴力内容。', NULL),
|
||||
('generic_prohibited', '赌博', 'high', '平台通常限制赌博相关内容。', NULL),
|
||||
('generic_prohibited', '博彩', 'high', '平台通常限制博彩相关内容。', NULL),
|
||||
('generic_prohibited', '毒品', 'high', '平台通常禁止毒品相关内容。', NULL),
|
||||
('generic_prohibited', '代开发票', 'high', '平台通常限制黑产交易相关内容。', NULL),
|
||||
('generic_prohibited', '刷单', 'high', '平台通常限制黑产交易相关内容。', NULL)
|
||||
)
|
||||
INSERT INTO ops.compliance_dictionary_terms (
|
||||
dictionary_id,
|
||||
match_type,
|
||||
pattern,
|
||||
level_override,
|
||||
hint,
|
||||
reference_law,
|
||||
enabled
|
||||
)
|
||||
SELECT d.id, 'exact', t.pattern, t.level_override, t.hint, t.reference_law, TRUE
|
||||
FROM seed_terms t
|
||||
JOIN all_dictionaries d ON d.code = t.dictionary_code
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM ops.compliance_dictionary_terms existing
|
||||
WHERE existing.dictionary_id = d.id
|
||||
AND existing.pattern = t.pattern
|
||||
);
|
||||
|
||||
INSERT INTO ops.compliance_dictionary_versions (
|
||||
dictionary_id,
|
||||
version,
|
||||
snapshot,
|
||||
published_by
|
||||
)
|
||||
SELECT
|
||||
cd.id,
|
||||
cd.version,
|
||||
jsonb_build_object(
|
||||
'code', cd.code,
|
||||
'name', cd.name,
|
||||
'platform_scope', cd.platform_scope,
|
||||
'applicable_platforms', COALESCE(to_jsonb(cd.applicable_platforms), '[]'::jsonb),
|
||||
'default_level', cd.default_level,
|
||||
'terms', COALESCE(
|
||||
(
|
||||
SELECT jsonb_agg(
|
||||
jsonb_build_object(
|
||||
'pattern', t.pattern,
|
||||
'match_type', t.match_type,
|
||||
'level_override', t.level_override,
|
||||
'hint', t.hint,
|
||||
'reference_law', t.reference_law,
|
||||
'enabled', t.enabled
|
||||
)
|
||||
ORDER BY t.id
|
||||
)
|
||||
FROM ops.compliance_dictionary_terms t
|
||||
WHERE t.dictionary_id = cd.id
|
||||
),
|
||||
'[]'::jsonb
|
||||
)
|
||||
),
|
||||
NULL
|
||||
FROM ops.compliance_dictionaries cd
|
||||
WHERE cd.code IN ('ad_law_extreme', 'political_sensitive', 'violence_pornography', 'generic_prohibited')
|
||||
ON CONFLICT (dictionary_id, version) DO NOTHING;
|
||||
|
||||
UPDATE ops.compliance_policies
|
||||
SET enabled_dictionaries = (
|
||||
SELECT COALESCE(jsonb_agg(id ORDER BY id), '[]'::jsonb)
|
||||
FROM ops.compliance_dictionaries
|
||||
WHERE code IN ('ad_law_extreme', 'political_sensitive', 'violence_pornography', 'generic_prohibited')
|
||||
),
|
||||
revision = revision + 1,
|
||||
updated_at = NOW()
|
||||
WHERE id = 1
|
||||
AND enabled_dictionaries = '[]'::jsonb;
|
||||
Reference in New Issue
Block a user