Files
junhong_cmp_fiber/openspec/changes/archive/2026-03-28-fix-code-quality-cleanup/design.md
huang f339fb1987
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m8s
fix: 资产钱包自动创建机制 — 修复C端购买时钱包不存在报错
- client_order: 新增 getOrCreateWallet 兜底,钱包不存在时自动创建
- device_import: 设备导入事务内同步创建设备钱包
- iot_card_import: IoT卡批量导入后批量创建卡钱包
- queue/handler: 传递 AssetWalletStore 给两个导入 handler
- migration 000098: 为存量IoT卡和设备补建资产钱包
2026-03-30 11:37:41 +08:00

3.7 KiB
Raw Blame History

Context

修正业务方案 v5 审查后,确认 5 处代码质量问题仍存在。这些问题分散在不同模块互不依赖可以并行修复。每个修复点改动面小1-3 个文件),无需 DB 迁移,无需新增依赖。

当前代码现状:

  • internal/task/sim.go:废弃的 SIM 状态同步任务,消费者核心是 time.Sleep,生产者全局无调用
  • internal/service/asset/service.go:至少 2 处 cards, _ := 吞掉错误
  • internal/handler/admin/order.go钱包支付未校验用户类型Service 层有校验但 Handler 层没有
  • internal/bootstrap/services.goSetStopResumeCallback / SetResumeCallback 未被调用
  • internal/service/client_order/service.goorderStatusToClientStatus() 做了不必要的枚举映射

Goals / Non-Goals

Goals:

  • 清除已确认的废弃代码F-2
  • 修复错误吞没提升可观测性F-3
  • 统一 Handler/Service 权限校验F-5
  • 激活停复机回调链路F-6
  • 统一 C端/管理端支付状态枚举J-4
  • 所有修改通过 go build ./...

Non-Goals:

  • 不做任何业务逻辑变更
  • 不新增自动化测试(遵循项目测试禁令)
  • 不触碰已正常工作的代码路径
  • 不做 DB 迁移

Decisions

1. F-2 废弃代码删除顺序

决策:按依赖倒序删除——先删注册行,再删常量,最后删文件。

原因:如果先删文件,go build 会在注册行报错。倒序删除确保每步都能编译通过。

删除清单:

  1. pkg/queue/handler.go — 删除 HandleSIMStatusSync 注册行和相关 import
  2. pkg/constants/constants.go — 删除 TaskTypeSIMStatusSync 常量
  3. internal/task/sim.go — 删除整个文件
  4. internal/service/sync/service.go — 检查是否存在,存在则删除

2. F-3 错误处理策略

决策:记录 Warn 日志但不中断主流程。

原因:这些查询是补充信息(获取绑定卡详情),失败不应阻断资产查询主链路。但吞掉错误会导致排查困难,日志记录是最小侵入的改进。

// 修改前
cards, _ := s.iotCardStore.GetByIDs(ctx, cardIDs)

// 修改后
cards, err := s.iotCardStore.GetByIDs(ctx, cardIDs)
if err != nil {
    s.logger.Warn("查询绑定卡信息失败,结果可能不完整",
        zap.Uints("card_ids", cardIDs),
        zap.Error(err))
}

3. F-5 Handler 层权限校验位置

决策:在 Handler 的 BodyParser 之后、调用 Service 之前添加校验。

原因:保持 Handler 层"参数验证 + 权限前置"的职责边界,与项目其他 Handler 一致。

4. F-6 回调注入时机

决策:在 bootstrap/services.go 所有 Service 初始化完成后,统一执行回调注入。

原因:回调注入需要 usageServicestopResumeServiceactivationService 都已创建。放在初始化最后一步最安全。

5. J-4 枚举统一方向

决策C端直接使用管理端枚举1/2/3/4删除映射函数。

替代方案:管理端改用 C端枚举0/1/2 — 拒绝,因为管理端已有大量数据使用 1/2/3/4改动面更大。

前端影响C端前端需更新状态解析这是 BREAKING CHANGE需通知前端团队。

Risks / Trade-offs

  • [F-2 遗漏引用] 删除代码后可能有隐藏引用 → 通过 go build ./...rg TaskTypeSIMStatusSync 双重验证
  • [J-4 前端不同步] C端前端未及时更新枚举 → 需在发布前通知前端,建议同版本发布
  • [F-6 回调循环依赖] Service 之间互相注入回调可能产生循环 → 当前 SetXxxCallback 是单向注入UsageService → StopResumeService不存在循环