# Proposal: 套餐系统升级 - 支持自然月/按天套餐与多套餐管理

## Why

现有套餐系统仅支持简单的按月计算模式，无法满足业务方提出的复杂套餐需求。具体痛点包括：(1) 代理商囤货场景无法支持 - 需要提前为未实名设备低价采购套餐，等待首次实名时自动激活；(2) 套餐类型单一 - 缺少自然月套餐（按月边界计算）和按天套餐（灵活天数）；(3) 多套餐管理混乱 - 主套餐可同时多个生效、加油包无生命周期管理、流量扣减无优先级；(4) 流量统计不精细 - 客户无法区分主套餐和加油包用量，缺少套餐维度的流量详单。这些限制直接影响运营效率和用户体验。

## What Changes

### 套餐模型扩展
- 新增 `calendar_type` 字段：支持 `natural_month`（自然月套餐）和 `by_day`（按天套餐）
- 新增 `data_reset_cycle` 字段：支持 `daily`、`monthly`、`yearly`、`none` 四种流量重置周期
- 新增 `enable_realname_activation` 字段：标识是否需要首次实名激活（后台囤货场景）

### 套餐使用记录扩展
- PackageUsage 表 `status` 字段扩展：
  - 0 - 待生效（等待实名或排队中）
  - 1 - 生效中
  - 2 - 已用完
  - 3 - 已过期
  - 4 - 已失效（加油包跟随主套餐失效）
- 新增 `priority` 字段：主套餐排队顺序（数字越小优先级越高）
- 新增 `master_usage_id` 字段：加油包关联的主套餐ID
- 新增 `has_independent_expiry` 字段：加油包是否有独立有效期
- 新增 `pending_realname_activation` 字段：是否等待实名激活
- 新增流量重置相关字段：`data_reset_cycle`、`last_reset_at`、`next_reset_at`

### 新增套餐流量日记录表
- 创建 `PackageUsageDailyRecord` 表，按套餐维度记录每日流量增量
- 字段：`package_usage_id`、`date`、`daily_usage_mb`、`cumulative_usage_mb`
- 索引：`package_usage_id + date` 联合唯一索引

### 业务逻辑改造
- **首次实名激活**：轮询系统检测到首次实名时，触发 Asynq 任务激活待生效套餐
- **主套餐排队**：订单服务购买主套餐时，自动分配 priority，当前主套餐过期后调度器自动激活下一个
- **加油包生命周期**：主套餐过期时，轮询系统级联失效其关联的所有加油包
- **流量扣减优先级**：轮询系统更新流量时，优先扣减加油包（按 priority），再扣主套餐
- **停机条件**：轮询系统检查主套餐 + 所有加油包流量都用完才触发停机
- **流量重置调度**：定时任务根据 `data_reset_cycle` 定期重置套餐流量

### API 改造
- **套餐管理 API** (`/api/admin/packages`)：
  - POST/PUT 支持新增字段（calendar_type, data_reset_cycle, enable_realname_activation）
  - GET 返回包含新增字段
- **订单 API** (`/api/admin/orders` 和 `/api/h5/orders`)：
  - POST 支持主套餐排队逻辑（自动分配 priority）
  - POST 支持加油包购买限制（必须有主套餐）
  - 客户端未实名时购买套餐返回错误
- **流量查询 API**（新增）：
  - `GET /api/h5/packages/my-usage` - 客户视图（主套餐、每个加油包、总计）
  - `GET /api/admin/package-usage/:id/daily-records` - 套餐流量详单（按日）
  - 现有卡流量详单继续按卡维度统计

### 轮询系统扩展
- 新增套餐激活检查任务（HandlePackageActivation）
- 新增流量重置调度任务（HandleDataReset）
- 扩展流量检查任务（HandleCarddataCheck）支持新的扣减优先级和停机条件

## Capabilities

### New Capabilities
- `package-calendar-type` - 套餐周期类型管理（自然月/按天）
- `package-data-reset` - 套餐流量重置周期管理
- `package-realname-activation` - 首次实名激活机制
- `package-queue-activation` - 主套餐排队生效机制
- `addon-package-lifecycle` - 加油包生命周期管理
- `package-usage-priority` - 流量扣减优先级机制
- `package-usage-daily-record` - 套餐流量日记录
- `package-usage-customer-view` - 客户视图流量查询

### Modified Capabilities
- `package-management` - 套餐管理能力扩展（新增字段支持）
- `order-management` - 订单管理能力扩展（主套餐排队、加油包购买限制）
- `iot-card` - IoT卡轮询系统扩展（流量扣减优先级、停机条件）

## Impact

### 数据库
- 修改 `tb_package` 表（新增 3 个字段）
- 修改 `tb_package_usage` 表（新增 7 个字段，扩展 status 枚举）
- 新增 `tb_package_usage_daily_record` 表
- 需要数据库迁移脚本

### 代码模块
- `internal/model/package.go` - Package 和 PackageUsage 模型扩展
- `internal/model/package_usage_daily_record.go` - 新增模型
- `internal/service/order/` - 订单服务改造（主套餐排队、加油包限制）
- `internal/service/package/` - 套餐服务改造（支持新字段）
- `internal/polling/` - 轮询系统扩展（激活调度、流量扣减优先级、重置调度）
- `internal/handler/admin/package.go` - Handler 层 API 改造
- `internal/handler/h5/package_usage.go` - 新增客户视图 Handler
- `internal/store/postgres/package*.go` - Store 层查询逻辑扩展
- `pkg/errors/codes.go` - 新增错误码

### API
- **BREAKING** - `POST /api/admin/packages` 请求体新增可选字段
- **BREAKING** - `GET /api/admin/packages/:id` 响应体新增字段
- **NEW** - `GET /api/h5/packages/my-usage` - 客户视图
- **NEW** - `GET /api/admin/package-usage/:id/daily-records` - 套餐流量详单
- **BREAKING** - `POST /api/admin/orders` 和 `POST /api/h5/orders` 行为变更（主套餐排队、加油包限制）

### 依赖系统
- **Asynq 任务队列** - 新增套餐激活任务类型、流量重置任务类型
- **轮询系统** - 扩展流量检查、新增激活检查、新增重置调度
- **OpenAPI 文档生成器** - 需要更新以支持新增 Handler

### 性能
- 套餐激活调度延迟目标 < 1分钟
- 流量查询 API P95 < 200ms（现有要求保持）
- 轮询系统千万级卡规模支持不退化

### 测试
- 核心业务逻辑单元测试覆盖率 ≥ 90%
- 所有 Spec Scenarios 有对应的验收测试
- 需要编写集成测试验证完整流程（囤货 → 实名 → 激活 → 扣减 → 重置）
