5.4 KiB
5.4 KiB
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-242 | 增加受约束的本地货运单删除 | 2 |
|
DONE | 2026-07-29 | 7e3aaac |
null |
|
问题 / 背景
Admin 可以导入、查看和生成采购需求,但误导入或不再需要的本地货运信息无法清理。货运商品
可能已经关联采购需求、采购任务和本地缓存图片,直接删除 freight_orders 会被外键阻止,
强制级联又会破坏采购来源审计或留下不可访问的 JPEG。
本功能只管理当前系统保存的 ERP 投影,不调用顺运宝删除接口,也不声称删除 ERP 源数据。
关联需求与交互
- ADMIN 在货运详情页明确确认后删除本系统中的货运单。
- 尚未创建任何采购需求的货运单可以删除;只要任一商品已进入采购流程,整单禁止删除。
- 删除成功后返回货运列表;操作不影响 ERP,可通过完整订单号重新导入。
- JSON 管理 API 提供同一删除能力和稳定的成功、冲突、未找到响应。
方案
- 在
FreightService增加删除命令;校验 ADMIN 作用域和 UUID 后调用仓储事务,并在提交后 通过图片服务清理已收集的本地缓存文件。 - SQLite 使用 immediate 写事务锁定删除过程:按
creator_subject读取订单,检查其全部 当前/历史商品是否被procurement_requests引用;有关联则不改数据并返回稳定冲突。 - 无采购关联时先收集 READY 图片
storage_key,再删除全部商品明细和货运单;图片数据库 记录依赖现有ON DELETE CASCADE。保留erp_sync_runs和增量水位作为同步审计。 - 文件删除在数据库提交后以独立短超时执行。失败文件不再有数据库记录或鉴权读取路径, 不把文件系统失败伪装成数据库回滚,也不记录 storage key 或真实订单内容;Web 成功事件 只记录内部订单 UUID 和操作人 UUID。
- Admin API 增加
DELETE /api/v1/freight-orders/:id:首次或重复删除均返回204, 其他 ADMIN 作用域中的 ID 也按不存在处理;已有采购关联返回409和稳定错误码FREIGHT_ORDER_IN_USE。 - SSR 增加
POST /freight/:id/delete,复用 ADMIN session、CSRF 和安全响应头。删除入口 位于详情页标题操作区,危险样式与“返回列表”分开;提交前确认本地删除边界。 - 成功后
303到/freight?notice=deleted;冲突时仍在详情页显示 “该货运单已进入采购流程,不能删除”。不在密集列表中增加直接删除按钮。
验收要点
- 未创建采购需求的货运单可删除,订单、商品和图片数据库记录均不存在。
- 所有缓存图片文件在提交后删除;文件已不存在时仍视为成功。
- 任一商品有关联采购需求时整单返回冲突,订单、全部商品、图片和采购记录均不变化。
- 删除不改变同步运行历史、同步水位或顺运宝 ERP 数据。
- 重复 API 删除为幂等
204;无权访问的 ID 不泄漏存在性。 - Web 删除必须通过 ADMIN session、CSRF 和确认交互,成功/冲突反馈明确。
- 删除后使用相同完整订单号重新导入可创建新的本地货运快照。
- 既有货运导入、图片读取、采购需求和采购任务流程不回归。
- 1440×900、390×844 和 375×667 下详情操作区无重叠、溢出或误触风险。
- 标准 Go 测试、race、vet 和三个入口构建通过。
边界
- 不删除或修改顺运宝 ERP 数据。
- 不删除同步运行记录,不回退日期增量水位;恢复必须使用完整订单号重新导入。
- 不级联删除采购需求、参考图、采购任务、执行结果或订单提交记录。
- 不提供批量删除、回收站、撤销、归档或自动过期清理。
- 不在页面、日志、fixture 或提交中加入真实货运单、店铺、商品或图片。
执行记录
- 2026-07-29:创建任务。第一版采用详情页单单删除和服务端强约束,以最小界面面积提供 可恢复的本地清理能力;采购审计优先于删除便利性。
- 2026-07-29:仓储使用现有
_txlock=immediate事务按 ADMIN 作用域检查整单采购引用; 成功时收集 READY 图片键、删除全部商品和订单并保留同步运行/水位。跨作用域与重复删除 均为空操作,采购关联映射为FREIGHT_ORDER_IN_USE;同单号新同步可建立全新 revision 1 快照。本任务不需要 schema migration。 - 2026-07-29:图片服务在数据库提交后用 5 秒总预算调用受路径约束且幂等的本地删除;
Admin API
DELETE返回 204/409,SSR POST 强制 CSRF 与confirm_delete=1,详情页使用 二次确认 dialog 和 noscript 复选框回退,成功事件只记录内部 UUID。 - 2026-07-29:
go test ./...、go test -race ./...、go vet ./...和 API、authctl、 migrate 三个入口构建通过。Playwright 连接隔离 Gin/SQLite,在 1440×900、390×844、 375×667 验证弹窗无越界,首次焦点位于保留动作,三个操作按钮均高 44px;实际删除后 跳转空列表、原图片接口返回 404、本地 JPEG 消失,控制台无警告或错误。