1. 新增config/get_many批量配置查询接口与Redis实现 2. 新增路由绑定相关端口与事件校验 3. 优化插件目录展示,新增last_error与重启提示字段 4. 新增插件配置更新与重启状态跟踪逻辑 5. 优化会话搜索参数支持,新增account_id过滤 6. 替换部分ValueError为ValidationError统一错误类型 7. 新增多类DTO与参数校验逻辑 8. 优化SQLAlchemy事务处理与乐观锁实现 9. 新增能力画像矩阵过滤功能
146 lines
5.6 KiB
Python
146 lines
5.6 KiB
Python
"""身份合并回滚 DTO(C-13)。
|
||
|
||
定义身份合并回滚用例的命令与结果值对象,供 ``IdentityMergeService`` 与
|
||
``identity/rollback-merge`` 控制面操作使用。所有 DTO 均为
|
||
``dataclass(frozen=True)``,仅依赖标准库,用于坏合并的回滚编排。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
|
||
from yuxi.channels.contract.errors import ValidationError
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class MergeRollbackCmd:
|
||
"""合并回滚命令。
|
||
|
||
将已合并的 sibling 从 canonical 分离,恢复 sibling 独立身份。
|
||
操作不可逆(sibling 的 user_id 仅在 ``restore_user_id`` 非 None 时恢复),
|
||
调用方需确保 ``canonical_identity_id`` 与 ``merged_identity_id`` 确实
|
||
存在合并关系。
|
||
|
||
字段:
|
||
canonical_identity_id: 规范身份 ID(合并目标)。
|
||
merged_identity_id: 被回滚的 sibling identity_id(合并来源)。
|
||
restore_user_id: 恢复 sibling 的 user_id,``None`` 时不恢复
|
||
(sibling 保持未绑定系统用户状态)。默认为 ``None``。
|
||
"""
|
||
|
||
canonical_identity_id: str
|
||
merged_identity_id: str
|
||
restore_user_id: str | None = None
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验 canonical_identity_id 与 merged_identity_id 非空。
|
||
|
||
必填身份 ID 必须非空,在构造时即抛出 ``ValidationError``,避免空
|
||
ID 传播到 IdentityMergeService 后才暴露(INV-8)。
|
||
"""
|
||
if not self.canonical_identity_id:
|
||
raise ValidationError("canonical_identity_id", "must not be empty")
|
||
if not self.merged_identity_id:
|
||
raise ValidationError("merged_identity_id", "must not be empty")
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class MergeRecord:
|
||
"""合并回滚结果记录。
|
||
|
||
描述一次合并回滚操作的产出,供控制面 handler 序列化返回给调用方。
|
||
|
||
字段:
|
||
canonical_identity_id: 规范身份 ID。
|
||
merged_identity_id: 被回滚的 sibling identity_id。
|
||
removed_bindings: 从 canonical 移除的 bindings,结构为
|
||
``{channel_type: [peer_id, ...]}``(来自 sibling 的贡献)。
|
||
migrated_session_count: 迁移回 sibling 的会话数。
|
||
canonical_version: 回滚后 canonical 的内存版本号。
|
||
sibling_version: 回滚后 sibling 的内存版本号。
|
||
"""
|
||
|
||
canonical_identity_id: str
|
||
merged_identity_id: str
|
||
removed_bindings: dict[str, list[str]]
|
||
migrated_session_count: int
|
||
canonical_version: int
|
||
sibling_version: int
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验身份 ID 非空与计数/版本号非负。
|
||
|
||
``migrated_session_count`` / ``canonical_version`` /
|
||
``sibling_version`` 必须非负,在构造时即抛出 ``ValidationError``,
|
||
避免负值进入控制面响应(INV-8)。
|
||
"""
|
||
if not self.canonical_identity_id:
|
||
raise ValidationError("canonical_identity_id", "must not be empty")
|
||
if not self.merged_identity_id:
|
||
raise ValidationError("merged_identity_id", "must not be empty")
|
||
if self.migrated_session_count < 0:
|
||
raise ValidationError("migrated_session_count", "must not be negative")
|
||
if self.canonical_version < 0:
|
||
raise ValidationError("canonical_version", "must not be negative")
|
||
if self.sibling_version < 0:
|
||
raise ValidationError("sibling_version", "must not be negative")
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class MergeApproveCmd:
|
||
"""合并审批放行命令(H-21)。
|
||
|
||
放行一个待审批的低置信度合并:将 ``pending_review`` 的 sibling 合并进
|
||
canonical,清除 ``pending_review`` 标志。
|
||
|
||
字段:
|
||
canonical_identity_id: 规范身份 ID(合并目标)。
|
||
merged_identity_id: 待审批的 sibling identity_id(合并来源)。
|
||
"""
|
||
|
||
canonical_identity_id: str
|
||
merged_identity_id: str
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验 canonical_identity_id 与 merged_identity_id 非空。
|
||
|
||
必填身份 ID 必须非空,在构造时即抛出 ``ValidationError``,避免空
|
||
ID 传播到 IdentityMergeService 后才暴露(INV-8)。
|
||
"""
|
||
if not self.canonical_identity_id:
|
||
raise ValidationError("canonical_identity_id", "must not be empty")
|
||
if not self.merged_identity_id:
|
||
raise ValidationError("merged_identity_id", "must not be empty")
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class MergeApproveResult:
|
||
"""合并审批放行结果记录(H-21)。
|
||
|
||
字段:
|
||
canonical_identity_id: 规范身份 ID。
|
||
merged_identity_id: 被放行合并的 sibling identity_id。
|
||
canonical_version: 合并后 canonical 的内存版本号。
|
||
sibling_version: 清除 pending_review 后 sibling 的内存版本号。
|
||
"""
|
||
|
||
canonical_identity_id: str
|
||
merged_identity_id: str
|
||
canonical_version: int
|
||
sibling_version: int
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验身份 ID 非空与版本号非负。
|
||
|
||
``canonical_version`` / ``sibling_version`` 必须非负,在构造时即
|
||
抛出 ``ValidationError``,避免负值进入控制面响应(INV-8)。
|
||
"""
|
||
if not self.canonical_identity_id:
|
||
raise ValidationError("canonical_identity_id", "must not be empty")
|
||
if not self.merged_identity_id:
|
||
raise ValidationError("merged_identity_id", "must not be empty")
|
||
if self.canonical_version < 0:
|
||
raise ValidationError("canonical_version", "must not be negative")
|
||
if self.sibling_version < 0:
|
||
raise ValidationError("sibling_version", "must not be negative")
|