feat: 实现受控真实下单安全边界 (#99)
This commit is contained in:
@@ -344,19 +344,21 @@ Client 与 Admin 的任务交互只有三种调用:领一个任务、提交结
|
||||
|
||||
### 任务领取与执行
|
||||
|
||||
1. 优先补交一条本地 Outbox。提交结果不依赖 Android 设备。
|
||||
2. 没有待提交结果时,在工作线程通过 ADB 检查已保存设备号是否仍为 `device` 状态。检查失败立即停止,不执行本地任务,也不领取新任务。
|
||||
3. 执行最早的本地待处理任务;没有本地任务时才调用 Admin `claim`。返回 204 表示暂时没活,按轮询周期退避后再试。
|
||||
4. Client 持久化新领取的任务,状态置 `claimed`。
|
||||
5. 根据 `task_type` 分派给采集或采购执行器。
|
||||
6. 工作线程执行,持续更新 `current_step`(只写本地,不上报 Admin)。
|
||||
7. 完成后在同一事务里写入结果与 Outbox,状态置 `result_pending`。
|
||||
8. Outbox 提交成功、Admin 返回 `accepted: true` 后标记 `succeeded`。
|
||||
9. 回到第 1 步处理下一轮。**同一时间只做一个任务。**
|
||||
1. 若存在 `irreversible_action_at`,只允许先核对该采购订单;不得补交其他结果、执行任务或领取任务。
|
||||
2. 没有待核对采购时,优先补交一条本地 Outbox;提交结果不依赖 Android 设备。
|
||||
3. 没有待提交结果时,在工作线程通过 ADB 检查已保存设备号是否仍为 `device` 状态。检查失败立即停止,不执行本地任务,也不领取新任务。
|
||||
4. 执行最早的本地待处理任务;没有本地任务时才调用 Admin `claim`。返回 204 表示暂时没活,按轮询周期退避后再试。
|
||||
5. Client 持久化新领取的任务,状态置 `claimed`。
|
||||
6. 根据 `task_type` 分派给采集或采购执行器。
|
||||
7. 工作线程执行,持续更新 `current_step`(只写本地,不上报 Admin)。
|
||||
8. 完成后在同一事务里写入结果与 Outbox,状态置 `result_pending`。
|
||||
9. Outbox 提交成功、Admin 返回 `accepted: true` 后标记 `succeeded`,然后继续下一轮。**同一时间只做一个任务。**
|
||||
|
||||
`TaskDispatcher` 是能力声明的唯一入口。没有可用采购演练 Adapter、没有已保存
|
||||
`TaskDispatcher` 是能力声明的唯一入口。没有可用采购 Adapter、没有已保存
|
||||
Android 设备或本地持久化未准备好时,只声明 `collect`;条件满足时才声明
|
||||
`collect,purchase`,且 `purchase_mode` 永远是 `dry_run`。领取响应必须先完整校验并
|
||||
`collect,purchase`。真实下单授权默认关闭;只有本地授权同时匹配当前 Client ID、
|
||||
已保存 Android 设备且 live Adapter 就绪时才声明 `purchase_mode=live`,否则声明
|
||||
`dry_run`。领取响应必须先完整校验并
|
||||
写入 SQLite,Repository 提交成功后才能分派,避免任务已在 Admin 领取却在本地丢失。
|
||||
|
||||
中途 Admin 是否取消了这个任务、是否重派给了别人,Client 不查也不管,做完照样提交——
|
||||
@@ -385,11 +387,15 @@ reconcile_purchase(task, run) -> PurchaseResult | ManualReview
|
||||
采购演练通过 `PddPurchaseAdapter` 的窄接口逐步读取最新页面状态。该接口只提供
|
||||
打开商品、读取状态、精确选择动态规格、设置数量、进入提交前确认页和停止,
|
||||
**不提供提交订单或付款方法**。这样即使应用层调用错误,也没有可误触的真实下单入口。
|
||||
真实采购另用 `PddLivePurchaseAdapter`,只增加 `submit_order_once`。服务层在最新
|
||||
页面复核规格、数量、价格、库存和唯一提交目标后,先提交
|
||||
`irreversible_action_at` 事务,再允许 Adapter 点击一次;之后无论点击结果是否明确,
|
||||
都只进入订单核对。该接口不提供付款或取消订单方法。
|
||||
采购规格使用完整 `options` 对象精确比较,不假定只有颜色和尺码两个维度。
|
||||
只读核对另用 `PddPurchaseReconcileAdapter`,只暴露 `read_order_match`
|
||||
和 `close`,不暴露选规格、设数量、下单或付款方法。
|
||||
|
||||
正式 Client 由 `pdd_u2_purchase_adapter.py` 实现上述演练接口,并在
|
||||
正式 Client 由 `pdd_u2_purchase_adapter.py` 分别实现演练和 live 接口,并在
|
||||
`ui_main.py` 注入工厂。Adapter 通过 `PddDeviceService` 独占连接,每次判断
|
||||
都重新读取当前包名和控件树。当前 Admin 下发的 `color` 和 `size`
|
||||
使用精确文字匹配;其他动态维度直接停止,不做相似匹配。原生 PDD
|
||||
|
||||
Reference in New Issue
Block a user