From 50bd31583c3251df4e1e8add3cfdb4a25c448bce Mon Sep 17 00:00:00 2001 From: ila Date: Fri, 7 Aug 2026 16:36:40 +0800 Subject: [PATCH] docs: import wiki at afc651f75a3a --- T-227.-.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 T-227.-.md diff --git a/T-227.-.md b/T-227.-.md new file mode 100644 index 0000000..7ef4855 --- /dev/null +++ b/T-227.-.md @@ -0,0 +1,84 @@ + +> 同步来源:[`docs/tasks/T-227.md`](/chengma/mroubao/src/commit/afc651f75a3abc2676bb13aa8a80f6aa6a25a72e/docs/tasks/T-227.md) · commit `afc651f75a3a` + +--- +id: T-227 +title: Go 直连顺运宝查询接入货运同步 +phase: 2 +deps: + - T-226 +status: DONE +created: 2026-07-29 +context_ref: d62a4af +work_branch: null +write_paths: + - docs/tasks/T-227.md + - docs/04-architecture.md + - docs/api.md + - docs/current-state.md + - backend-api/cmd/api/** + - backend-api/internal/platform/shunyunbao/** + - backend-api/internal/usecase/** + - backend-api/internal/transport/httpapi/** + - backend-api/internal/transport/webui/** + - backend-api/internal/config/** +--- + +## 问题 / 背景 + +T-226 能在 Go 后端建立受控 ERP 会话,但货运同步仍通过 Python Connector。需要将 +`FreightSource` 的运行时实现替换为 Go 直连客户端,同时完整保留 T-222 至 T-224 的 +异步同步、幂等、日期窗口、水位、revision 与采购需求语义。 + +## 关联需求与交互 + +- 功能:F-011、F-012。 +- 用户故事:US-011、US-012。 +- 交互:IX-012、IX-013;现有“按完整单号”“按创建日期”“同步至现在”入口不变。 +- 架构:`FreightService` 后台同步继续只依赖 `FreightSource`,Go 顺运宝实现直接调用 + 外部 HTTPS,不经 loopback HTTP 或共享服务密钥。 + +## 方案 + +1. 将 Go 顺运宝 source 注入 API 进程;查询前验证会话,按完整单号或 Asia/Shanghai + 日期范围执行有界分页和详情批量读取。 +2. 保留既有同步记录和异步执行:浏览器只创建同步 run,后台工作执行外部请求,进程 + 中断后的 RUNNING run 仍按现有规则恢复为稳定失败。 +3. 复用 T-225 allowlist 归一化;响应不完整、超限、重复外部身份冲突或会话失效均整批 + 失败,不保存半批数据、不推进水位。 +4. 单 ERP 账号同步使用有界串行执行,避免登录/验证码与查询竞争;不增加无界 goroutine + 或系统级队列。 +5. 真实验证只在人员已配置凭证并完成验证码登录后按单号执行一次;测试和开发使用 + `httptest` 伪 ERP。 + +## 验收要点 + +- [x] 完整单号、日期范围、重叠水位、分页去重、详情多商品、失败不推进水位均有 Go 集成测试。 +- [x] Admin 输入单号后创建异步 run,并由 Go source 直接得到相同规范化货运/明细结果。 +- [x] 缺会话显示 `ERP_SESSION_REQUIRED`;运行时不再出现 Connector URL/API Key 相关错误。 +- [x] 真实受控单号 smoke 可选且不记录订单内容;未具备凭证,明确未运行。 +- [x] `go test ./...`、`go test -race ./...`、`go vet ./...` 通过。 + +## 边界 + +- 不改变商品采购状态判定、参考图上传和采购任务生成。 +- 不将 ERP 原始图片引用解释为可访问 URL。 +- 不删除 Python Connector;切换清理属于 T-228。 + +## 执行记录 + +- 2026-07-29:由 T-226 依赖创建,等待 Admin 会话能力完成。 +- 2026-07-29:开始实施;T-226 已由 `a5a61c0` 完成。货运同步保留既有异步 run、 + 日期水位和 SQLite 幂等语义,仅将运行时 `FreightSource` 切换为 Go 直连实现。 +- 2026-07-29:`SessionManager` 现实现 `FreightSource`;每次查询先以同一 Cookie jar + 校验 `/am/user/get`,再按 `listTotal -> list -> listByStock?hist=0` 执行。查询上限为 + 100 条、分页为 20 条、详情批量为 100 个 ID;重复的完全相同外部身份去重,缺失详情、 + 冲突身份、超限和协议异常均整批失败。 +- 2026-07-29:API 进程已直接注入 Go source,不再构造 `erpconnector.Client`。同步失败码 + 调整为 `ERP_NOT_CONFIGURED`、`ERP_SESSION_REQUIRED`、`ERP_FREIGHT_NOT_FOUND`、 + `ERP_RESPONSE_INVALID`、`ERP_UNAVAILABLE`;旧 Connector 代码和配置仅留待 T-228 删除。 +- 验证:在 `backend-api/` 执行 `$env:GOTOOLCHAIN='local'; go test ./...; go test -race ./...;` + `go vet ./...; go build ./cmd/api; go build ./cmd/migrate; go build ./cmd/authctl`,全部通过。 + `httptest` 覆盖同 Cookie jar、完整单号、多商品详情、日期分页去重、allowlist、未配置/ + 未登录和稳定错误码;既有 Go 集成测试继续覆盖日期切窗、重叠水位与失败不推进水位。 +- 未运行:没有读取或使用真实 ERP 凭证,因此未执行真实受控单号 smoke;未记录订单内容。