Files
huang 76b539e867
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m22s
chore: 归档 OpenSpec 变更 refactor-series-binding-to-series-id
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-02 12:21:00 +08:00

14 KiB
Raw Blame History

Tasks: refactor-series-binding-to-series-id

1. 数据库迁移

  • 1.1 创建数据库迁移文件 migrations/000XXX_refactor_series_binding_to_series_id.up.sql,重命名 tb_iot_card.series_allocation_idseries_idtb_device.series_allocation_idseries_id,更新字段注释
  • 1.2 创建回滚迁移文件 migrations/000XXX_refactor_series_binding_to_series_id.down.sql
  • 1.3 验证索引是否存在:检查 tb_shop_series_allocation 是否有 (shop_id, series_id) 复合索引,如不存在则添加
  • 1.4 执行迁移:运行 migrate up,验证字段重命名成功,无错误

2. Model 层修改

  • 2.1 修改 internal/model/iot_card.go:将 SeriesAllocationID 字段重命名为 SeriesID,更新 gorm 标签和注释
  • 2.2 修改 internal/model/device.go:将 SeriesAllocationID 字段重命名为 SeriesID,更新 gorm 标签和注释
  • 2.3 验证编译:运行 go build ./internal/model/...,确认无编译错误

3. DTO 层修改

  • 3.1 修改 internal/model/dto/iot_card_dto.go:更新 ListStandaloneIotCardRequest 的查询参数 SeriesAllocationIDSeriesID
  • 3.2 修改 internal/model/dto/iot_card_dto.go:更新 StandaloneIotCardResponse 的响应字段 SeriesAllocationIDSeriesID
  • 3.3 修改 internal/model/dto/iot_card_dto.go:更新 BatchSetCardSeriesBindngRequest 的请求字段 SeriesAllocationIDSeriesID,更新 description 为 "套餐系列ID0表示清除关联"
  • 3.4 修改 internal/model/dto/device_dto.go:更新 ListDeviceRequest 的查询参数 SeriesAllocationIDSeriesID
  • 3.5 修改 internal/model/dto/device_dto.go:更新 DeviceResponse 的响应字段 SeriesAllocationIDSeriesID
  • 3.6 修改 internal/model/dto/device_dto.go:更新 BatchSetDeviceSeriesBindngRequest 的请求字段 SeriesAllocationIDSeriesID,更新 description 为 "套餐系列ID0表示清除关联"
  • 3.7 验证编译:运行 go build ./internal/model/dto/...,确认无编译错误

4. Store 层修改

  • 4.1 修改 internal/store/postgres/iot_card_store.go:更新 ListStandalone 方法,将过滤条件 series_allocation_id 改为 series_id
  • 4.2 修改 internal/store/postgres/iot_card_store.go:更新 Count 方法,将过滤条件 series_allocation_id 改为 series_id
  • 4.3 修改 internal/store/postgres/iot_card_store.go:重命名方法 BatchUpdateSeriesAllocationBatchUpdateSeriesID,更新 SQL 字段名
  • 4.4 修改 internal/store/postgres/iot_card_store.go:重命名方法 ListBySeriesAllocationIDListBySeriesID,更新 WHERE 条件
  • 4.5 修改 internal/store/postgres/device_store.go:更新 List 方法,将过滤条件 series_allocation_id 改为 series_id
  • 4.6 修改 internal/store/postgres/device_store.go:重命名方法 BatchUpdateSeriesAllocationBatchUpdateSeriesID,更新 SQL 字段名
  • 4.7 修改 internal/store/postgres/device_store.go:重命名方法 ListBySeriesAllocationIDListBySeriesID,更新 WHERE 条件
  • 4.8 修改 internal/store/postgres/shop_series_allocation_store.go:新增方法 GetByShopAndSeries(ctx, shopID, seriesID),实现根据店铺和系列查询分配配置
  • 4.9 验证或创建 internal/store/postgres/package_series_store.go:如不存在则创建,实现 GetByID(ctx, id) 方法
  • 4.10 如果创建了新 Storeinternal/bootstrap/stores.go 中注册 PackageSeriesStore
  • 4.11 验证编译:运行 go build ./internal/store/...,确认无编译错误

