feat: 技术债务清理(支付配置动态化、API文档补全、轮询常量提取、废弃代码清理)
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m13s

This commit is contained in:
2026-04-14 11:11:15 +08:00
parent c0b64c9e30
commit 42c5ec912f
63 changed files with 1979 additions and 775 deletions

View File

@@ -1,12 +1,12 @@
{
"active_plan": "/Users/break/csxjProject/junhong_cmp_fiber/.sisyphus/plans/realname-trigger-priority-enhancement.md",
"started_at": "2026-04-13T06:40:48.711Z",
"active_plan": "/Users/break/csxjProject/junhong_cmp_fiber/.sisyphus/plans/tech-debt-cleanup.md",
"started_at": "2026-04-14T02:13:33.272Z",
"session_ids": [
"ses_27a6dbcacffe7LBhCAdrKJVgDi"
"ses_2763c0ebcffexMb1ee6rY7gHOT"
],
"session_origins": {
"ses_27a6dbcacffe7LBhCAdrKJVgDi": "direct"
"ses_2763c0ebcffexMb1ee6rY7gHOT": "start-work"
},
"plan_name": "realname-trigger-priority-enhancement",
"plan_name": "tech-debt-cleanup",
"agent": "atlas"
}
}

View File

@@ -0,0 +1,15 @@
# tech-debt-cleanup 决策记录
## [2026-04-14] 初始化
### 任务执行顺序策略
1. **优先执行独立任务(并行)**Task 2 (API docs)、Task 3 (polling constants)、Task 4 (deprecated cleanup)、Task 7 (unused constants)、Task 8 (empty files)
2. **Task 1支付配置**:需要先确认 pkg/payment/ 现有结构
3. **Task 5Model 字段)**代码变更可与其他任务并行DB 迁移执行需 DB 环境
4. **Task 6DTO _name**:分模块逐批,每批独立验证
5. **Task 0DB迁移合并**:需要 DB 环境,最后执行
### 支付配置动态加载架构
- 新建 `pkg/payment/loader.go`,定义 `PaymentConfigLoader` 接口
- Redis 缓存 TTL 1hkey: `payment:config:{configID}`
- 权限检查:仅用户主动操作时校验;支付回调场景验证商户号一致性

View File

@@ -0,0 +1,5 @@
# tech-debt-cleanup 问题记录
## [2026-04-14] 初始化
暂无已知问题。执行过程中发现的问题将记录于此。

View File

