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

Open
opened 2026-08-17 16:30:18 +08:00 by ila · 3 comments
Owner

基本信息

  • 类型:需求 / 重构
  • 父级大工单:#96
  • 所属 MVP / 版本:#253 采购运行时 AI 规格纠偏闭环
  • 阶段:1. 接口契约与审计数据模型

要解决什么

当前 Client–Admin 契约只有登记、领取、提交结果和提交失败四类调用,Client 在采购规格面板找不到任务尺码时只能结束任务。要在同一次、尚未进入不可逆阶段的采购中取得 Admin 规格决策,必须新增一个语义明确的运行时解析命令,并先确定版本、幂等、最小数据、审计和隐私边界。

现有提交失败接口会改变任务状态,不能同时承载“返回决策并继续执行”;也不能让 Client 周期性查询 Admin 状态。

做什么 / 不做什么

  • 做:
    • 定义 POST /api/v1/client/tasks/{task_id}/spec-resolution 的版本化请求、响应和稳定错误代码。
    • 使用 Idempotency-Key,业务身份包含 task_id + attempt_id + candidate_snapshot_hash;相同键同内容返回同一决策,相同���不同内容返回冲突。
    • 请求只包含任务版本、执行尝试、PDD 商品 ID、原任务动态规格、已选颜色、目标尺码、当前颜色下的可购买尺码候选、候选快照哈希和观测时间。
    • 响应只返回 matched / uncertain / rejected / failed、解析记录 ID、来源、候选编号、原始候选规格、置信度、候选哈希和可读原因。
    • 新增一张运行时规格解析记录表,保存候选观察与最终决策;候选和结果使用 JSON,金额仍为整数分,时间为 UTC ISO 8601。
    • 同步更新 Client 侧契约、Admin 接口实现文档和数据模型文档;Client 契约仍是事实来源。
    • 明确该调用是一次性业务命令,不是任务状态查询、心跳或轮询。
  • 不做:
    • 本工单不实现公斤/斤规则、AI 调用、真机候选采集或继续点击规格。
    • 不复用失败提交接口,不修改任务状态,不创建采购任务。
    • 不保存原始无障碍 XML、订单号、收货信息、Cookie、Token 或 API Key。
    • 不把候选观察覆盖到 pdd_products.skus_json。

怎么做

  1. 在 docs/client/04-admin-api-contract.md 定义完整 HTTP 契约、幂等规则、错误格式、兼容策略和安全边界;同步更新 docs/admin/04-client-api.md。
  2. 为协议定义明确的 schema 版本。候选由 Client 提供稳定短编号和原始文字,Admin 必须重新编号或严格验证;响应不得包含模型生成的新规格。
  3. 增加 MySQL 下一未占用 migration 和 schema 自检,建立 purchase_spec_resolutions(名称实施时可保持同等清晰语义)及唯一约束;一个记录同时保存观察、决策和审计,避免拆分无必要的多表。
  4. Repository 只提供按业务身份新增、读取、完成决策及幂等复查的参数化方法,不在 SQL 层做匹配逻辑。
  5. 文档明确旧 Client 不调用新接口,继续按当前“规格不匹配即失败”行为安全运行;Admin 原四个接口保持兼容。

预计修改文件:

  • docs/client/04-admin-api-contract.md
  • docs/client/03-data-model.md
  • docs/admin/04-client-api.md
  • docs/admin/03-data-model.md
  • admin/model/model.go
  • admin/repository/mysql_db.go 及相邻 migration / repository 测试
  • 完成后归档 docs/task/<工单号>-运行时规格解析契约与审计模型.md

验收标准

  • Client 和 Admin 文档对请求、响应、错误、幂等和兼容行为描述一致。
  • 新调用明确为一次性解析命令,未增加状态查询、轮询、租约或心跳。
  • 请求不含原始 XML、订单号、收货信息和凭据,字段长度、候选数量和 JSON 大小均有限制。
  • 同一任务、尝试和候选快照可唯一定位解析记录;重复请求可返回同一记录。
  • MySQL 首建、上一版本升级和重复启动均通过,schema 版本只在自检完成后记录。
  • 解析记录能表示规则、AI、复用、不确定、拒绝和失败结果,并保留置信度可空语义。
  • 不更新 pdd_products.skus_json,不改变采购任务状态和原四个 Client 接口。
  • Go 1.23.0 build、test、vet 通过。

怎么验证

从 admin/ 执行:

$env:GOTOOLCHAIN='go1.23.0'
gofmt -l .
go build ./...
go test ./... -count=1
go vet ./...
Remove-Item Env:GOTOOLCHAIN

使用独立 MySQL 8.4 _test 库验证首次迁移、上一版本升级、重复迁移、唯一键和候选 JSON 边界;逐项对照两侧契约字段。

风险和回退

  • 风险:第五个调用被误用为状态轮询。契约和路由只允许一次性提交候选并返回持久化决策,不提供 GET 状态接口。
  • 风险:候选或业务信息泄露。严格限制字段,禁止原始 XML 和个人数据,日志只记录解析 ID、数量和结果。
  • 风险:迁移中断。DDL 必须可重放并通过 schema 自检后才记录版本。
  • 回退:停用新路由并回退调用代码;新增审���表保留,不删除历史记录,不影响原四接口。
