## 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.go`:`SetStopResumeCallback` / `SetResumeCallback` 未被调用 - `internal/service/client_order/service.go`:`orderStatusToClientStatus()` 做了不必要的枚举映射 ## 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 日志但不中断主流程。 **原因**:这些查询是补充信息(获取绑定卡详情),失败不应阻断资产查询主链路。但吞掉错误会导致排查困难,日志记录是最小侵入的改进。 ```go // 修改前 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 初始化完成后,统一执行回调注入。 **原因**:回调注入需要 `usageService`、`stopResumeService`、`activationService` 都已创建。放在初始化最后一步最安全。 ### 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),不存在循环