Admin:档口入库码安全回写、核验与异常恢复 #234

Open
opened 2026-08-15 08:40:47 +08:00 by ila · 1 comment
Owner

基本信息

  • 类型:需求
  • 父级大工单:#14
  • 所属 MVP / 版本:#224
  • 阶段:安全回写与集成验收

要解决什么

可回写计划仍需在用户明确确认后安全写入顺运宝商品明细的 innerExpCode。远端接口为删除旧值后写新值,网络超时或进程退出时结果可能未知,禁止盲目重试。

做什么 / 不做什么

  • 做:为 syb.Client 增加清除旧 innerExpCode 和写入新值的方法,写请求严格单次发送、不启用自动重试。
  • 做:每行写前重新读取并核验 detail 身份、采购字段和远端原值;必要时删旧值后写入;写后重新读取,只有远端值等于目标值才标记已回写。
  • 做:逐行保存处理中、已回写、已存在、失败、需核对;服务启动时把残留处理中转为需核对;需核对入口只重新读取,不再次写入。
  • 不做:不自动批量重试删除或写入;不自动选择记录;不改变采购/付款逻辑;不在测试中连接真实顺运宝。

怎么做

  • 在 admin/syb/client.go 封装 deleteInnerCode 与 updateDetailCode,对业务失败、HTTP 失败和结果未知使用可区分错误类型。
  • 新增 admin/service/inner_code_apply.go 编排门禁与状态机,repository 使用条件更新实现单行领取,阻止重复提交。
  • Handler 只接收用户已选 ID 并调用 service;页面完成后展示每行结果。启动恢复逻辑只把 applying 改为 needs_check,不触发网络写请求。
  • 回写失败时保留旧值、阶段和原因;日志不输出 Cookie、个人数据或完整远端响应。

验收标准

  • 非可回写、未选中或已被领取的记录不会发送远端写请求。
  • 每行写前重新读取并核验唯一 detail、采购字段为空和当前值;状态变化则停止并给出原因。
  • 旧值为空时不调用删除;旧值非空时删除成功才写新值;删除/写入均只尝试一次。
  • 写后读取一致才标为已回写;超时、断连或无法确认结果标为需核对且不自动重写。
  • 需核对操作仅重新读取;远端已是目标值时收敛为已回写,否则保留需核对并显示当前值。
  • 重启后残留处理中记录自动转需核对;全套 Go 1.23 构建、测试、vet 通过。

怎么验证

在 admin/ 执行 go test ./syb ./service ./handler/web -run InnerCode -count=1,并执行固定 Go 1.23 的 build、test、vet;使用 httptest.Server 覆盖无需删除、删后写、删除失败、写入失败、响应超时、写后不一致、重启恢复和只读重新核对,不连接真实顺运宝。

风险和回退

  • 风险:删旧值成功但写新值失败,远端可能暂时为空;记录进入失败/需核对并保留完整原因,禁止自动重试,由操作员先重新核对。
  • 风险:重复提交造成重复写;使用数据库条件领取和远端写前再读双重门禁。
  • 回退:关闭/移除页面回写路由即可停止新写入;保留表和审计结果,不逆向修改远端。
## 基本信息 - 类型:需求 - 父级大工单:#14 - 所属 MVP / 版本:#224 - 阶段:安全回写与集成验收 ## 要解决什么 可回写计划仍需在用户明确确认后安全写入顺运宝商品明细的 `innerExpCode`。远端接口为删除旧值后写新值,网络超时或进程退出时结果可能未知,禁止盲目重试。 ## 做什么 / 不做什么 - 做:为 `syb.Client` 增加清除旧 `innerExpCode` 和写入新值的方法,写请求严格单次发送、不启用自动重试。 - 做:每行写前重新读取并核验 detail 身份、采购字段和远端原值;必要时删旧值后写入;写后重新读取,只有远端值等于目标值才标记已回写。 - 做:逐行保存处理中、已回写、已存在、失败、需核对;服务启动时把残留处理中转为需核对;需核对入口只重新读取,不再次写入。 - 不做:不自动批量重试删除或写入;不自动选择记录;不改变采购/付款逻辑;不在测试中连接真实顺运宝。 ## 怎么做 - 在 `admin/syb/client.go` 封装 `deleteInnerCode` 与 `updateDetailCode`,对业务失败、HTTP 失败和结果未知使用可区分错误类型。 - 新增 `admin/service/inner_code_apply.go` 编排门禁与状态机,repository 使用条件更新实现单行领取,阻止重复提交。 - Handler 只接收用户已选 ID 并调用 service;页面完成后展示每行结果。启动恢复逻辑只把 `applying` 改为 `needs_check`,不触发网络写请求。 - 回写失败时保留旧值、阶段和原因;日志不输出 Cookie、个人数据或完整远端响应。 ## 验收标准 - [ ] 非可回写、未选中或已被领取的记录不会发送远端写请求。 - [ ] 每行写前重新读取并核验唯一 detail、采购字段为空和当前值;状态变化则停止并给出原因。 - [ ] 旧值为空时不调用删除;旧值非空时删除成功才写新值;删除/写入均只尝试一次。 - [ ] 写后读取一致才标为已回写;超时、断连或无法确认结果标为需核对且不自动重写。 - [ ] 需核对操作仅重新读取;远端已是目标值时收敛为已回写,否则保留需核对并显示当前值。 - [ ] 重启后残留处理中记录自动转需核对;全套 Go 1.23 构建、测试、vet 通过。 ## 怎么验证 在 `admin/` 执行 `go test ./syb ./service ./handler/web -run InnerCode -count=1`,并执行固定 Go 1.23 的 build、test、vet;使用 `httptest.Server` 覆盖无需删除、删后写、删除失败、写入失败、响应超时、写后不一致、重启恢复和只读重新核对,不连接真实顺运宝。 ## 风险和回退 - 风险:删旧值成功但写新值失败,远端可能暂时为空;记录进入失败/需核对并保留完整原因,禁止自动重试,由操作员先重新核对。 - 风险:重复提交造成重复写;使用数据库条件领取和远端写前再读双重门禁。 - 回退:关闭/移除页面回写路由即可停止新写入;保留表和审计结果,不逆向修改远端。
Author
Owner

状态:已实现,待用户验收。
实现提交:2778eed;归档提交:9ca7f83;归档:docs/task/234-档口入库码安全回写.md
验证:假服务端覆盖单次删除/写入、写前核验、写后复读、未知结果禁止重试和启动恢复;固定 Go 1.23.0 build/test/vet 全部通过。未执行真实顺运宝写入。

状态:已实现,待用户验收。 实现提交:2778eed;归档提交:9ca7f83;归档:docs/task/234-档口入库码安全回写.md 验证:假服务端覆盖单次删除/写入、写前核验、写后复读、未知结果禁止重试和启动恢复;固定 Go 1.23.0 build/test/vet 全部通过。未执行真实顺运宝写入。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmautobuy#234