## ADDED Requirements

### Requirement: 套餐流量对外语义统一
系统 SHALL 以套餐使用记录为事实源，对外统一返回 `real_total_mb`、`real_used_mb`、`virtual_total_mb`、`virtual_used_mb` 和 `reduction_pct`，不再要求调用方从旧字段或 live `tb_package` 值自行拼接流量语义。

**字段语义**:
- `real_total_mb`: 套餐真实总量
- `real_used_mb`: 套餐真实已用量
- `virtual_total_mb`: 套餐业务停机阈值
- `virtual_used_mb`: 将 `real_used_mb` 映射到 `real_total_mb` 刻度后的展示值
- `reduction_pct`: 默认按 `(real_total_mb / virtual_total_mb) - 1` 计算，字段名继续沿用业务口语“缩减比例”，接口返回值使用 `0.428571` 这种比例小数格式

#### Scenario: 启用虚流量时返回统一五字段
- **WHEN** 某条套餐使用记录的 `real_total_mb=100`、`real_used_mb=50`、`virtual_total_mb=70`
- **THEN** 系统返回 `virtual_used_mb=71.43`
- **AND** 同时返回 `reduction_pct=0.428571...`

#### Scenario: 未启用虚流量时退化为真流量视图
- **WHEN** 某条套餐使用记录未启用虚流量
- **THEN** 系统返回 `virtual_total_mb = real_total_mb`
- **AND** `virtual_used_mb = real_used_mb`
- **AND** `reduction_pct=0`

### Requirement: 虚已用展示公式统一
系统 SHALL 使用统一公式计算 `virtual_used_mb`：`min(real_used_mb * (real_total_mb / virtual_total_mb), real_total_mb)`。

#### Scenario: 真已用接近虚阈值时展示接近满量程
- **WHEN** `real_total_mb=100`、`virtual_total_mb=70`、`real_used_mb=69`
- **THEN** 系统返回 `virtual_used_mb=98.57`

#### Scenario: 真已用达到虚阈值时展示封顶
- **WHEN** `real_total_mb=100`、`virtual_total_mb=70`、`real_used_mb=70`
- **THEN** 系统返回 `virtual_used_mb=100`

### Requirement: 套餐耗尽阈值统一
系统 SHALL 将套餐业务耗尽阈值统一定义为：启用虚流量时使用 `virtual_total_mb`，未启用虚流量时使用 `real_total_mb`。

#### Scenario: 启用虚流量时按虚阈值耗尽
- **WHEN** 某条套餐使用记录 `real_total_mb=100`、`virtual_total_mb=70`、`real_used_mb=70`
- **THEN** 系统将该套餐判定为已用完

#### Scenario: 未启用虚流量时按真总量耗尽
- **WHEN** 某条套餐使用记录未启用虚流量且 `real_used_mb=real_total_mb`
- **THEN** 系统将该套餐判定为已用完

### Requirement: 历史套餐流量快照可回放
系统 SHALL 在 `tb_package_usage` 上持久化虚总量与展示映射所需快照，以保证历史流量展示不继续依赖 live `tb_package` 值。

#### Scenario: 创建新套餐使用记录时写入快照
- **WHEN** 系统创建新的 `PackageUsage`
- **THEN** 同步写入 `virtual_total_mb_snapshot`、展示倍率快照和虚流量开关快照

#### Scenario: 历史套餐记录执行一次性回填
- **WHEN** 本次变更上线执行历史数据迁移
- **THEN** 系统为已有 `PackageUsage` 回填虚总量与展示倍率快照
- **AND** 后续读链路优先读取快照值而不是 `tb_package` 当前值
