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

94 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-243
title: 允许货运删除清理未完成采购需求草稿
phase: 2
deps:
- T-242
status: DONE
created: 2026-07-29
context_ref: e5f403f
work_branch: null
write_paths:
- docs/tasks/T-243.md
- docs/current-state.md
- backend-api/internal/usecase/**
- backend-api/internal/repository/sqlite/freight_*
- backend-api/internal/transport/httpapi/**
- backend-api/internal/transport/webui/**
---
## Bug / 背景
T-242 把任意 `procurement_requests` 记录都视为“已进入采购流程”。采购人员点击“创建采购
需求”后,系统会先生成 `NEEDS_IMAGE` 需求,但只有上传参考图并显式生成后才会出现
`purchase_tasks`。因此无参考图、无任务的需求既不会显示在采购任务列表,又会阻止货运删除,
用户无法从界面完成清理。
这不是采购任务列表漏查:任务列表应继续只展示真实 `purchase_tasks`。Bug 是删除保护边界把
采购准备草稿和不可丢失的参考图/采购任务混为一谈,且冲突提示没有说明实际阻止原因。
## 修订契约
- `reference_asset_id IS NULL` 且 `purchase_task_id IS NULL` 的采购需求属于可清理草稿。
- 可清理草稿只允许处于 `BLOCKED`、`NEEDS_IMAGE` 或 `SOURCE_CHANGED`;删除货运单时在同一
事务内一并删除。
- 任一需求已绑定参考图但尚未生成任务时,整单禁止删除并返回
`FREIGHT_ORDER_HAS_REFERENCE`。
- 任一需求已生成采购任务时,整单禁止删除并优先返回
`FREIGHT_ORDER_HAS_PURCHASE_TASK`。
- 货运详情把 `NEEDS_IMAGE` 显示为“需要参考图,尚未生成任务”,避免与采购任务列表混淆。
## 方案
1. 用两个来源中立仓储错误替换过宽的 `ErrFreightOrderInUse`,由 usecase 映射为两个稳定
`409` 错误码;若同单同时存在参考图和任务,优先报告采购任务。
2. SQLite immediate transaction 先检查全部历史商品关联:任何非空 `purchase_task_id`
立即回滚;其次任何非空 `reference_asset_id` 立即回滚。
3. 无保护性关联时,删除该订单商品下状态为 `BLOCKED`、`NEEDS_IMAGE`、`SOURCE_CHANGED`
且两个关联 ID 均为空的采购需求,再沿用 T-242 的图片键收集、商品和订单删除。
4. 不依赖状态字符串来放宽保护:无法归类、数据不一致或未来新增状态的需求保持 fail-closed,
由剩余外键阻止删除并映射内部错误。
5. SSR 对两类冲突使用独立提示;确认弹窗明确未绑定参考图的草稿需求会一并删除,已有参考图
或任务时系统拒绝。API 保持相同 DELETE 路由和幂等 204。
6. 仓储、usecase、API 与 Web 测试覆盖草稿删除、参考图保护、任务保护、优先级、事务不变性
和现有无需求删除;真实响应式 smoke 使用脱敏隔离数据,不操作线上 ERP。
## 验收要点
- [x] 仅含 `NEEDS_IMAGE` 且无参考图/任务的货运单可删除,草稿需求、商品和订单同事务消失。
- [x] `BLOCKED` 及无参考图的 `SOURCE_CHANGED` 草稿遵守相同删除规则。
- [x] 已绑定参考图但未生成任务返回 409 `FREIGHT_ORDER_HAS_REFERENCE`,全部记录不变化。
- [x] 已生成采购任务返回 409 `FREIGHT_ORDER_HAS_PURCHASE_TASK`,全部采购链路不变化。
- [x] 同单同时存在两类保护关联时优先报告已生成采购任务。
- [x] 未知或不一致需求不能被静默删除。
- [x] 采购任务列表仍只展示 `purchase_tasks`;货运详情准确说明需求尚未生成任务。
- [x] Web 成功、参考图冲突和任务冲突反馈明确,CSRF、确认和响应式交互不回归。
- [x] 删除不影响 ERP、同步历史、水位和 T-242 图片文件清理。
- [x] 标准 Go 测试、race、vet 和三个入口构建通过。
## 边界
- 不把采购需求加入采购任务列表,不新增第二套采购列表。
- 不删除已绑定参考图、采购任务、执行、候选、授权、下单或支付记录。
- 不增加采购需求单独撤销、批量删除、回收站或归档。
- 不修改顺运宝 ERP,不回退同步水位。
- 不在文档、测试、日志或提交中写入真实订单、商品、店铺或图片。
## 执行记录
- 2026-07-29:根据真实本地状态审计确认,删除冲突来自 `NEEDS_IMAGE` 采购需求,且其
`reference_asset_id`、`purchase_task_id` 均为空;采购任务列表只查 `purchase_tasks`
的行为正确。本任务修复保护边界和反馈,不改变任务列表定义。
- 2026-07-29:SQLite immediate 事务先检查 `purchase_task_id`,再检查
`reference_asset_id`;两者均不存在时只删除 `BLOCKED`、`NEEDS_IMAGE`、
`SOURCE_CHANGED` 草稿,并在删除商品前确认没有其他需求残留。任务冲突优先于参考图
冲突,未来或不一致状态保持 fail-closed;无需 schema migration。
- 2026-07-29:Admin API 保持原 DELETE 路由和幂等 204,保护分支分别返回
`FREIGHT_ORDER_HAS_REFERENCE`、`FREIGHT_ORDER_HAS_PURCHASE_TASK`。SSR 使用独立提示,
详情把 `NEEDS_IMAGE` 显示为“需要参考图,尚未生成任务”,确认文案明确草稿会被清理。
- 2026-07-29:仓储测试覆盖三种草稿状态、参考图保护、任务保护和任务优先级;usecase、
API、SSR 测试覆盖稳定错误映射及实际 `NEEDS_IMAGE` 删除。`go test ./...`、
`go test -race ./...`、`go vet ./...` 和 API、authctl、migrate 三个入口构建通过。
Playwright 连接脱敏隔离 Gin/SQLite,以桌面和 390×844 验证状态说明、确认弹窗、真实
登录及删除后空列表,控制台无警告或错误;未访问顺运宝 ERP。