Files
cmroubao/docs/tasks/T-245.md
T

6.6 KiB
Raw Blame History

id, title, phase, deps, status, created, context_ref, work_branch, write_paths
id title phase deps status created context_ref work_branch write_paths
T-245 创建采购需求时采用 ERP 商品图 2
T-243
T-244
DONE 2026-07-29 9195019 null
docs/tasks/T-245.md
docs/current-state.md
backend-api/migrations/00017_procurement_reference_sources.sql
backend-api/internal/domain/**
backend-api/internal/usecase/**
backend-api/internal/repository/sqlite/**
backend-api/internal/transport/httpapi/**
backend-api/internal/transport/webui/**
backend-api/cmd/api/**

需求 / 背景

货运详情已经展示并缓存 ERP 商品图片,但采购人员确认“仍需采购”后,采购需求固定进入 NEEDS_IMAGE,还要重新选择并上传同一张图片。ERP 图片与当前货运商品直接关联,通常是 图片搜索最准确、操作成本最低的默认参考图。

现有货运缓存图和采购参考资产属于不同生命周期:freight_item_images 会随重新同步、图片 变化或货运删除而替换/清理;采购任务则通过 assets / TASK_REFERENCE 保存不可变参考图。 因此不能让采购任务直接共享货运图片的 storage_key。

修订契约

  • ADMIN 显式确认创建采购需求时,若当前商品资料完整且对应缓存图为 READY,系统自动将 本地缓存 JPEG 复制并重新校验为独立 TASK_REFERENCE asset,需求直接进入 READY。
  • 自动采用图片只读取 CMROUBAO_ASSET_DIR 中已验证的本地缓存,不在创建需求请求中访问 ERP,也不依赖 ERP 会话、OCR 或网络。
  • ERP 图片不存在、MISSING 或 FAILED 时正常创建 NEEDS_IMAGE 需求,继续提供人工上传。
  • 标题、SKU、数量或来源取消造成资料阻塞时保持 BLOCKED,不创建参考资产。
  • 同商品 revision 的重复创建保持幂等;既有 NEEDS_IMAGE 且来源未变化时,如果 ERP 图片 后来变为 READY,重复操作可原子升级为 READY。
  • 自动图片必须在事务提交时仍与当前商品、图片引用、SHA-256 和 storage key 一致;并发 来源变化或图片替换时回滚,复制文件通过补偿清理,不留下 asset 或半绑定需求。
  • 自动采用后的参考图记录来源 ERP_FREIGHT_IMAGE、原图片数字引用和 SHA-256;人工上传 记录 MANUAL_UPLOAD。
  • 采购任务生成前允许人工上传替换参考图。替换自动 ERP 参考图时,事务删除旧自动 asset, 提交后清理其独立文件;任务已生成后继续禁止替换。

方案

  1. v17 增加 procurement_reference_sources,以采购需求 ID 为主键保存来源、ERP 图片引用、 原图片 SHA-256 和绑定时间;现有已绑定参考图回填为 MANUAL_UPLOAD。Down 在存在来源 记录时 fail-closed,避免静默丢失审计。
  2. 为 ProcurementService 增加可选本地参考图 store;生产组合传入现有 asset store, 未配置的纯仓储测试保持原 NEEDS_IMAGE 行为。
  3. 创建需求时先构造来源快照和阻塞状态。非阻塞时读取当前 READY 图片元数据并打开本地 文件,经现有 Put 再次执行完整 JPEG 解码、尺寸/像素、20 MB 和 SHA-256 校验,生成 独立 storage key 与 asset 候选。
  4. SQLite immediate 事务统一校验商品 revision/hash、缓存图引用/hash/key,插入 asset、 采购需求和 ERP 来源记录;对既有 NEEDS_IMAGE 执行相同原子升级。事务未使用复制文件 时,由用例幂等删除。
  5. 人工绑定事务允许 NEEDS_IMAGE -> READY 或替换尚未生成任务的 READY 引用,来源记录 统一改为 MANUAL_UPLOAD。只删除无上传幂等记录的旧 ERP 自动 asset,文件在提交后清理。
  6. Admin API 返回 reference_origin;SSR 显示“已使用 ERP 商品图”或“已上传参考图”, READY 状态同时提供“生成采购任务”和“更换参考图”。
  7. 任务仍只携带现有 image_asset_id,Roubao 领取、下载和图片搜索协议不变。

验收要点

  • 当前商品有 READY ERP 图时,创建需求返回 READY、独立 asset 和 ERP_FREIGHT_IMAGE 来源。
  • 自动 asset 使用不同 storage key;货运缓存图替换不会破坏采购参考图。
  • 无可用 ERP 图时返回 NEEDS_IMAGE,人工上传路径不回归。
  • 资料阻塞时不复制文件、不创建 asset,状态保持 BLOCKED。
  • 重复创建不产生重复需求/asset;既有 NEEDS_IMAGE 可在图片恢复后升级。
  • 商品或图片并发变化时无采购 asset、来源记录或孤立复制文件。
  • READY 需求可人工替换;旧 ERP 自动 asset/文件被清理,任务创建后禁止替换。
  • API/SSR 展示参考图来源,生成的采购任务和 Roubao 图片契约不变化。
  • 已自动绑定参考图的货运单继续受 T-243 删除保护。
  • v17 上下迁移、标准 Go 测试、race、vet 和三个入口构建通过。

边界

  • 不在采购需求创建时请求 ERP,不把 ERP URL 暴露给 Admin 或 Roubao。
  • 不直接共享货运图片 storage key,不引入跨表隐式文件引用。
  • 不自动生成采购任务;采购人员仍需明确点击“生成采购任务”。
  • 不在任务生成后替换参考图,不改写已有任务快照。
  • 不自动为既有 NEEDS_IMAGE 批量回填;由详情操作显式触发升级。
  • 不增加通用 asset 回收站或全局引用计数;人工上传产生的历史未绑定 asset 继续沿用现状。
  • 不记录图片正文、ERP Cookie/Token 或真实订单、商品、店铺和图片 ID。

执行记录

  • 2026-07-29:审计确认当前 CreateRequest 对非阻塞商品固定写入 NEEDS_IMAGE;ERP 缓存图只有 freight_item_images 记录,而采购任务要求 assets 外键。确定采用独立 文件/asset 快照,不共享可变货运 storage key;Roubao 协议无需变化。
  • 2026-07-29:v17 已增加参考图来源记录;生产组合启用本地 ERP 缓存图复制。SQLite 事务复核商品 revision/hash 和图片引用/hash/key 后,原子写 asset、需求及来源;重复 创建可升级既有 NEEDS_IMAGE,未使用或失败的复制文件由用例补偿清理。
  • 2026-07-29:人工绑定已支持任务生成前替换自动参考图,提交后清理旧自动 asset/文件; API 返回 reference_origin,货运详情显示来源并提供“更换参考图”。任务仍使用既有 image_asset_id,未改变 Roubao 协议。
  • 2026-07-29:go test ./...、go test -race ./...、go vet ./... 通过; go build ./cmd/api、go build ./cmd/authctl、go build ./cmd/migrate 通过。 测试仅使用运行时生成图片和脱敏 ID,未访问真实 ERP。