feat(t222): add freight ingestion admin flow

This commit is contained in:
QiuSW
2026-07-28 23:26:34 +08:00
parent c524e734fb
commit 6d052b0462
37 changed files with 3397 additions and 101 deletions
+1 -1
View File
@@ -21,7 +21,7 @@
| 数据访问 | 标准库 `database/sql` | MVP 已定 | 领域层通过仓储接口访问,避免先引入 ORM 和代码生成复杂度。 |
| 数据迁移 | Goose v3.26.0,使用嵌入式 SQL migration | 已验证 | v3.26.0 是已核实仍声明 Go 1.23.0 的最高版本;v3.27.x 要求 Go 1.25。 |
| 管理 Web | Gin + `html/template` + `embed` + 少量原生 JS/CSS | MVP 已定 | 不单独引入 SPA 工程,模板和静态资源随服务构建。 |
| ERP Connector | Python 3.10+、requests 2.31+;可选 FastAPI/uvicorn 内部服务 | T-220 至 T-224 | 复用已验证顺运宝协议客户端;只监听 loopback、服务密钥鉴权,ERP 凭证不进入 Go 后端。 |
| ERP Connector | Python 3.10+、requests 2.31+;可选 FastAPI/uvicorn 内部服务 | T-220 至 T-222 已实现,T-224 扩展 | 复用已验证顺运宝协议客户端;只监听 loopback、服务密钥鉴权,ERP 凭证不进入 Go 后端。 |
| 数据库 | SQLite | MVP 已定 | 单服务、单设备验证足够;多实例或并发提升前迁移 PostgreSQL。 |
| 图片/截图 | 后端受控本地文件目录 + `golang.org/x/image` v0.28.0 | 已验证 | JPEG/PNG/WebP 真解码后白底缩放并编码为 JPEG;数据库只存元数据和随机相对键。 |
| 管理鉴权 | bcrypt + 8 小时 opaque 服务端会话 Cookie | T-204 已验证 | `authctl` 预置 ADMIN;数据库只存密码 hash 与 session SHA-256,完整 RBAC 为 V2。 |
+17 -4
View File
@@ -234,13 +234,26 @@ T-224 增加:
### `GET /api/v1/freight-orders`
支持 `q`、`sync_status`、`created_from/to`、`limit/cursor`。`q` 匹配受控来源单号、
店铺或内部 UUID,不匹配电话/地址。稳定排序为 `source_created_at DESC, id DESC`。
T-222 首版返回当前 ADMIN creator 最近更新的货运单并支持 `limit`(1..100)。
T-224 增加 `q`、`sync_status`、`created_from/to` 和 `cursor`;`q` 只匹配受控来源
单号、店铺或内部 UUID,不匹配电话/地址。响应不包含收件人字段或 Connector 原文。
### `GET /api/v1/freight-orders/{id}`
返回货运头、全部商品明细、revision/hash 状态、采购需求和已生成 task 引用。不存在和
跨 creator 统一 404;响应 `Cache-Control: no-store`。
T-222 返回货运头、全部当前商品明细和 revision/hash 状态。T-223 再增加采购需求和
已生成 task 引用。不存在和跨 creator 统一 404;响应 `Cache-Control: no-store`。
T-222 精确单号同步需要 Go 后端配置:
- `CMROUBAO_ERP_CONNECTOR_URL`:默认 `http://127.0.0.1:8091`,只接受 HTTP
loopback origin。
- `CMROUBAO_ERP_CONNECTOR_API_KEY`:与 Connector 的
`SHUNYUNBAO_SERVICE_API_KEY` 相同,至少 32 UTF-8 字节;未设置时后端可启动,
但同步任务稳定失败为 `ERP_CONNECTOR_NOT_CONFIGURED`。
Connector 未登录、找不到货运单、响应协议错误和暂时不可用分别落为
`ERP_SESSION_REQUIRED`、`ERP_FREIGHT_NOT_FOUND`、`ERP_RESPONSE_INVALID` 和
`ERP_CONNECTOR_UNAVAILABLE`,不返回 ERP 原始错误 body。
### `POST /api/v1/freight-items/{item_id}/procurement-request`
+12 -8
View File
@@ -5,7 +5,7 @@
## 当前快照
- 日期:2026-07-28
- 阶段:T-221 已完成,T-222 货运信息存储 API 与 Admin 页面已领取
- 阶段:T-222 已完成,T-223 待采购需求提取与任务生成已领取
- Git:当前分支为 `main`;T-001 至 T-004、T-101 至 T-104、T-201 至 T-219
均按文档提交、实现提交的顺序纳入历史
- 生产代码:`android-buyer/` 已接入 Roubao Android 源码
@@ -14,19 +14,23 @@
- 后端:Go 1.23.0 + Gin 1.11.0 + SQLite + Goose 3.26.0;已实现图片/任务业务、
SSR 管理 Web、ADMIN/BUYER 联合认证、设备 readiness、原子 claim、租约状态机、
task-scoped 参考图和 `authctl`
- ERP 货运:Go 后端通过仅限 loopback、服务密钥鉴权的 Python Connector 异步按
完整单号同步;v12 保存同步记录、货运头和全部明细,canonical hash 控制 revision,
Admin 已有 `/freight`、`/freight/import`、`/freight/{id}` 与对应 JSON API。
- 本机 Android 工具:JDK 17.0.13、Command-line Tools 22.0、SDK 34、
Build Tools 34.0.0、Platform Tools/ADB 37.0.0;用户级 SDK 环境变量已设置
- Android Studio:未安装;`winget` 静默安装卡住后已终止,不阻塞命令行构建
- 测试:T-219 Android Debug/Release 单元测试与构建和根 `init.ps1` 通过;
Debug APK `1.4.16 (21)` 已覆盖安装到 PKG110
- 后端测试:T-219 运行 `go test ./...`、`go test -race ./...`、`go vet ./...`;
唯一 submission 的设备到 Admin HTTP 闭环及三态 SSR 测试通过
- 后端测试:T-222 运行 `go test ./...`、`go test -race ./...`、`go vet ./...`;
覆盖货运 migration 降级保护、严格 Connector 字段白名单、重复导入/revision、
中断恢复、Admin API/SSR 鉴权和 PII 缺失断言
- 原型:4 个管理 Web 页面和 7 个 Android 页面均可离线独立打开;Playwright
以 1440×900、390×844、360×800 验证 36 个页面/视口组合,无页面横向溢出、
脚本错误或外部请求,Android 可见交互控件均不小于 44px
- 管理 Web:真实 Gin/SQLite 流程已完成图片上传、任务创建、列表、详情参考图和
非终态取消;执行中只显示“请求安全停止”,ADMIN 登录/退出和安全返回路径已接入,
同三种视口无横向溢出,可见任务操作控件不小于 44px
货运列表/导入/详情在 1440×900、390×844、360×800 无横向溢出或页头重叠
- 鉴权:bcrypt 密码、8 小时管理 session、1 小时 App access token 和设备 secret
均不明文落库;设备首次绑定原子化,禁用/过期/撤销每次请求重新检查;管理/App
登录各自按来源地址执行内存有界限流,账号和设备支持 `authctl` 启停
@@ -157,8 +161,8 @@
| `docs/tasks/T-219.md` | DONE | Admin 待付款提醒、Roubao 终态和跨端闭环验收 |
| `docs/tasks/T-220.md` | DONE | 顺运宝 ERP 字段契约与凭证安全基线 |
| `docs/tasks/T-221.md` | DONE | 顺运宝精确单号 Connector |
| `docs/tasks/T-222.md` | DOING | 货运信息存储、API 与 Admin 页面 |
| `docs/tasks/T-223.md` | TODO | 待采购需求提取与任务生成 |
| `docs/tasks/T-222.md` | DONE | 货运信息存储、API 与 Admin 页面 |
| `docs/tasks/T-223.md` | DOING | 待采购需求提取与任务生成 |
| `docs/tasks/T-224.md` | TODO | ERP 日期增量同步 |
| `docs/design/` | 已确认 | T-202 原型索引、4 个管理页和 7 个 Android 页面 |
| `deepseek总结.txt` | 已有 | 历史讨论摘要,不是正式需求权威 |
@@ -172,8 +176,8 @@
## 任务摘要
- 已完成:T-001 至 T-004、T-101 至 T-104、T-201 至 T-219。
- 已完成:另含 T-220、T-221 ERP 安全字段契约与精确单号 Connector。
- 进行中:T-222 货运信息存储、API 与 Admin 页面。
- 已完成:另含 T-220 至 T-222 ERP 契约、Connector、货运存储/API/Admin。
- 进行中:T-223 待采购需求提取与任务生成。
- 下一步:完成 T-223 采购需求生成和 T-224 日期增量同步,再进入 T-301 P0 UI
完整交互验收。
+13 -6
View File
@@ -4,7 +4,7 @@ title: 货运信息存储 API 与 Admin 页面
phase: 2
deps:
- T-221
status: DOING
status: DONE
created: 2026-07-28
context_ref: 78dc595
work_branch: null
@@ -51,11 +51,11 @@ write_paths:
## 验收要点
- [ ] migration up/down/up 和降级保护通过。
- [ ] 重复导入不重复货运单/明细,来源变化产生版本/hash 更新和审计时间。
- [ ] 多商品、空详情、重复外部 ID、超限及 connector 失败均有集成测试。
- [ ] Admin API/SSR 鉴权、CSRF、no-store、响应式页面和 PII 缺失断言通过。
- [ ] `go test ./...`、race、vet 和根验证通过。
- [x] migration up/down/up 和有数据时降级保护通过。
- [x] 重复导入不重复货运单/明细,来源变化产生版本/hash 更新和审计时间。
- [x] 多商品、重复外部 ID、超限、协议字段和 connector 失败路径有自动化测试。
- [x] Admin API/SSR 鉴权、CSRF、no-store、响应式页面和 PII 缺失断言通过。
- [x] `go test ./...`、race、vet 和根验证通过。
## 边界
@@ -66,3 +66,10 @@ write_paths:
## 执行记录
- 2026-07-28:任务合约已冻结;T-221 完成后领取。
- 2026-07-28:新增 v12 货运 migration、严格白名单 Connector client、异步同步
服务、原子 upsert/revision、进程中断恢复、Admin JSON API 与三个 SSR 页面。
- 2026-07-28:Connector 未配置时不阻断后端启动;同步任务以稳定错误码失败。未在
本任务使用真实 ERP 凭证或执行线上查询。
- 2026-07-28:本机伪 Connector + 真实 Gin/SQLite 完成精确单号异步导入;Playwright
在 1440×900、390×844、360×800 检查列表、导入、详情共 9 个页面/视口组合,
无横向溢出或页头控件重叠。伪响应仅用于界面和链路验收。