Files
cmautobuy/docs/task/73-采购任务安全恢复.md
T
2026-08-10 00:29:49 +08:00

78 lines
4.4 KiB
Markdown
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.
# 73 完善采购任务崩溃恢复与安全门禁验证
- 类型:需求
- 父级大工单:#1
- 所属 MVP / 版本:#2 Client 可运行任务闭环(MVP)
- 状态:已完成,待用户验收
- 日期:2026-08-10
- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/73
## 背景与目标
采购演练可以执行和领取后,还需要明确处理进程退出、设备断开、结果
提交失败和结果不确定。本任务用 SQLite 已提交事实作为唯一恢复依据,
并证明只要 `irreversible_action_at` 有值,程序就不会再次执行采购。
## 最终方案
- 每个采购关键动作前,先同时保存任务和执行记录的 `current_step`。
- 启动时发现无不可逆标记的中断采购演练,先关闭旧执行记录,再把任务
改回待执行;新演练必须创建更大的 `attempt_no` 和新 `attempt_id`。
- 有不可逆标记时,任务和运行改为 `manual_review / reconcile_purchase`。
- 新增独立 `PddPurchaseReconcileAdapter` 和 `PurchaseReconcileService`,只提供读取
订单候选能力,没有选规格、设数量、提交订单或付款方法。
- 唯一匹配、未找到、多候选和未知结果均保存到执行诊断,任务仍等待人工确认。
- 采购的设备断开等可重试技术错误也先转人工处理,不隐式重跑采购。
- Outbox 继续优先补交;结果已落库时不再访问 PDD。
- `ClaimCapabilities` 只接受 `dry_run`,`live` 在数据对象创建时就被拒绝。
- 界面为采购演练、结果待提交、只读核对和人工处理步骤提供中文说明。
## 改了哪些文件
- `client/src/task_repository.py`:采购中断恢复、最新执行记录、只读核对结果。
- `client/src/pdd_purchase_reconcile_adapter.py`:只读核对边界。
- `client/src/purchase_reconcile_service.py`:核对条件、读取、记录与人工处理。
- `client/src/task_dispatcher.py`、`client/src/pdd_ui_event.py`:恢复分支优先于普通采购。
- `client/src/purchase_task_service.py`:保留服务步骤和诊断,采购错误不自动重跑。
- `client/src/admin_gateway.py`:从数据边界禁止 `live`。
- `client/src/task_detail_view.py`:采购和恢复步骤的中文文案。
- `client/test/`:崩溃步骤、重启、不可逆恢复、设备断开、重复轮询和界面文案测试。
- `docs/client/`:同步架构、数据模型、界面和质量安全基线。
本任务没有修改数据库表结构,直接使用已有的 `current_step`、
`irreversible_action_at` 和 `diagnostics_json`。
## 验收结果
| 验收标准 | 结果 |
|---|---|
| 采购关键步骤在动作前持久化 | 通过 |
| 无不可逆标记时关闭旧运行后才恢复 | 通过 |
| 不可逆标记非空时 purchase 调用次数为 0 | 通过 |
| 已落库 Outbox 只补交,不重跑手机流程 | 通过 |
| 重复启动和重复轮询不会创建并发采购运行 | 通过 |
| 停止、设备断开、验证码、登录失效和未知结果安全停止 | 通过 |
| 采购继续禁止“重新执行” | 通过 |
| 采购与恢复步骤使用明确中文 | 通过 |
| `purchase_mode=live` 不能通过参数开启 | 通过 |
| 语法、全量测试和离屏界面冒烟 | 通过 |
## 测试
- 执行的命令:
- `C:/Python310/python.exe -m unittest discover -s test -p "test_purchase*.py" -v`
- `C:/Python310/python.exe -m unittest discover -s test -p "test_task_repository.py" -v`
- `C:/Python310/python.exe -m unittest discover -s test -p "test_task_detail_view.py" -v`
- `C:/Python310/python.exe -m unittest discover -s test`
- `C:/Python310/python.exe -m py_compile src/admin_gateway.py src/pdd_ui_event.py src/pdd_purchase_reconcile_adapter.py src/purchase_reconcile_service.py src/purchase_task_service.py src/task_detail_view.py src/task_dispatcher.py src/task_repository.py`
- 按 `client/AGENTS.md` 设置 `QT_QPA_PLATFORM=offscreen` 并创建 `MainWindow`
- 结果:采购专项 12 项通过;Repository 14 项通过;Client 全量 207 项通过;
语法检查通过;离屏冒烟输出 `OK`。Qt 同时输出环境缺少字体目录警告,不影响本次结果。
- **未验证到的部分**:未连接真实 Admin、Android 设备或 PDD 页面;没有执行
真实崩溃进程杀死,崩溃点由可注入 Adapter 抛错和 SQLite 历史状态构造验证。
本工单不代表真实下单安全门禁已放行。
## 相关提交
- `c86c748` 完善采购任务安全恢复