# one-time-commission-trigger Specification

## Purpose
一次性佣金触发机制 - 定义单次充值和累计充值两种触发条件、佣金发放规则、配置获取和幂等性保障。
## Requirements
### Requirement: 一次性充值触发佣金

系统 SHALL 支持"一次性充值"触发条件：当单笔订单金额 ≥ 配置阈值时触发一次性佣金。

#### Scenario: 达到一次性充值阈值
- **WHEN** 订单金额 500 元，配置阈值 300 元，该卡未发放过一次性佣金
- **THEN** 系统发放一次性佣金，标记卡的 first_commission_paid 为 true

#### Scenario: 未达到阈值
- **WHEN** 订单金额 200 元，配置阈值 300 元
- **THEN** 系统不发放一次性佣金

#### Scenario: 已发放过一次性佣金
- **WHEN** 订单金额 500 元，但卡的 first_commission_paid 已为 true
- **THEN** 系统不重复发放一次性佣金

---

### Requirement: 累计充值触发佣金

系统 SHALL 支持"累计充值"触发条件：当卡/设备的累计充值金额 ≥ 配置阈值时触发一次性佣金。

**关键修复**：每次支付成功后必须更新累计充值金额，确保累计值能正确递增并达到阈值。

#### Scenario: 累计达到阈值

- **WHEN** 卡之前累计充值 200 元，本次充值 150 元，配置阈值 300 元
- **THEN** 系统更新累计充值为 350 元
- **AND** 累计 350 元 ≥ 300 元，系统发放一次性佣金
- **AND** 标记 first_commission_paid = true

#### Scenario: 累计未达到阈值

- **WHEN** 卡之前累计充值 100 元，本次充值 100 元，配置阈值 300 元
- **THEN** 系统更新累计充值为 200 元
- **AND** 累计 200 元 < 300 元，系统不发放一次性佣金

#### Scenario: 每次支付都更新累计值

- **WHEN** 卡累计充值为 50 元
- **AND** 连续发生 3 次充值：100 元、150 元、80 元
- **THEN** 第 1 次充值后累计 150 元
- **AND** 第 2 次充值后累计 300 元
- **AND** 第 3 次充值后累计 380 元

---

### Requirement: 一次性佣金只发放一次

每张卡/设备的一次性佣金 SHALL 只发放一次，通过 first_commission_paid 字段控制。

#### Scenario: 首次触发
- **WHEN** 首次满足触发条件
- **THEN** 发放佣金，设置 first_commission_paid = true

#### Scenario: 再次满足条件
- **WHEN** 再次满足触发条件但 first_commission_paid 已为 true
- **THEN** 不发放佣金

---

### Requirement: 一次性佣金配置获取

一次性佣金的触发条件和金额 SHALL 从 ShopSeriesAllocation 配置获取。

**关键修复**：配置必须能够通过 ShopSeriesAllocation 创建/更新接口正确落库并生效。

#### Scenario: 获取触发条件和金额

- **WHEN** 触发一次性佣金检查
- **THEN** 系统从卡关联的 ShopSeriesAllocation 获取 one_time_commission_trigger（触发类型）、one_time_commission_threshold（阈值）、one_time_commission_mode（模式）、one_time_commission_value（金额/比例）

#### Scenario: 固定类型配置

- **WHEN** 创建 ShopSeriesAllocation 时设置 one_time_commission_type = "fixed"
- **AND** 设置 one_time_commission_mode = "fixed"，one_time_commission_value = 5000（50 元）
- **THEN** 系统将配置正确写入数据库
- **AND** 查询该配置时能正确返回所有一次性佣金字段

#### Scenario: 梯度类型配置

- **WHEN** 创建 ShopSeriesAllocation 时设置 one_time_commission_type = "tiered"
- **AND** 提供梯度档位配置：[{threshold: 100, mode: "fixed", value: 2000}, {threshold: 300, mode: "percent", value: 10}]
- **THEN** 系统将主配置写入 tb_shop_series_allocation
- **AND** 将档位配置写入 tb_shop_series_one_time_commission_tier
- **AND** 查询该配置时能正确返回主配置和关联的档位列表

#### Scenario: 更新梯度配置

- **WHEN** 更新 ShopSeriesAllocation 的梯度配置
- **AND** 新档位配置与旧配置不同
- **THEN** 系统先删除旧档位数据（WHERE allocation_id = ?）
- **AND** 再批量插入新档位数据
- **AND** 查询时返回最新的档位配置

#### Scenario: 无一次性佣金配置

- **WHEN** 卡关联的系列分配未启用一次性佣金（enable_one_time_commission = false）
- **THEN** 不发放一次性佣金

---

### Requirement: 一次性佣金发放对象

一次性佣金 SHALL 发放给卡/设备的直接归属店铺。

#### Scenario: 发放给归属店铺
- **WHEN** 卡归属店铺 A，触发一次性佣金
- **THEN** 佣金入账到店铺 A 的钱包

---

### Requirement: 配置参数校验

系统 MUST 在创建/更新 ShopSeriesAllocation 时校验一次性佣金配置的完整性。

#### Scenario: 启用一次性佣金必须提供配置

- **WHEN** 创建 ShopSeriesAllocation 时设置 enable_one_time_commission = true
- **AND** 未提供 one_time_commission_config
- **THEN** 系统返回错误：一次性佣金配置无效（错误码 40101）

#### Scenario: 固定类型必须提供 mode 和 value

- **WHEN** 一次性佣金类型为 "fixed"
- **AND** one_time_commission_mode 或 one_time_commission_value 为空
- **THEN** 系统返回错误：一次性佣金模式/金额缺失（错误码 40102/40103）

#### Scenario: 梯度类型必须提供 tiers

- **WHEN** 一次性佣金类型为 "tiered"
- **AND** tiers 配置为空或 null
- **THEN** 系统返回错误：梯度佣金档位配置缺失（错误码 40104）

#### Scenario: 梯度档位配置校验

- **WHEN** 提供的梯度档位缺少必填字段（threshold_value、commission_mode、commission_value）
- **THEN** 系统返回错误：梯度佣金档位配置无效（错误码 40105）

### Requirement: 一次性佣金触发条件

系统 SHALL 在满足一次性佣金阈值规则的前提下，仅对客户端订单触发一次性佣金。

完整触发判断 MUST 为：`!order.IsPurchaseOnBehalf && order.Source == "client"`。

#### Scenario: 客户端自购订单触发
- **WHEN** 订单满足阈值条件，且 `order.IsPurchaseOnBehalf=false`，`order.Source="client"`
- **THEN** 系统 SHALL 触发一次性佣金计算

#### Scenario: 代购订单不触发
- **WHEN** 订单满足阈值条件，但 `order.IsPurchaseOnBehalf=true`
- **THEN** 系统 SHALL 不触发一次性佣金

#### Scenario: 后台订单不触发
- **WHEN** 订单满足阈值条件，且 `order.Source="admin"`
- **THEN** 系统 SHALL 不触发一次性佣金

