"""审计本体(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