冻结 SYB 同步店铺白名单快照并保留审计证据 #212

Open
opened 2026-09-04 09:56:50 +08:00 by ila · 1 comment
Owner

来源与目标

2026-09-04 用户要求修复 SYB 同步中“Admin 当前已启用,但历史成功同步将该店铺货运单统计为 skipped”的不可追溯问题。已核验:店铺“樂齡樂活美學館|銀髮居家熟齡悅己壯世代優雅生活”当前启用且名称与 #257 的 SYB 统计逐字符一致;#257 将其 15 张货运单记为 accepted=0、skipped=15,且当次店铺哈希与当前白名单不同。

根因与方案

当前导入处理器在创建同步记录时读取一次启用店铺并只存哈希;后台 SyncWithProgress 开始时又重新读一次启用店铺。完整名称快照未持久化,历史上无法确定执行时的白名单,且两次读取之间存在状态漂移窗口。

改为:

  1. 创建同步任务时读取并冻结“规范化名称 -> 展示名称”的完整白名单快照及哈希;
  2. 后台同步接收该快照,不再重新查询 syb_shop;
  3. 使用现有 syb_sync_run.shop_breakdown_json 的版本化 JSON 信封同时保存统计与快照,避免数据库迁移;兼容既有仅含统计的 JSON;
  4. 同步详情 API 返回只读快照店铺名称与快照可用标志,便于审计;不显示凭据、Token、原始响应或个人数据;
  5. 更新长期业务规则与 Agent/API 契约(如契约字段变化)。

范围与非目标

  • 影响 server/ 的 SYB 同步编排、同步记录 DTO/测试及相关 Wiki。
  • 不修改既有 syb_shop 数据,不重新同步,不补写 SYB 商品。
  • 不修改 SYB 登录、OCR、采购、订单或支付。
  • 不做数据库迁移;旧同步记录的快照明确标注不可用。

设计证据与验收

这是现有同步审计数据的后端缺陷修复,无新页面或导航;以 SYBSyncRun、SyncReport 和既有同步详情 API 为设计证据。

  • 同步创建后即使店铺启停/改名,后台实际筛选仍使用创建时冻结的同一快照。
  • 新记录能返回冻结快照与哈希;旧 JSON 记录仍可正常读取且标注无快照。
  • 统计 accepted/skipped 行为不回归;无原始 SYB 响应或敏感数据落库。
  • 服务端单测、受影响 API 契约测试、严格文档检查通过。

风险、依赖与文档

风险是 JSON 历史兼容;采用版本化信封与回退解析控制。无外部依赖、不可并行范围。长期文档影响:Business-Rules-and-Glossary,以及如 DTO 增字段则 Android-Agent-API-Contract(仅在确有共享契约影响时更新)。

## 来源与目标 2026-09-04 用户要求修复 SYB 同步中“Admin 当前已启用,但历史成功同步将该店铺货运单统计为 skipped”的不可追溯问题。已核验:店铺“樂齡樂活美學館|銀髮居家熟齡悅己壯世代優雅生活”当前启用且名称与 #257 的 SYB 统计逐字符一致;#257 将其 15 张货运单记为 accepted=0、skipped=15,且当次店铺哈希与当前白名单不同。 ## 根因与方案 当前导入处理器在创建同步记录时读取一次启用店铺并只存哈希;后台 `SyncWithProgress` 开始时又重新读一次启用店铺。完整名称快照未持久化,历史上无法确定执行时的白名单,且两次读取之间存在状态漂移窗口。 改为: 1. 创建同步任务时读取并冻结“规范化名称 -> 展示名称”的完整白名单快照及哈希; 2. 后台同步接收该快照,不再重新查询 `syb_shop`; 3. 使用现有 `syb_sync_run.shop_breakdown_json` 的版本化 JSON 信封同时保存统计与快照,避免数据库迁移;兼容既有仅含统计的 JSON; 4. 同步详情 API 返回只读快照店铺名称与快照可用标志,便于审计;不显示凭据、Token、原始响应或个人数据; 5. 更新长期业务规则与 Agent/API 契约(如契约字段变化)。 ## 范围与非目标 - 影响 `server/` 的 SYB 同步编排、同步记录 DTO/测试及相关 Wiki。 - 不修改既有 `syb_shop` 数据,不重新同步,不补写 SYB 商品。 - 不修改 SYB 登录、OCR、采购、订单或支付。 - 不做数据库迁移;旧同步记录的快照明确标注不可用。 ## 设计证据与验收 这是现有同步审计数据的后端缺陷修复,无新页面或导航;以 `SYBSyncRun`、`SyncReport` 和既有同步详情 API 为设计证据。 - 同步创建后即使店铺启停/改名,后台实际筛选仍使用创建时冻结的同一快照。 - 新记录能返回冻结快照与哈希;旧 JSON 记录仍可正常读取且标注无快照。 - 统计 accepted/skipped 行为不回归;无原始 SYB 响应或敏感数据落库。 - 服务端单测、受影响 API 契约测试、严格文档检查通过。 ## 风险、依赖与文档 风险是 JSON 历史兼容;采用版本化信封与回退解析控制。无外部依赖、不可并行范围。长期文档影响:Business-Rules-and-Glossary,以及如 DTO 增字段则 Android-Agent-API-Contract(仅在确有共享契约影响时更新)。
Author
Owner

