From 9f6705a24cef751cec37d33373fc2f3e5822e5f6 Mon Sep 17 00:00:00 2001 From: chengma Date: Tue, 18 Aug 2026 09:56:06 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=BD=92=E6=A1=A3=E4=BB=BB=E5=8A=A1=20?= =?UTF-8?q?#262?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../262-安全分流失败采购任务并继续只读核单.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 docs/task/262-安全分流失败采购任务并继续只读核单.md diff --git a/docs/task/262-安全分流失败采购任务并继续只读核单.md b/docs/task/262-安全分流失败采购任务并继续只读核单.md new file mode 100644 index 0000000..2a06c43 --- /dev/null +++ b/docs/task/262-安全分流失败采购任务并继续只读核单.md @@ -0,0 +1,65 @@ +# 262 安全分流失败采购任务并继续只读核单 + +- 类型:需求 +- 父级大工单:#96 +- 所属 MVP / 版本:#97 真实采购首单闭环(不支付) +- 状态:已完成 +- 日期:2026-08-18 +- Gitea 工单: + +## 背景与目标 + +采购任务提交订单前失败时可以安全重新采购;订单已经提交并写入不可逆标记后,如果只读核单失败进入 `reconcile_manual_review`,原“重新采购”入口只显示安全阻止,无法再次读取已经存在的待付款订单。 + +本任务保留同一个操作入口并增加安全分流:提交前失败仍重新采购;提交后失败只恢复原运行继续核单,绝不重新下单。 + +## 最终方案 + +- 批量预检分别返回可重新采购、只继续核单、类型过滤和安全阻止任务。 +- 只有任务和最新运行都处于 `reconcile_manual_review`、最新运行存在不可逆标记且没有未发送 Outbox 时,才允许继续核单。 +- Repository 在一个事务中把原任务和原运行恢复为 `reconcile_purchase`;不创建新运行,不修改原 `attempt_id`、确认快照或不可逆时间。 +- 工作线程把只读核单任务排在真正重新采购之前,直接调用 `PurchaseReconcileService`;核单结果不确定、状态变化或上报失败时停止剩余采购任务。 +- 核单成功后复用已保存 Outbox 的提交方法,并注入一个禁止创建采购 Adapter 的工厂,保证该分支没有重新下单路径。 +- 确认框分别显示“可重新采购”和“只继续核单”数量;只有只读任务时,确认按钮显示“继续核单”。 + +最终实现与建单方案一致,没有修改数据库结构、Admin 接口或现有不可逆数据。 + +## 改了哪些 + +- `client/src/task_models.py`:批量预检和执行命令增加只读核单分类。 +- `client/src/task_repository.py`:增加继续核单预检及原子恢复事务。 +- `client/src/pdd_ui_event.py`:同一入口安全分流、只读优先执行、明确确认文案和失败停队。 +- `client/test/test_task_repository.py`:覆盖分类、原运行复用及提交前失败仍可重购。 +- `client/test/test_pdd_ui_event.py`:覆盖混合任务确认文案和只读任务优先顺序。 +- `client/test/test_purchase_recovery.py`:覆盖继续核单成功、禁止采购 Adapter 和核单失败停止后续采购。 +- `docs/client/05-ui-specification.md`、`docs/client/06-quality-security.md`:同步稳定交互与安全规则。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 提交订单前失败且无不可逆标记的任务仍可重新采购 | 通过 | +| `reconcile_manual_review` 的最新不可逆运行可从同一入口继续核单 | 通过 | +| 继续核单保留原运行编号、不可逆时间和确认数据,不创建新运行 | 通过 | +| 继续核单不创建采购 Adapter,不重新提交订单或付款 | 通过 | +| 确认框分别显示重新采购和只继续核单数量 | 通过 | +| 只读核单优先,核单失败时停止后续重新采购 | 通过 | +| 其他不可逆状态、未发送 Outbox 和类型不符任务保持安全阻止或过滤 | 通过 | + +## 测试 + +- 执行的命令: + - `C:/Python310/python.exe -m py_compile src/task_models.py src/task_repository.py src/pdd_ui_event.py test/test_task_repository.py test/test_pdd_ui_event.py test/test_purchase_recovery.py` + - `C:/Python310/python.exe -m pytest -q --disable-warnings test/test_task_repository.py test/test_pdd_ui_event.py test/test_purchase_recovery.py` + - `C:/Python310/python.exe -m pytest -q test` + - 设置 `QT_QPA_PLATFORM=offscreen` 后创建 `MainWindow`。 +- 结果:语法检查通过;定向测试 96 项全部通过;完整 Client 测试 511 项通过、2 项与本工单无关的既有版本号断言失败;离屏界面冒烟输出 `OK`。 +- **没验证到的部分**:未连接真实 Android 设备继续核对现有订单;没有重新提交订单、触发支付或修改本机 `cg44` 的任务状态。 + +## 遗留问题 + +- 工作区 Client 版本为 `0.1.2`,两项更新模块测试仍固定期待 `0.1.0`,不属于本工单范围。 + +## 相关提交 + +- `5ea8aa3` 安全继续失败采购核单。