@@ -0,0 +1,181 @@
# tech-debt-cleanup 学习记录
## [2026-04-14] 初始化
### 项目规范关键点
- 所有注释必须使用中文
- Redis Key 必须通过函数生成(格式:`Redis{Module}{Purpose}Key(params...)`
- 错误码必须定义在 `pkg/errors/codes.go`
- 常量定义在 `pkg/constants/`
- 架构Handler → Service → Store → Model
- 禁止使用外键约束
- 禁止 Go 测试文件(*_test.go
### 关键文件路径
- 支付服务: `internal/service/order/service.go`, `internal/service/recharge/service.go`
- 轮询服务: `internal/service/polling/manual_trigger_service.go`, `alert_service.go`
- 轮询 Handler: `internal/handler/admin/polling_manual_trigger.go`
- 轮询 Store: `internal/store/postgres/polling_manual_trigger_store.go`
- 文档生成: `cmd/api/docs.go`, `cmd/gendocs/main.go`
- Redis Key: `pkg/constants/redis.go`
- 支付包: `pkg/payment/`
- 废弃 DTO: `internal/model/dto/enterprise_card_authorization_dto.go`
- 废弃任务: `internal/task/sync.go`
- 空文件: `internal/routes/recharge.go`
- Model: `internal/model/iot_card.go`, `internal/model/device.go`
## [2026-04-14] Task 3: 轮询状态常量提取
### 发现和注意点
1. **alert_service.go 的 "pending" 只有 1 处**`NotificationStatus: "pending"``triggerAlert()` 函数中,其他字符串如 `"sent"``"partial"``"failed"` 是通知发送状态(非轮询触发日志状态),不在替换范围内。
2. **Store 层 SQL 字符串处理**`polling_manual_trigger_store.go``GetRunning` 函数原本使用 SQL 字面量 `status IN ('pending', 'processing')`,改为 GORM 参数化查询 `status IN (?, ?)` 并传入常量,既消除硬编码又提升安全性。
3. **Store 层需要新增 import**`polling_manual_trigger_store.go` 原本未导入 `constants` 包,添加时注意 Go import 分组规范stdlib / 第三方 / 内部包)。
4. **constants 包在 handler 文件已存在**`polling_manual_trigger.go` 已导入 `pkg/constants`,无需额外修改 import。
5. **manual_trigger_service.go 共 6 处替换**3 处 `"processing"`triggerLog 创建、2 处 `"completed"`UpdateStatus 调用、1 处同时含 `"pending"` + `"processing"` + `"cancelled"` 的 CancelTrigger 状态检查。
## [2026-04-14] Task 4: 废弃代码清理
### 废弃别名实际引用情况
扫描 `internal/``pkg/` 后,真正使用废弃别名的只有 3 处(其他文件早已用新常量):
- `shop_commission/service.go:645``TransactionTypeWithdrawal` 替换为 `AgentTransactionTypeWithdrawal`
- `recharge/service.go:91,94,417,418``RechargeMinAmount/RechargeMaxAmount` 替换为 `AssetRechargeMinAmount/AssetRechargeMaxAmount`资产钱包充值场景最小1元/最大100000元
### CheckAndStopCard 无法删除
`stop_resume_service.go` 中的 `CheckAndStopCard` 在接口 `StopResumeServiceInterface``usage_service.go:20`)中声明,并在 `package_activation_handler.go`327、347行`usage_service.go`230、255行中活跃调用。任务描述要求"确认无调用后再删除",此方法有调用,故跳过删除。
### grep 验证注意事项
- `SyncHandler` 的 grep 命中了 `CommissionStatsSyncHandler`(合法),不是废弃的 DataSync handler。
- `CardWallet` 出现在 `data_scope.go:82` 的注释字符串里(非代码引用),不需要修改。
### 删除的代码统计
- `sync.go` 整个文件166行
- `handler.go` 3行syncHandler var + HandleFunc + logger.Info
- `constants.go` 1行TaskTypeDataSync
- `wallet.go` 86行149-234行废弃别名块
- `enterprise_card_authorization_dto.go` 22行DeviceBundle、DeviceBundleCard、AllocatedDevice
- `order/service.go` 约243行CreateLegacy 方法)
## [2026-04-14] Task 7+8: 常量清理和空文件删除
### 执行内容
**Task 7.1:删除 CodeExceedLimit 错误码**
- 删除常量定义:`CodeExceedLimit = 1055` (line 68)
- 删除 allErrorCodes 列表条目 (line 227)
- 删除 errorMessages 映射条目 (line 359)
- 验证grep 确认代码库中无任何引用
**Task 7.2:为预留常量添加 [预留] 注释**
- LadderType 系列(激活量、提货量、充值量):添加 `[预留] 用于分佣阶梯功能,待产品规划`
- ApprovalType/ApprovalStatus 系列(审批类型/状态):添加 `[预留] 用于审批流程功能,待产品规划`
- MerchantType 系列(支付宝、微信、银行卡):添加 `[预留] 用于未来商户管理功能,待产品规划`
- ReplacementStatus 系列(换卡申请状态):添加 `[预留] 用于换卡申请功能,待产品规划`
- ReplacementReason 系列(换货原因):添加 `[预留] 用于换卡原因管理功能,待产品规划`
**Task 8.1:删除空文件**
- 删除 `internal/routes/recharge.go`(仅包含 `package routes`
**Task 8.2:删除 postgres.go 的 AutoMigrate 注释块**
- 删除 lines 90-95 的注释掉的 AutoMigrate 代码块
**Task 8.3:更新 client_order/service.go 注释**
- 在 line 140 的实名认证检查注释前添加:`// [待确认] 业务是否需要实名认证检查?参见 tech-debt-cleanup 提案`
### 验证结果
-`go build ./cmd/api ./cmd/worker` 通过
-`go vet ./pkg/errors/ ./pkg/constants/ ./pkg/database/` 无报告
-`grep -r "CodeExceedLimit"` 无结果(完全删除)
- ✅ 所有预留常量已添加 [预留] 标记和产品规划说明
## [2026-04-14] Task 2: API 文档生成器补全
### 发现
- `BuildDocHandlers()` 缺少 3 个 Handler`ClientAuth``AdminAuth``AssetLifecycle`,它们在 `bootstrap/types.go` 中有定义,但从未加入文档生成器
- `AdminAuth``docs.go``gendocs/main.go` 中**完全未被设置**(连手动覆写都没有),这意味着 Admin Auth 相关路由一直缺失于 OpenAPI 文档
- `docs.go``gendocs/main.go` 的手动覆写列表9 行 `handlers.Xxx = ...`)中,大多数 handler 其实已经在 `BuildDocHandlers()` 中了,属于纯冗余
### 操作
1. `pkg/openapi/handlers.go`:按 types.go 字段顺序插入 `ClientAuth`PersonalCustomer 后)、`AdminAuth`ShopRole 后)、`AssetLifecycle`Asset 后)
2. `cmd/api/docs.go`删除所有手动覆写行9 行)+ 移除 `admin``apphandler` import
3. `cmd/gendocs/main.go`:同上
### 注意点
- `admin.NewAuthHandler` 需要 2 个 nil 参数authService + validator
- `app.NewClientAuthHandler` 需要 2 个 nil 参数service + logger
- `admin.NewAssetLifecycleHandler` 只需 1 个 nil 参数service 接口)
- 清理完 import 后 `go build` + `go vet` 均通过,无报错
## [2026-04-14] Task 5: Model 废弃字段清理
### 引用情况(超出预期的额外文件)
计划中列出的文件之外,还发现了额外引用:
- `internal/service/device/service.go` line 576-577`DeviceResponse` 构建中有引用(计划中未提及)
- `internal/service/recharge/service.go` line 31`ForceRechargeRequirement` struct 有 `FirstCommissionPaid` 字段
- `internal/service/recharge/service.go` line 458`result.FirstCommissionPaid = firstCommissionPaid` 赋值
### 关键判断recharge/service.go 的 firstCommissionPaid 变量
`checkForceRechargeRequirement` 中的 `firstCommissionPaid` 变量**不是废弃字段**
- 它读自 `card.IsFirstRechargeTriggeredBySeries(*seriesID)``device.IsFirstRechargeTriggeredBySeries(*seriesID)`(均是新 BySeries 方法)
- 该变量用于 `if firstCommissionPaid {` 的业务判断(已发放则跳过强充检查)
- 正确做法:只删 `ForceRechargeRequirement.FirstCommissionPaid` 字段 + `result.FirstCommissionPaid = firstCommissionPaid` 赋值,保留变量声明和 if 判断
### 迁移文件
- 新建 `migrations/000116_remove_legacy_commission_fields.up.sql`
- 新建 `migrations/000116_remove_legacy_commission_fields.down.sql`
### 验证结果
-`go build ./cmd/api ./cmd/worker` 通过,无任何错误
## [2026-04-14] Task 1: 支付配置动态加载
### 实现架构决策
#### 1. PaymentConfigLoader 位置
- 新建 `pkg/payment/loader.go`(包名 `payment`
- `pkg/` 下可以 import `internal/` 包(项目中已有先例:`pkg/wechat/config.go` import `internal/model`
#### 2. 缓存策略
- 不缓存 Payment 实例(含连接/状态,不可序列化)
- 缓存 **WechatConfig JSON 数据**key: `payment:config:{id}`TTL: 1 小时)
- 每次从缓存数据构建 Payment 实例(轻量操作,无 I/O
#### 3. v2 适配器模式
- `PaymentV2Service` 未实现完整 `PaymentServiceInterface`(缺少 H5/查单/关单/HandlePaymentNotify
- 通过 `v2PaymentAdapter` 包装,补全缺失方法(返回"不支持"错误)
- **不修改** `payment_v2.go` 原文件
#### 4. `appID` 来源
- `NewPaymentAppFromConfig` / `NewPaymentV2ServiceFromConfig` 均需要 `appID` 参数
- 使用 `wechatConfig.OaAppID`(公众号 AppID
#### 5. wechatCache 共享
- loader 在构造时通过 `wechat.NewRedisCache(rdb)` 创建一次,所有 LoadConfig 调用复用
- v3 Payment 实例构建需要此 cache用于 PowerWeChat SDK 内部 token 缓存)
#### 6. worker_services.go 也需更新
- `internal/bootstrap/worker_services.go` 里有另一处 `orderSvc.New` 调用(超时取消专用)
- 需额外传 `nil` 占位
### 关键文件变更
| 文件 | 变更内容 |
|------|---------|
| `pkg/constants/redis.go` | +`RedisPaymentConfigKey` |
| `pkg/payment/loader.go` | 新建:接口 + 实现 + v2 适配器 |
| `internal/service/order/service.go` | +`paymentLoader` 字段/参数,替换 2 处 TODO |
| `internal/service/recharge/service.go` | +`paymentLoader` 字段/参数,更新 1 处 TODO 注释 |
| `internal/bootstrap/services.go` | 创建 loader 实例,传入 Order/Recharge 构造函数 |
| `internal/bootstrap/worker_services.go` | `orderSvc.New` 补传 `nil` |
### 验证结果
-`go build ./cmd/api ./cmd/worker` 通过,无任何错误
-`go vet` 无报告

View File

@@ -0,0 +1,108 @@
# tech-debt-cleanup 执行计划
## TL;DR
> **快速摘要**清理项目技术债务API 文档补全18.75% → 100%、支付配置动态化、轮询常量提取、废弃代码清理、Model 字段清理、DTO _name 字段补全、数据库迁移基线合并。
>
> **提案文件**`openspec/changes/tech-debt-cleanup/`
---
## TODOs
### Task 1: 支付配置动态加载pkg/payment + service层
- [x] 1.1 在 `pkg/constants/redis.go` 中新增 `RedisPaymentConfigKey(configID uint) string` 函数
- [x] 1.2 确认 `pkg/payment/` 包中现有支付接口定义
- [x] 1.3 创建 `pkg/payment/loader.go`,定义 `PaymentConfigLoader` 接口和实现Redis 缓存 TTL 1h
- [x] 1.4 修改 `internal/service/order/service.go`,注入 paymentLoader替换两处 TODO
- [x] 1.5 修改 `internal/service/recharge/service.go`,注入 paymentLoader替换 TODO
- [x] 1.7 运行 `go build ./cmd/api ./cmd/worker` 确认编译,`go vet` 静态分析
### Task 2: API 文档生成器补全docs.go + gendocs
- [x] 2.1 修改 `cmd/api/docs.go`,注册所有 48 个 Handler含 39 个缺失 Handler
- [x] 2.2 修改 `cmd/gendocs/main.go`,同步注册所有 48 个 Handler
- [x] 2.3 运行 `go run cmd/gendocs/main.go` 生成 OpenAPI 文档,验证覆盖率
- [x] 2.4 人工核查生成文档接口数量与路由注册数量一致
### Task 3: 轮询状态常量提取pkg/constants + handler/service/store
- [x] 3.1 在 `pkg/constants/polling.go` 中新增轮询手动触发日志状态常量4 个)
- [x] 3.2 修改 `internal/handler/admin/polling_manual_trigger.go`,替换硬编码字符串为常量
- [x] 3.3 修改 `internal/service/polling/manual_trigger_service.go`,替换硬编码字符串
- [x] 3.4 修改 `internal/store/postgres/polling_manual_trigger_store.go`,替换硬编码字符串
- [x] 3.5 修改 `internal/service/polling/alert_service.go`,替换 NotificationStatus 中的硬编码
- [x] 3.6 运行 grep 确认无剩余硬编码,`go vet` 静态分析
### Task 4: 废弃代码清理sync.go + wallet.go + DTO + 方法)
- [x] 4.1 删除 `internal/task/sync.go`,清理 queue/handler.go 注册和 constants.go 中的 TaskTypeDataSync
- [x] 4.2 全局搜索 wallet.go 中 15 个废弃别名的引用情况
- [x] 4.3 替换所有有引用的废弃别名为新常量
- [x] 4.4 删除 `pkg/constants/wallet.go` 中所有 Deprecated 别名定义15 个)
- [x] 4.5 删除 `internal/model/dto/enterprise_card_authorization_dto.go` 中的 3 个废弃 DTO 类型
- [x] 4.6 删除 `internal/service/order/service.go` 中的 `CreateLegacy()` 方法
- [x] 4.7 [跳过] `CheckAndStopCard()` 仍在 StopResumeServiceInterface 接口中且被活跃调用,不是废弃代码
- [x] 4.8 运行 `go build ./cmd/api ./cmd/worker``go vet` 确认编译无误
### Task 5: Model 废弃字段删除与数据库迁移
- [x] 5.1 从 `internal/model/iot_card.go` 中删除 `FirstCommissionPaid``AccumulatedRecharge` 字段
- [x] 5.2 从 `internal/model/device.go` 中删除 `FirstCommissionPaid``AccumulatedRecharge` 字段
- [x] 5.3 创建 `migrations/000116_remove_legacy_commission_fields.up.sql`DROP COLUMN
- [x] 5.4 创建 `migrations/000116_remove_legacy_commission_fields.down.sql`ADD COLUMN 回滚)
- [ ] 5.5 在测试环境执行迁移,通过 PostgreSQL MCP 确认字段已删除(需 DB 环境)
- [x] 5.6 运行 `go build ./cmd/api ./cmd/worker` 确认编译通过
### Task 6: DTO _name 字段补全(分模块逐批)
- [ ] 6.1 遍历 `internal/model/dto/` 统计所有 int 状态字段缺少 _name 字段的清单
- [ ] 6.2 **Account 模块**:补全 DTO _name 字段 + 常量映射函数 + Service 层赋值
- [ ] 6.3 **Asset 模块**:补全 DTO _name 字段 + 常量映射函数 + Service 层赋值
- [ ] 6.4 **Order 模块**:补全 DTO _name 字段 + 常量映射函数 + Service 层赋值
- [ ] 6.5 **Commission 模块**:补全 DTO _name 字段 + 常量映射函数 + Service 层赋值
- [ ] 6.6 **IotCard / Device 模块**:补全 DTO _name 字段 + 常量映射函数 + Service 层赋值
- [ ] 6.7 **剩余模块**Recharge、Wallet、Package、Shop 等):批量补全
- [ ] 6.8 全量编译与静态分析(`go build + go vet`
- [ ] 6.9 使用 curl/Postman 抽查各模块接口,确认 _name 字段有值且正确
### Task 7: 未使用常量和错误码清理
- [x] 7.1 删除 `pkg/errors/codes.go` 中的 `CodeExceedLimit` 常量和对应错误消息映射
- [x] 7.2 为 `pkg/constants/iot.go` 中约 22 个未引用的预留常量添加用途注释
- [x] 7.3 运行 `go build``go vet` 确认清理无破坏
### Task 8: 删除空文件和注释代码
- [x] 8.1 删除 `internal/routes/recharge.go` 空文件
- [x] 8.2 删除 `pkg/database/postgres.go` 中的 AutoMigrate 注释块(行 90-95
- [x] 8.3 保留 `internal/service/client_order/service.go` 中的实名认证检查注释,添加待确认标记
### Task 9: 全量编译验证
- [ ] 9.1 运行 `go mod tidy` 确认依赖无变化
- [ ] 9.2 运行 `go build ./cmd/api``go build ./cmd/worker` 确认编译通过
- [ ] 9.3 运行 `go vet ./...` 进行静态分析
- [ ] 9.4 运行 `gofmt -l ./internal ./pkg` 检查代码格式
### Task 0: 数据库迁移文件合并为生产基线(需 DB 环境)
- [ ] 0.1 确认当前数据库 schema 完整可用(服务启动无错误)
- [ ] 0.2 使用 pg_dump 生成当前完整 schema仅 DDL`migrations/000114_squash_baseline.up.sql`
- [ ] 0.3 编写 `migrations/000114_squash_baseline.down.sql`DROP 所有表)
- [ ] 0.4 创建 `migrations/000115_init_data.up.sql`(合并轮询配置初始数据 + purchase_role 回填)
- [ ] 0.5 创建 `migrations/000115_init_data.down.sql`(回滚初始数据)
- [ ] 0.6 归档旧迁移文件到 `migrations/archive/`000000~000113 + backfill 脚本)
- [ ] 0.7 编写测试环境重置脚本 `scripts/reset_db.sh`
- [ ] 0.8 在全新数据库上验证 migrate up 完整链路
- [ ] 0.9 重置测试环境数据库,切换到新基线
---
## Final Verification Wave
- [ ] F1 全量编译通过:`go build ./cmd/api ./cmd/worker` 无错误
- [ ] F2 静态分析通过:`go vet ./...` 无报告,`gofmt -l` 无格式问题
- [ ] F3 API 文档覆盖率 100%`go run cmd/gendocs/main.go` 生成文档包含 48/48 Handler
- [ ] F4 核心功能验证支付、轮询、账号管理等模块接口正常响应_name 字段有值