ForcePilot/backend/package/yuxi/channels/contract/dtos/ack.py
Kris 00092c818e chore: 批量代码优化与规范完善
本次提交包含多项代码优化与规范修正:
1. 文档与注释优化:修正注释术语、补充注解与FR编号
2. 代码格式调整:统一空格、换行与缩进规范
3. 类型与接口完善:补充__all__导出、修正返回类型注解
4. 错误处理增强:新增领域错误类与校验逻辑
5. 依赖与导入调整:修复路径引用、统一时区导入
6. 协议与契约更新:完善接口文档与一致性注解
2026-07-03 19:18:13 +08:00

82 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""分阶段 ACK DTO。
定义分阶段 ACKFR-24的枚举与不可变值对象包括 ACK 策略、ACK 阶段
与 ACK 决策。所有枚举继承 ``str, Enum`` 以支持 JSON 序列化DTO 均为
``dataclass(frozen=True)``,仅依赖标准库,用于入站消息的分阶段 ACK
决策与幂等控制。
"""
from __future__ import annotations
from dataclasses import dataclass
from enum import StrEnum
from typing import Literal
from yuxi.channels.contract.errors import ValidationError
class AckPolicy(StrEnum):
"""ACK 策略。
标识入站消息的 ACK 时机,用于控制 ACK 与消息处理流程的耦合关系。
继承 ``str, Enum`` 以支持 JSON 序列化与字符串比较。
取值:
AFTER_RECORD: 消息记录后 ACK。
AFTER_AGENT_DISPATCH: Agent 分发后 ACK。
AFTER_PERSIST: 持久化投递后 ACK。
MANUAL: 手动 ACK。
"""
AFTER_RECORD = "after_record"
AFTER_AGENT_DISPATCH = "after_agent_dispatch"
AFTER_PERSIST = "after_persist"
MANUAL = "manual"
class AckStage(StrEnum):
"""ACK 阶段。
标识 ACK 决策所属的处理阶段,用于分阶段 ACK 的状态机推进。继承
``str, Enum`` 以支持 JSON 序列化与字符串比较。
取值:
RECORD: 记录阶段。
DISPATCH: 分发阶段。
PERSIST: 持久化阶段。
MANUAL: 手动阶段。
"""
RECORD = "record"
DISPATCH = "dispatch"
PERSIST = "persist"
MANUAL = "manual"
@dataclass(frozen=True)
class AckDecision:
"""ACK 决策FR-24
描述一次 ACK 决策的结果,包括决策动作、所属阶段与幂等键,用于
分阶段 ACK 的决策传递与幂等控制。
字段:
decision: 决策动作ack | nack | retry | pending
stage: ACK 阶段。
idempotency_key: 幂等键(可选)。
"""
decision: Literal["ack", "nack", "retry", "pending"]
stage: AckStage
idempotency_key: str | None = None
def __post_init__(self) -> None:
"""校验 decision 取值合法。
``decision`` 必须为 ``ack`` / ``nack`` / ``retry`` / ``pending`` 之一,在构造时
即抛出 ``ValidationError``,避免非法决策动作导致 ACK 状态机推进
异常INV-8
"""
if self.decision not in ("ack", "nack", "retry", "pending"):
raise ValidationError("decision", "must be one of ack, nack, retry, pending")