feat: 安全应用采购规格解析结果 (#257)

This commit is contained in:
chengma
2026-08-17 17:43:25 +08:00
parent 484ce4e8ec
commit afc1cdf719
19 changed files with 1669 additions and 24 deletions
+34 -4
View File
@@ -278,8 +278,7 @@ CREATE INDEX idx_task_runs_task
[接口契约 §7.1](04-admin-api-contract.md) 定义了一个与 `task_runs.attempt_id` 绑定的一次性
规格解析命令。Admin 的 `purchase_spec_resolutions` 是服务端候选观察和最终决策的权威
审计;Client 本地仍必须在发送前保存以下最小信息,后续由工单 #257 增加 SQLite migration
和 Repository:
审计;Client 本地仍必须在发送前保存以下最小信息:
- `task_id`(本地外键)与 `attempt_id`;
- 完整且大小受限的请求 JSON、确定性 `Idempotency-Key` 和请求哈希;
@@ -292,8 +291,39 @@ CREATE INDEX idx_task_runs_task
`task_runs` 的执行期有效规格。进入过 `irreversible_action_at` 的运行不得新建或重放解析
以继续采购,只能核对订单。
#254 只冻结接口和 Admin 审计模型,当前 Client SQLite schema 不在本工单改动。未实现
#257 的旧 Client 继续按“规格不匹配即失败”运行,不调用新接口,也不会出现半持久化状态。
Client 使用 `purchase_spec_resolutions` 保存这些执行期记录:
```sql
CREATE TABLE purchase_spec_resolutions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id INTEGER NOT NULL,
attempt_id TEXT NOT NULL,
idempotency_key TEXT NOT NULL UNIQUE,
request_json TEXT NOT NULL,
request_hash TEXT NOT NULL,
candidate_snapshot_hash TEXT NOT NULL,
status TEXT NOT NULL, -- pending / resolved
resolution_id TEXT,
outcome TEXT,
source TEXT,
confidence_bps INTEGER,
match_candidate_id TEXT,
match_raw_text TEXT,
match_options_json TEXT,
reason TEXT,
resolved_at TEXT,
received_at TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (task_id) REFERENCES pdd_tasks(id) ON DELETE CASCADE,
UNIQUE (task_id, attempt_id, candidate_snapshot_hash)
);
```
`pending` 表示请求已落库但尚未得到可验证的业务响应,不能据此继续采购;`resolved`
表示完整响应已经落库,仍须通过候选白名单和真机快照复核。网络调用不放在 SQLite
事务中。旧任务原始规格不覆盖,最终结果分别保存原始请求规格、实际采用规格和
`resolution_id`。
## 5. `outbox_events`
+6
View File
@@ -115,6 +115,12 @@ Client 不保存或读取 `purchase.live_*` 手工授权设置。`purchase_mode`
当前前台应用,避免在部分真机上重复等待十秒以上。最终下单点击前仍必须单独
查询前台应用。性能日志分别记录状态读取、颜色选择和尺码选择耗时。
- 规格选择后读取最新控件树并验证选中状态。
- 运行时规格解析请求必须在网络发送前写入独立 SQLite 记录;只调用一次专用命令,
不轮询 Admin。只有 `matched` 响应的哈希、候选编号、原文和 options 都是本次候选的
逐字副本时才继续。响应返回后重新完整遍历真机候选并复算哈希,页面、颜色或候选
有任何变化都在可逆阶段停止。
- 解析记录不能覆盖任务原始规格。成功结果同时保留原始规格、实际采用规格和
`resolution_id`;解析失败不自动重新采购,已有不可逆标记时永远不调用规格解析。
- 设置采购数量时先读取当前值;数量相同不聚焦输入框,小差值优先使用加减按钮。
只有输入框兜底路径确认输入法已经显示时才允许按一次返回键;输入法关闭后必须
重新核对规格、数量、价格和唯一提交目标,规格面板丢失时立即停止。