Files
cmautobuy/docs/task/254-运行时规格解析契约与审计模型.md
T
2026-08-17 16:54:27 +08:00

5.2 KiB
Raw Blame History

254 Admin:定义采购运行时规格解析接口与审计模型

  • 类型:需求 / 重构
  • 父级大工单:#96
  • 所属 MVP / 版本:#253 采购运行时 AI 规格纠偏闭环
  • 状态:已完成,待用户验收
  • 日期:2026-08-17
  • Gitea 工单:#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 定义运行时规格解析契约与审计模型