## 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 ``` 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` 表的外部系统**? - 状态:待确认 - 建议:检查是否有数据分析、报表系统等外部依赖