feat(t242): delete unused freight orders

This commit is contained in:
QiuSW
2026-07-29 16:10:45 +08:00
parent c80a5c26ed
commit e5f403ff7d
20 changed files with 915 additions and 27 deletions
+15 -8
View File
@@ -5,7 +5,7 @@
## 当前快照
- 日期:2026-07-29
- 阶段:T-241 已完成 ERP 货运列表与商品详情展示优化
- 阶段:T-242 已完成受约束的本地货运单删除
- Git:当前分支为 `main`;T-001 至 T-004、T-101 至 T-104、T-201 至 T-219
均按文档提交、实现提交的顺序纳入历史
- 生产代码:`android-buyer/` 已接入 Roubao Android 源码
@@ -21,7 +21,9 @@
`FAILED`,日期范围仍后台异步。HTTP `WriteTimeout` 为 70 秒。T-238 已兼容真实详情
`created` 的分钟精度,仍按 Asia/Shanghai 严格解析并转 UTC。T-239 至 T-241 已保存
`productSpec`、TWD 原始单价和数字图片引用,以有界并发缓存归一化 JPEG,并在鉴权
本地路由、货运列表和详情中显示图片、状态与采购字段。
本地路由、货运列表和详情中显示图片、状态与采购字段。T-242 允许 ADMIN 从详情页删除
尚未进入采购流程的本地货运快照及缓存图;已有采购引用时原子拒绝,不修改 ERP、同步
运行历史或增量水位,完整订单号可重新导入。
- ERP Go 迁移:T-225 已用脱敏 fixture 固定 `internal/platform/shunyunbao` 的 header、
单号/日期查询、分页、详情批量和字段 allowlist,并使货运用例依赖来源中立错误。T-226
已增加受锁保护的 Go 内存 Cookie jar、验证码 ticket、登录和用户校验,以及 ADMIN 的
@@ -43,7 +45,7 @@
- Android Studio:未安装;`winget` 静默安装卡住后已终止,不阻塞命令行构建
- 测试:T-219 Android Debug/Release 单元测试与构建和根 `init.ps1` 通过;
Debug APK `1.4.16 (21)` 已覆盖安装到 PKG110
- 后端测试:T-226 至 T-241 已运行 `go test ./...`、`go test -race ./...`、`go vet ./...`
- 后端测试:T-226 至 T-242 已运行 `go test ./...`、`go test -race ./...`、`go vet ./...`
和三个 Go 入口构建;T-227 增加 Go source 的伪 ERP 会话预检、完整单号、日期分页去重、
详情 allowlist 和稳定错误码覆盖;根 `init.ps1` 的 Android 测试/Debug APK 与 Go 标准
验证也通过,均未访问真实 ERP;
@@ -59,6 +61,9 @@
总项数;详情展示 84px/移动端 72px 本地图片、单一规格 SKU、数量、TWD 原始单价、
图片状态和采购操作。Playwright 已在 1440、768、390、375 四档宽度验证无横向溢出、
破图、遮挡和控制台错误。
- 货运本地删除:详情页二次确认后调用 CSRF 保护的 SSR POST,JSON API 提供幂等 DELETE;
删除事务覆盖全部历史商品并阻止任何采购引用,提交后以有界预算清理缓存 JPEG。真实
隔离服务已验证成功后列表为空、图片 404 和文件消失;顺运宝 ERP 未被调用。
- 鉴权:bcrypt 密码、8 小时管理 session、1 小时 App access token 和设备 secret
均不明文落库;设备首次绑定原子化,禁用/过期/撤销每次请求重新检查;管理/App
登录各自按来源地址执行内存有界限流,账号和设备支持 `authctl` 启停
@@ -210,6 +215,7 @@
| `docs/tasks/T-239.md` | DONE | 冻结货运规格 SKU、TWD 原始单价和图片引用契约 |
| `docs/tasks/T-240.md` | DONE | 后端受控缓存并鉴权提供货运商品图片 |
| `docs/tasks/T-241.md` | DONE | 优化货运列表代表图与商品采购信息展示 |
| `docs/tasks/T-242.md` | DONE | 受约束删除本地货运快照并保护采购审计 |
| `docs/design/` | 已确认 | T-202 原型索引、4 个管理页和 7 个 Android 页面 |
| `deepseek总结.txt` | 已有 | 历史讨论摘要,不是正式需求权威 |
| `android-buyer/` | 已有 | Roubao `main` 固定 commit 的 Android 基线 |
@@ -221,13 +227,14 @@
## 任务摘要
- 已完成:T-001 至 T-004、T-101 至 T-104、T-201 至 T-219。
- 已完成:另含 T-220 至 T-241 ERP 契约、货运存储、采购需求生成、日期增量同步、Go
- 已完成:另含 T-220 至 T-242 ERP 契约、货运存储、采购需求生成、日期增量同步、Go
直连协议、OCR 会话预检、稳定预检错误、安全诊断日志、直连 `FreightSource`、旧 Connector
清理、受控本地凭证加载、同步单号导入、分钟时间兼容、货运商品元数据契约、本地图片缓存
和货运管理展示优化。
清理、受控本地凭证加载、同步单号导入、分钟时间兼容、货运商品元数据契约、本地图片缓存、
货运管理展示优化和受约束本地删除。
- 进行中:无。
- 下一步:用真实 ERP 账号受控导入一个测试货运单,复核真实图片响应、缓存状态、规格、
TWD 原始单价和重新导入幂等性;不把真实数据或诊断响应提交到仓库。
- 下一步:用真实 ERP 账号受控导入一个测试货运单,复核真实图片、规格、TWD 原始单价,
再验证无采购关联删除和完整单号重新导入;不删除真实 ERP 数据,不把真实数据或诊断
响应提交到仓库。
## 当前可运行内容
+24 -12
View File
@@ -4,7 +4,7 @@ title: 增加受约束的本地货运单删除
phase: 2
deps:
- T-241
status: TODO
status: DONE
created: 2026-07-29
context_ref: 7e3aaac
work_branch: null
@@ -41,7 +41,8 @@ Admin 可以导入、查看和生成采购需求,但误导入或不再需要
3. 无采购关联时先收集 READY 图片 `storage_key`,再删除全部商品明细和货运单;图片数据库
记录依赖现有 `ON DELETE CASCADE`。保留 `erp_sync_runs` 和增量水位作为同步审计。
4. 文件删除在数据库提交后以独立短超时执行。失败文件不再有数据库记录或鉴权读取路径,
不把文件系统失败伪装成数据库回滚;记录不含真实订单内容的受控诊断事件。
不把文件系统失败伪装成数据库回滚,也不记录 storage key 或真实订单内容;Web 成功事件
只记录内部订单 UUID 和操作人 UUID。
5. Admin API 增加 `DELETE /api/v1/freight-orders/:id`:首次或重复删除均返回 `204`,
其他 ADMIN 作用域中的 ID 也按不存在处理;已有采购关联返回 `409` 和稳定错误码
`FREIGHT_ORDER_IN_USE`。
@@ -52,16 +53,16 @@ Admin 可以导入、查看和生成采购需求,但误导入或不再需要
## 验收要点
- [ ] 未创建采购需求的货运单可删除,订单、商品和图片数据库记录均不存在。
- [ ] 所有缓存图片文件在提交后删除;文件已不存在时仍视为成功。
- [ ] 任一商品有关联采购需求时整单返回冲突,订单、全部商品、图片和采购记录均不变化。
- [ ] 删除不改变同步运行历史、同步水位或顺运宝 ERP 数据。
- [ ] 重复 API 删除为幂等 `204`;无权访问的 ID 不泄漏存在性。
- [ ] Web 删除必须通过 ADMIN session、CSRF 和确认交互,成功/冲突反馈明确。
- [ ] 删除后使用相同完整订单号重新导入可创建新的本地货运快照。
- [ ] 既有货运导入、图片读取、采购需求和采购任务流程不回归。
- [ ] 1440×900、390×844 和 375×667 下详情操作区无重叠、溢出或误触风险。
- [ ] 标准 Go 测试、race、vet 和三个入口构建通过。
- [x] 未创建采购需求的货运单可删除,订单、商品和图片数据库记录均不存在。
- [x] 所有缓存图片文件在提交后删除;文件已不存在时仍视为成功。
- [x] 任一商品有关联采购需求时整单返回冲突,订单、全部商品、图片和采购记录均不变化。
- [x] 删除不改变同步运行历史、同步水位或顺运宝 ERP 数据。
- [x] 重复 API 删除为幂等 `204`;无权访问的 ID 不泄漏存在性。
- [x] Web 删除必须通过 ADMIN session、CSRF 和确认交互,成功/冲突反馈明确。
- [x] 删除后使用相同完整订单号重新导入可创建新的本地货运快照。
- [x] 既有货运导入、图片读取、采购需求和采购任务流程不回归。
- [x] 1440×900、390×844 和 375×667 下详情操作区无重叠、溢出或误触风险。
- [x] 标准 Go 测试、race、vet 和三个入口构建通过。
## 边界
@@ -75,3 +76,14 @@ Admin 可以导入、查看和生成采购需求,但误导入或不再需要
- 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 消失,控制台无警告或错误。