ForcePilot/backend/package/yuxi/channels/contract/dtos/identity.py

134 lines
4.1 KiB
Python
Raw Normal View History

"""身份 DTO。
定义身份解析相关的不可变值对象包括统一身份 ID身份置信度枚举
身份解析结果身份提供者配置与身份解析命令所有 DTO 均为
``dataclass(frozen=True)``仅依赖标准库与契约层内部类型用于
身份解析统一身份关联与置信度评估FR-05
"""
from __future__ import annotations
from dataclasses import dataclass
from enum import StrEnum
from typing import Any
from yuxi.channels.contract.dtos.channel import ChannelType
from yuxi.channels.contract.errors import ValidationError
@dataclass(frozen=True)
class UnifiedIdentityId:
"""统一身份 ID。
标识用户统一身份的唯一 ID用于跨渠道身份关联与路由匹配
字段
value: 统一身份 ID 字符串
"""
value: str
class IdentityConfidence(StrEnum):
"""身份置信度。
标识身份解析结果的置信度等级用于路由决策与审计继承
``str, Enum`` 以支持 JSON 序列化与字符串比较
取值
HIGH: 高置信度
MEDIUM: 中置信度
LOW: 低置信度
"""
HIGH = "high"
MEDIUM = "medium"
LOW = "low"
@property
def _rank(self) -> int:
"""返回置信度序值用于比较高低low=0 < medium=1 < high=2"""
return self._ORDER[self.value]
# StrEnum 会将类体内的 dict 视为成员值(要求 str故 _ORDER 在类体外赋值。
IdentityConfidence._ORDER = {"low": 0, "medium": 1, "high": 2}
@dataclass(frozen=True)
class IdentityResolveResult:
"""身份解析结果FR-05
描述身份解析的产出包括统一身份 ID身份类型置信度与可选的
关联用户 ID 及元数据用于 FR-05 身份解析与统一身份关联
字段
unified_identity_id: 统一身份 ID
identity_type: 身份类型邮箱 / 手机 / 组织员工 ID
confidence: 置信度数值型0.0-1.0
metadata: 渠道侧元数据可选
resolved_user_id: 关联用户 ID可选
channel_type: 渠道类型可选channel_guest 身份用于持久化定位
channel_sender_id: 渠道侧发送者 ID可选channel_guest 身份用于
持久化定位
"""
unified_identity_id: UnifiedIdentityId
identity_type: str
confidence: float
metadata: dict[str, Any] | None = None
resolved_user_id: str | None = None
channel_type: ChannelType | None = None
channel_sender_id: str | None = None
@dataclass(frozen=True)
class IdentityProviderConfig:
"""身份提供者配置。
描述身份解析器的配置包括名称启用状态优先级与配置字典用于
FR-05 身份解析器注册与执行顺序控制
字段
name: 解析器名称
enabled: 是否启用默认 True
priority: 优先级默认 100
config: 配置字典可选
"""
name: str
enabled: bool = True
priority: int = 100
config: dict[str, Any] | None = None
@dataclass(frozen=True)
class IdentityResolveCmd:
"""身份解析命令FR-05
由身份解析端口方法引用描述一次身份解析请求携带渠道类型对端
ID账户 ID 与可选元数据用于驱动身份解析流程
字段
channel_type: 渠道类型
peer_id: 对端 ID
account_id: 渠道账户 ID
metadata: 入站消息元数据可选供手机号解析器等读取
"""
channel_type: ChannelType
peer_id: str
account_id: str
metadata: dict[str, Any] | None = None
def __post_init__(self) -> None:
"""校验必填字段非空FR-05
``peer_id`` ``account_id`` 必须非空在构造时即抛出
``ValidationError``adapter 不再做该校验INV-8
"""
if not self.peer_id:
raise ValidationError("peer_id", "must not be empty")
if not self.account_id:
raise ValidationError("account_id", "must not be empty")