# Number Card Management

## Purpose

Manage number cards (virtual products) for carrier order callbacks, supporting carrier order passthrough, agent promotion, commission processing, and carrier settlement tracking.

This capability supports:
- Number card entity definition as virtual product mapping
- Carrier order callbacks from Gateway project
- Agent promotion via links or offline cards
- Commission processing for number card orders
- Carrier settlement tracking for financial reconciliation
- Integration with existing commission rules (one-time, long-term, combined)

## Requirements

### Requirement: 号卡实体定义

系统 SHALL 定义号卡(NumberCard)实体,作为运营商订单回传的映射,支持代理分销和分佣。

**实体字段**:
- `id`: 号卡 ID(主键,BIGINT)
- `virtual_product_code`: 虚拟商品编码(VARCHAR(100),唯一,用于对应运营商订单)
- `product_name`: 商品名称(VARCHAR(255))
- `carrier`: 运营商名称(VARCHAR(100),如 "中国移动"、"中国联通"、"中国电信")
- `carrier_product_id`: 运营商商品 ID(VARCHAR(100))
- `package_type`: 套餐类型(VARCHAR(50),如 "月套餐"、"流量包")
- `data_amount_mb`: 流量额度(BIGINT,MB 为单位,可选)
- `voice_minutes`: 语音分钟数(INT,可选)
- `sms_count`: 短信条数(INT,可选)
- `price`: 固定售价(DECIMAL(10,2),由运营商定价)
- `status`: 号卡状态(INT,1-上架 2-下架)
- `created_at`: 创建时间(TIMESTAMP,自动填充)
- `updated_at`: 更新时间(TIMESTAMP,自动填充)

#### Scenario: 创建号卡商品

- **WHEN** 平台创建号卡商品,虚拟商品编码为 "VC-CMCC-001",运营商为"中国移动",固定售价为 30.00 元
- **THEN** 系统创建号卡记录,`virtual_product_code` 为 "VC-CMCC-001",`carrier` 为 "中国移动",`price` 为 30.00,状态为 1(上架)

#### Scenario: 虚拟商品编码唯一性

- **WHEN** 平台创建号卡商品,虚拟商品编码为已存在的 "VC-CMCC-001"
- **THEN** 系统拒绝创建,返回错误信息"虚拟商品编码已存在"

---

### Requirement: 号卡运营商订单回传

系统 SHALL 接收 Gateway 项目转换后的运营商订单回传,通过虚拟商品编码匹配号卡,创建订单和分佣记录。

**订单回传字段**:
- `carrier_order_id`: 运营商订单 ID(VARCHAR(255),唯一)
- `virtual_product_code`: 虚拟商品编码(VARCHAR(100),用于匹配号卡)
- `user_phone`: 用户手机号(VARCHAR(20))
- `amount`: 订单金额(DECIMAL(10,2))
- `order_time`: 订单时间(TIMESTAMP)
- `agent_id`: 代理 ID(BIGINT,可空,如果通过代理推广则有值)
- `carrier_order_data`: 运营商订单原始数据(JSONB)

**回传处理流程**:
1. Gateway 接收运营商订单,统一转换为 JSON 格式
2. Gateway 通过 HTTP POST 回传给 CMP 系统
3. CMP 系统根据 `virtual_product_code` 匹配号卡
4. CMP 系统创建订单记录(`order_type` 为 "number_card")
5. 如果有 `agent_id`,触发代理分佣流程

#### Scenario: 接收运营商订单回传

- **WHEN** Gateway 回传运营商订单,虚拟商品编码为 "VC-CMCC-001",代理 ID 为 123,订单金额为 30.00 元
- **THEN** 系统创建订单记录,`order_type` 为 "number_card",`source_id` 为号卡 ID,`agent_id` 为 123,触发分佣计算

#### Scenario: 虚拟商品编码不存在

- **WHEN** Gateway 回传运营商订单,虚拟商品编码为不存在的 "VC-UNKNOWN"
- **THEN** 系统拒绝创建订单,返回错误信息"虚拟商品编码不存在"并记录到日志

---

### Requirement: 号卡代理分销

系统 SHALL 支持号卡的代理分销,代理通过推广链接或卡板推广号卡给终端用户。