## 基本信息 - 类型:需求 / 重构 - 父级大工单:#96 - 所属 MVP / 版本:#253 采购运行时 AI 规格纠偏闭环 - 阶段:1. 接口契约与审计数据模型 ## 要解决什么 当前 Client–Admin 契约只有登记、领取、提交结果和提交失败四类调用,Client 在采购规格面板找不到任务尺码时只能结束任务。要在同一次、尚未进入不可逆阶段的采购中取得 Admin 规格决策,必须新增一个语义明确的运行时解析命令,并先确定版本、幂等、最小数据、审计和隐私边界。 现有提交失败接口会改变任务状态,不能同时承载“返回决策并继续执行”;也不能让 Client 周期性查询 Admin 状态。 ## 做什么 / 不做什么 - 做: - 定义 `POST /api/v1/client/tasks/{task_id}/spec-resolution` 的版本化请求、响应和稳定错误代码。 - 使用 `Idempotency-Key`,业务身份包含 `task_id + attempt_id + candidate_snapshot_hash`;相同键同内容返回同一决策,相同���不同内容返回冲突。 - 请求只包含任务版本、执行尝试、PDD 商品 ID、原任务动态规格、已选颜色、目标尺码、当前颜色下的可购买尺码候选、候选快照哈希和观测时间。 - 响应只返回 `matched / uncertain / rejected / failed`、解析记录 ID、来源、候选编号、原始候选规格、置信度、候选哈希和可读原因。 - 新增一张运行时规格解析记录表,保存候选观察与最终决策;候选和结果使用 JSON,金额仍为整数分,时间为 UTC ISO 8601。 - 同步更新 Client 侧契约、Admin 接口实现文档和数据模型文档;Client 契约仍是事实来源。 - 明确该调用是一次性业务命令,不是任务状态查询、心跳或轮询。 - 不做: - 本工单不实现公斤/斤规则、AI 调用、真机候选采集或继续点击规格。 - 不复用失败提交接口,不修改任务状态,不创建采购任务。 - 不保存原始无障碍 XML、订单号、收货信息、Cookie、Token 或 API Key。 - 不把候选观察覆盖到 `pdd_products.skus_json`。 ## 怎么做 1. 在 `docs/client/04-admin-api-contract.md` 定义完整 HTTP 契约、幂等规则、错误格式、兼容策略和安全边界;同步更新 `docs/admin/04-client-api.md`。 2. 为协议定义明确的 schema 版本。候选由 Client 提供稳定短编号和原始文字,Admin 必须重新编号或严格验证;响应不得包含模型生成的新规格。 3. 增加 MySQL 下一未占用 migration 和 schema 自检,建立 `purchase_spec_resolutions`(名称实施时可保持同等清晰语义)及唯一约束;一个记录同时保存观察、决策和审计,避免拆分无必要的多表。 4. Repository 只提供按业务身份新增、读取、完成决策及幂等复查的参数化方法,不在 SQL 层做匹配逻辑。 5. 文档明确旧 Client 不调用新接口,继续按当前“规格不匹配即失败”行为安全运行;Admin 原四个接口保持兼容。 预计修改文件: - `docs/client/04-admin-api-contract.md` - `docs/client/03-data-model.md` - `docs/admin/04-client-api.md` - `docs/admin/03-data-model.md` - `admin/model/model.go` - `admin/repository/mysql_db.go` 及相邻 migration / repository 测试 - 完成后归档 `docs/task/<工单号>-运行时规格解析契约与审计模型.md` ## 验收标准 - [ ] Client 和 Admin 文档对请求、响应、错误、幂等和兼容行为描述一致。 - [ ] 新调用明确为一次性解析命令,未增加状态查询、轮询、租约或心跳。 - [ ] 请求不含原始 XML、订单号、收货信息和凭据,字段长度、候选数量和 JSON 大小均有限制。 - [ ] 同一任务、尝试和候选快照可唯一定位解析记录;重复请求可返回同一记录。 - [ ] MySQL 首建、上一版本升级和重复启动均通过,schema 版本只在自检完成后记录。 - [ ] 解析记录能表示规则、AI、复用、不确定、拒绝和失败结果,并保留置信度可空语义。 - [ ] 不更新 `pdd_products.skus_json`,不改变采购任务状态和原四个 Client 接口。 - [ ] Go 1.23.0 build、test、vet 通过。 ## 怎么验证 从 `admin/` 执行: ```powershell $env:GOTOOLCHAIN='go1.23.0' gofmt -l . go build ./... go test ./... -count=1 go vet ./... Remove-Item Env:GOTOOLCHAIN ``` 使用独立 MySQL 8.4 `_test` 库验证首次迁移、上一版本升级、重复迁移、唯一键和候选 JSON 边界;逐项对照两侧契约字段。 ## 风险和回退 - 风险:第五个调用被误用为状态轮询。契约和路由只允许一次性提交候选并返回持久化决策,不提供 GET 状态接口。 - 风险:候选或业务信息泄露。严格限制字段,禁止原始 XML 和个人数据,日志只记录解析 ID、数量和结果。 - 风险:迁移中断。DDL 必须可重放并通过 schema 自检后才记录版本。 - 回退:停用新路由并回退调用代码;新增审���表保留,不删除历史记录,不影响原四接口。
Author
Owner

