All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m22s
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
5.4 KiB
5.4 KiB
Proposal: refactor-series-binding-to-series-id
Why
当前系统中,IoT卡和设备通过 series_allocation_id(套餐系列分配ID)字段绑定到 ShopSeriesAllocation 表,而不是直接绑定到 PackageSeries(套餐系列)。这导致了严重的语义混乱和架构问题:
- 语义错误:卡/设备应该表达"只能购买某个系列的套餐",而不是"绑定到某个权限分配"
- 职责耦合:资源属性(可购买的套餐范围)与权限配置(返佣规则)混在一起
- 查询冗余:每次需要
series_id时都要通过allocation表查询,增加数据库负担 - 配置僵化:修改店铺的返佣配置时,需要重新绑定所有卡/设备
这是一个设计失误,需要在开发阶段彻底重构。正确的设计应该是:卡/设备直接绑定 series_id,权限验证和返佣查询时按需通过 (shop_id, series_id) 查询 ShopSeriesAllocation。
What Changes
- 数据库结构:将
tb_iot_card和tb_device的series_allocation_id字段重命名为series_id,直接关联到tb_package_series - Model 层:修改
IotCard和Device模型,将SeriesAllocationID字段改为SeriesID - DTO 层:更新所有相关 DTO,包括查询请求、响应对象、批量设置请求
- Store 层:
- 更新查询过滤条件(
series_allocation_id→series_id) - 重命名批量更新方法(
BatchUpdateSeriesAllocation→BatchUpdateSeriesID) - 重命名列表查询方法(
ListBySeriesAllocationID→ListBySeriesID) - 新增
ShopSeriesAllocationStore.GetByShopAndSeries(shopID, seriesID)方法,用于按需查询返佣配置 - 新增
PackageSeriesStore(如不存在)及其GetByID()方法
- 更新查询过滤条件(
- Service 层:重构核心业务逻辑
BatchSetSeriesBinding:验证series_id是否存在,检查操作者权限(通过GetByShopAndSeries查询)ValidateCardPurchase/ValidateDevicePurchase:直接使用card.series_id验证套餐,按需查询返佣配置CalculateOrderCommission:根据(shop_id, series_id)查询返佣配置,而不是通过allocation_idCreateRecharge:同样改为按需查询返佣配置
- API 文档:更新路由描述,说明参数从
series_allocation_id改为series_id - 测试:更新约 100+ 个测试用例,包括单元测试、集成测试、Store 测试
关键行为变更:
- API
/api/admin/iot-cards/series-binding和/api/admin/devices/series-binding的请求参数从series_allocation_id改为series_id - 卡/设备列表的查询参数和响应字段同步改为
series_id - 内部逻辑从"通过 allocation 获取 series_id"改为"直接使用 series_id,按需查询 allocation"
Capabilities
New Capabilities
Modified Capabilities
card-series-bindng: 修改 IoT 卡系列绑定的数据模型和验证逻辑,从绑定"分配ID"改为绑定"系列ID"device-series-bindng: 修改设备系列绑定的数据模型和验证逻辑,从绑定"分配ID"改为绑定"系列ID"
Impact
影响范围统计
- 数据库迁移:2 个迁移文件(新增重命名迁移,修改旧迁移注释)
- Model 层:2 个文件(
internal/model/iot_card.go,internal/model/device.go) - DTO 层:2 个文件,6 个结构体(
internal/model/dto/iot_card_dto.go,internal/model/dto/device_dto.go) - Store 层:3 个文件,新增 2 个查询方法(
iot_card_store.go,device_store.go,shop_series_allocation_store.go) - Service 层:6 个文件的核心逻辑重构
internal/service/iot_card/service.gointernal/service/device/service.gointernal/service/purchase_validation/service.go(关键)internal/service/commission_calculation/service.go(关键)internal/service/recharge/service.gointernal/service/order/service.go
- Handler/Routes 层:2 个文件的路由描述更新
- 测试层:约 10 个文件,100+ 测试用例更新
受影响的 API 端点
PATCH /api/admin/iot-cards/series-binding:请求参数series_allocation_id→series_idPATCH /api/admin/devices/series-binding:请求参数series_allocation_id→series_idGET /api/admin/iot-cards/standalone:查询参数和响应字段series_allocation_id→series_idGET /api/admin/devices:查询参数和响应字段series_allocation_id→series_id
向后兼容性
- BREAKING CHANGE:API 请求/响应字段名变更,前端需要同步修改
- 数据迁移:字段重命名,不需要数据转换(字段含义保持一致,只是重新指向
PackageSeries.ID) - 业务影响:开发阶段,无生产数据,可直接重构
依赖和约束
- 依赖现有的
tb_package_series表和tb_shop_series_allocation表 - 依赖现有的
PackageSeries模型 - 需要创建或完善
PackageSeriesStore(如不存在) - 测试需要创建完整的测试数据链路:
PackageSeries→ShopSeriesAllocation→IotCard/Device
性能影响
- 查询优化:购买验证时减少一次数据库查询(不再需要先查
ShopSeriesAllocation获取series_id) - 返佣查询:增加一次按条件查询
ShopSeriesAllocation(WHERE shop_id = ? AND series_id = ?),但有索引支持,性能影响可忽略 - 整体影响:轻微性能提升(减少了冗余查询)