docs: 归档任务 #254

This commit is contained in:
chengma
2026-08-17 16:54:27 +08:00
parent 12414658d0
commit f187bfe0fe
@@ -0,0 +1,93 @@
# 254 Admin:定义采购运行时规格解析接口与审计模型
- 类型:需求 / 重构
- 父级大工单:#96
- 所属 MVP / 版本:#253 采购运行时 AI 规格纠偏闭环
- 状态:已完成,待用户验收
- 日期:2026-08-17
- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/254
## 背景与目标
Client 在真实采购规格面板找不到任务尺码时,原流程只能提交失败。为了让同一次、尚未
进入不可逆阶段的采购可以取得受审计的 Admin 规格决策,本任务先冻结第五个 Client API
契约,并建立保存候选观察和最终决策的最小数据模型。
本任务不实现 AI 匹配、HTTP Handler、Client 真机候选采集或采购续跑,也不复用会改变
任务状态的失败提交接口。
## 最终方案
- 定义一次性命令 `POST /api/v1/client/tasks/{task_id}/spec-resolution`,不增加 GET、
状态轮询、租约或心跳。
- 请求 schema v1 只包含任务/执行身份、PDD 商品、原任务规格、已选颜色、目标尺码、
当前颜色下最多 100 条可购买候选、快照哈希和观测时间;整个请求最多 64 KiB。
- 候选使用连续短编号 `c1`~`c100`。快照和幂等键都使用明确的 UTF-8 长度前缀
SHA-256 算法,Admin 必须重新计算,不能信任 Client 自报哈希。
- 响应固定为 `matched/uncertain/rejected/failed`。只有 matched 返回请求内候选的逐字
副本;来源为 `rule/ai/reused/null`,置信度使用可空的 0~10000 基点。
- MySQL v26 新增一张 `purchase_spec_resolutions`:同一行保存 pending 候选观察和最终
决策,业务唯一键为 `(task_id, attempt_id, candidate_snapshot_hash)`,另存
`request_hash` 识别同一身份的不同内容。
- Repository 提供新增、按解析编号读取、按业务身份读取、幂等复查和只完成一次决策。
候选观察先用短事务落库,规则/AI 网络调用不得占用事务;最终决策和可重放响应由后续
Handler/Service 在另一个短事务与 `idempotency_keys` 一起提交。
- 审计表不设任务和 Client 外键,避免既有硬删除流程阻塞或级联清除审计;不修改任务
状态、`pdd_products.skus_json` 或长期 `spec_mappings`。
- 表中不保存原始无障碍 XML、截图、订单号、收货信息、Cookie、Token、密码、API Key、
完整提示词或完整模型响应。
最终实现与工单方案一致。实施时进一步明确了跨 Python/Go 可复现的长度前缀哈希算法,
以及“短事务保存观察 → 事务外解析 → 短事务完成决策”的崩溃恢复边界。
## 改了哪些
- `admin/model/model.go`
- 增加解析 outcome/source 枚举、完整审计模型和完成决策模型。
- `admin/repository/mysql_db.go`
- schema 版本升级到 v26,增加解析审计表、约束、索引和启动自检。
- `admin/repository/purchase_spec_resolution.go`
- 增加候选观察新增、读取、幂等复查和只完成一次的参数化 Repository。
- `admin/repository/mysql_db_integration_test.go`
- 覆盖 v25→v26、重复迁移、业务唯一键、请求冲突、决策只完成一次和候选上限。
- `docs/client/04-admin-api-contract.md`
- 写入权威 HTTP schema、限制、哈希、响应、错误、兼容和隐私边界。
- `docs/admin/04-client-api.md`
- 同步 Admin 处理顺序、事务边界、稳定错误和实现清单。
- `docs/client/03-data-model.md`
- 明确 Client 后续持久化边界、原任务不可覆盖和旧 Client 兼容行为。
- `docs/admin/03-data-model.md`
- 记录 MySQL v26 表结构、约束、幂等关系和数据安全边界。
## 验收结果
| 验收标准 | 结果 |
|---|---|
| Client 和 Admin 文档的请求、响应、错误、幂等和兼容行为一致 | 通过 |
| 新调用是一次性业务命令,无状态查询、轮询、租约或心跳 | 通过 |
| 请求不含原始 XML、订单、收货信息和凭据,并限制字段、100 条候选和 64 KiB | 通过 |
| 任务、尝试和候选快照唯一定位记录,相同请求可读取同一记录 | 通过 |
| MySQL 8.4 全新建库、v25 升级和重复迁移通过,自检后才记录 v26 | 通过 |
| 可表达规则、AI、复用、不确定、拒绝和失败,置信度保留 NULL | 通过 |
| 不更新 PDD 主数据、任务状态和原四个 Client API | 通过 |
| Go 1.23.0 build、test、vet 和格式检查 | 通过 |
## 测试
- 执行的命令:
- `gofmt -l .`
- `$env:GOTOOLCHAIN='go1.23.0'; go build ./...`
- `$env:GOTOOLCHAIN='go1.23.0'; go test ./... -count=1`
- `$env:GOTOOLCHAIN='go1.23.0'; go vet ./...`
- 配置指向本机临时隔离的 MySQL 8.4 `_test` 库后:
`go test ./repository -run 'TestMySQLMigrate_(真实MySQL8|V25升级V26且规格解析审计幂等)$' -count=1 -v`
- 结果:
- Go 1.23.0 格式、构建、全量测试和 vet 全部通过。
- MySQL Community Server 8.4.8 实际通过全新建库、v25→v26、重复迁移和 Repository
幂等/约束集成测试;测试使用临时 `_test` 库,未连接或修改生产库。
- **没验证到的部分**:无。HTTP Handler、AI 调用和 Client 真机行为属于 #255~#258,
不在本工单范围。
## 相关提交
- `1241465` 定义运行时规格解析契约与审计模型