开始实施。已确认范围仅包含:冻结 POST /api/v1/client/tasks/{task_id}/spec-resolution 契约、增加 MySQL v26 审计表与模型/Repository、同步 Admin/Client 数据模型和接口文档、补充迁移/Repository 验证。不会在本工单实现路由 Handler、AI 匹配逻辑、Client 真机候选采集或采购续跑;也不会改动现有 Client 本地未提交文件。

开始实施。已确认范围仅包含:冻结 `POST /api/v1/client/tasks/{task_id}/spec-resolution` 契约、增加 MySQL v26 审计表与模型/Repository、同步 Admin/Client 数据模型和接口文档、补充迁移/Repository 验证。不会在本工单实现路由 Handler、AI 匹配逻辑、Client 真机候选采集或采购续跑;也不会改动现有 Client 本地未提交文件。
Author
Owner

实施进度:已完成 MySQL v26 purchase_spec_resolutions、Admin 模型与 Repository(新增、按编号/业务身份读取、幂等复查、只完成一次),并同步 Client/Admin 接口契约和数据模型。接口固定为一次性 POST /api/v1/client/tasks/{task_id}/spec-resolution,无 GET、轮询、租约或心跳;候选最大 100 条、请求最大 64 KiB,响应只能复用请求候选。验证已通过:Go 1.23.0 gofmt、go build ./...、go test ./... -count=1、go vet ./...;另在本机临时隔离 MySQL 8.4 实例实际通过全新建库、v25→v26、重复迁移、唯一键/幂等复查、决策只完成一次和候选数量约束测试。未连接或修改生产库。

实施进度:已完成 MySQL v26 `purchase_spec_resolutions`、Admin 模型与 Repository(新增、按编号/业务身份读取、幂等复查、只完成一次),并同步 Client/Admin 接口契约和数据模型。接口固定为一次性 `POST /api/v1/client/tasks/{task_id}/spec-resolution`,无 GET、轮询、租约或心跳;候选最大 100 条、请求最大 64 KiB,响应只能复用请求候选。验证已通过:Go 1.23.0 `gofmt`、`go build ./...`、`go test ./... -count=1`、`go vet ./...`;另在本机临时隔离 MySQL 8.4 实例实际通过全新建库、v25→v26、重复迁移、唯一键/幂等复查、决策只完成一次和候选数量约束测试。未连接或修改生产库。
Author
Owner

完成记录(待用户验收)

已按工单范围完成:

  • 冻结第五个一次性规格解析接口契约、稳定错误、确定性哈希、幂等和旧 Client 兼容行为;
  • 新增 MySQL v26 purchase_spec_resolutions,一张表保存候选观察与最终决策;
  • 新增模型及 Repository 的新增、读取、幂等复查和只完成一次;
  • 同步 Client/Admin 四份接口与数据模型文档;
  • 未实现 #255 的 Handler/AI 服务、#256/#257 的 Client 流程,也未修改任务状态或 PDD 主数据。

验证结果:Go 1.23.0 gofmt、go build ./...、go test ./... -count=1、go vet ./... 全部通过;本机临时隔离 MySQL 8.4.8 实际通过全新建库、v25→v26、重复迁移、唯一键/冲突、决策只完成一次和候选上限测试。未连接或修改生产库。

提交:

  • 1241465 feat: 定义运行时规格解析契约与审计模型 (#254)
  • f187bfe docs: 归档任务 #254

归档:docs/task/254-运行时规格解析契约与审计模型.md

当前状态:已完成,待用户验收;工单暂不关闭。

## 完成记录(待用户验收) 已按工单范围完成: - 冻结第五个一次性规格解析接口契约、稳定错误、确定性哈希、幂等和旧 Client 兼容行为; - 新增 MySQL v26 `purchase_spec_resolutions`,一张表保存候选观察与最终决策; - 新增模型及 Repository 的新增、读取、幂等复查和只完成一次; - 同步 Client/Admin 四份接口与数据模型文档; - 未实现 #255 的 Handler/AI 服务、#256/#257 的 Client 流程,也未修改任务状态或 PDD 主数据。 验证结果:Go 1.23.0 `gofmt`、`go build ./...`、`go test ./... -count=1`、`go vet ./...` 全部通过;本机临时隔离 MySQL 8.4.8 实际通过全新建库、v25→v26、重复迁移、唯一键/冲突、决策只完成一次和候选上限测试。未连接或修改生产库。 提交: - `1241465` `feat: 定义运行时规格解析契约与审计模型 (#254)` - `f187bfe` `docs: 归档任务 #254` 归档:`docs/task/254-运行时规格解析契约与审计模型.md` 当前状态:已完成,待用户验收;工单暂不关闭。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmautobuy#254