diff --git a/docs/task/99-受控真实下单安全边界.md b/docs/task/99-受控真实下单安全边界.md new file mode 100644 index 0000000..7397c52 --- /dev/null +++ b/docs/task/99-受控真实下单安全边界.md @@ -0,0 +1,65 @@ +# 99 实现受控真实下单并停在支付前 + +- 类型:需求 +- 父级大工单:#96 +- 所属 MVP / 版本:#97 +- 状态:已完成 +- 日期:2026-08-10 +- Gitea 工单: + +## 背景与目标 + +Client 原来只支持采购演练,会停在最终提交订单之前。本任务增加默认关闭、绑定 +Client 和 Android 设备的真实下单能力,只允许创建一笔未付款订单,并保证进入 +不可逆阶段后只核对订单,绝不重新下单。 + +## 最终方案 + +- SQLite 升级到版本 3,在任务上保存 Admin 下发的不可变 `execution_mode`;历史任务默认为 `dry_run`。 +- 设置页增加“真实下单(不支付)”卡片。启用时必须精确输入“创建未付款订单”,授权绑定当前 Client ID 和已保存 Android 设备;缺失、损坏或绑定不一致时按关闭处理。 +- `TaskDispatcher` 只在授权匹配且 live Adapter 就绪时向 Admin 声明 `purchase_mode=live`,不会把任务从演练自行提升为真实。 +- 演练与真实采购使用不同 Adapter 接口。演练接口没有提交方法;真实接口只增加一次性提交方法,两者都没有付款或取消订单方法。 +- 最终点击前重新核对确认页、规格、数量、价格、库存和唯一提交目标。先用 SQLite 事务写入 `irreversible_action_at`,再允许单击一次。 +- 点击返回或抛错后都转入只读订单核对。存在不可逆任务时,核单优先于 Outbox、其他本地任务和领取新任务。 + +实现与建单方案一致。真实订单匹配和向 Admin 上报结果不在本任务范围内,由后续工单完成。 + +## 改了哪些 + +- `client/src/live_purchase_authorization.py`:保存和校验本地真实下单授权。 +- `client/src/settings_ui.py`、`client/src/settings_ui_event.py`:增加中文授权界面和后台保存、Admin 能力登记。 +- `client/src/admin_gateway.py`、`client/src/http_admin_gateway.py`、`client/src/task_models.py`:传递并校验 live 能力和任务执行模式。 +- `client/src/db_schema.py`、`client/src/task_repository.py`:增加数据库迁移、不可逆事务和只读核单状态转换。 +- `client/src/pdd_purchase_adapter.py`、`client/src/pdd_u2_purchase_adapter.py`:分离演练/live 接口并限制最终点击最多一次。 +- `client/src/purchase_task_service.py`、`client/src/task_dispatcher.py`:实现最终复核、不可逆先落库和核单优先级。 +- `client/test/`:补充授权、迁移、协议、调度、一次性点击和恢复测试。 +- `docs/client/`:同步架构、数据、接口、界面和安全基线。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 新装、升级和未确认设备默认关闭 live | 通过 | +| 环境变量和普通启动参数不能开启 live | 通过 | +| Client、设备或 Adapter 不匹配时只声明 dry_run | 通过 | +| 提交前重新核对确认页和全部安全字段 | 通过(自动化测试) | +| 不可逆标记事务成功后才允许点击 | 通过(自动化测试) | +| 最终提交目标唯一且最多点击一次 | 通过(自动化测试) | +| 安全异常停止并转人工或核单 | 通过(自动化测试) | +| 不存在付款方法和付款点击路径 | 通过(代码检查) | +| dry_run 和采集任务无回归 | 通过 | + +## 测试 + +- 执行的命令:`cd client; C:\Python310\python.exe -m pytest -q --disable-warnings` +- 结果:`286 passed, 527 warnings in 13.17s` +- **没验证到的部分**:未使用真实 PDD 账号和 Wi-Fi Android 设备点击最终提交订单;未验证真实订单生成后的匹配与 Admin 上报,这两项留给独立真机验收和后续工单。 + +## 遗留问题 + +- live 任务提交后暂时保持“只允许核对订单”;订单唯一匹配及成功上报由后续工单实现。 +- 真机验收必须重新获得当次明确授权,不因本工单自动化测试通过而自动执行。 + +## 相关提交 + +- `e960cab` 实现受控真实下单安全边界