5. Service 层修改 - iot_card

  • 5.1 修改 internal/service/iot_card/service.go:更新 ListStandalone 方法,将过滤条件 key series_allocation_id 改为 series_id
  • 5.2 修改 internal/service/iot_card/service.go:更新 buildStandaloneResponse 方法,将字段 SeriesAllocationID 改为 SeriesID
  • 5.3 修改 internal/service/iot_card/service.go:重构 BatchSetSeriesBinding 方法
  • 5.4 在 internal/service/iot_card/service.goService 结构体中添加 packageSeriesStore 依赖(如果不存在)
  • 5.5 验证编译:运行 go build ./internal/service/iot_card/...,确认无编译错误
  • 5.6 运行 lsp_diagnostics 检查 internal/service/iot_card/service.go,确认无类型错误

6. Service 层修改 - device

  • 6.1 修改 internal/service/device/service.go:更新 List 方法,将过滤条件 key series_allocation_id 改为 series_id
  • 6.2 修改 internal/service/device/service.go:更新 buildDeviceResponse 方法,将字段 SeriesAllocationID 改为 SeriesID
  • 6.3 修改 internal/service/device/service.go:重构 BatchSetSeriesBinding 方法
  • 6.4 在 internal/service/device/service.goService 结构体中添加 packageSeriesStore 依赖(如果不存在)
  • 6.5 验证编译:运行 go build ./internal/service/device/...,确认无编译错误
  • 6.6 运行 lsp_diagnostics 检查 internal/service/device/service.go,确认无类型错误

7. Service 层修改 - purchase_validation关键

  • 7.1 修改 internal/service/purchase_validation/service.go:重构 ValidateCardPurchase 方法
  • 7.2 修改 internal/service/purchase_validation/service.go:重构 ValidateDevicePurchase 方法
  • 7.3 更新 ValidateCardPurchaseValidateDevicePurchase 的错误消息,从 "套餐系列分配不存在" 改为 "该卡/设备未关联套餐系列"
  • 7.4 验证编译:运行 go build ./internal/service/purchase_validation/...,确认无编译错误
  • 7.5 运行 lsp_diagnostics 检查 internal/service/purchase_validation/service.go,确认无类型错误

8. Service 层修改 - commission_calculation关键

  • 8.1 修改 internal/service/commission_calculation/service.go:重构 CalculateOrderCommission 方法
  • 8.2 修改 internal/service/commission_calculation/service.go:重构 CalculateDeviceOrderCommission 方法(同样的逻辑)
  • 8.3 验证编译:运行 go build ./internal/service/commission_calculation/...,确认无编译错误
  • 8.4 运行 lsp_diagnostics 检查 internal/service/commission_calculation/service.go,确认无类型错误

9. Service 层修改 - recharge

  • 9.1 修改 internal/service/recharge/service.go:重构充值相关方法,将获取 seriesAllocationID 的逻辑改为直接使用 seriesID
  • 9.2 修改 internal/service/recharge/service.go:更新返佣查询逻辑,使用 GetByShopAndSeries(shopID, seriesID) 而不是 GetByID(allocationID)
  • 9.3 验证编译:运行 go build ./internal/service/recharge/...,确认无编译错误
  • 9.4 运行 lsp_diagnostics 检查 internal/service/recharge/service.go,确认无类型错误

10. Service 层修改 - order

  • 10.1 检查 internal/service/order/service.go 中是否有直接使用 SeriesAllocationID 的地方,如有则更新为 SeriesID
  • 10.2 验证编译:运行 go build ./internal/service/order/...,确认无编译错误
  • 10.3 运行 lsp_diagnostics 检查 internal/service/order/service.go,确认无类型错误

