"""控制面管道上下文。 定义控制面管道的可变局部上下文 ``ControlPlaneContext``,携带请求从 auth 到 audit 各阶段产生的状态。上下文为 ``@dataclass``(不 frozen),阶段直接修改 字段以推进管道状态。 """ from __future__ import annotations from collections.abc import Awaitable, Callable from dataclasses import dataclass, field from typing import TYPE_CHECKING, Any from yuxi.channels.contract.dtos.audit.audit import AuditTxStrategy from yuxi.channels.contract.dtos.messaging.channel import ChannelType from yuxi.channels.contract.dtos.messaging.common import Operator from yuxi.channels.contract.dtos.shared.control import ControlPlaneResult from yuxi.channels.contract.errors import Error if TYPE_CHECKING: from yuxi.channels.contract.ports.driven.shared.transaction_port import TransactionContext @dataclass class ControlPlaneContext: """控制面管道可变局部上下文。 携带控制面请求从 auth 到 audit 各阶段产生的状态,阶段按顺序填充字段。 字段按阶段分组,便于追溯状态来源。 事务边界(§10.1):``tx`` 字段由 ``ChannelControlService`` 在管道 执行前通过 ``TransactionPort.begin()`` 开启,dispatch 与 audit 阶段 的写操作共享此事务上下文。``audit_tx_strategy`` 由 dispatch 阶段 根据操作副作用可回滚性设置:SHARED 策略下 audit 共享事务(fail-closed, FR-34),INDEPENDENT 策略下 audit 使用独立事务(best-effort,适用于 已产生不可回滚外部副作用的操作)。 """ # ---- 基础字段 ---- trace_id: str request_id: str operator: Operator operation: str params: dict[str, Any] target_channel: ChannelType | None = None # ---- 事务上下文(由 ChannelControlService 注入,dispatch/audit 共享)---- tx: TransactionContext | None = None # ---- auth 阶段字段 ---- authenticated: bool = False # ---- permission 阶段字段 ---- permission_granted: bool = False required_permission: str | None = None # ---- rate-limit 阶段字段 ---- rate_limit_passed: bool = False # ---- dispatch 阶段字段 ---- dispatch_result: ControlPlaneResult | None = None # dispatch 阶段幂等短路标记:当操作命中幂等条件(如 account/enable # 对已启用账户)时,handler 未执行任何状态变更即提前返回,设置为 True # 通知 audit 阶段跳过"状态变更类"审计写入,避免幂等请求被误记为 # 实际状态变更(§10.1 审计精确性)。 dispatch_skipped: bool = False # dispatch 阶段部分成功标记:批量操作(如 message/batch_recall)中 # 部分目标成功、部分失败时由 handler 设置为 True,供 # ``ChannelControlService._executeControl`` 构造 # ``ControlResult(status="partial")``,使响应 envelope 能准确反映 # 部分成功语义,避免外层 ``success: True`` 误导客户端。 dispatch_partial: bool = False # ---- audit 阶段字段 ---- audit_logged: bool = False # dispatch 阶段根据操作副作用可回滚性设置(§10.1 事务边界) audit_tx_strategy: AuditTxStrategy = AuditTxStrategy.SHARED # INDEPENDENT 策略下 audit 写入失败时的错误(best-effort,由 # ChannelControlService 记录告警,不中止业务) audit_error: Error | None = None # ---- 降级标志字段 ---- degraded: bool = False degraded_reason: Error | None = None # ---- 事务后副作用钩子(dispatch 阶段注册,由 ChannelControlService # 在事务提交成功后执行)。用于处理"DB 写入可回滚 + 外部副作用不可回滚" # 混合场景:将不可回滚的外部副作用(如 ARQ 任务入队)推迟到事务提交后 # 执行,避免事务回滚时产生孤儿副作用(§10.1 事务边界)。 post_commit_hooks: list[Callable[[], Awaitable[None]]] = field(default_factory=list)