docs(erp): define freight ingestion tasks
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: T-220
|
||||
title: 顺运宝 ERP 字段契约与凭证安全基线
|
||||
phase: 2
|
||||
deps:
|
||||
- T-219
|
||||
status: DOING
|
||||
created: 2026-07-28
|
||||
context_ref: 78dc595
|
||||
work_branch: null
|
||||
write_paths:
|
||||
- .gitignore
|
||||
- shunyunbaoerp_single.py
|
||||
- docs/integrations/**
|
||||
- docs/tasks/T-220.md
|
||||
- docs/current-state.md
|
||||
---
|
||||
|
||||
## 问题 / 背景
|
||||
|
||||
采购资料将以顺运宝 ERP 货运单为主要来源。现有单文件脚本证明了验证码登录、
|
||||
Cookie 会话、按“全部单号”查询、按 stock id 批量读取详情的协议,但运行入口含
|
||||
明文账号/密码/订单号,并会把完整结果写文件、打印到终端。货运响应包含收件人、
|
||||
电话、地址、金额和商品信息,不能直接进入 Git、普通日志、VLM 或采购任务。
|
||||
|
||||
ERP 详情的 `details[]` 才是商品级来源;一个货运头可能有多个明细。必须先冻结
|
||||
`stock.id -> detail.id -> details[].id` 的身份和字段映射,再开发导入链路。
|
||||
|
||||
## 关联需求与交互
|
||||
|
||||
- 功能:F-011、F-012
|
||||
- 用户故事:US-011、US-012
|
||||
- 交互:IX-012、IX-013
|
||||
- 架构/API:ERP Connector、货运来源数据模型和内部安全边界
|
||||
|
||||
## 方案
|
||||
|
||||
1. 清除单文件脚本中的明文账号、密码和固定订单号,只允许环境变量或交互输入。
|
||||
2. 查询结果默认只写被忽略的 `.local/`,控制台只输出数量和匿名结果文件位置。
|
||||
3. 新增顺运宝集成字段契约,记录已由本地 HAR/脱敏结构确认的端点、查询关系和字段,
|
||||
不复制 HAR、Cookie、JWT、真实订单号或个人信息。
|
||||
4. 定义最小规范化对象:
|
||||
- 货运单身份:`source_system + stock.id`
|
||||
- 商品明细身份:`source_system + stock.id + details[].id`
|
||||
- 待采购字段:标题、原始规格、`sku/variationSku`、正整数数量、`productThumb`
|
||||
引用、采购状态和来源内容 hash
|
||||
5. `productThumb` 当前只确认是 ERP 引用值,不猜测为公开 URL;图片未解析时必须
|
||||
`NEEDS_IMAGE`,禁止生成采购任务。
|
||||
6. 私有 HAR、验证码、查询结果、ERP session 和 connector 环境文件进入忽略规则。
|
||||
|
||||
## 验收要点
|
||||
|
||||
- [ ] Git 跟踪内容不含 ERP 账号、密码、Cookie、JWT、真实单号和货运 PII。
|
||||
- [ ] 单文件脚本无硬编码凭证/订单号,不再向 stdout 输出完整响应。
|
||||
- [ ] 字段契约覆盖一货运头多商品、重复同步、缺详情、缺图片和来源更新。
|
||||
- [ ] 可用静态命令证明脚本可编译,安全扫描和仓库根验证通过;不访问线上 ERP。
|
||||
|
||||
## 边界
|
||||
|
||||
- 不提交本地 HAR 和 `freight_detail.json`。
|
||||
- 不在本任务启动 connector、写数据库或创建采购任务。
|
||||
- 不解释未确认的 ERP 数字状态含义,不自动 OCR 绕过验证码。
|
||||
- 不因字段缺失猜测标题、SKU、数量或图片。
|
||||
|
||||
## 执行记录
|
||||
|
||||
- 2026-07-28:在 T-219 `78dc595` 后领取。静态读取本机单文件和独立 ERP 参考工程;
|
||||
只提取协议结构和字段名,没有执行登录、线上查询或写操作。
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
id: T-221
|
||||
title: 顺运宝精确单号 Connector
|
||||
phase: 2
|
||||
deps:
|
||||
- T-220
|
||||
status: TODO
|
||||
created: 2026-07-28
|
||||
context_ref: 78dc595
|
||||
work_branch: null
|
||||
write_paths:
|
||||
- erp-connector/**
|
||||
- scripts/start-erp-connector.bat
|
||||
- docs/integrations/**
|
||||
- docs/tasks/T-221.md
|
||||
- docs/current-state.md
|
||||
---
|
||||
|
||||
## 问题 / 背景
|
||||
|
||||
Go 后端不应在 Gin 请求里启动 Python,也不应保存 ERP 密码、Cookie 或 JWT。需要把
|
||||
已验证的 Python 客户端收敛为仅监听 loopback、带服务密钥的内部 Connector。首版只
|
||||
支持完整单号,先验证稳定读取和规范化,不提前做定时同步。
|
||||
|
||||
## 关联需求与交互
|
||||
|
||||
- 功能:F-011
|
||||
- 用户故事:US-011
|
||||
- 交互:IX-012
|
||||
- 架构/API:ERP Connector 内部 API
|
||||
|
||||
## 方案
|
||||
|
||||
1. 采用 Python 3.10+、requests 和可选 FastAPI/uvicorn,复用本机已验证客户端结构;
|
||||
不复制 HAR、真实响应或凭证。
|
||||
2. Connector 默认 `127.0.0.1`,除健康检查外所有接口要求至少 32 字节服务密钥并
|
||||
常量时间比较;ERP 密码仅从进程环境读取。
|
||||
3. 保留人工/受控验证码登录,不承诺无人值守 OCR。读取型列表/详情请求才允许有界
|
||||
重试;登录不自动重放。
|
||||
4. `POST /v1/freight/query` 接受完整单号,查询 listTotal/list 和 listByStock,
|
||||
按 stock id 去重并保留所有 `details[]`。
|
||||
5. 响应经过规范化和 PII 最小化,只返回后续货运模块所需字段;错误不包含服务端
|
||||
body、Cookie、JWT、账号、收件人、电话或地址。
|
||||
|
||||
## 验收要点
|
||||
|
||||
- [ ] 伪 ERP 响应覆盖验证码约束、登录、分页、重试、安全上限、多货运头和多商品。
|
||||
- [ ] 精确单号响应具有稳定 schema,商品不被 dict 覆盖或错误关联。
|
||||
- [ ] API Key 缺失/错误、未登录、未找到、ERP 超时和协议异常返回稳定状态。
|
||||
- [ ] `pytest`/编译和无网络单测通过;启动脚本不包含秘密。
|
||||
|
||||
## 边界
|
||||
|
||||
- 不支持日期区间查询,属于 T-224。
|
||||
- 不把 Connector 暴露到局域网,不提供 ERP 密码 Web 表单。
|
||||
- 不持久化货运数据,不调用 Go 采购任务接口。
|
||||
|
||||
## 执行记录
|
||||
|
||||
- 2026-07-28:任务合约已冻结,等待 T-220。
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: T-222
|
||||
title: 货运信息存储 API 与 Admin 页面
|
||||
phase: 2
|
||||
deps:
|
||||
- T-221
|
||||
status: TODO
|
||||
created: 2026-07-28
|
||||
context_ref: 78dc595
|
||||
work_branch: null
|
||||
write_paths:
|
||||
- backend-api/cmd/**
|
||||
- backend-api/internal/config/**
|
||||
- backend-api/internal/domain/**
|
||||
- backend-api/internal/usecase/**
|
||||
- backend-api/internal/repository/sqlite/**
|
||||
- backend-api/internal/transport/httpapi/**
|
||||
- backend-api/internal/transport/webui/**
|
||||
- backend-api/migrations/**
|
||||
- docs/api.md
|
||||
- docs/routes.md
|
||||
- docs/tasks/T-222.md
|
||||
- docs/current-state.md
|
||||
---
|
||||
|
||||
## 问题 / 背景
|
||||
|
||||
现有 `purchase_tasks.source_ref` 只能防止任务重复创建,无法表示 ERP 同步、货运头、
|
||||
多商品明细、来源版本和待处理异常。需要独立货运数据层,Admin 先查看来源事实,再
|
||||
进入采购需求生成。
|
||||
|
||||
## 关联需求与交互
|
||||
|
||||
- 功能:F-011
|
||||
- 用户故事:US-011
|
||||
- 交互:IX-012
|
||||
- 架构/API:`erp_sync_runs`、`freight_orders`、`freight_order_items`
|
||||
|
||||
## 方案
|
||||
|
||||
1. 新增 migration,按 creator scope 保存同步记录、货运单和商品明细。
|
||||
2. 唯一键分别为 `(creator, source_system, external_stock_id)` 和
|
||||
`(freight_order_id, external_item_id)`;重复响应按 canonical hash 幂等 upsert。
|
||||
3. 只保存采购和审计必要字段;不保存收件人姓名、电话、详细地址、Cookie/JWT 或
|
||||
未裁剪原始响应。
|
||||
4. Admin 创建“按单号导入”同步记录,由后台有界调用 loopback Connector;请求返回
|
||||
job id,不把验证码/ERP 延迟绑定到浏览器长请求。
|
||||
5. 新增 `/freight` 列表、`/freight/import` 和 `/freight/{id}` 详情;页面展示来源
|
||||
单号、店铺、ERP 时间、状态、明细数量、同步状态和可修复异常。
|
||||
6. 进程重启时遗留 RUNNING job 转稳定失败;失败不写半批货运数据。
|
||||
|
||||
## 验收要点
|
||||
|
||||
- [ ] migration up/down/up 和降级保护通过。
|
||||
- [ ] 重复导入不重复货运单/明细,来源变化产生版本/hash 更新和审计时间。
|
||||
- [ ] 多商品、空详情、重复外部 ID、超限及 connector 失败均有集成测试。
|
||||
- [ ] Admin API/SSR 鉴权、CSRF、no-store、响应式页面和 PII 缺失断言通过。
|
||||
- [ ] `go test ./...`、race、vet 和根验证通过。
|
||||
|
||||
## 边界
|
||||
|
||||
- 不在本任务生成采购任务。
|
||||
- 不自动下载 `productThumb`,只保存非秘密 ERP 引用。
|
||||
- 不按 ERP 数字状态自动判断“应采购”,状态枚举确认属于 T-223。
|
||||
|
||||
## 执行记录
|
||||
|
||||
- 2026-07-28:任务合约已冻结,等待 T-221。
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: T-223
|
||||
title: 待采购需求提取与任务生成
|
||||
phase: 2
|
||||
deps:
|
||||
- T-222
|
||||
status: TODO
|
||||
created: 2026-07-28
|
||||
context_ref: 78dc595
|
||||
work_branch: null
|
||||
write_paths:
|
||||
- backend-api/internal/domain/**
|
||||
- backend-api/internal/usecase/**
|
||||
- backend-api/internal/repository/sqlite/**
|
||||
- backend-api/internal/transport/httpapi/**
|
||||
- backend-api/internal/transport/webui/**
|
||||
- backend-api/migrations/**
|
||||
- docs/api.md
|
||||
- docs/routes.md
|
||||
- docs/tasks/T-223.md
|
||||
- docs/current-state.md
|
||||
---
|
||||
|
||||
## 问题 / 背景
|
||||
|
||||
货运明细是外部可变事实,采购任务是执行时不可变快照。两者之间需要可复核的采购
|
||||
需求层,避免 ERP 重同步直接修改运行任务,也避免缺图、含糊 SKU 或错误数量进入
|
||||
Roubao 队列。
|
||||
|
||||
## 关联需求与交互
|
||||
|
||||
- 功能:F-012
|
||||
- 用户故事:US-012
|
||||
- 交互:IX-013
|
||||
- 架构/API:`procurement_requests`、`purchase_task_sources`
|
||||
|
||||
## 方案
|
||||
|
||||
1. 每个货运商品明细按来源 revision 生成一条 procurement request,不合并多 SKU。
|
||||
2. 确定性提取标题、规格/SKU 和正整数数量;优先保留原始 `productSpec`、
|
||||
`sku/variationSku`,不调用 VLM 改写。
|
||||
3. `productThumb` 仍无法解析时标记 `NEEDS_IMAGE`;Admin 使用现有受控图片上传并
|
||||
绑定参考图后才能进入 `READY`。
|
||||
4. Admin 在详情核对标题、SKU、数量和图片后显式生成 `purchase_task`。使用
|
||||
procurement request id + revision 作为幂等来源,重复点击返回同一任务。
|
||||
5. 来源更新不修改已有任务:未生成时追加新 revision;已生成后显示
|
||||
`SOURCE_CHANGED` 并要求人员决定是否取消旧任务和生成新版本。
|
||||
6. 被取消、已采购或状态语义未确认的 ERP 明细默认不可生成,允许的状态值必须来自
|
||||
脱敏样本/人工配置,不根据数字猜测。
|
||||
|
||||
## 验收要点
|
||||
|
||||
- [ ] 一货运单多商品形成多条独立采购需求。
|
||||
- [ ] 缺标题/SKU/数量/图片和来源状态不明时不能生成任务。
|
||||
- [ ] 同一 revision 并发/重试只生成一个采购任务。
|
||||
- [ ] 来源变化不覆写 PENDING/CLAIMED/RUNNING/终态任务。
|
||||
- [ ] 生成任务可被现有 Roubao claim,原始字段和参考图 hash 一致。
|
||||
|
||||
## 边界
|
||||
|
||||
- 不让 VLM 推断或修改 ERP SKU/数量。
|
||||
- 不自动决定取消旧采购任务。
|
||||
- 不抓取未经确认的第三方图片 URL。
|
||||
|
||||
## 执行记录
|
||||
|
||||
- 2026-07-28:任务合约已冻结,等待 T-222。
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: T-224
|
||||
title: ERP 日期增量同步
|
||||
phase: 2
|
||||
deps:
|
||||
- T-223
|
||||
status: TODO
|
||||
created: 2026-07-28
|
||||
context_ref: 78dc595
|
||||
work_branch: null
|
||||
write_paths:
|
||||
- erp-connector/**
|
||||
- backend-api/internal/domain/**
|
||||
- backend-api/internal/usecase/**
|
||||
- backend-api/internal/repository/sqlite/**
|
||||
- backend-api/internal/transport/httpapi/**
|
||||
- backend-api/internal/transport/webui/**
|
||||
- backend-api/migrations/**
|
||||
- docs/api.md
|
||||
- docs/routes.md
|
||||
- docs/tasks/T-224.md
|
||||
- docs/current-state.md
|
||||
---
|
||||
|
||||
## 问题 / 背景
|
||||
|
||||
精确单号适合第一版人工导入,但日常运营需要按时间发现新货运单。已验证 HAR 使用
|
||||
`t_stock.created` 日期区间条件;增量同步必须处理分页过程中数据变化、重复窗口、
|
||||
失败重试和服务端时区,不能简单保存“最后一页”。
|
||||
|
||||
## 关联需求与交互
|
||||
|
||||
- 功能:F-011、F-012
|
||||
- 用户故事:US-011、US-012
|
||||
- 交互:IX-012、IX-013
|
||||
- 架构/API:日期查询、sync watermark 和重叠窗口
|
||||
|
||||
## 方案
|
||||
|
||||
1. Connector 增加日期区间请求,严格使用已验证字段:
|
||||
`colName=created, op=0, type=3, optType=0`,日期使用 Asia/Shanghai。
|
||||
2. 单次窗口最大 7 天,分页/总数均设上限,按 stock id 去重后批量取详情。
|
||||
3. 后端保存 last successful watermark;每次从成功水位前回看 10 分钟/至少同一自然日,
|
||||
依靠外部 ID + hash 去重更新。
|
||||
4. 只有整批事务成功才推进水位;认证、网络、协议、超限或明细缺失时保留旧水位并
|
||||
显示可重试错误。
|
||||
5. Admin 提供手动日期范围和“同步至现在”,不在本任务引入系统级计划任务;定时器
|
||||
后置到运行稳定后。
|
||||
|
||||
## 验收要点
|
||||
|
||||
- [ ] 日期 query 与脱敏 HAR 合约一致,时区和闭区间规则有测试。
|
||||
- [ ] 重叠窗口、重复页、来源更新、空窗口和中途失败不丢单/不重复。
|
||||
- [ ] 失败不推进 watermark,成功重放得到相同货运与采购需求集合。
|
||||
- [ ] Admin 可查看范围、状态、计数和匿名错误,不显示 PII/秘密。
|
||||
- [ ] Python、Go 全量测试、race/vet、根验证和响应式 SSR 验收通过。
|
||||
|
||||
## 边界
|
||||
|
||||
- 不做无人值守验证码 OCR、cron、消息队列或多 ERP 租户。
|
||||
- 不承诺逆向页面接口 SLA;正式生产前仍需确认 ERP 开放 API 和数据使用权限。
|
||||
- 不因时间同步自动领取或执行 Roubao 任务。
|
||||
|
||||
## 执行记录
|
||||
|
||||
- 2026-07-28:任务合约已冻结,等待 T-223。
|
||||
Reference in New Issue
Block a user