28 KiB
28 KiB
代码重构提纲
目标:删繁就简,将状态机、日志、持久化部分写扎实,提升代码质量
当前状态:基本功能已打通,所有业务类型可以从零推送,但代码存在重复、错误、不严谨、赘余、与文档不符等问题
重构原则
- 严格遵循文档:以
docs/文件夹中的架构文档为准 - 类型安全优先:充分利用 Python 类型系统和 Pydantic
- 单一职责:每个模块、类、方法只做一件事
- 可测试性:重构后的代码应该更易测试
- 可观测性:完善的日志和错误处理
第一阶段:核心状态机强化(最高优先级)
1.1 状态转换规范化
问题诊断:
- 检查状态转换是否严格遵循
状态定义规范.md - 检查是否有非法的状态转换路径
- 检查状态转换是否都有日志记录
重构任务:
Task 1.1.1: 状态转换集中管理
# sync_system_new/common/state_machine.py (新建)
class StateMachine:
"""集中管理所有合法的状态转换"""
@staticmethod
def can_transition(
from_status: SyncStatus,
to_status: SyncStatus
) -> bool:
"""检查状态转换是否合法"""
pass
@staticmethod
def validate_binding_status_transition(
from_status: BindingStatus,
to_status: BindingStatus
) -> bool:
"""检查绑定状态转换是否合法"""
pass
操作步骤:
- 创建
state_machine.py,定义状态转换矩阵 - 在
SyncNode的状态设置方法中调用验证 - 添加状态转换日志(包含 from/to/reason)
- 更新所有修改状态的代码,使用统一的转换方法
验收标准:
- 所有状态转换都经过
StateMachine验证 - 非法转换会抛出明确的异常
- 每次转换都有日志记录
1.2 BindingStatus 判定逻辑强化
问题诊断:
- 检查
BaseSyncStrategy.bind()是否严格遵循核心状态判定表(状态定义规范 § 1) - 检查依赖解析逻辑是否符合规范(状态定义规范 § 2)
- 检查自动绑定逻辑是否符合 1:1 原则(状态定义规范 § 3)
重构任务:
Task 1.2.1: 核心状态判定表实现
# sync_system_new/sync_system/binding_matrix.py (新建)
class BindingMatrix:
"""实现核心状态判定表(状态定义规范 § 1)"""
@staticmethod
def determine_binding_status(
has_binding: bool,
local_data_valid: bool,
remote_data_valid: bool
) -> Tuple[Optional[BindingStatus], Optional[BindingStatus]]:
"""
返回 (local_status, remote_status)
实现状态定义规范 § 1 的判定表
"""
pass
Task 1.2.2: 依赖解析逻辑分离
# sync_system_new/sync_system/dependency_checker.py (已存在,需强化)
class DependencyChecker:
"""依赖检查与业务键解析(状态定义规范 § 2)"""
@staticmethod
def check_dependencies(
node: SyncNode,
local_collection: DataCollection,
remote_collection: DataCollection,
binding_manager: BindingManager
) -> Tuple[bool, Optional[str]]:
"""
返回 (can_proceed, error_message)
检查:
1. 依赖节点是否存在
2. 依赖节点的绑定状态是否为 NORMAL
3. 依赖节点的 data_id 是否非空
"""
pass
Task 1.2.3: 自动绑定逻辑重写
# sync_system_new/sync_system/auto_binder.py (新建)
class AutoBinder:
"""自动绑定逻辑(状态定义规范 § 3)"""
@staticmethod
def try_auto_bind(
local_nodes: List[SyncNode],
remote_nodes: List[SyncNode],
biz_key: tuple,
binding_manager: BindingManager
) -> AutoBindResult:
"""
实现去噪后 1:1 自动绑定
算法:
1. 全集搜索:寻找共享相同业务键的记录
2. 排除稳态对:移除成对且互绑的 NORMAL 记录
3. 判定剩余:L_remain=1 且 R_remain=1 才执行绑定
"""
pass
操作步骤:
- 创建
binding_matrix.py,实现核心判定表 - 强化
dependency_checker.py,严格按规范检查依赖 - 创建
auto_binder.py,将自动绑定逻辑从strategy.py中分离 - 重构
BaseSyncStrategy.bind()方法,调用上述三个模块 - 添加详细的日志和错误信息(特别是 DEPENDENCY_ERROR 的格式)
验收标准:
bind()方法逻辑清晰,不超过 50 行- 每个判定步骤都有日志记录
- DEPENDENCY_ERROR 的 error 字段格式符合文档规范
- 自动绑定只在 1:1 场景下触发
1.3 CREATE/UPDATE 逻辑规范化
问题诊断:
- 检查 CREATE 阶段的 ID 替换逻辑是否完整
- 检查 UPDATE 阶段是否正确跳过 FAILED 节点
- 检查是否正确处理空数据(业务键缺失)
重构任务:
Task 1.3.1: ID 替换逻辑统一
# sync_system_new/sync_system/id_replacer.py (新建)
class IDReplacer:
"""ID 替换逻辑(架构分层设计 § 6)"""
@staticmethod
def replace_ids_for_create(
data: Dict[str, Any],
id_fields: List[str],
binding_manager: BindingManager,
direction: str # "local_to_remote" or "remote_to_local"
) -> Dict[str, Any]:
"""
创建新节点时,将依赖字段的本地 ID 替换为远程 ID
示例:
data = {"project_id": "P1", "code": "C01"}
-> {"project_id": "RP_99", "code": "C01"}
"""
pass
@staticmethod
def replace_ids_for_update(
data: Dict[str, Any],
id_fields: List[str],
binding_manager: BindingManager,
direction: str
) -> Dict[str, Any]:
"""准备更新数据时,替换数据中的依赖 ID"""
pass
Task 1.3.2: UPDATE 阶段保护逻辑
# sync_system_new/sync_system/strategy.py
class BaseSyncStrategy:
def update(self):
"""UPDATE 操作必须跳过 FAILED 节点"""
# 过滤掉 status == FAILED 的节点
# 详见:持久化与人工介入规范 § 1.2 (UPDATE 阶段保护)
pass
操作步骤:
- 创建
id_replacer.py,集中管理 ID 替换逻辑 - 从
strategy.py中提取 ID 替换代码,迁移到IDReplacer - 在
update()方法开头添加 FAILED 节点过滤 - 添加空数据检查(业务键缺失标记为 WARNING)
验收标准:
- CREATE/UPDATE 使用统一的 ID 替换逻辑
- UPDATE 不会覆盖 FAILED 节点的状态
- 空数据不参与同步,状态为 WARNING
第二阶段:持久化与状态重置强化
2.1 持久化规则严格执行
问题诊断:
depend_ids 是否已移除持久化✅ 已修复- 检查阶段1重置是否正确实现
- 检查阶段2清理是否正确实现
重构任务:
Task 2.1.1: 阶段1重置逻辑审查
# sync_system_new/common/state_reset.py
def get_phase1_reset_defaults() -> Dict[str, Any]:
"""
阶段1:加载时重置(持久化与人工介入规范 § 1.2)
必须重置:
- data/origin_data → None(等待重新加载)
- depend_ids → []
- binding_status → UNCHECKED
- error → None
必须保留:
- node_id, data_id
- action(用于识别 CREATE 失败节点)
- status(只保留 FAILED,其他重置为 PENDING)
- context
"""
pass
Task 2.1.2: 阶段2清理逻辑审查
# sync_system_new/pipeline/full_sync_pipeline.py
async def _cleanup_create_failed_zombies(self):
"""
阶段2:数据加载后清理(持久化与人工介入规范 § 1.2)
清理步骤:
1. 检测:action == CREATE && status == FAILED
2. 删除本地失败节点
3. 解除绑定记录
4. 删除远程僵尸节点
5. 重置所有剩余节点的 action 为 NONE
"""
pass
操作步骤:
- 审查
state_reset.py,确保阶段1重置符合规范 - 审查
_cleanup_create_failed_zombies(),确保清理逻辑完整 - 添加详细的日志(清理了哪些节点,原因是什么)
- 编写单元测试,验证重置和清理逻辑
验收标准:
- 阶段1重置字段完全符合文档表格
- 阶段2清理逻辑不遗漏任何步骤
- 每次重置/清理都有明确的日志
2.2 绑定记录持久性保证
问题诊断:
- 检查绑定记录是否真的"永久保留"
- 检查是否有意外修改绑定记录的代码
重构任务:
Task 2.2.1: 绑定记录保护机制
# sync_system_new/common/binding.py
class BindingManager:
"""
绑定记录持久性规则(持久化与人工介入规范 § 1.3):
- 只能手工 bind/unbind
- 或 CREATE 失败自动清理
- 其他情况绝不修改
"""
def bind(self, local_node_id: str, remote_node_id: str, manual: bool = False):
"""
建立绑定记录
Args:
manual: 是否为手工绑定(用于审计日志)
"""
pass
def unbind(self, node_id: str, manual: bool = False):
"""解除绑定(只在手工或 CREATE 失败时调用)"""
pass
操作步骤:
- 审查所有调用
bind()/unbind()的地方 - 添加
manual参数,区分手工和自动操作 - 添加审计日志(谁在何时为何修改了绑定)
- 确保只有允许的场景才能修改绑定
验收标准:
- 绑定记录修改有完整的审计日志
- 自动绑定只在 1:1 场景触发
- CREATE 失败清理有明确的日志
第三阶段:日志与可观测性
3.1 结构化日志体系
问题诊断:
- 检查当前日志是否足够定位问题
- 检查日志格式是否统一
- 检查是否缺少关键操作的日志
重构任务:
Task 3.1.1: 统一日志格式
# sync_system_new/common/logger.py (新建)
import logging
from typing import Optional, Dict, Any
class SyncLogger:
"""统一的结构化日志工具"""
@staticmethod
def log_state_transition(
logger: logging.Logger,
node_type: str,
node_id: str,
from_status: str,
to_status: str,
reason: str,
extra: Optional[Dict[str, Any]] = None
):
"""状态转换日志"""
logger.info(
f"[{node_type}] State transition: {node_id} "
f"{from_status} -> {to_status} | Reason: {reason}",
extra=extra or {}
)
@staticmethod
def log_binding_operation(
logger: logging.Logger,
operation: str, # "bind", "unbind", "auto_bind"
local_node_id: str,
remote_node_id: Optional[str],
reason: str,
manual: bool = False
):
"""绑定操作日志"""
op_type = "MANUAL" if manual else "AUTO"
logger.info(
f"[{op_type}] Binding {operation}: "
f"local={local_node_id} <-> remote={remote_node_id} | {reason}"
)
@staticmethod
def log_sync_action(
logger: logging.Logger,
action: str, # "CREATE", "UPDATE", "DELETE"
node_type: str,
node_id: str,
data_id: str,
success: bool,
error: Optional[str] = None
):
"""同步操作日志"""
status = "SUCCESS" if success else "FAILED"
msg = f"[{node_type}] {action} {status}: node_id={node_id}, data_id={data_id}"
if error:
msg += f" | Error: {error}"
if success:
logger.info(msg)
else:
logger.error(msg)
@staticmethod
def log_dependency_error(
logger: logging.Logger,
node_type: str,
node_id: str,
dependency_errors: List[str]
):
"""依赖错误日志"""
logger.warning(
f"[{node_type}] DEPENDENCY_ERROR: {node_id} | "
f"Errors: {'; '.join(dependency_errors)}"
)
操作步骤:
- 创建
logger.py,定义结构化日志方法 - 在关键模块引入
SyncLogger - 替换所有
logger.info/warning/error为结构化方法 - 添加日志级别配置(DEBUG/INFO/WARNING/ERROR)
验收标准:
- 所有状态转换都有日志
- 所有绑定操作都有日志
- 所有同步操作(CREATE/UPDATE/DELETE)都有成功/失败日志
- 日志格式统一,易于搜索和过滤
3.2 关键路径日志补充
问题诊断:
- bind() 阶段是否记录了每个判定步骤
- create()/update() 是否记录了 ID 替换细节
- cleanup 阶段是否记录了清理的节点
重构任务:
Task 3.2.1: bind() 阶段日志强化
# sync_system_new/sync_system/strategy.py
class BaseSyncStrategy:
def bind(self):
# 1. 核心状态判定
logger.debug(f"[{self.node_type}] Checking binding records...")
# 2. 依赖检查
logger.debug(f"[{self.node_type}] Checking dependencies for {node_id}...")
# 3. 自动绑定尝试
logger.info(f"[{self.node_type}] Auto-bind attempt: L_remain={L}, R_remain={R}")
# 4. 状态转换
SyncLogger.log_state_transition(...)
Task 3.2.2: create()/update() 日志强化
class BaseSyncStrategy:
def create(self):
# 1. 孤儿节点识别
logger.info(f"[{self.node_type}] Found {len(orphans)} orphan nodes")
# 2. ID 替换
logger.debug(f"[{self.node_type}] Replacing IDs: {old_ids} -> {new_ids}")
# 3. action 设置
SyncLogger.log_state_transition(...)
操作步骤:
- 在
bind()的每个判定步骤添加日志 - 在
create()/update()的关键操作添加日志 - 在
_cleanup_create_failed_zombies()添加详细日志 - 设置合理的日志级别(DEBUG/INFO/WARNING)
验收标准:
- 开启 DEBUG 日志时,可以完整追踪每个节点的处理过程
- 生产环境只需 INFO 日志即可定位问题
- 关键错误都有 ERROR 级别日志
3.3 sync_log 字段利用
问题诊断:
- 检查
SyncNode.sync_log是否被使用 - 检查是否记录了完整的处理历史
重构任务:
Task 3.3.1: sync_log 结构定义
# sync_system_new/common/sync_node.py
class SyncNode:
"""
sync_log 格式:
[
{
"timestamp": "2025-01-15T10:30:00",
"phase": "bind",
"from_status": "UNCHECKED",
"to_status": "NORMAL",
"reason": "Found binding record",
"details": {}
},
{
"timestamp": "2025-01-15T10:30:05",
"phase": "update",
"action": "UPDATE",
"reason": "Data diff detected",
"details": {"changed_fields": ["name", "amount"]}
}
]
"""
def append_log(self, phase: str, action: str, reason: str, details: Optional[Dict] = None):
"""向 sync_log 添加记录"""
pass
操作步骤:
- 定义
sync_log的 JSON 结构 - 在每个阶段(bind/create/update/sync)添加日志记录
- 持久化
sync_log,用于审计和调试 - 提供查询接口,筛选特定类型的日志
验收标准:
- 每个节点的
sync_log记录了完整的处理历史 - 可以通过
sync_log回溯任何状态变化 - 失败节点的
sync_log包含详细的错误信息
第四阶段:代码质量与结构优化
4.1 代码重复消除
问题诊断:
- 搜索重复的业务键提取逻辑
- 搜索重复的 ID 解析逻辑
- 搜索重复的数据校验逻辑
重构任务:
Task 4.1.1: 业务键处理统一
# sync_system_new/sync_system/biz_key.py (新建)
class BizKeyExtractor:
"""业务键提取与处理"""
@staticmethod
def extract_from_data(
data: Dict[str, Any],
fields: List[str]
) -> Optional[Dict[str, Any]]:
"""从数据中提取业务键"""
pass
@staticmethod
def to_tuple(biz_key: Dict[str, Any]) -> tuple:
"""转换为可哈希的 tuple"""
pass
@staticmethod
def is_complete(biz_key: Dict[str, Any]) -> bool:
"""检查业务键是否完整(无空值)"""
pass
操作步骤:
- 创建
biz_key.py,集中业务键处理逻辑 - 从各个 Strategy 中提取重复代码
- 统一业务键的提取、验证、比较逻辑
- 添加单元测试
验收标准:
- 业务键处理逻辑在一个文件中
- 各 Strategy 调用统一的工具方法
- 代码行数减少 20% 以上
4.2 错误处理统一
问题诊断:
- 检查是否有裸露的 try-except
- 检查异常类型是否明确
- 检查错误信息是否包含足够的上下文
重构任务:
Task 4.2.1: 自定义异常体系
# sync_system_new/common/exceptions.py (新建)
class SyncSystemException(Exception):
"""同步系统基础异常"""
pass
class StateTransitionError(SyncSystemException):
"""非法状态转换"""
def __init__(self, from_status, to_status, reason):
self.from_status = from_status
self.to_status = to_status
super().__init__(
f"Illegal state transition: {from_status} -> {to_status} | {reason}"
)
class DependencyError(SyncSystemException):
"""依赖错误"""
def __init__(self, node_id, dependency_errors):
self.node_id = node_id
self.dependency_errors = dependency_errors
super().__init__(
f"Dependency error for {node_id}: {'; '.join(dependency_errors)}"
)
class DataValidationError(SyncSystemException):
"""数据校验错误"""
pass
class BindingConflictError(SyncSystemException):
"""绑定冲突(如 N:N)"""
pass
操作步骤:
- 创建
exceptions.py,定义异常类型 - 替换通用异常为自定义异常
- 在异常中包含足够的上下文信息
- 在顶层捕获并记录异常
验收标准:
- 所有业务异常都是
SyncSystemException的子类 - 异常信息包含 node_id、node_type 等上下文
- 顶层有统一的异常处理和日志记录
4.3 类型注解完善
问题诊断:
- 检查是否所有方法都有类型注解
- 检查返回值是否都有明确类型
- 运行 mypy 检查类型错误
重构任务:
Task 4.3.1: 类型注解审查
# 运行 mypy 检查
mypy sync_system_new/ --strict
操作步骤:
- 为所有公共方法添加类型注解
- 为复杂的返回值定义 TypedDict 或 Pydantic 模型
- 修复 mypy 报告的类型错误
- 添加 mypy 到 CI/CD 流程
验收标准:
- mypy 检查通过(允许少量 type: ignore)
- 所有公共 API 都有完整的类型注解
- IDE 可以提供准确的类型提示
4.4 文档字符串完善
问题诊断:
- 检查关键类/方法是否有 docstring
- 检查 docstring 是否符合 Google/Numpy 风格
重构任务:
Task 4.4.1: Docstring 补充
class BaseSyncStrategy:
"""
同步策略基类。
职责:
1. bind(): 判定 binding_status
2. create(): 处理孤儿节点
3. update(): 处理差异节点
4. pre_sync_check() / post_sync_check(): 状态验证
子类使用示例:
```python
class ProjectStrategy(DefaultSyncStrategy):
default_config = StrategyConfig(
auto_bind_fields=["code"],
local_orphan_action=OrphanAction.CREATE_REMOTE
)
schema = ProjectResponse
```
参考文档:
- 架构分层设计.md § 3
- 状态定义规范.md § 1-4
"""
def bind(self):
"""
判定绑定状态。
执行步骤:
1. 核心状态判定(状态定义规范 § 1)
2. 依赖检查(状态定义规范 § 2)
3. 自动绑定尝试(状态定义规范 § 3)
状态转换:
- UNCHECKED -> NORMAL/MISSING/ABNORMAL/WARNING/DEPENDENCY_ERROR
Raises:
DependencyError: 依赖节点未就绪
BindingConflictError: 出现 N:N 绑定冲突
"""
pass
操作步骤:
- 为所有公共类添加类级别 docstring
- 为所有公共方法添加方法级别 docstring
- 在 docstring 中引用相关文档章节
- 添加使用示例和注意事项
验收标准:
- 核心类(SyncNode, BaseSyncStrategy, FullSyncPipeline 等)都有完整的 docstring
- 关键方法都有参数说明、返回值说明、异常说明
- 文档引用链接正确
第五阶段:测试覆盖与 pytest 修复
5.1 单元测试强化
问题诊断:
- 运行 pytest,检查失败的测试
- 检查测试覆盖率(目标 >80%)
重构任务:
Task 5.1.1: 修复现有测试
# 运行测试并查看失败原因
pytest sync_system_new/tests/ -v --tb=short
# 检查覆盖率
pytest sync_system_new/tests/ --cov=sync_system_new --cov-report=html
操作步骤:
- 运行 pytest,逐个修复失败的测试
- 更新测试用例,匹配重构后的代码
- 添加缺失的测试(特别是状态转换、绑定逻辑)
- 确保测试覆盖所有关键路径
验收标准:
- 所有测试通过
- 核心模块测试覆盖率 >80%
- 关键逻辑(状态判定、依赖检查、自动绑定)有完整的单元测试
5.2 集成测试补充
问题诊断:
- 检查是否有端到端的集成测试
- 检查集成测试是否覆盖主要场景
重构任务:
Task 5.2.1: 端到端测试场景
# tests/integration/test_full_workflow.py
async def test_full_sync_workflow():
"""
完整同步流程测试:
1. 加载 JSONL 数据
2. 执行策略(bind/create/update)
3. 推送到 API
4. 验证结果
"""
pass
async def test_create_failed_recovery():
"""
CREATE 失败恢复测试:
1. 模拟 CREATE 失败
2. 下次同步自动清理僵尸节点
3. 重新尝试 CREATE
"""
pass
async def test_dependency_blocking():
"""
依赖阻断测试:
1. 父节点 CREATE 失败
2. 子节点标记为 DEPENDENCY_ERROR
3. 修复父节点后,子节点自动恢复
"""
pass
操作步骤:
- 创建
tests/integration/目录 - 编写端到端集成测试
- 使用真实的 JSONL 数据和 Mock API
- 验证关键场景(自动绑定、CREATE 失败恢复、依赖阻断)
验收标准:
- 有至少 5 个集成测试场景
- 集成测试覆盖主要业务流程
- 集成测试可以在 CI/CD 中自动运行
第六阶段:文档与代码对齐
6.1 文档与代码对齐检查
问题诊断:
- 逐个对照文档,检查代码实现是否一致
- 检查文档中的示例代码是否可运行
重构任务:
Task 6.1.1: 对齐检查清单
| 文档章节 | 代码位置 | 对齐状态 | 备注 |
|---|---|---|---|
| 架构分层设计 § 2 | common/sync_node.py | ✅ | SyncNode 定义 |
| 架构分层设计 § 3 | sync_system/strategy.py | ⚠️ | 需补充 ID 替换逻辑 |
| 状态定义规范 § 1 | sync_system/binding_matrix.py | ❌ | 需新建 |
| 状态定义规范 § 2 | sync_system/dependency_checker.py | ⚠️ | 需强化 |
| 状态定义规范 § 3 | sync_system/auto_binder.py | ❌ | 需新建 |
| 编排流程规范 | pipeline/full_sync_pipeline.py | ✅ | 流程正确 |
| 持久化与人工介入规范 § 1.2 | common/state_reset.py | ✅ | 阶段1/2 重置 |
操作步骤:
- 创建对齐检查表
- 逐个章节对照代码
- 标记不一致的地方
- 更新代码或文档,确保一致
验收标准:
- 所有文档章节都有对应的代码实现
- 代码实现严格遵循文档规范
- 文档示例代码可以直接运行
6.2 文档更新
问题诊断:
- 检查重构后的代码是否需要更新文档
- 检查是否有新增的设计决策需要文档化
重构任务:
Task 6.2.1: 文档更新清单
- 更新
架构分层设计.md,补充新模块说明 - 更新
状态定义规范.md,补充状态转换图 - 创建
日志规范.md,说明日志格式和级别 - 创建
异常处理规范.md,说明异常类型和处理 - 更新
README.md,补充使用示例
操作步骤:
- 根据重构内容,识别需要更新的文档
- 更新或创建文档
- 添加架构图和流程图(使用 Mermaid)
- 添加代码示例和最佳实践
验收标准:
- 文档完整覆盖重构后的架构
- 文档包含清晰的架构图和流程图
- 文档包含可运行的示例代码
执行计划与优先级
优先级定义
- P0 (关键):影响正确性,必须立即修复
- P1 (高):影响可维护性,应尽快完成
- P2 (中):改善代码质量,可以分批完成
- P3 (低):锦上添花,时间允许时完成
阶段划分
| 阶段 | 优先级 | 预计工时 | 依赖关系 |
|---|---|---|---|
| 第一阶段:核心状态机强化 | P0 | 3-4 天 | 无 |
| 第二阶段:持久化与状态重置 | P0 | 1-2 天 | 第一阶段 |
| 第三阶段:日志与可观测性 | P1 | 2-3 天 | 第一、二阶段 |
| 第四阶段:代码质量优化 | P2 | 2-3 天 | 第一阶段 |
| 第五阶段:测试覆盖 | P1 | 2-3 天 | 第一、二阶段 |
| 第六阶段:文档对齐 | P2 | 1-2 天 | 所有阶段 |
建议执行顺序(3天计划)
Day 1:
- 完成第一阶段(状态机强化)- P0
- 完成第二阶段(持久化审查)- P0
Day 2: 3. 完成第三阶段(日志强化)- P1 4. 完成第五阶段(pytest 修复)- P1
Day 3: 5. 完成第四阶段(代码优化)- P2 6. 完成第六阶段(文档对齐)- P2 7. 全面回归测试
验收标准
代码质量指标
- pytest 通过率: 100%
- 测试覆盖率: 核心模块 >80%
- mypy 类型检查: 通过(允许 <10 个 type: ignore)
- 代码重复率: <5% (使用 pylint 检查)
- 文档覆盖率: 所有公共 API 都有 docstring
功能完整性
- 所有业务类型可以从零推送
- CREATE 失败自动恢复
- 依赖阻断正确工作
- 自动绑定只在 1:1 场景触发
- 手工绑定永不自动修改
可观测性
- 每个节点都有完整的 sync_log
- 关键操作都有结构化日志
- 错误信息包含足够的上下文
- 可以通过日志快速定位问题
文档一致性
- 代码实现与文档规范一致
- 文档示例代码可运行
- 架构图和流程图准确
附录:重构检查清单
状态机检查
- 状态转换是否经过
StateMachine验证 - 每次转换是否都有日志
- 是否有非法的状态路径
绑定逻辑检查
- 核心判定表是否实现(状态定义规范 § 1)
- 依赖检查是否完整(状态定义规范 § 2)
- 自动绑定是否只在 1:1 场景触发(状态定义规范 § 3)
- DEPENDENCY_ERROR 格式是否符合规范
持久化检查
- depend_ids 是否不持久化 ✅
- 阶段1重置是否正确
- 阶段2清理是否完整
- 绑定记录是否永久保留
日志检查
- 是否使用结构化日志
- 关键操作是否都有日志
- 日志级别是否合理
- sync_log 是否记录完整历史
错误处理检查
- 是否使用自定义异常
- 异常信息是否包含上下文
- 是否有顶层异常处理
- 错误是否正确传播
代码质量检查
- 是否有重复代码
- 是否有明确的类型注解
- 是否有完整的 docstring
- 是否通过 mypy 检查
总结
本重构提纲基于以下文档制定:
- 架构分层设计.md - 四层架构模型
- 状态定义规范.md - 状态机逻辑
- 编排流程规范.md - Pipeline 流程
- 持久化与人工介入规范.md - 持久化和重置规则
- 业务流程与依赖关系.md - 业务实体依赖
核心目标:
- 删繁就简:消除重复,提取公共逻辑
- 状态机强化:严格遵循状态定义规范
- 日志完善:结构化日志,完整的 sync_log
- 持久化规范:阶段1/2 重置,绑定记录保护
- 代码质量:类型安全,错误处理,文档完善
关键原则:
- 以文档为准,代码严格遵循规范
- 类型安全优先,充分利用 Python 类型系统
- 可观测性优先,完善的日志和错误信息
- 单一职责,每个模块只做一件事
- 可测试性,易于编写和维护测试
按照此提纲逐步执行,可以系统性地提升代码质量,同时保持与文档的一致性。