Files
InternalAuditInterprise/backend/app/datahub/ontology.py
T
2026-06-16 00:38:57 +08:00

87 lines
3.4 KiB
Python

"""审计本体(Ontology)定义。
定义电信内审域的核心实体类型与关系类型,作为知识图谱与主数据对齐的基准。
对应需求 R2。
"""
from __future__ import annotations
from enum import Enum
class EntityType(str, Enum):
"""审计本体核心实体类型。"""
CUSTOMER = "customer" # 客户(含政企)
CONTRACT = "contract" # 合同
MSISDN = "msisdn" # 号码
IMEI = "imei" # 终端设备
ACCOUNT = "account" # 账户(付款/收款)
WORK_ORDER = "work_order" # 工单
SUPPLIER = "supplier" # 供应商
SETTLEMENT = "settlement" # 结算单
EMPLOYEE = "employee" # 员工
CHANNEL = "channel" # 渠道/代理商
LEGAL_PERSON = "legal_person" # 法人/自然人
ADDRESS = "address" # 地址
class RelationshipType(str, Enum):
"""审计本体核心关系类型(有向)。"""
SIGNED = "signed" # 客户 —签约→ 合同
PAID_BY = "paid_by" # 合同 —回款账户→ 账户
OWNS_ACCOUNT = "owns_account" # 客户/供应商 —拥有→ 账户
REGISTERED_AT = "registered_at" # 客户/供应商 —注册地址→ 地址
LEGAL_REP_OF = "legal_rep_of" # 法人 —法定代表人→ 客户/供应商
RELATED_TO = "related_to" # 法人 —亲属/关联→ 法人
HOLDS_MSISDN = "holds_msisdn" # 客户 —持有→ 号码
BOUND_DEVICE = "bound_device" # 号码 —绑定→ IMEI
BELONGS_TO_CHANNEL = "belongs_to_channel" # 号码/合同 —归属→ 渠道
SUPPLIES = "supplies" # 供应商 —供货→ 合同/工单
HANDLED_BY = "handled_by" # 工单 —处理人→ 员工
SETTLES = "settles" # 结算单 —结算→ 合同
# 关系的合法 (源实体类型, 目标实体类型) 约束,用于校验图谱写入
RELATIONSHIP_DOMAIN: dict[RelationshipType, tuple[set[EntityType], set[EntityType]]] = {
RelationshipType.SIGNED: ({EntityType.CUSTOMER}, {EntityType.CONTRACT}),
RelationshipType.PAID_BY: ({EntityType.CONTRACT}, {EntityType.ACCOUNT}),
RelationshipType.OWNS_ACCOUNT: (
{EntityType.CUSTOMER, EntityType.SUPPLIER, EntityType.LEGAL_PERSON},
{EntityType.ACCOUNT},
),
RelationshipType.REGISTERED_AT: (
{EntityType.CUSTOMER, EntityType.SUPPLIER},
{EntityType.ADDRESS},
),
RelationshipType.LEGAL_REP_OF: (
{EntityType.LEGAL_PERSON},
{EntityType.CUSTOMER, EntityType.SUPPLIER},
),
RelationshipType.RELATED_TO: ({EntityType.LEGAL_PERSON}, {EntityType.LEGAL_PERSON}),
RelationshipType.HOLDS_MSISDN: ({EntityType.CUSTOMER}, {EntityType.MSISDN}),
RelationshipType.BOUND_DEVICE: ({EntityType.MSISDN}, {EntityType.IMEI}),
RelationshipType.BELONGS_TO_CHANNEL: (
{EntityType.MSISDN, EntityType.CONTRACT},
{EntityType.CHANNEL},
),
RelationshipType.SUPPLIES: (
{EntityType.SUPPLIER},
{EntityType.CONTRACT, EntityType.WORK_ORDER},
),
RelationshipType.HANDLED_BY: ({EntityType.WORK_ORDER}, {EntityType.EMPLOYEE}),
RelationshipType.SETTLES: ({EntityType.SETTLEMENT}, {EntityType.CONTRACT}),
}
def is_valid_relationship(
rel: RelationshipType, source: EntityType, target: EntityType
) -> bool:
"""校验一条关系的源/目标实体类型是否符合本体约束。"""
domain = RELATIONSHIP_DOMAIN.get(rel)
if domain is None:
return False
sources, targets = domain
return source in sources and target in targets