11. Bootstrap 依赖注入

  • 11.1 如果创建了 PackageSeriesStore,在 internal/bootstrap/stores.go 中初始化并添加到 Stores 结构体
  • 11.2 在 internal/bootstrap/services.go 中,为 iot_card.Servicedevice.Service 注入 packageSeriesStore 依赖
  • 11.3 验证编译:运行 go build ./internal/bootstrap/...,确认无编译错误

12. Handler & Routes 层

  • 12.1 修改 internal/routes/iot_card.go:更新 /series-binding 路由的 Description说明参数从 series_allocation_id 改为 series_id
  • 12.2 修改 internal/routes/device.go:更新 /series-binding 路由的 Description说明参数从 series_allocation_id 改为 series_id
  • 12.3 验证 Handler 层代码:internal/handler/admin/iot_card.godevice.go 无需修改(使用 DTO
  • 12.4 验证编译:运行 go build ./internal/routes/... ./internal/handler/...,确认无编译错误

13. Store 层测试更新

  • 13.1 修改 internal/store/postgres/iot_card_store_test.go:更新所有测试用例,将 SeriesAllocationID 改为 SeriesID
  • 13.2 修改 internal/store/postgres/iot_card_store_test.go:重命名测试函数 TestIotCardStore_ListBySeriesAllocationIDTestIotCardStore_ListBySeriesID
  • 13.3 修改 internal/store/postgres/iot_card_store_test.go:更新过滤条件测试,将 series_allocation_id 改为 series_id
  • 13.4 修改 internal/store/postgres/device_store_test.go:更新所有测试用例,将 SeriesAllocationID 改为 SeriesID
  • 13.5 修改 internal/store/postgres/device_store_test.go:重命名测试函数 TestDeviceStore_ListBySeriesAllocationIDTestDeviceStore_ListBySeriesID
  • 13.6 新增测试:在 shop_series_allocation_store_test.go 中添加 TestShopSeriesAllocationStore_GetByShopAndSeries 测试
  • 13.7 运行 Store 层测试:source .env.local && go test -v ./internal/store/postgres/...,确认全部通过

14. Service 层测试更新 - iot_card

  • 14.1 修改 internal/service/iot_card/service_test.go:更新 TestIotCardService_BatchSetSeriesBinding 测试
  • 14.2 更新测试数据准备顺序:先 PackageSeries,再 ShopSeriesAllocation,最后 IotCard
  • 14.3 运行 Service 层测试:source .env.local && go test -v ./internal/service/iot_card/...,确认全部通过

15. Service 层测试更新 - device

  • 15.1 修改 internal/service/device/service_test.go:更新 TestDeviceService_BatchSetSeriesBinding 测试
  • 15.2 更新测试数据准备顺序:先 PackageSeries,再 ShopSeriesAllocation,最后 Device
  • 15.3 运行 Service 层测试:source .env.local && go test -v ./internal/service/device/...,确认全部通过

16. Service 层测试更新 - purchase_validation

  • 16.1 修改 internal/service/purchase_validation/service_test.go:更新所有测试用例
  • 16.2 运行 Service 层测试:source .env.local && go test -v ./internal/service/purchase_validation/...,确认全部通过

17. Service 层测试更新 - commission_calculation

  • 17.1 修改 internal/service/commission_calculation/service_test.go:更新所有测试用例
  • 17.2 运行 Service 层测试:source .env.local && go test -v ./internal/service/commission_calculation/...,确认全部通过

18. Service 层测试更新 - recharge & order

  • 18.1 修改 internal/service/recharge/service_test.go:更新测试用例,将 SeriesAllocationID 改为 SeriesID
  • 18.2 修改 internal/service/order/service_test.go:更新测试用例,将 SeriesAllocationID 改为 SeriesID
  • 18.3 运行 Service 层测试:source .env.local && go test -v ./internal/service/recharge/... ./internal/service/order/...,确认全部通过

19. 集成测试更新 - iot_card

  • 19.1 修改 tests/integration/iot_card_test.go:更新 TestIotCard_BatchSetSeriesBinding 测试
  • 19.2 更新所有子测试用例的 JSON 请求体(约 10 个)
  • 19.3 运行集成测试:source .env.local && cd tests/integration && go test -v -run "TestIotCard_BatchSetSeriesBinding",确认全部通过

20. 集成测试更新 - device

  • 20.1 修改 tests/integration/device_test.go:更新 TestDevice_BatchSetSeriesBinding 测试
  • 20.2 更新所有子测试用例的 JSON 请求体(约 10 个)
  • 20.3 运行集成测试:source .env.local && cd tests/integration && go test -v -run "TestDevice_BatchSetSeriesBinding",确认全部通过

21. 单元测试更新 - commission_calculation

  • 21.1 修改 tests/unit/commission_calculation_service_test.go:更新所有测试用例
  • 21.2 运行单元测试:source .env.local && go test -v ./tests/unit/...,确认全部通过

22. 全量测试验证

  • 22.1 运行所有测试:source .env.local && go test -v ./...,确认全部通过,无遗漏
  • 22.2 运行编译检查:go build ./...,确认无编译错误
  • 22.3 使用 grep 搜索遗漏:grep -r "SeriesAllocationID" internal/ --include="*.go",确认无遗漏
  • 22.4 使用 grep 搜索遗漏:grep -r "series_allocation_id" internal/ --include="*.go",确认无遗漏(仅数据库注释除外)

23. API 手动测试

  • 23.1 启动本地服务:go run cmd/api/main.go
  • 23.2 测试 IoT 卡系列绑定 APIPATCH /api/admin/iot-cards/series-binding,使用 Postman 或 curl 发送请求,验证参数 series_id 生效
  • 23.3 测试设备系列绑定 APIPATCH /api/admin/devices/series-binding,使用 Postman 或 curl 发送请求,验证参数 series_id 生效
  • 23.4 测试卡列表查询:GET /api/admin/iot-cards/standalone?series_id=1,验证过滤生效
  • 23.5 测试设备列表查询:GET /api/admin/devices?series_id=1,验证过滤生效
  • 23.6 检查日志确认无错误日志SQL 查询使用 series_id 而不是 series_allocation_id

24. API 文档更新

  • 24.1 更新 OpenAPI 文档注释:确保路由描述中明确说明参数从 series_allocation_id 改为 series_id
  • 24.2 重新生成 API 文档:运行 go run cmd/gendocs/main.go,生成最新的 OpenAPI spec
  • 24.3 验证生成的文档:检查 docs/admin-openapi.yaml/iot-cards/series-binding/devices/series-binding 的参数定义
  • 24.4 如有前端文档,更新前端接口文档,说明 BREAKING CHANGE

25. 清理和最终验证

  • 25.1 删除所有临时代码和注释
  • 25.2 运行 gofmt -w . 格式化所有代码
  • 25.3 运行 go mod tidy 清理依赖
  • 25.4 再次运行全量测试:source .env.local && go test -v ./...,确认全部通过
  • 25.5 使用 git diff 检查所有改动,确认无遗漏,无多余修改
  • 25.6 更新 CHANGELOG如有记录 BREAKING CHANGE

26. 提交和归档

  • 26.1 提交代码:创建 Git commit使用中文 commit message"重构: 将卡/设备的套餐系列绑定从分配ID改为系列ID"
  • 26.2 运行 OpenSpec 归档:openspec archive refactor-series-binding-to-series-id
  • 26.3 验证归档成功:检查 openspec/changes/archive/ 目录,确认变更已归档
  • 26.4 清理工作目录:删除 openspec/changes/refactor-series-binding-to-series-id/(已归档)