**分销规则**:
- 号卡由运营商定价,平台无权修改价格
- 代理通过推广链接或卡板获取用户激活
- 用户激活充值后,资金直接支付给运营商,不经过平台
- 运营商周期性结算总佣金给平台
- 平台根据代理分佣规则分配佣金给代理

**代理推广方式**:
- **推广链接**: 代理生成带有 `agent_id` 的推广链接,用户点击链接激活
- **卡板**: 代理线下分发印有二维码的卡板,用户扫码激活

#### Scenario: 代理生成推广链接

- **WHEN** 代理商(用户 ID 为 123)为号卡(ID 为 5001)生成推广链接
- **THEN** 系统生成带有 `agent_id=123` 和 `product_id=5001` 的推广链接,如 `https://example.com/activate?agent=123&product=5001`

#### Scenario: 用户通过代理链接激活

- **WHEN** 用户通过代理推广链接激活号卡并充值 30.00 元
- **THEN** 运营商接收用户支付,Gateway 回传订单时包含 `agent_id=123`,系统触发代理分佣流程

---

### Requirement: 号卡分佣处理

系统 SHALL 根据号卡分佣规则计算代理佣金,支持冻结和解冻流程。

**分佣规则**:
- 号卡分佣配置在代理分佣规则表(`commission_rules`)中
- 分佣类型:一次性分佣、长期分佣、组合分佣(参考 iot-agent-commission 规范)
- 号卡订单的分佣需要满足条件:激活(实名) + 达到充值金额 + 在网状态 + 三无校验
- 分佣记录创建时状态为"冻结",满足条件后变为"解冻中",审批通过后变为"已发放"

#### Scenario: 号卡订单触发分佣

- **WHEN** 运营商回传订单,代理 ID 为 123,订单金额为 30.00 元,该代理配置了一次性分佣 5.00 元
- **THEN** 系统创建分佣记录,金额为 5.00 元,状态为"冻结",等待满足解冻条件

#### Scenario: 号卡分佣解冻

- **WHEN** 号卡订单满足解冻条件(激活 + 充值 + 在网 + 三无校验)
- **THEN** 系统将分佣记录状态从"冻结"变更为"解冻中",创建分佣解冻审批记录

---

### Requirement: 号卡运营商结算

系统 SHALL 记录运营商周期性结算的佣金总额,用于财务对账和利润计算。

**结算字段**:
- `settlement_id`: 结算记录 ID(主键,BIGINT)
- `carrier`: 运营商名称(VARCHAR(100))
- `settlement_period`: 结算周期(VARCHAR(50),如 "2025-01")
- `total_commission`: 运营商结算的佣金总额(DECIMAL(18,2))
- `settlement_time`: 结算时间(TIMESTAMP)
- `status`: 结算状态(INT,1-待确认 2-已确认)
- `created_at`: 创建时间(TIMESTAMP,自动填充)
- `updated_at`: 更新时间(TIMESTAMP,自动填充)

#### Scenario: 记录运营商结算

- **WHEN** 运营商"中国移动"结算 2025 年 1 月的佣金总额 50000.00 元
- **THEN** 系统创建结算记录,`carrier` 为 "中国移动",`settlement_period` 为 "2025-01",`total_commission` 为 50000.00,状态为 1(待确认)

#### Scenario: 确认运营商结算

- **WHEN** 财务确认运营商结算记录(ID 为 1001)
- **THEN** 系统将结算记录状态从 1(待确认) 变更为 2(已确认)

---

### Requirement: 号卡数据校验

系统 SHALL 对号卡数据进行校验,确保数据完整性和一致性。

**校验规则**:
- 虚拟商品编码(virtual_product_code):必填,长度 1-100 字符,唯一
- 商品名称(product_name):必填,长度 1-255 字符
- 运营商名称(carrier):必填,长度 1-100 字符
- 固定售价(price):必填,≥ 0,最多 2 位小数
- 状态(status):必填,枚举值 1(上架) | 2(下架)

#### Scenario: 创建号卡时虚拟商品编码为空

- **WHEN** 平台创建号卡,虚拟商品编码为空
- **THEN** 系统拒绝创建,返回错误信息"虚拟商品编码不能为空"

#### Scenario: 创建号卡时固定售价为负数

- **WHEN** 平台创建号卡,固定售价为 -10.00
- **THEN** 系统拒绝创建,返回错误信息"固定售价必须 ≥ 0"
