2026-07-02 03:22:12 +08:00
|
|
|
|
"""配置校验 DTO。
|
|
|
|
|
|
|
|
|
|
|
|
定义渠道插件配置校验的不可变值对象,包括配置校验错误项、警告项与校验
|
|
|
|
|
|
结果。所有 DTO 均为 ``dataclass(frozen=True)``,仅依赖标准库,用于
|
|
|
|
|
|
``WizardAdapter.runWizardStep``(安装时)与 ``DoctorAdapter.runItem``
|
|
|
|
|
|
(运行时)的配置校验流程(PRD §4.0.4 核心方法 2:配置校验)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
from yuxi.channels.contract.errors import ValidationError
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class ConfigError:
|
|
|
|
|
|
"""配置校验错误项。
|
|
|
|
|
|
|
|
|
|
|
|
描述单项配置校验错误,包括字段路径、错误消息与错误码,用于配置校验
|
|
|
|
|
|
结果的错误详情。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
field_path: 字段路径(如 "credentials.app_id")。
|
|
|
|
|
|
message: 错误消息。
|
|
|
|
|
|
error_code: 错误码(如 "missing_field" / "invalid_format")。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
field_path: str
|
|
|
|
|
|
message: str
|
|
|
|
|
|
error_code: str
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
def __post_init__(self) -> None:
|
|
|
|
|
|
"""校验 field_path / message / error_code 非空。
|
|
|
|
|
|
|
|
|
|
|
|
必填字符串字段必须非空,在构造时即抛出 ``ValidationError``,避免
|
|
|
|
|
|
空字段路径或空错误码导致校验错误项无法定位与分类(INV-8)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.field_path:
|
|
|
|
|
|
raise ValidationError("field_path", "must not be empty")
|
|
|
|
|
|
if not self.message:
|
|
|
|
|
|
raise ValidationError("message", "must not be empty")
|
|
|
|
|
|
if not self.error_code:
|
|
|
|
|
|
raise ValidationError("error_code", "must not be empty")
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class ConfigWarning:
|
|
|
|
|
|
"""配置校验警告项。
|
|
|
|
|
|
|
|
|
|
|
|
描述单项配置校验警告,包括字段路径与警告消息,用于配置校验结果的
|
|
|
|
|
|
警告详情。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
field_path: 字段路径。
|
|
|
|
|
|
message: 警告消息。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
field_path: str
|
|
|
|
|
|
message: str
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
def __post_init__(self) -> None:
|
|
|
|
|
|
"""校验 field_path 与 message 非空。
|
|
|
|
|
|
|
|
|
|
|
|
``field_path`` 与 ``message`` 必须非空,在构造时即抛出
|
|
|
|
|
|
``ValidationError``,避免空字段路径或空消息导致警告项无法定位与
|
|
|
|
|
|
展示(INV-8)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.field_path:
|
|
|
|
|
|
raise ValidationError("field_path", "must not be empty")
|
|
|
|
|
|
if not self.message:
|
|
|
|
|
|
raise ValidationError("message", "must not be empty")
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class ConfigValidateResult:
|
|
|
|
|
|
"""配置校验结果。
|
|
|
|
|
|
|
|
|
|
|
|
描述配置校验的最终结果,包括是否有效、错误列表与警告列表,作为
|
|
|
|
|
|
``WizardAdapter.runWizardStep`` / ``DoctorAdapter.runItem``
|
|
|
|
|
|
配置校验流程的返回值(PRD §4.0.4 核心方法 2:配置校验)。
|
|
|
|
|
|
集合字段使用 tuple 以保证 frozen dataclass 的不可变语义。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
valid: 是否校验通过。
|
|
|
|
|
|
errors: 错误列表(默认空 tuple)。
|
|
|
|
|
|
warnings: 警告列表(默认空 tuple)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
valid: bool
|
|
|
|
|
|
errors: tuple[ConfigError, ...] = ()
|
|
|
|
|
|
warnings: tuple[ConfigWarning, ...] = ()
|