已完成并推送,待验收。

实现:

  • StartImport 在创建同步记录时冻结启用店铺规范化映射,并将同一快照传给后台执行;后台同步不再重新读取 syb_shop。
  • 使用既有 shop_breakdown_json 存储版本化信封:保留分店铺 accepted/skipped 统计,并保存冻结时的展示名称快照。无需数据库迁移。
  • 同步详情 DTO 新增 shopFilterSnapshot 与 shopFilterSnapshotPresent;旧记录的裸统计 JSON 继续解析,并明确返回“无快照”。
  • 新增用例覆盖:后台店铺状态变化后仍按冻结快照筛选;新旧同步记录的快照/统计兼容。

提交与分支:8c76e09 fix(syb): 冻结同步店铺快照 (#212),fix/212-syb-sync-shop-snapshot。
验证:go test ./app/goauto/sybimport ./app/goauto/sybshop 通过;harness.py check --strict、git diff --check 通过。全量 go test ./app/goauto/... 仅在无关 apprelease 的当前 APK 版本断言失败(当前 APK 0.9.39 与该测试预期不一致),未修改该模块。
文档:线上 Business-Rules-and-Glossary 已更新并在线回读,revision 21c38a21b979c52c68edbb82b9efb73112e6d735。harness.py sync 因既有无关改动 docs/12-syb-erp-interface.md 被保护性阻止,未覆盖;sync --check 已执行。

未执行 SYB 补同步、未写入 SYB 商品、未改店铺状态。

已完成并推送,待验收。 实现: - `StartImport` 在创建同步记录时冻结启用店铺规范化映射,并将同一快照传给后台执行;后台同步不再重新读取 `syb_shop`。 - 使用既有 `shop_breakdown_json` 存储版本化信封:保留分店铺 accepted/skipped 统计,并保存冻结时的展示名称快照。无需数据库迁移。 - 同步详情 DTO 新增 `shopFilterSnapshot` 与 `shopFilterSnapshotPresent`;旧记录的裸统计 JSON 继续解析,并明确返回“无快照”。 - 新增用例覆盖:后台店铺状态变化后仍按冻结快照筛选;新旧同步记录的快照/统计兼容。 提交与分支:8c76e09 fix(syb): 冻结同步店铺快照 (#212),`fix/212-syb-sync-shop-snapshot`。 验证:`go test ./app/goauto/sybimport ./app/goauto/sybshop` 通过;`harness.py check --strict`、`git diff --check` 通过。全量 `go test ./app/goauto/...` 仅在无关 `apprelease` 的当前 APK 版本断言失败(当前 APK 0.9.39 与该测试预期不一致),未修改该模块。 文档:线上 Business-Rules-and-Glossary 已更新并在线回读,revision `21c38a21b979c52c68edbb82b9efb73112e6d735`。`harness.py sync` 因既有无关改动 `docs/12-syb-erp-interface.md` 被保护性阻止,未覆盖;`sync --check` 已执行。 未执行 SYB 补同步、未写入 SYB 商品、未改店铺状态。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#212