docs: import wiki at afc651f75a3a

ila
2026-08-07 16:37:14 +08:00
parent d0d9773112
commit 6de9102437
+78
@@ -0,0 +1,78 @@
<!-- docs-wiki-sync:docs/tasks/T-278.md@afc651f75a3abc2676bb13aa8a80f6aa6a25a72e -->
> 同步来源:[`docs/tasks/T-278.md`](/chengma/mroubao/src/commit/afc651f75a3abc2676bb13aa8a80f6aa6a25a72e/docs/tasks/T-278.md) · commit `afc651f75a3a`
---
id: T-278
title: 任务价格为空时使用冻结的低价采购上限
phase: 2
deps:
- T-277
status: DONE
created: 2026-08-01
context_ref: 757a522
work_branch: null
write_paths:
- docs/tasks/T-278.md
- docs/current-state.md
- docs/04-architecture.md
- docs/05-coding-rules.md
- docs/api.md
- backend-api/migrations/**
- backend-api/internal/**
- backend-api/.env.example
- android-buyer/app/src/main/**
- android-buyer/app/src/test/**
---
## 问题 / 背景
候选价格可能为空或只是搜索结果展示价。现有 Android 策略在采购任务未设置最高总预算时,
要求下单时的规格单价必须和候选价格文本完全相同;候选价格为空会让已人工确认的商品永远
无法进入订单确认页。直接取消价格判断又会失去自动采购的金额安全边界。
## 行为契约
1. 采购任务设置 `max_budget` 时,以该最高总预算作为订单总额上限;未设置时,以后台
`CMROUBAO_DEFAULT_ORDER_TOTAL_CAP_CENTS` 配置作为低价采购上限,默认 `20000` 分。
2. 创建人工确认授权时,把最终上限和来源
`TASK_MAX_BUDGET|DEFAULT_LOW_PRICE_CAP` 冻结到授权记录和设备命令;配置后续变化不影响
已创建授权。
3. 设备命令 schema 升级,上限参与 `command_sha256`;App 不从任务缓存自行推导默认值。
4. 候选 `price_text` 只作为观察数据,不再要求和当前规格价格完全相等,也不作为授权上限。
5. App 仍必须在规格选择后读取唯一、已验证的当前单价,并在订单确认页读取总价;
`当前单价 × 数量`、确认页总价和冻结上限必须同时一致/满足,任何缺失、歧义、溢出或超额
均失败关闭。
6. 后端接收 dry-run 时再次校验总价不超过授权记录中的冻结上限,不能只信任手机校验。
## 方案
1. 配置层增加整数分单位的默认总额上限,限制在合理范围,并允许从现有 `.env` 读取。
2. migration 为 `order_authorizations` 增加非空总额上限及来源;历史授权按保守方式迁移,
down migration 对非默认数据失败关闭。
3. 授权仓储根据任务预算或服务配置生成冻结值,设备命令、哈希、HTTP JSON 和 Android
安全存储透传该值。
4. 重写 Android 价格策略和 Go dry-run 仓储校验,补充空候选价格、任务预算、默认上限、
超额、篡改哈希及迁移回归测试。
## 验收要点
- [x] 任务有预算时,命令冻结任务预算并标记 `TASK_MAX_BUDGET`。
- [x] 任务无预算且候选价格为空时,仍可按默认 200 元上限执行 dry-run。
- [x] 候选价格变化不阻止执行,但当前规格价格缺失或歧义仍阻止执行。
- [x] 当前总价或订单确认总价超过冻结上限时,App 和后端均拒绝。
- [x] 上限和来源参与命令哈希及持久化,重启和配置变化不改变旧授权。
- [x] migration up/down/up、Go 全量测试、Android 双变体单测、lint 和构建通过。
## 边界
- 本任务不修复确认商品链接身份复核、订单 dry-run 的 VLM 规格兜底或终态失败上报,
由 T-279 完成。
- 不允许价格不可读时自动下单,不允许模型独立生成金额。
- 不自动点击支付,最终仍停留在拼多多待支付订单。
## 执行记录
- 2026-08-01:按“价格为空时取消候选价等值判断,但保留冻结总额上限”的方案创建任务,
状态 `TODO`。
- 2026-08-01:完成 v22 授权上限持久化、schema v3 命令、双端金额校验和 Admin 展示;
Go 全量测试/vet、Android Debug/Release 共 942 项测试、lint 和构建通过,状态 `DONE`。