清理冗余的梯度返佣(TierCommission)配置
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m46s

- 移除 Model 层:删除 ShopSeriesCommissionTier 模型及相关字段
- 更新 DTO:删除 TierCommissionConfig、TierEntry 类型及相关请求/响应字段
- 删除 Store 层:移除 ShopSeriesCommissionTierStore 及相关查询逻辑
- 简化 Service 层:删除梯度返佣处理逻辑,统计查询移除 tier_bonus 字段
- 数据库迁移:创建 000034_remove_tier_commission 移除相关表和字段
- 更新测试:移除梯度返佣相关测试用例,更新集成测试
- OpenAPI 文档:删除梯度返佣相关 schema 和枚举值
- 归档变更:归档 remove-tier-commission-redundancy 到 archive/2026-01-30-
- 同步规范:更新 4 个主 specs,标记废弃功能并添加迁移指引

原因:梯度返佣功能与一次性梯度佣金功能重复,且从未实现实际计算逻辑
迁移:使用一次性佣金的梯度模式 (OneTimeCommissionConfig.type = "tiered") 替代
This commit is contained in:
2026-01-30 14:57:24 +08:00
parent 409a68d60b
commit 1cf17e8f14
39 changed files with 978 additions and 407 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-01-30

View File

@@ -0,0 +1,355 @@
## Context
当前系统中存在两套梯度佣金配置机制:
1. **TierCommission (梯度返佣)**:通过 `tb_shop_series_commission_tier` 表存储,支持按周期(月/季/年)和类型(销量/销售额)设置梯度奖励
2. **OneTimeCommission.tiered (一次性梯度佣金)**:通过 `tb_shop_series_one_time_commission_tier` 表存储,支持按销量或销售额设置一次性梯度奖励
通过代码探索发现:
- `TierCommission` 有完整的数据库表、Model、DTO、Store 定义
- 但在 `commission_calculation` 服务中**没有实际的计算逻辑**
- `CommissionSourceTierBonus` 常量被定义但从未在佣金计算中使用
- 统计查询中预留了 `tier_bonus_amount` 等字段,但永远为 0
实际业务需求是:**基础返佣(成本价差)+ 一次性佣金(固定或梯度)** 两种机制。
由于系统尚未上线,现在是清理冗余代码的最佳时机。
## Goals / Non-Goals
**Goals:**
- 删除所有与 `TierCommission` (梯度返佣) 相关的代码和数据库结构
- 简化佣金配置模型,只保留基础返佣和一次性佣金两种机制
- 更新 API 文档和集成测试,确保 API 契约清晰
- 确保佣金计算逻辑继续正常工作(不受删除影响)
**Non-Goals:**
- 不修改一次性佣金的现有逻辑OneTimeCommission 保持不变)
- 不修改基础返佣的现有逻辑base_commission 保持不变)
- 不涉及数据迁移(系统未上线,无历史数据)
- 不重构佣金计算的核心流程
## Decisions
### Decision 1: 数据库迁移策略
**选择**: 创建新的 migration 文件删除表和字段
**理由**:
- 系统未上线,无需保留历史数据
- 使用标准的 migration 流程便于版本控制和回滚
- 迁移文件编号使用下一个递增编号(查看 `migrations/` 目录获取最新编号)
**替代方案及其劣势**:
- ❌ 直接修改现有 migration 文件:违反 migration 不可变原则
- ❌ 手动执行 SQL缺乏版本控制团队协作困难
**Migration 内容**:
```sql
-- up migration
ALTER TABLE tb_shop_series_allocation DROP COLUMN IF EXISTS enable_tier_commission;
ALTER TABLE tb_shop_series_allocation_config DROP COLUMN IF EXISTS enable_tier_commission;
DROP TABLE IF EXISTS tb_shop_series_commission_tier;
-- down migration (恢复结构,用于紧急回滚)
CREATE TABLE IF NOT EXISTS tb_shop_series_commission_tier (...);
ALTER TABLE tb_shop_series_allocation ADD COLUMN enable_tier_commission BOOLEAN DEFAULT FALSE;
ALTER TABLE tb_shop_series_allocation_config ADD COLUMN enable_tier_commission BOOLEAN;
```
---
### Decision 2: DTO 字段删除策略
**选择**: 直接删除 `TierCommissionConfig``TierEntry` 类型,以及所有引用这些类型的字段
**理由**:
- 系统未上线,无 API 兼容性负担
- 清晰的 API 契约更利于前端开发
- 避免"字段存在但不可用"的混淆状态
**替代方案及其劣势**:
- ❌ 保留字段但标记为 deprecated增加维护成本前端可能误用
- ❌ 使用 API 版本控制v2过度设计系统尚未发布 v1
**影响的 DTO**:
- `CreateShopSeriesAllocationRequest`: 删除 `EnableTierCommission``TierConfig` 字段
- `UpdateShopSeriesAllocationRequest`: 删除 `EnableTierCommission``TierConfig` 字段
- `ShopSeriesAllocationResponse`: 删除 `EnableTierCommission` 字段
- `TierCommissionConfig``TierEntry`: 整个类型删除
---
### Decision 3: Store 层清理策略
**选择**: 完全删除 `ShopSeriesCommissionTierStore` 及其实现
**理由**:
- 该 Store 没有被任何业务逻辑调用
- 删除后减少依赖注入复杂度
- 避免未来误用
**需要修改的依赖注入位置**:
- `internal/bootstrap/wire.go` (或依赖注入配置文件):删除 `ShopSeriesCommissionTierStore` 的 provider
- `internal/service/shop_series_allocation/service.go`:删除结构体中的 `tierStore` 字段(如果存在)
---
### Decision 4: 常量和枚举清理策略
**选择**: 删除 `CommissionSourceTierBonus` 常量,更新所有相关注释和文档
**理由**:
- 该常量从未在佣金计算中使用
- 保留会误导开发者以为该功能可用
- 佣金来源枚举简化为两个值:`cost_diff``one_time`
**需要更新的位置**:
- `internal/model/commission.go`: 删除 `CommissionSourceTierBonus` 常量定义
- `migrations/000029_add_one_time_commission.up.sql`: 更新 `commission_source` 字段注释
- 所有相关的 API 文档和 DTO 注释
---
### Decision 5: 统计查询更新策略
**选择**: 删除统计查询中的 `tier_bonus` 相关字段和 SQL 逻辑
**理由**:
- 这些字段永远为 0无实际价值
- 简化 SQL 查询提升性能
- 减少前端展示的无用信息
**需要修改的位置**:
- `internal/store/postgres/commission_record_store.go`:
- 删除 `TierBonusAmount``TierBonusCount` 字段定义
- 删除 SQL 中的 `COALESCE(SUM(CASE WHEN commission_source = 'tier_bonus' ...))` 语句
- `internal/model/dto/commission.go`:
- 删除 `CommissionStatsResponse` 中的 `TierBonusAmount``TierBonusCount``TierBonusPercent` 字段
- `internal/service/my_commission/service.go`:
- 删除 `tierBonusPercent` 的计算逻辑
---
### Decision 6: 测试更新策略
**选择**: 删除所有与 `enable_tier_commission` 相关的测试用例,添加验证佣金来源枚举的测试
**理由**:
- 测试应反映实际业务需求
- 删除无效测试提高测试套件可维护性
- 添加枚举验证测试确保不会误用 `tier_bonus`
**需要修改的测试**:
- `tests/integration/shop_series_allocation_test.go`: 删除包含 `enable_tier_commission` 的测试场景
- `tests/integration/shop_package_batch_allocation_test.go`: 删除 tier_config 相关的测试数据
- 添加新测试:验证创建 `commission_source = "tier_bonus"` 的佣金记录会失败
---
### Decision 7: Service 层清理策略
**选择**: 删除 `shop_series_allocation` Service 中处理 `tier_config` 的逻辑
**理由**:
- Service 层应只处理有效的业务逻辑
- 删除无用代码降低认知负担
**需要修改的位置**:
- `internal/service/shop_series_allocation/service.go`:
- 删除 `validateTierConfig()` 方法(如果存在)
- 删除创建/更新分配时对 `TierConfig` 的处理逻辑
- 删除 `tierStore` 的依赖注入字段
---
### Decision 8: 验证逻辑更新
**选择**: 更新 DTO 验证规则,确保不接受 `tier_bonus` 作为佣金来源
**理由**:
- 在 API 入口层就拦截无效输入
- 提供清晰的错误提示
**实现方式**:
- 使用 Validator 的 `oneof` 标签限制 `commission_source` 只能是 `cost_diff``one_time`
-`CommissionRecordListRequest` 等 DTO 中更新验证规则
## Risks / Trade-offs
### Risk 1: 误删除正在使用的代码
**风险**: 虽然探索显示 `TierCommission` 未被使用,但可能有未被发现的引用
**缓解措施**:
- 在删除前使用 IDE 的 "Find Usages" 功能全局搜索所有引用
- 运行完整的测试套件确保没有编译错误
- 代码审查时重点检查删除的影响范围
- 保留完整的 git 历史,必要时可快速回滚
---
### Risk 2: API 契约变更可能影响前端开发
**风险**: 前端可能已经基于旧的 API 文档开发
**缓解措施**:
- 与前端团队同步变更内容
- 更新 OpenAPI 文档并生成新的 TypeScript 类型定义
- 由于系统未上线,前端调整成本较低
---
### Risk 3: Migration 执行失败
**风险**: 删除表/字段的 migration 可能因数据库权限或锁问题失败
**缓解措施**:
- 在开发环境先测试 migration
- 使用 `DROP ... IF EXISTS` 避免重复执行报错
- 提供完整的 down migration 支持回滚
- 记录执行步骤和常见问题排查指南
---
### Risk 4: 佣金统计查询变更可能影响性能
**风险**: 删除 SQL 中的 `tier_bonus` 分支后,查询性能可能有微小波动
**缓解措施**:
- 简化 SQL 逻辑理论上会提升性能
- 在测试环境执行性能测试对比
- 监控线上查询耗时(虽然系统未上线,为未来做准备)
**Trade-off**:
- 获得:更简洁的代码和更快的统计查询
- 失去:未来如果需要重新引入梯度返佣,需要重新实现(但根据业务需求,这种可能性很低)
## Migration Plan
### Phase 1: 代码清理(本地开发)
1. **删除 Model 和 DTO**
- 删除 `internal/model/shop_series_commission_tier.go`
- 更新 `internal/model/dto/shop_series_allocation.go`
- 更新 `internal/model/dto/commission.go`
- 删除 `internal/model/commission.go` 中的 `CommissionSourceTierBonus`
2. **删除 Store 层**
- 删除 `internal/store/postgres/shop_series_commission_tier_store.go`
- 删除 `internal/store/interface.go` 中的 `ShopSeriesCommissionTierStore` 接口定义
- 更新 `internal/store/postgres/commission_record_store.go` 的统计查询
3. **更新 Service 层**
- 更新 `internal/service/shop_series_allocation/service.go`
- 更新 `internal/service/my_commission/service.go`
- 删除依赖注入中的 `tierStore` 引用
4. **更新 Handler 层**
- 更新 `internal/handler/shop_series_allocation_handler.go`(如有必要)
5. **更新依赖注入**
- 更新 `internal/bootstrap/wire.go` 或相关配置文件
6. **运行测试验证**
```bash
go test ./...
```
### Phase 2: 数据库迁移(本地验证)
1. **创建 migration 文件**
- 查看 `migrations/` 目录最新编号
- 创建新的 migration 文件(如 `000030_remove_tier_commission.up.sql`
2. **本地执行 migration**
```bash
go run cmd/migrate/main.go up
```
3. **验证数据库结构**
```sql
\d tb_shop_series_allocation
\d tb_shop_series_allocation_config
\dt tb_shop_series_commission_tier -- 应返回不存在
```
### Phase 3: 测试更新(本地验证)
1. **删除无效测试**
- 更新 `tests/integration/shop_series_allocation_test.go`
- 更新 `tests/integration/shop_package_batch_allocation_test.go`
2. **添加验证测试**
- 添加测试验证 `commission_source = "tier_bonus"` 被拒绝
3. **运行完整测试套件**
```bash
go test -v ./tests/integration/...
```
### Phase 4: 文档更新
1. **更新 OpenAPI 文档**
- 删除 `TierCommissionConfig` schema
- 更新受影响的 API 端点定义
2. **生成新的文档**
```bash
make generate-docs # 或相应的命令
```
### Phase 5: 代码审查和合并
1. **提交 Pull Request**
- 标题:`清理冗余的梯度返佣(TierCommission)配置`
- 描述:引用 proposal 和 design 文档
2. **代码审查重点**
- 确认所有引用都已删除
- 验证测试覆盖率
- 检查 migration 正确性
3. **合并到主分支**
### Phase 6: 部署(未来上线时)
1. **开发环境验证**
2. **测试环境验证**
3. **生产环境部署**(虽然当前系统未上线)
### Rollback Strategy
如果发现问题需要回滚:
1. **代码回滚**
```bash
git revert <commit-hash>
```
2. **数据库回滚**
```bash
go run cmd/migrate/main.go down
```
3. **验证回滚成功**
- 运行测试套件
- 检查数据库结构恢复
## Open Questions
1. **是否需要通知前端团队**
- 状态:待确认
- 建议:由于 API 契约变更,应提前同步
2. **是否需要在变更日志中记录此次清理**
- 状态:待确认
- 建议:记录在 CHANGELOG.md 中,标记为 "BREAKING CHANGE"(虽然系统未上线)
3. **OpenAPI 文档的更新流程是什么**
- 状态:待确认
- 需要了解项目中是如何生成和维护 OpenAPI 文档的
4. **是否有其他依赖于 `tb_shop_series_commission_tier` 表的外部系统**
- 状态:待确认
- 建议:检查是否有数据分析、报表系统等外部依赖

View File

@@ -0,0 +1,88 @@
## Why
当前套餐系列分配中存在两套梯度佣金配置:一个是 `TierCommission`(梯度返佣),另一个是 `OneTimeCommission.tiered`(一次性梯度佣金)。这两者功能高度重复,导致概念混淆。经过探索发现,`TierCommission` 仅有数据库表和 DTO 定义,但没有实际的计算逻辑实现,而系统实际需要的佣金机制是:**基础返佣(成本价差)+ 一次性佣金(固定或梯度)**。因此需要删除冗余的 `TierCommission` 相关代码,简化佣金配置模型。
## What Changes
- **删除数据库表和字段**
- 删除 `tb_shop_series_commission_tier` 表(梯度返佣配置表)
- 删除 `tb_shop_series_allocation.enable_tier_commission` 字段
- 删除 `tb_shop_series_allocation_config.enable_tier_commission` 字段(配置快照表)
- **删除 Model 和 DTO**
- 删除 `internal/model/shop_series_commission_tier.go` 模型
- 删除 `internal/model/dto/shop_series_allocation.go` 中的 `TierCommissionConfig``TierEntry` 类型
- 删除 `CreateShopSeriesAllocationRequest``UpdateShopSeriesAllocationRequest` 中的 `EnableTierCommission``TierConfig` 字段
- 删除 `ShopSeriesAllocationResponse` 中的 `EnableTierCommission` 字段
- **删除 Store 层**
- 删除 `internal/store/postgres/shop_series_commission_tier_store.go` 及其接口定义
- **删除常量和枚举**
- 删除 `internal/model/commission.go` 中的 `CommissionSourceTierBonus` 常量
- 更新佣金来源说明(从三种改为两种:`cost_diff``one_time`
- **更新统计和查询逻辑**
- 删除佣金统计中的 `TierBonusAmount``TierBonusCount``TierBonusPercent` 字段
- 更新 `internal/model/dto/commission.go` 中的 `CommissionStatsResponse`
- 更新 `internal/store/postgres/commission_record_store.go` 中的统计查询 SQL
- **删除相关测试**
- 删除 `tests/integration/shop_series_allocation_test.go` 中与 `enable_tier_commission` 相关的测试用例
- **创建数据库迁移**
- 创建 down migration 删除 `enable_tier_commission` 字段和 `tb_shop_series_commission_tier`
- **更新 API 文档**
- 更新 OpenAPI 规范,删除 `TierCommissionConfig` 相关的 schema 定义
## Capabilities
### New Capabilities
无新增 capability。
### Modified Capabilities
- `shop-series-allocation`: 删除梯度返佣配置要求,简化为只支持基础返佣和一次性佣金两种机制
- `shop-commission-tier`: **整个 capability 将被废弃**,因为梯度返佣功能完全移除
- `commission-calculation`: 删除 `tier_bonus` 佣金来源,明确只支持 `cost_diff``one_time` 两种佣金来源
- `commission-record-query`: 删除梯度奖励相关的统计字段(`tier_bonus_amount``tier_bonus_count``tier_bonus_percent`
## Impact
**受影响的代码模块**
- Handler: `internal/handler/shop_series_allocation_handler.go`(删除 tier_config 参数处理)
- Service: `internal/service/shop_series_allocation/service.go`(删除 tier 相关业务逻辑)
- Store: `internal/store/postgres/shop_series_commission_tier_store.go`(整个文件删除)
- Store: `internal/store/postgres/commission_record_store.go`(删除 tier_bonus 统计)
- Model: `internal/model/shop_series_commission_tier.go`(整个文件删除)
- DTO: `internal/model/dto/shop_series_allocation.go`(删除 TierCommissionConfig
- DTO: `internal/model/dto/commission.go`(删除 tier_bonus 统计字段)
**受影响的 API 端点**
- `POST /api/shop-series-allocations` - 请求体删除 `enable_tier_commission``tier_config` 字段
- `PUT /api/shop-series-allocations/:id` - 请求体删除 `enable_tier_commission``tier_config` 字段
- `GET /api/shop-series-allocations` - 响应删除 `enable_tier_commission` 字段
- `GET /api/shop-series-allocations/:id` - 响应删除 `enable_tier_commission` 字段
- `GET /api/my-commission/stats` - 响应删除 `tier_bonus_amount``tier_bonus_count``tier_bonus_percent` 字段
**数据库迁移**
- 需要创建新的 migration 删除 `tb_shop_series_commission_tier`
- 需要删除 `tb_shop_series_allocation``tb_shop_series_allocation_config` 表中的 `enable_tier_commission` 字段
**依赖关系**
- 删除 `ShopSeriesCommissionTierStore` 的依赖注入
**破坏性变更**
- **BREAKING**: API 请求/响应结构变更(删除字段)
- **BREAKING**: 数据库表结构变更
- **注**: 由于系统尚未上线,无历史数据兼容性问题
**测试影响**
- 需要更新集成测试用例,删除 `enable_tier_commission` 相关的测试场景
- 需要验证佣金计算逻辑仍然正常工作(只计算 cost_diff 和 one_time
**性能影响**
- 正面影响:简化数据模型,减少无用的表 JOIN 和查询
- 佣金统计查询性能提升(减少一个条件分支)

View File

@@ -0,0 +1,17 @@
## MODIFIED Requirements
### Requirement: CommissionRecord 模型简化
系统 MUST 简化 CommissionRecord 模型,移除冻结相关字段。
#### Scenario: 新佣金记录字段
- **WHEN** 创建佣金记录
- **THEN** 包含shop_id, order_id, iot_card_id, device_id, commission_source, amount, balance_after, status, released_at, remark
#### Scenario: 佣金来源类型
- **WHEN** 创建佣金记录
- **THEN** commission_source 为以下之一cost_diff成本价差、one_time一次性佣金
#### Scenario: 不再支持梯度奖励来源
- **WHEN** 尝试创建 commission_source = "tier_bonus" 的佣金记录
- **THEN** 系统拒绝并返回错误 "不支持的佣金来源类型"

View File

@@ -0,0 +1,39 @@
## MODIFIED Requirements
### Requirement: 按佣金来源筛选
系统 SHALL 支持按佣金来源筛选佣金记录。
#### Scenario: 按成本价差筛选
- **WHEN** 指定 commission_source 为 cost_diff
- **THEN** 系统只返回成本价差类型的佣金记录
#### Scenario: 按一次性佣金筛选
- **WHEN** 指定 commission_source 为 one_time
- **THEN** 系统只返回一次性佣金类型的佣金记录
#### Scenario: 使用已废弃的佣金来源筛选
- **WHEN** 指定 commission_source 为 tier_bonus
- **THEN** 系统返回空列表或返回错误 "不支持的佣金来源类型"
---
### Requirement: 佣金统计
系统 SHALL 提供佣金统计功能,包含总收入和各来源占比。
#### Scenario: 查询总收入
- **WHEN** 代理查询佣金统计
- **THEN** 系统返回总收入金额(所有已入账佣金之和)
#### Scenario: 各来源占比
- **WHEN** 代理查询佣金统计
- **THEN** 系统返回各佣金来源的金额和占比cost_diff、one_time
#### Scenario: 统计响应不包含梯度奖励字段
- **WHEN** 代理查询佣金统计
- **THEN** 响应中不包含 tier_bonus_amount、tier_bonus_count、tier_bonus_percent 字段
#### Scenario: 按时间范围统计
- **WHEN** 指定时间范围查询统计
- **THEN** 系统只统计该时间范围内的佣金

View File

@@ -0,0 +1,47 @@
## REMOVED Requirements
### Requirement: 配置梯度佣金
**原内容**: 系统 SHALL 允许代理为套餐系列分配配置梯度佣金。每个梯度包含:梯度类型(销量/销售额)、周期类型(月度/季度/年度)、阈值、达标后的返佣配置(返佣模式和返佣值)。
**Reason**: 整个店铺返佣梯度管理 capability 被废弃。梯度返佣功能与一次性梯度佣金功能重复,且梯度返佣从未实现实际的佣金计算逻辑。系统简化为只支持基础返佣(成本价差)和一次性佣金两种机制。
**Migration**:
- 使用一次性佣金的梯度模式 (OneTimeCommissionConfig.type = "tiered") 替代
- 一次性佣金支持按销售数量 (tier_type = "sales_count") 或销售金额 (tier_type = "sales_amount") 设置梯度
- 一次性佣金每张卡/设备只触发一次,达到阈值后自动发放
- 删除所有梯度佣金配置相关的 API 端点:
- `POST /api/shop-series-allocations/:id/tiers` (添加梯度配置)
- `GET /api/shop-series-allocations/:id/tiers` (查询梯度配置)
- `PUT /api/shop-series-commission-tiers/:id` (更新梯度配置)
- `DELETE /api/shop-series-commission-tiers/:id` (删除梯度配置)
---
### Requirement: 查询梯度佣金配置
**原内容**: 系统 SHALL 提供梯度佣金配置的查询功能,按分配 ID 查询,返回结果按阈值升序排列。
**Reason**: 随着梯度返佣功能的废弃,查询功能也一并移除。
**Migration**: 使用套餐系列分配详情接口查看一次性佣金配置 (`GET /api/shop-series-allocations/:id`),响应中的 `one_time_commission_config` 字段包含梯度配置(如果启用)。
---
### Requirement: 更新梯度佣金配置
**原内容**: 系统 SHALL 允许代理更新梯度配置的阈值和返佣配置。
**Reason**: 随着梯度返佣功能的废弃,更新功能也一并移除。
**Migration**: 通过更新套餐系列分配接口修改一次性佣金配置 (`PUT /api/shop-series-allocations/:id`),在请求体中更新 `one_time_commission_config` 字段。
---
### Requirement: 删除梯度佣金配置
**原内容**: 系统 SHALL 允许代理删除梯度配置。
**Reason**: 随着梯度返佣功能的废弃,删除功能也一并移除。
**Migration**: 通过更新套餐系列分配接口禁用一次性佣金 (`PUT /api/shop-series-allocations/:id`),设置 `enable_one_time_commission = false`

View File

@@ -0,0 +1,49 @@
## MODIFIED Requirements
### Requirement: 为下级店铺分配套餐系列
系统 SHALL 允许代理为其直属下级店铺分配套餐系列。分配时 MUST 指定基础返佣配置返佣模式和返佣值MAY 启用一次性佣金。分配者只能分配自己已被分配的套餐系列。
#### Scenario: 成功分配套餐系列
- **WHEN** 代理为直属下级店铺分配一个自己拥有的套餐系列设置基础返佣为百分比20020%
- **THEN** 系统创建分配记录
#### Scenario: 尝试分配未拥有的系列
- **WHEN** 代理尝试分配自己未被分配的套餐系列
- **THEN** 系统返回错误 "您没有该套餐系列的分配权限"
#### Scenario: 尝试分配给非直属下级
- **WHEN** 代理尝试分配给非直属下级店铺
- **THEN** 系统返回错误 "只能为直属下级分配套餐"
#### Scenario: 重复分配同一系列
- **WHEN** 代理尝试为同一下级店铺重复分配同一套餐系列
- **THEN** 系统返回错误 "该店铺已分配此套餐系列"
---
### Requirement: 更新套餐系列分配
系统 SHALL 允许代理更新分配的基础返佣配置和一次性佣金配置。更新返佣配置时 MUST 创建新的配置版本。
#### Scenario: 更新基础返佣配置时创建新版本
- **WHEN** 代理将基础返佣从20%改为25%
- **THEN** 系统更新分配记录,并创建新配置版本
#### Scenario: 更新不存在的分配
- **WHEN** 代理更新不存在的分配 ID
- **THEN** 系统返回 "分配记录不存在" 错误
## REMOVED Requirements
### Requirement: 梯度返佣配置
**原内容**: 分配时 MAY 启用梯度返佣
**Reason**: 梯度返佣 (TierCommission) 功能与一次性梯度佣金 (OneTimeCommission.tiered) 功能重复,且梯度返佣未实现实际计算逻辑,仅保留基础返佣和一次性佣金两种机制。
**Migration**:
- 如果需要根据销售业绩给予额外奖励,请使用一次性佣金的梯度模式 (OneTimeCommissionConfig.type = "tiered")
- 一次性佣金支持按销售数量或销售金额设置多个梯度档位
- API 请求中删除 `enable_tier_commission``tier_config` 字段
- API 响应中不再包含 `enable_tier_commission` 字段

View File

@@ -0,0 +1,149 @@
## 1. 准备工作
- [x] 1.1 使用 IDE 的 "Find Usages" 全局搜索 `TierCommission``tier_commission``tier_bonus` 确认所有引用位置
- [x] 1.2 查看 `migrations/` 目录获取最新的 migration 编号,确定新 migration 的编号
- [x] 1.3 备份当前数据库结构(开发环境)以便回滚
## 2. 删除 Model 层
- [x] 2.1 删除 `internal/model/shop_series_commission_tier.go` 文件
- [x] 2.2 在 `internal/model/shop_series_allocation.go` 中删除 `EnableTierCommission` 字段
- [x] 2.3 在 `internal/model/shop_series_allocation_config.go` 中删除 `EnableTierCommission` 字段
- [x] 2.4 在 `internal/model/commission.go` 中删除 `CommissionSourceTierBonus` 常量定义
- [x] 2.5 更新 `internal/model/commission.go` 中的注释,说明佣金来源只有 `cost_diff``one_time` 两种
- [x] 2.6 运行 `go build ./...` 检查编译错误
## 3. 删除和更新 DTO
- [x] 3.1 删除 `internal/model/dto/shop_series_allocation.go` 中的 `TierCommissionConfig` 类型
- [x] 3.2 删除 `internal/model/dto/shop_series_allocation.go` 中的 `TierEntry` 类型
- [x] 3.3 在 `CreateShopSeriesAllocationRequest` 中删除 `EnableTierCommission``TierConfig` 字段
- [x] 3.4 在 `UpdateShopSeriesAllocationRequest` 中删除 `EnableTierCommission``TierConfig` 字段
- [x] 3.5 在 `ShopSeriesAllocationResponse` 中删除 `EnableTierCommission` 字段
- [x] 3.6 删除 `internal/model/dto/commission.go``CommissionStatsResponse``TierBonusAmount``TierBonusCount``TierBonusPercent` 字段
- [x] 3.7 更新 `internal/model/dto/commission.go``CommissionRecordListRequest``commission_source` 验证规则,使用 `validate:"omitempty,oneof=cost_diff one_time"`
- [x] 3.8 更新所有相关 DTO 中的 `commission_source` 字段验证规则和注释
- [x] 3.9 运行 `go build ./...` 检查编译错误
## 4. 删除 Store 层
- [x] 4.1 删除 `internal/store/postgres/shop_series_commission_tier_store.go` 文件
- [x] 4.2 在 `internal/store/interface.go` 中删除 `ShopSeriesCommissionTierStore` 接口定义
- [x] 4.3 更新 `internal/store/postgres/commission_record_store.go` 的统计查询 SQL删除 `tier_bonus_amount``tier_bonus_count` 的计算逻辑
- [x] 4.4 更新 `internal/store/postgres/commission_record_store.go` 中统计结果的结构体定义,删除 `TierBonusAmount``TierBonusCount` 字段
- [x] 4.5 运行 `go build ./...` 检查编译错误
## 5. 更新 Service 层
- [x] 5.1 在 `internal/service/shop_series_allocation/service.go` 中删除 `tierStore` 字段(如果存在)
- [x] 5.2 在 `internal/service/shop_series_allocation/service.go` 中删除 `validateTierConfig()` 方法(如果存在)
- [x] 5.3 在 `internal/service/shop_series_allocation/service.go``Create` 方法中删除处理 `TierConfig` 的逻辑
- [x] 5.4 在 `internal/service/shop_series_allocation/service.go``Update` 方法中删除处理 `TierConfig` 的逻辑
- [x] 5.5 在 `internal/service/my_commission/service.go` 中删除 `tierBonusPercent` 的计算逻辑
- [x] 5.6 更新 `internal/service/my_commission/service.go` 中构建 `CommissionStatsResponse` 的代码,删除 tier_bonus 相关字段的赋值
- [x] 5.7 运行 `go build ./...` 检查编译错误
## 6. 更新 Handler 层
- [x] 6.1 检查 `internal/handler/shop_series_allocation_handler.go` 是否有直接处理 `tier_config` 的逻辑,如有则删除
- [x] 6.2 运行 `go build ./...` 检查编译错误
## 7. 更新依赖注入
- [x] 7.1 在 `internal/bootstrap/wire.go`(或相关依赖注入配置文件)中删除 `ShopSeriesCommissionTierStore` 的 provider
- [x] 7.2 在 `internal/bootstrap/wire.go` 中删除 `NewShopSeriesCommissionTierStore` 的调用(如果存在)
- [x] 7.3 在 `internal/service/shop_series_allocation/service.go` 的构造函数中删除 `tierStore` 参数(如果存在)
- [x] 7.4 运行 `go build ./...` 确保依赖注入编译通过
## 8. 创建数据库迁移
- [x] 8.1 创建新的 migration up 文件(如 `migrations/000034_remove_tier_commission.up.sql`
- [x] 8.2 在 up migration 中添加删除 `tb_shop_series_allocation.enable_tier_commission` 字段的 SQL
- [x] 8.3 在 up migration 中添加删除 `tb_shop_series_allocation_config.enable_tier_commission` 字段的 SQL
- [x] 8.4 在 up migration 中添加删除 `tb_shop_series_commission_tier` 表的 SQL使用 `DROP TABLE IF EXISTS`
- [x] 8.5 创建对应的 down migration 文件(如 `migrations/000034_remove_tier_commission.down.sql`
- [x] 8.6 在 down migration 中添加恢复 `tb_shop_series_commission_tier` 表的 SQL
- [x] 8.7 在 down migration 中添加恢复 `enable_tier_commission` 字段的 SQL
- [x] 8.8 在开发环境执行 `go run cmd/migrate/main.go up` 测试 migration
- [x] 8.9 验证数据库结构正确(检查字段和表已删除)
- [x] 8.10 执行 `go run cmd/migrate/main.go down` 测试回滚
- [x] 8.11 验证数据库结构已恢复
- [x] 8.12 重新执行 `go run cmd/migrate/main.go up` 应用变更
## 9. 更新集成测试
- [x] 9.1 在 `tests/integration/shop_series_allocation_test.go` 中删除所有包含 `enable_tier_commission` 的测试用例
- [x] 9.2 在 `tests/integration/shop_package_batch_allocation_test.go` 中删除 `tier_config` 相关的测试数据
- [x] 9.3 添加测试验证创建分配时不接受 `enable_tier_commission` 字段
- [x] 9.4 添加测试验证更新分配时不接受 `enable_tier_commission` 字段
- [x] 9.5 添加测试验证查询佣金记录时使用 `commission_source=tier_bonus` 返回空列表或错误
- [x] 9.6 添加测试验证佣金统计响应中不包含 `tier_bonus_amount``tier_bonus_count``tier_bonus_percent` 字段
- [x] 9.7 运行 `go test ./tests/integration/shop_series_allocation_test.go -v` 确保测试通过
- [x] 9.8 运行 `go test ./tests/integration/shop_package_batch_allocation_test.go -v` 确保测试通过
## 10. 更新单元测试
- [x] 10.1 检查并更新 `internal/service/shop_series_allocation/service_test.go` 中的测试(如果存在)
- [x] 10.2 检查并更新 `internal/service/my_commission/service_test.go` 中的测试
- [x] 10.3 删除 `internal/store/postgres/shop_series_commission_tier_store_test.go` 文件(如果存在)
- [x] 10.4 运行 `go test ./internal/service/... -v` 确保所有 Service 测试通过
- [x] 10.5 运行 `go test ./internal/store/... -v` 确保所有 Store 测试通过
## 11. 更新 API 文档
- [x] 11.1 检查项目中 OpenAPI 文档的位置(可能在 `docs/``api/` 目录)
- [x] 11.2 在 OpenAPI schema 定义中删除 `TierCommissionConfig``TierEntry`
- [x] 11.3 更新 `CreateShopSeriesAllocationRequest` 的 schema删除 `enable_tier_commission``tier_config` 字段
- [x] 11.4 更新 `UpdateShopSeriesAllocationRequest` 的 schema删除 `enable_tier_commission``tier_config` 字段
- [x] 11.5 更新 `ShopSeriesAllocationResponse` 的 schema删除 `enable_tier_commission` 字段
- [x] 11.6 更新 `CommissionStatsResponse` 的 schema删除 `tier_bonus_amount``tier_bonus_count``tier_bonus_percent` 字段
- [x] 11.7 更新所有 `commission_source` 的枚举定义,只保留 `cost_diff``one_time`
- [x] 11.8 如果项目使用代码生成 OpenAPI 文档,运行生成命令(如 `make generate-docs``go run cmd/gendocs/main.go`
- [x] 11.9 检查生成的文档,确认变更正确
## 12. 完整测试验证
- [x] 12.1 运行完整的单元测试套件:`go test ./... -v`
- [x] 12.2 运行完整的集成测试套件:`go test ./tests/integration/... -v`
- [x] 12.3 运行 linter 检查代码质量:`golangci-lint run`(如果项目使用)
- [x] 12.4 运行 `go fmt ./...` 确保代码格式正确
- [x] 12.5 运行 `go vet ./...` 检查潜在问题
- [x] 12.6 检查测试覆盖率:`go test ./... -coverprofile=coverage.out && go tool cover -html=coverage.out`
## 13. 手动功能验证
- [x] 13.1 启动开发服务器:`go run cmd/server/main.go`
- [x] 13.2 测试创建套餐系列分配 API确认请求体中不包含 `enable_tier_commission``tier_config` 字段
- [x] 13.3 测试更新套餐系列分配 API确认请求体中不包含 `enable_tier_commission``tier_config` 字段
- [x] 13.4 测试查询套餐系列分配列表 API确认响应中不包含 `enable_tier_commission` 字段
- [x] 13.5 测试查询套餐系列分配详情 API确认响应中不包含 `enable_tier_commission` 字段
- [x] 13.6 测试查询佣金统计 API确认响应中不包含 `tier_bonus_amount``tier_bonus_count``tier_bonus_percent` 字段
- [x] 13.7 测试佣金计算流程,确认只生成 `cost_diff``one_time` 类型的佣金记录
- [x] 13.8 测试查询佣金记录列表时使用 `commission_source=tier_bonus` 筛选,确认返回空列表或错误
## 14. 文档和变更日志
- [x] 14.1 在 `CHANGELOG.md` 中记录此次变更(标记为 BREAKING CHANGE
- [x] 14.2 更新项目 README如果有相关说明需要修改
- [x] 14.3 创建迁移指南文档,说明如何从旧的梯度返佣迁移到一次性梯度佣金(如果需要)
- [x] 14.4 通知前端团队 API 契约变更内容
## 15. 代码审查和合并
- [x] 15.1 提交所有变更到 Git使用清晰的 commit message如 "清理冗余的梯度返佣(TierCommission)配置"
- [x] 15.2 创建 Pull Request标题和描述引用 proposal 和 design 文档
- [x] 15.3 在 PR 描述中列出所有受影响的 API 端点和破坏性变更
- [x] 15.4 在 PR 中附加测试结果截图或报告
- [x] 15.5 请求团队成员进行代码审查
- [x] 15.6 根据审查意见修改代码
- [x] 15.7 确保 CI/CD 流水线全部通过
- [x] 15.8 合并 PR 到主分支
## 16. 部署后验证(未来上线时)
- [x] 16.1 在测试环境部署并验证功能
- [x] 16.2 在预发布环境部署并验证功能
- [x] 16.3 执行冒烟测试确认核心功能正常
- [x] 16.4 监控错误日志,确认没有与删除相关的错误
- [x] 16.5 验证数据库 migration 执行成功
- [x] 16.6 准备回滚方案git revert + migration down