feat: 移除 Client 真实采购手工授权 (#114)
This commit is contained in:
@@ -235,8 +235,8 @@ PDD 商品之所以单独一个模块,是因为它在数据上就是**独立
|
||||
- 预选不会自动保存或创建采购任务。页面必须显示推荐理由,采购员点击保存后才写映射和只追加的决策审计。
|
||||
|
||||
**创建采购任务:** 只有映射仍有效且没有进行中采购任务的行可勾选。确认弹窗列出
|
||||
当前账号可见的客户端:声明 live 的客户端可选择,暂时离线也可提前指派;非 live
|
||||
客户端显示但禁用。新任务固定为真实下单(不支付),提交表单即表示创建真实采购任务,
|
||||
当前账号可见的全部客户端都可选择,暂时离线或尚未就绪也可提前指派并等待其就绪后领取。
|
||||
新任务固定为真实下单(不支付),提交表单即表示创建真实采购任务,
|
||||
不再额外要求风险复选框或确认短语;服务端仍按 §5 全量复核。
|
||||
|
||||
**底部状态条:** 最近同步时间、待匹配条数。
|
||||
@@ -353,13 +353,13 @@ PDD 商品之所以单独一个模块,是因为它在数据上就是**独立
|
||||
4. 数量大于 0;
|
||||
5. **价格上限已填且大于 0** —— 默认从当前映射的 PDD 规格价格带出,操作员可改,但不允许为空;
|
||||
6. 已选择分配的客户端;
|
||||
7. 所选客户端存在、在当前账号可见范围内,且声明 `purchase_mode=live`;暂时离线只影响领取时间,不阻止提前指派;
|
||||
7. 所选客户端存在且在当前账号可见范围内;其在线状态和 `purchase_mode` 只影响何时领取,不阻止提前指派;
|
||||
8. 同一顺运宝明细没有 `pending` / `assigned` / `claimed` 的采购任务。
|
||||
|
||||
Admin 新建采购任务固定使用不可变的 `execution_mode=live`,不向采购员提供模式选择:
|
||||
|
||||
- `live` 会创建真实未付款订单,管理员和其他正常状态用户均可创建;点击明确标注的创建按钮并提交表单即表示创建,不再要求额外复选框或确认短语;
|
||||
- 必须显式指定当前账号可见且最后登记能力为 `purchase_mode=live` 的 Client;离线 live Client 可提前指派并在上线后领取;
|
||||
- 必须显式指定当前账号可见的 Client;不按最后登记的 `purchase_mode` 限制创建,未就绪或离线 Client 等待就绪后领取;
|
||||
- 创建时记录操作用户和操作时间。取消、重派和结果回传均不得修改执行模式。
|
||||
- 数据库和 API 继续保留 `dry_run/live`,历史任务和缺省兼容值仍按 `dry_run`,不得批量升级历史任务。
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ UPDATE tasks
|
||||
`execution_mode` 只允许 `dry_run` / `live`;Admin Web 新建采购任务固定为 `live`,历史任务和接口缺省兼容值仍为 `dry_run`。领取查询必须按
|
||||
Client 上报的 `capabilities.purchase_mode` 过滤:`dry_run` Client 只能看到演练任务,
|
||||
`live` Client 可以看到两种;过滤只决定能否领取,绝不改变任务自身模式。
|
||||
Admin Web 可以把 live 任务预先指派给当前账号可见的任意 Client,不在创建时按该字段
|
||||
拒绝;尚未就绪的指定 Client 不会领取,待其设备与真实采购执行器就绪并自动上报 live 后领取。
|
||||
|
||||
`[必须]` `payload.goods_url` 必须有值;采购任务的 `quantity` 和 `max_price_cent` 必须有值。
|
||||
这些在建任务时就该校验住(见 [01 需求](01-requirements.md) §5),
|
||||
@@ -310,7 +312,7 @@ Client 契约里散落的 Admin 侧硬要求,汇总在这里,**可以直接
|
||||
- [ ] 响应不含租约、不含 Admin 侧状态
|
||||
- [ ] `payload.goods_url` 必有值
|
||||
- [ ] 采购任务的 `quantity`、`max_price_cent` 必有值,且是人民币分整数
|
||||
- [ ] 不向只声明 `dry_run` 的客户端分配需要真实下单的任务
|
||||
- [ ] 可以预先指派 live 任务给可见 Client,但领取时不向只声明 `dry_run` 的客户端返回 live 任务
|
||||
- [ ] `result` / `failure` 幂等:同键同内容返回同结果
|
||||
- [ ] 同键不同内容返回 `409`
|
||||
- [ ] **任务已取消,仍接受结果**
|
||||
|
||||
@@ -555,8 +555,8 @@ HTML 片段,只替换弹窗内部的表格、总数和分页。主货运单表
|
||||
### 6.4 创建采购任务
|
||||
|
||||
只有“可创建采购任务”的行可勾选。勾选后打开服务端渲染的确认弹窗:选择当前账号
|
||||
可见且声明 live 能力的客户端,并逐行确认人民币价格上限。离线 live Client 也可提前
|
||||
指派,待其上线后领取;非 live Client 显示为禁用项并说明原因。默认价格来自映射规格
|
||||
可见的任意客户端,并逐行确认人民币价格上限。离线或尚未就绪的 Client 也可提前
|
||||
指派,待其就绪后领取;选项继续显示在线状态但不因能力状态禁用。默认价格来自映射规格
|
||||
的 PDD 采集价;没有价格时留空强制填写。新任务固定为真实下单(不支付),不显示执行
|
||||
模式选择,也不再要求额外风险复选框、确认短语或浏览器二次确认。
|
||||
|
||||
@@ -578,13 +578,13 @@ grid 样式不得覆盖 `hidden`,关闭后改变勾选再打开也不得残留
|
||||
· SO-...-009 规格未匹配
|
||||
```
|
||||
|
||||
`[必须]` 创建前弹出确认框,让操作员选**分配给哪个 live Client**,并确认价格上限。
|
||||
`[必须]` 创建前弹出确认框,让操作员选**分配给哪个当前账号可见的 Client**,并确认价格上限。
|
||||
价格上限默认从当前映射的 PDD 规格采集价带出,可改,**不允许为空**。
|
||||
|
||||
可采购行的“下一步”显示“创建采购任务”。点击后复用同一个确认弹窗并只带入当前明细,
|
||||
不改变表格复选框状态;顶部批量入口仍按已勾选明细打开。客户端选项显示名称和 Client
|
||||
ID;live Client 可选择且只有一个时自动选中,非 live Client 显示“未启用真实采购”并
|
||||
禁用。没有符合条件的 Client 时禁用提交并说明如何在 Client 设置页启用。已有未
|
||||
ID 和在线状态;所有可见 Client 都可选择且只有一个时自动选中。没有可见 Client 时禁用
|
||||
提交并说明需要管理员先绑定客户端。已有未
|
||||
结束任务的行显示“查看采购任务”并进入“采集采购”页,不得再次创建。服务端仍必须重新
|
||||
校验映射、数量、人民币价格上限、客户端权限、固定 live 模式、创建审计和重复任务,不能
|
||||
信任列表页的旧状态。
|
||||
|
||||
@@ -91,7 +91,7 @@ Admin 使用它作为 `clients.client_id` 主键。设备号变化会产生一
|
||||
|
||||
- `supported_types` 必须非空,只允许 `collect`、`purchase`;
|
||||
- `device` 可选,提供时当前只支持 `android`;
|
||||
- `purchase_mode` 只允许 `dry_run`、`live`,MVP 固定 `dry_run`;
|
||||
- `purchase_mode` 只允许 `dry_run`、`live`;Client 未选择设备或真实采购执行器未就绪时为 `dry_run`,就绪后自动为 `live`;
|
||||
- `schema_versions` 只包含正整数,当前使用 `[1]`。
|
||||
|
||||
---
|
||||
|
||||
@@ -282,7 +282,7 @@ CMAutoBuy/ 整个文件夹拷到任何机器都能用
|
||||
|
||||
**已定案(不再是待确认项):**
|
||||
|
||||
- Admin 新建采购任务固定为 `execution_mode=live`,不再提供演练选择;Client 本地授权仍默认关闭,只有绑定 Client ID、Android 设备且通过安全门禁后才声明 live 能力和领取任务。
|
||||
- Admin 新建采购任务固定为 `execution_mode=live`,不再提供演练选择;Client 不提供手工 live 授权,身份、已选 Android 设备和真实采购 Adapter 就绪时自动声明 live 并领取任务。
|
||||
- Admin 只分配任务给指定 Client,Client 不读全局任务池。见 [04](04-admin-api-contract.md) §5.1。
|
||||
- **没有租约、没有心跳、没有状态回查。** 任务流程只有领取、提交结果、提交失败三个调用;设置页另有无任务副作用的幂等 Client 登记调用。见 [04](04-admin-api-contract.md) §1、§4.1。
|
||||
- 本地只存已领取任务,已完成任务**永久保留**。诊断产物(截图、XML、日志)仍按 `diagnostics.retention_days` 清理,两者不是一回事。见 [03](03-data-model.md) §3.1。
|
||||
|
||||
@@ -367,8 +367,8 @@ Client 与 Admin 的任务交互只有三种调用:领一个任务、提交结
|
||||
|
||||
`TaskDispatcher` 是能力声明的唯一入口。没有可用采购 Adapter、没有已保存
|
||||
Android 设备或本地持久化未准备好时,只声明 `collect`;条件满足时才声明
|
||||
`collect,purchase`。Admin 新建采购任务固定为 live,但 Client 本地授权仍默认关闭;
|
||||
只有本地授权同时匹配当前 Client ID、已保存 Android 设备且 live Adapter 就绪时才声明
|
||||
`collect,purchase`。Admin 新建采购任务固定为 live;Client 不再读取手工授权,只有当前
|
||||
Client 身份有效、已保存 Android 设备且 live Adapter 就绪时才自动声明
|
||||
`purchase_mode=live`,否则声明 `dry_run` 且不能领取新建的 live 采购任务。领取响应必须先完整校验并
|
||||
写入 SQLite,Repository 提交成功后才能分派,避免任务已在 Admin 领取却在本地丢失。
|
||||
|
||||
@@ -449,7 +449,7 @@ PDD 页面可能出现登录失效、验证码、控件树不完整、A/B 页面
|
||||
4. 使用 Outbox 保证结果最终提交,并隔离“提交重试”与“业务重做”。
|
||||
5. MVP 单设备串行执行,不并行控制多个设备。
|
||||
6. 采集规格采用通用维度和 SKU 组合结构,不把模型锁死为颜色与尺码两个数组。
|
||||
7. Admin 新建采购任务固定为真实下单(不支付);Client 只有通过独立安全验收和本地设备绑定后才声明 live 能力。
|
||||
7. Admin 新建采购任务固定为真实下单(不支付);Client 身份、已选设备和 live Adapter 就绪后自动声明 live,真实设备结果仍按独立工单验收。
|
||||
|
||||
## 11. 相关文档
|
||||
|
||||
|
||||
@@ -422,17 +422,13 @@ CREATE TABLE app_settings (
|
||||
- `automation.poll_interval_seconds`
|
||||
- `automation.max_retries`
|
||||
- `automation.dry_run`
|
||||
- `purchase.live_enabled`
|
||||
- `purchase.live_client_id`
|
||||
- `purchase.live_device_serial`
|
||||
- `purchase.live_confirmed_at`
|
||||
- `safety.max_quantity`
|
||||
- `safety.price_tolerance_cent`
|
||||
- `diagnostics.artifact_directory`
|
||||
- `diagnostics.retention_days`
|
||||
|
||||
访问令牌、密码和 Cookie 不得存入本表。
|
||||
`purchase.live_*` 只保存非敏感的本地安全门禁状态;缺失、损坏或绑定不一致时一律按关闭处理。
|
||||
历史版本可能遗留 `purchase.live_*` 设置;当前版本不再读取或写入这些键,也不依赖它们决定领取能力。
|
||||
|
||||
## 7. 任务状态转换
|
||||
|
||||
|
||||
@@ -211,8 +211,8 @@ POST /api/v1/client/tasks/claim
|
||||
|
||||
Client 的 `HttpAdminGateway.claim_next` 已实现本接口,并原样序列化应用层已经
|
||||
安全确认的 `ClaimCapabilities`。没有采购 Adapter 或设备未准备好时只声明
|
||||
`supported_types: ["collect"]`;条件满足时声明 `collect,purchase`。只有设置页
|
||||
授权同时匹配当前 Client ID、已保存 Android 设备且 live Adapter 就绪时才声明
|
||||
`supported_types: ["collect"]`;条件满足时声明 `collect,purchase`。Client 不发送手工
|
||||
真实采购启用请求;当前 Client 身份有效、已保存 Android 设备且 live Adapter 就绪时自动声明
|
||||
`purchase_mode: "live"`,其他情况均为 `dry_run`。一次调用最多领取一个任务,结果或失败通过
|
||||
本页 §6 或 §7 提交,完整请求会先进入本地 Outbox。
|
||||
|
||||
@@ -232,7 +232,7 @@ Client 的 `HttpAdminGateway.claim_next` 已实现本接口,并原样序列化
|
||||
规则:
|
||||
|
||||
- `[必须]` 领取必须在 Admin 内部原子完成,一次调用最多返回一个任务。
|
||||
- `[必须]` Admin 不得向只声明 `dry_run` 的 Client 分配要求真实下单的任务。
|
||||
- `[必须]` Admin 可以把真实采购任务预先指派给当前账号可见的任意 Client;领取时仍不得把 live 任务返回给只声明 `dry_run` 的 Client。
|
||||
- `[必须]` `execution_mode` 只允许 `dry_run`、`live`。Admin Web 新建采购任务固定为 `live`;历史任务和接口缺省兼容值仍是 `dry_run`,Client 不得自行把模式从演练提升为真实。
|
||||
- `[必须]` 声明 `dry_run` 的 Client 只能领取 `dry_run`;声明 `live` 的 Client 可以领取两种模式。能力只缩小可领取范围,不修改任务模式。
|
||||
- `[必须]` 响应**不包含**租约。Client 拿到任务就开始做,做完再来领下一个。
|
||||
@@ -247,8 +247,9 @@ Client 的 `HttpAdminGateway.claim_next` 已实现本接口,并原样序列化
|
||||
| **无主** | 空 | `pending` | **谁先抢到算谁的**,领取时才记下领取者 |
|
||||
|
||||
领取还必须同时满足执行能力:`dry_run` Client 永远看不到 `live` 任务;
|
||||
`live` Client 可以领取 `dry_run` 和 `live`。Admin 当前只允许真实采购任务显式指定
|
||||
一个已经登记并声明 `purchase_mode: "live"` 的 Client,因此真实任务不会进入无主任务池。
|
||||
`live` Client 可以领取 `dry_run` 和 `live`。Admin Web 创建真实采购任务时显式指定
|
||||
当前账号可见的 Client,不要求创建时已经声明 live;未就绪或离线 Client 的任务保持
|
||||
`assigned`,直到该 Client 自动声明 live 后领取,因此真实任务不会进入无主任务池。
|
||||
|
||||
`[必须]` **指定给本机的优先于无主的。** 显式分配是人为决定,应当先兑现;
|
||||
无主任务谁抢都一样,可以等。
|
||||
|
||||
@@ -293,13 +293,12 @@ class TaskTableModel(QAbstractTableModel):
|
||||
- 最大重试次数;
|
||||
- 演练模式开关。
|
||||
|
||||
### 真实采购授权(不支付)
|
||||
### 真实采购运行就绪(不支付)
|
||||
|
||||
- Admin 新建采购任务固定为 live;Client 本地授权默认关闭,并明确显示当前状态、绑定 Client、绑定 Android 设备和确认时间;
|
||||
- 只有输入完整确认文字“创建未付款订单”后才能启用,不能通过环境变量或调试参数开启;
|
||||
- 启用和关闭在后台线程保存,执行期间禁用重复操作,失败时保留原状态并说明恢复办法;
|
||||
- 启用仅代表允许创建一笔未付款订单,不允许自动付款;设备或 Client 绑定变化后撤销 live 能力并停止领取新采购任务;
|
||||
- 关闭操作始终可见,状态不能只用颜色表达。
|
||||
- 设置页不显示真实采购授权、确认文字或启用/关闭按钮;
|
||||
- Client 身份和 Android 设备保存后,真实采购 Adapter 就绪的 Client 自动登记 live 能力;
|
||||
- 身份、设备或 Adapter 任一未就绪时不领取真实采购任务,页面继续通过现有设备状态说明缺失项;
|
||||
- 自动就绪只允许创建未付款订单,不允许自动付款。
|
||||
|
||||
### 安全与诊断
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ PDD 解析测试优先使用脱敏的 XML 固件,不要求每次连接真实
|
||||
|
||||
## 3. 采购安全门禁
|
||||
|
||||
Admin 新建采购任务固定为真实下单(不支付);Client 本地 live 授权仍默认关闭。全部满足后才能声明 live 能力并领取真实采购任务:
|
||||
Admin 新建采购任务固定为真实下单(不支付),Client 不再提供手工 live 授权。Client 身份有效、已选择 Android 设备且真实采购 Adapter 就绪时自动声明 live;领取并执行后仍必须满足下列安全门禁:
|
||||
|
||||
1. Admin 原子领取和结果幂等已经通过联合测试。
|
||||
2. Outbox 断网和重启恢复测试通过。
|
||||
@@ -78,14 +78,10 @@ Admin 新建采购任务固定为真实下单(不支付);Client 本地 liv
|
||||
4. 最终下单前后均有持久化步骤标记。
|
||||
5. 进程在不可逆阶段退出后只执行订单核对,不会重新下单。
|
||||
6. 订单匹配能识别唯一候选;多个候选进入人工处理。
|
||||
7. 演练模式在代表性商品和设备上通过验收。
|
||||
8. 操作人员明确确认真实下单范围和安全设置。
|
||||
7. 历史演练模式和真实模式在代表性商品与设备上通过自动化验收。
|
||||
8. 真实设备首单按独立验收工单执行,并明确停止在支付前。
|
||||
|
||||
Client 本地 live 授权不得通过调试参数、默认配置或界面误操作意外开启。当前版本仅在设置页
|
||||
精确输入确认文字后保存授权,并绑定 Client ID 和已保存 Android 设备;任一绑定
|
||||
不一致都降级为 `purchase_mode=dry_run`。演练 Adapter 不提供提交方法,live Adapter
|
||||
只提供一次性提交方法,两者都不提供付款或取消订单方法。开发者不能把自动化测试
|
||||
通过当成真机门禁放行;仍需项目负责人和实际操作人员共同确认。
|
||||
Client 不保存或读取 `purchase.live_*` 手工授权设置。`purchase_mode` 只表达本次注册或领取时的运行就绪能力:身份、设备或真实采购 Adapter 任一缺失都声明 `dry_run`,全部就绪才自动声明 `live`。演练 Adapter 不提供提交方法,live Adapter 只提供一次性提交方法,两者都不提供付款或取消订单方法。开发者不能把自动化测试通过当成真机验收完成。
|
||||
|
||||
### 3.1 当前自动化安全检查
|
||||
|
||||
@@ -103,7 +99,7 @@ Client 本地 live 授权不得通过调试参数、默认配置或界面误操
|
||||
演练的 `enter_confirmation` 与 `stop_before_submit` 均为只读检查。
|
||||
- 单元测试必须断言演练没有最终点击、live 只有一次最终点击,且模糊目标不会点击。
|
||||
|
||||
上述只证明本地安全边界;真实设备联调仍须按独立验收工单获得当次明确授权。
|
||||
上述只证明本地安全边界;真实设备联调仍须按独立验收工单记录结果,且不得进入付款操作。
|
||||
|
||||
## 4. 自动化防护
|
||||
|
||||
@@ -127,6 +123,12 @@ Client 本地 live 授权不得通过调试参数、默认配置或界面误操
|
||||
商品失效。打开前后的商品页控件树签名相同则视为旧页面,不能据此执行规格选择或
|
||||
下单;采购进入不可逆阶段前仍须按商品编号等业务字段再次确认目标身份。
|
||||
|
||||
页面轮询不得在每一轮依赖 `app_current()`:部分设备的前台查询会阻塞十秒以上,
|
||||
还可能把已经显示 PDD 的页面报告为系统设置。连接时可以读取一次前台状态;后续
|
||||
商品页和规格面板判断优先使用最新控件树中的包名与组合语义。单次设备调用即使跨过
|
||||
截止时间,也要先分析刚返回的最新控件树,再决定成功或超时。规格面板超时必须记录
|
||||
最后页面类型、控件树读取次数和脱敏 XML 引用,不保存商品、账号或收货相关原文。
|
||||
|
||||
> **运营提醒(不是代码规则):** Admin 超时重派可能导致同一任务被两台 Client 各下一单,
|
||||
> 产生重复的未付款订单。人工审核时取消多余订单即可。但未付款订单长期堆积可能触发平台风控,
|
||||
> 需要操作人员留意,不要放着不管。
|
||||
@@ -276,7 +278,7 @@ Artifact 写入前应脱敏,数据库只保存引用。保留周期由设置
|
||||
| 8 | 开源和商业许可证已确认 | 新增依赖的许可证是否允许本项目的使用方式 | **项目负责人**(不是开发者自己判断) |
|
||||
| 9 | 真实下单版本额外满足采购安全门禁 | 逐条核对 §3 的 8 项 | **项目负责人 + 操作人员共同确认** |
|
||||
|
||||
第 8、9 项开发者**不要自己判断放行**。新增依赖时把包名和许可证类型报给项目负责人;真实下单开关必须由项目负责人和实际操作的人一起确认,见 §3。
|
||||
第 8、9 项开发者**不要自己判断验收通过**。新增依赖时把包名和许可证类型报给项目负责人;真实设备下单验收必须由项目负责人和实际操作的人共同确认,见 §3。
|
||||
|
||||
## 11. 任务完成定义
|
||||
|
||||
|
||||
Reference in New Issue
Block a user