Initial commit: InternalAuditInterprise

This commit is contained in:
freedakgmail
2026-06-16 00:38:57 +08:00
commit 7b1e2b10a8
57 changed files with 4622 additions and 0 deletions
@@ -0,0 +1,76 @@
"""知识图谱穿透集成测试(需 PostgreSQL)。
验证 R2 关键能力:通过关系边的多跳穿透识别"疑似同一实控人"
以及本体约束对非法关系的拒绝。对应场景一(政企拆单+隐性实控人,R8)的图谱基础。
"""
from __future__ import annotations
import pytest
from app.datahub.graph_repo import (
OntologyViolationError,
add_relationship,
find_related_entities,
upsert_entity,
)
from app.datahub.ontology import EntityType, RelationshipType
def test_upsert_entity_is_idempotent(session):
e1 = upsert_entity(session, EntityType.CUSTOMER, "CUST-001", "客户甲")
e2 = upsert_entity(session, EntityType.CUSTOMER, "CUST-001", "客户甲")
assert e1.id == e2.id
def test_ontology_violation_rejected(session):
contract = upsert_entity(session, EntityType.CONTRACT, "C-1")
customer = upsert_entity(session, EntityType.CUSTOMER, "CUST-2")
# 合同 —签约→ 客户 方向非法
with pytest.raises(OntologyViolationError):
add_relationship(session, RelationshipType.SIGNED, contract, customer)
def test_detect_shared_controller_across_customers(session):
"""模拟"8 个客户疑似同一实控人":多个客户经法人关联到同一实控自然人。
构图:每个客户 <-法定代表人- 各自法人;各法人 -关联-> 同一实控人。
从实控人出发,应能穿透到全部客户。
"""
controller = upsert_entity(session, EntityType.LEGAL_PERSON, "PER-CTRL", "实控人")
customers = []
for i in range(8):
cust = upsert_entity(session, EntityType.CUSTOMER, f"CUST-{i}", f"政企客户{i}")
rep = upsert_entity(session, EntityType.LEGAL_PERSON, f"PER-{i}", f"法人{i}")
# 法人 —法定代表人→ 客户
add_relationship(session, RelationshipType.LEGAL_REP_OF, rep, cust)
# 法人 —关联(亲属/实控)→ 实控人
add_relationship(session, RelationshipType.RELATED_TO, rep, controller)
customers.append(cust)
session.flush()
related = find_related_entities(session, controller.id, max_depth=3)
related_ids = {rid for rid, _ in related}
# 从实控人 3 跳内应能穿透到全部 8 个客户
for cust in customers:
assert cust.id in related_ids, f"未穿透到 {cust.business_key}"
def test_traversal_respects_max_depth(session):
a = upsert_entity(session, EntityType.LEGAL_PERSON, "A")
b = upsert_entity(session, EntityType.LEGAL_PERSON, "B")
c = upsert_entity(session, EntityType.CUSTOMER, "C")
add_relationship(session, RelationshipType.RELATED_TO, a, b)
add_relationship(session, RelationshipType.LEGAL_REP_OF, b, c)
session.flush()
# depth=1:从 A 只能到 B,到不了 C
ids_d1 = {rid for rid, _ in find_related_entities(session, a.id, max_depth=1)}
assert b.id in ids_d1
assert c.id not in ids_d1
# depth=2:能到 C
ids_d2 = {rid for rid, _ in find_related_entities(session, a.id, max_depth=2)}
assert c.id in ids_d2