# IoT SIM 管理 - 数据模型与数据库表结构实现任务

本任务清单聚焦于 IoT SIM 管理模块的数据模型定义和数据库表结构实现，不包含业务逻辑代码。

---

## 1. 数据库迁移脚本

### 1.1 核心业务表
- [x] 1.1.1 创建迁移脚本文件：`migrations/YYYYMMDDHHMMSS_create_iot_sim_management_tables.up.sql` 和 `*.down.sql`
- [x] 1.1.2 创建运营商表(carriers)及其索引
  - 主键索引
  - `carrier_code` 唯一索引
  - 初始数据：中国移动(CMCC)、中国联通(CUCC)、中国电信(CTCC)
- [x] 1.1.3 创建 IoT 卡表(iot_cards)及其索引
  - 主键索引
  - `iccid` 唯一索引
  - `card_category` 字段：枚举值 "normal"(普通卡) | "industry"(行业卡),默认 "normal"
  - `carrier_id` 索引（关联运营商表）
  - `owner_type` + `owner_id` + `status` 组合索引
  - `batch_no` 索引
  - `activated_at` 索引
  - `card_category` 索引（用于区分普通卡和行业卡）
  - `enable_polling` + `activation_status` + `last_data_check_at` 组合索引（卡流量轮询查询优化）
  - `enable_polling` + `real_name_status` + `last_real_name_check_at` 组合索引（实名轮询查询优化）
- [x] 1.1.4 创建设备表(devices)及其索引
  - 主键索引
  - `device_no` 唯一索引
  - `owner_type` + `owner_id` + `status` 组合索引
- [x] 1.1.5 创建号卡表(number_cards)及其索引
  - 主键索引
  - `virtual_product_code` 唯一索引
  - `agent_id` + `status` 组合索引
- [x] 1.1.6 创建套餐系列表(package_series)及其索引
  - 主键索引
  - `series_code` 唯一索引
- [x] 1.1.7 创建套餐表(packages)及其索引
  - 主键索引
  - `package_code` 唯一索引
  - `series_id` + `status` 组合索引
- [x] 1.1.8 创建代理套餐分配表(agent_package_allocations)及其索引
  - 主键索引
  - `agent_id` + `package_id` 唯一组合索引
- [x] 1.1.9 创建设备-IoT卡绑定关系表(device_sim_bindings)及其索引
  - 主键索引
  - `device_id` + `bind_status` 组合索引
  - `iot_card_id` + `bind_status` 组合索引
  - `iot_card_id` 部分唯一索引(WHERE bind_status = 1)
- [x] 1.1.10 创建订单表(orders)及其索引
  - 主键索引
  - `order_no` 唯一索引
  - `user_id` + `status` 组合索引
  - `agent_id` + `status` 组合索引
  - `iot_card_id` 索引
  - `device_id` 索引
  - `number_card_id` 索引

### 1.2 套餐和轮询相关表
- [x] 1.2.1 创建套餐使用情况表(package_usages)及其索引
  - 主键索引
  - `order_id` 索引
  - `package_id` 索引
  - `iot_card_id` 索引
  - `device_id` 索引
  - `status` + `expires_at` + `last_package_check_at` 组合索引（套餐流量检查优化）
- [x] 1.2.2 创建轮询配置表(polling_configs)及其索引
  - 主键索引
  - `config_name` 唯一索引
  - `status` + `card_condition` + `carrier_id` + `priority` 组合索引（配置匹配优化）
- [x] 1.2.3 创建流量使用记录表(data_usage_records)及其索引
  - 主键索引
  - `iot_card_id` + `check_time` 组合索引（按卡和时间查询）
  - `check_time` 索引（按时间范围查询）
  - 注意：此表数据量会快速增长，建议定期清理 90 天前的记录或使用分区表

### 1.3 分佣相关表
- [x] 1.3.1 创建代理层级关系表(agent_hierarchies)及其索引
  - 主键索引
  - `agent_id` 唯一索引
  - `parent_agent_id` 索引
- [x] 1.3.2 创建分佣规则表(commission_rules)及其索引
  - 主键索引
  - `agent_id` + `business_type` + `card_type` 组合索引
- [x] 1.3.3 创建阶梯分佣配置表(commission_ladder)及其索引
  - 主键索引
  - `rule_id` 索引
- [x] 1.3.4 创建组合分佣条件表(commission_combined_conditions)及其索引
  - 主键索引
  - `rule_id` 唯一索引
- [x] 1.3.5 创建分佣记录表(commission_records)及其索引
  - 主键索引
  - `agent_id` + `status` 组合索引
  - `order_id` 索引
  - `rule_id` 索引
- [x] 1.3.6 创建分佣审批表(commission_approvals)及其索引
  - 主键索引
  - `commission_record_id` 索引
  - `status` 索引
- [x] 1.3.7 创建分佣模板表(commission_templates)及其索引
  - 主键索引
  - `template_name` 唯一索引
- [x] 1.3.8 创建号卡运营商结算表(carrier_settlements)及其索引
  - 主键索引
  - `commission_record_id` 唯一索引
  - `agent_id` + `status` 组合索引

### 1.4 财务管理表
- [x] 1.4.1 创建佣金提现申请表(commission_withdrawal_requests)及其索引
  - 主键索引
  - `agent_id` + `status` 组合索引
  - `created_at` 索引
- [x] 1.4.2 创建佣金提现设置表(commission_withdrawal_settings)及其索引
  - 主键索引
  - `status` 索引
- [x] 1.4.3 创建收款商户设置表(payment_merchant_settings)及其索引
  - 主键索引
  - `user_id` + `is_default` 组合索引
  - `merchant_type` + `status` 组合索引

### 1.5 系统管理表
- [x] 1.5.1 创建开发能力配置表(dev_capability_configs)及其索引
  - 主键索引
  - `app_id` 唯一索引
  - `user_id` + `status` 组合索引
- [x] 1.5.2 创建换卡申请表(card_replacement_requests)及其索引
  - 主键索引
  - `user_id` + `status` 组合索引
  - `old_iccid` 索引
  - `new_iccid` 索引

### 1.6 迁移脚本验证
- [x] 1.6.1 编写迁移脚本的 down 部分(删除所有表)
- [x] 1.6.2 在本地测试数据库执行 up 迁移
- [x] 1.6.3 验证所有表和索引创建成功
- [x] 1.6.4 执行 down 迁移验证回滚成功
- [x] 1.6.5 编写迁移脚本的 README 说明(执行步骤、注意事项)

---

## 2. GORM 模型定义

### 2.1 目录结构
- [x] 2.1.1 创建 `internal/iot/model` 目录
- [x] 2.1.2 创建模型文件结构：
  - `carrier.go` - 运营商模型
  - `iot_card.go` - IoT 卡模型
  - `device.go` - 设备模型
  - `number_card.go` - 号卡模型
  - `package.go` - 套餐、套餐系列、套餐使用情况模型
  - `order.go` - 订单模型
  - `polling.go` - 轮询配置模型
  - `data_usage.go` - 流量使用记录模型
  - `commission.go` - 分佣相关模型
  - `financial.go` - 财务管理模型
  - `system.go` - 系统管理模型

### 2.2 核心业务模型
- [x] 2.2.1 定义运营商(Carrier)模型
  - 字段包括：id, carrier_code, carrier_name, description, status, created_at, updated_at
  - 初始数据：中国移动(CMCC)、中国联通(CUCC)、中国电信(CTCC)
- [x] 2.2.2 定义 IoT 卡(IotCard)模型
  - 所有字段必须显式指定 `gorm:"column:字段名"`
  - 添加中文字段注释(comment 标签)
  - 字段包括：id, iccid, card_type, card_category, carrier_id, imsi, msisdn, batch_no, supplier, cost_price, distribute_price, status, owner_type, owner_id, activated_at, activation_status, real_name_status, network_status, data_usage_mb, enable_polling, last_data_check_at, last_real_name_check_at, last_sync_time, created_at, updated_at
  - **关键调整**：
    - `card_category` 字段：枚举值 "normal"(普通卡) | "industry"(行业卡),默认 "normal"
    - `carrier_id` 关联运营商表（替代原来的 carrier 字符串字段）
    - `enable_polling` 控制是否参与轮询（默认 true）
    - `last_data_check_at` 卡流量检查时间
    - `last_real_name_check_at` 实名检查时间
    - 行业卡可以在 `real_name_status` 为 0 的情况下激活使用
- [x] 2.2.3 定义设备(Device)模型
  - 字段包括：id, device_no, device_name, device_model, device_type, max_sim_slots, manufacturer, batch_no, owner_type, owner_id, status, activated_at, device_username, device_password_encrypted, device_api_endpoint, created_at, updated_at
- [x] 2.2.4 定义号卡(NumberCard)模型
  - 字段包括：id, virtual_product_code, card_name, card_type, carrier, data_amount_mb, price, agent_id, status, created_at, updated_at
- [x] 2.2.5 定义套餐系列(PackageSeries)模型
  - 字段包括：id, series_code, series_name, description, status, created_at, updated_at
- [x] 2.2.6 定义套餐(Package)模型
  - 字段包括：id, package_code, package_name, series_id, package_type, duration_months, data_type, real_data_mb, virtual_data_mb, data_amount_mb, price, status, created_at, updated_at
- [x] 2.2.7 定义代理套餐分配(AgentPackageAllocation)模型
  - 字段包括：id, agent_id, package_id, cost_price, retail_price, status, created_at, updated_at
- [x] 2.2.8 定义设备-IoT卡绑定关系(DeviceSimBinding)模型
  - 字段包括：id, device_id, iot_card_id, slot_number, bind_status, bound_at, unbound_at, created_at, updated_at
- [x] 2.2.9 定义订单(Order)模型
  - 字段包括：id, order_no, order_type, iot_card_id, device_id, number_card_id, package_id, user_id, agent_id, amount, payment_method, status, carrier_order_id, carrier_order_data, paid_at, completed_at, created_at, updated_at

### 2.3 套餐和轮询相关模型
- [x] 2.3.1 定义套餐使用情况(PackageUsage)模型
  - 字段包括：id, order_id, package_id, usage_type, iot_card_id, device_id, data_limit_mb, data_usage_mb, real_data_usage_mb, virtual_data_usage_mb, activated_at, expires_at, status, last_package_check_at, created_at, updated_at
  - **业务逻辑**：
    - `usage_type` = "single_card" 时，`iot_card_id` 有值，`device_id` 为 NULL
    - `usage_type` = "device" 时，`device_id` 有值，`iot_card_id` 为 NULL
    - `data_usage_mb` 通过汇总卡的流量计算（单卡套餐直接读卡流量，设备级套餐汇总所有卡流量）
- [x] 2.3.2 定义轮询配置(PollingConfig)模型
  - 字段包括：id, config_name, description, card_condition, carrier_id, real_name_check_enabled, real_name_check_interval, card_data_check_enabled, card_data_check_interval, package_check_enabled, package_check_interval, priority, status, created_at, updated_at
  - **配置说明**：
    - `carrier_id` 为 NULL 表示匹配所有运营商
    - `priority` 数字越小优先级越高
    - 支持独立配置实名检查、卡流量检查、套餐流量检查
- [x] 2.3.3 定义流量使用记录(DataUsageRecord)模型
  - 字段包括：id, iot_card_id, data_usage_mb, data_increase_mb, check_time, source, created_at
  - **业务逻辑**：
    - Worker 每次轮询卡流量后插入一条记录
    - `data_increase_mb` = 本次流量 - 上次流量
    - `source` 数据来源（polling-轮询 manual-手动 gateway-回调）

### 2.4 分佣相关模型
- [x] 2.4.1 定义代理层级关系(AgentHierarchy)模型
  - 字段包括：id, agent_id, parent_agent_id, agent_path, level, created_at, updated_at
- [x] 2.4.2 定义分佣规则(CommissionRule)模型
  - 字段包括：id, agent_id, business_type, card_type, commission_type, commission_mode, commission_value, unfreeze_days, min_activation_for_unfreeze, approval_type, status, created_at, updated_at
- [x] 2.4.3 定义阶梯分佣配置(CommissionLadder)模型
  - 字段包括：id, rule_id, ladder_type, threshold_value, commission_mode, commission_value, created_at, updated_at
- [x] 2.4.4 定义组合分佣条件(CommissionCombinedCondition)模型
  - 字段包括：id, rule_id, one_time_commission_mode, one_time_commission_value, long_term_commission_mode, long_term_commission_value, long_term_unfreeze_days, long_term_min_activation, created_at, updated_at
- [x] 2.4.5 定义分佣记录(CommissionRecord)模型
  - 字段包括：id, agent_id, order_id, rule_id, commission_type, amount, status, unfrozen_at, released_at, created_at, updated_at
- [x] 2.4.6 定义分佣审批(CommissionApproval)模型
  - 字段包括：id, commission_record_id, approver_id, status, reason, created_at, updated_at
- [x] 2.4.7 定义分佣模板(CommissionTemplate)模型
  - 字段包括：id, template_name, business_type, card_type, commission_type, commission_mode, commission_value, unfreeze_days, min_activation_for_unfreeze, approval_type, created_at, updated_at
- [x] 2.4.8 定义号卡运营商结算(CarrierSettlement)模型
  - 字段包括：id, commission_record_id, agent_id, settlement_month, settlement_amount, status, created_at, updated_at

### 2.5 财务管理模型
- [x] 2.5.1 定义佣金提现申请(CommissionWithdrawalRequest)模型
  - 字段包括：id, agent_id, amount, withdrawal_method, merchant_id, account_info, status, approved_by, approved_at, rejected_reason, paid_at, created_at, updated_at
- [x] 2.5.2 定义佣金提现设置(CommissionWithdrawalSetting)模型
  - 字段包括：id, min_withdrawal_amount, max_withdrawal_amount, daily_withdrawal_limit, fee_rate, status, created_at, updated_at
- [x] 2.5.3 定义收款商户设置(PaymentMerchantSetting)模型
  - 字段包括：id, user_id, merchant_type, account_name, account_number, bank_name, is_verified, is_default, status, created_at, updated_at

### 2.6 系统管理模型
- [x] 2.6.1 定义开发能力配置(DevCapabilityConfig)模型
  - 字段包括：id, user_id, app_id, app_secret, callback_url, status, created_at, updated_at
- [x] 2.6.2 定义换卡申请(CardReplacementRequest)模型
  - 字段包括：id, user_id, old_iccid, new_iccid, reason, status, processed_by, processed_at, created_at, updated_at

---

## 3. 常量定义

### 3.1 核心业务常量
- [x] 3.1.1 在 `pkg/constants/iot.go` 中定义以下常量：
  - IoT 卡状态：IotCardStatusInStock(1), IotCardStatusDistributed(2), IotCardStatusActivated(3), IotCardStatusSuspended(4)
  - 设备状态：DeviceStatusInStock(1), DeviceStatusDistributed(2), DeviceStatusActivated(3), DeviceStatusSuspended(4)
  - 号卡状态：NumberCardStatusOnSale(1), NumberCardStatusOffSale(2)
  - IoT 卡激活状态：ActivationStatusInactive(0), ActivationStatusActive(1)
  - IoT 卡实名状态：RealNameStatusNotVerified(0), RealNameStatusVerified(1)
  - IoT 卡网络状态：NetworkStatusOffline(0), NetworkStatusOnline(1)
  - 套餐流量类型：DataTypeReal("real"), DataTypeVirtual("virtual")
  - 套餐类型：PackageTypeFormal("formal"), PackageTypeAddon("addon")
  - 订单类型：OrderTypePackage(1), OrderTypeNumberCard(2)
  - 订单状态：OrderStatusPending(1), OrderStatusPaid(2), OrderStatusCompleted(3), OrderStatusCancelled(4), OrderStatusRefunded(5)
  - 支付方式：PaymentMethodWallet("wallet"), PaymentMethodOnline("online"), PaymentMethodCarrier("carrier")
  - 所有者类型：OwnerTypePlatform("platform"), OwnerTypeAgent("agent"), OwnerTypeUser("user"), OwnerTypeDevice("device")
  - 绑定状态：BindStatusBound(1), BindStatusUnbound(2)

### 3.2 套餐和轮询相关常量
- [x] 3.2.1 定义套餐使用类型常量：
  - PackageUsageTypeSingleCard("single_card") - 单卡套餐
  - PackageUsageTypeDevice("device") - 设备级套餐
- [x] 3.2.2 定义套餐使用状态常量：
  - PackageUsageStatusActive(1) - 生效中
  - PackageUsageStatusExhausted(2) - 已用完
  - PackageUsageStatusExpired(3) - 已过期
- [x] 3.2.3 定义轮询配置卡条件常量：
  - CardConditionNotRealName("not_real_name") - 未实名
  - CardConditionRealName("real_name") - 已实名
  - CardConditionActivated("activated") - 已激活
  - CardConditionSuspended("suspended") - 已停用
- [x] 3.2.4 定义流量使用记录来源常量：
  - DataUsageSourcePolling("polling") - 轮询
  - DataUsageSourceManual("manual") - 手动
  - DataUsageSourceGateway("gateway") - Gateway 回调

### 3.3 分佣相关常量
- [x] 3.3.1 定义分佣相关常量：
  - 分佣类型：CommissionTypeOneTime("one_time"), CommissionTypeLongTerm("long_term"), CommissionTypeCombined("combined")
  - 分佣模式：CommissionModeFixed("fixed"), CommissionModePercent("percent")
  - 分佣状态：CommissionStatusFrozen(1), CommissionStatusUnfreezing(2), CommissionStatusReleased(3), CommissionStatusInvalid(4)
  - 阶梯类型：LadderTypeActivation("activation"), LadderTypePickup("pickup"), LadderTypeDeposit("deposit")
  - 卡类型：CardTypeNumberCard("number_card"), CardTypeIotCard("iot_card")
  - 审批类型：ApprovalTypeAuto("auto"), ApprovalTypeManual("manual")
  - 审批状态：ApprovalStatusPending(1), ApprovalStatusApproved(2), ApprovalStatusRejected(3)

### 3.4 财务管理常量
- [x] 3.4.1 定义财务相关常量：
  - 提现状态：WithdrawalStatusPending(1), WithdrawalStatusApproved(2), WithdrawalStatusRejected(3), WithdrawalStatusPaid(4)
  - 提现方式：WithdrawalMethodAlipay("alipay"), WithdrawalMethodWechat("wechat"), WithdrawalMethodBank("bank")
  - 商户类型：MerchantTypeAlipay("alipay"), MerchantTypeWechat("wechat"), MerchantTypeBank("bank")

### 3.5 系统管理常量
- [x] 3.5.1 定义系统管理常量：
  - 换卡申请状态：ReplacementStatusPending(1), ReplacementStatusApproved(2), ReplacementStatusRejected(3), ReplacementStatusCompleted(4)
  - 开发能力配置状态：DevCapabilityStatusEnabled(1), DevCapabilityStatusDisabled(2)

---

## 4. 模型和表结构文档

### 4.1 代码注释
- [x] 4.1.1 为所有 GORM 模型添加中文结构体注释(描述表的业务用途)
- [x] 4.1.2 为所有模型字段添加清晰的中文注释
- [x] 4.1.3 为所有常量添加中文注释(说明枚举值含义)
- [x] 4.1.4 在迁移脚本中为所有表和字段添加 SQL COMMENT

### 4.2 数据库设计文档
- [x] 4.2.1 在 `docs/iot-sim-management/` 目录下创建 `数据库设计.md`
- [x] 4.2.2 使用 Markdown 表格描述所有表结构(字段名、类型、约束、说明)
- [x] 4.2.3 使用 dbdiagram.io 或 draw.io 创建数据库 ERD 图
- [x] 4.2.4 导出 ERD 图并保存到 `docs/iot-sim-management/erd.png`
- [x] 4.2.5 在 `数据库设计.md` 中嵌入 ERD 图

### 4.3 模型使用说明
- [x] 4.3.1 创建 `docs/iot-sim-management/模型说明.md`
- [x] 4.3.2 说明每个模型的用途和关键字段含义
- [x] 4.3.3 说明表之间的关联关系(虽然没有外键，但逻辑关联需要说明)
- [x] 4.3.4 说明关键枚举字段的取值和含义
- [x] 4.3.5 说明特殊设计决策(如无外键约束、owner_type/owner_id 模式等)

### 4.4 轮询机制说明文档
- [x] 4.4.1 创建 `docs/iot-sim-management/轮询机制说明.md`
- [x] 4.4.2 说明三个独立轮询流程：实名状态轮询、卡流量轮询、套餐流量检查
- [x] 4.4.3 说明轮询配置的匹配规则和优先级
- [x] 4.4.4 说明 `enable_polling` 字段的使用场景
- [x] 4.4.5 说明流量使用记录表的数据保留策略

### 4.5 项目文档更新
- [x] 4.5.1 更新 `README.md`，添加 IoT SIM 管理模块描述
- [x] 4.5.2 在 README 中添加数据库设计文档链接
- [x] 4.5.3 在 README 中添加模型说明文档链接
- [x] 4.5.4 在 README 中添加轮询机制说明文档链接

---

## 5. 数据迁移验证

### 5.1 本地验证
- [x] 5.1.1 在本地 PostgreSQL 测试数据库执行迁移脚本 up
- [x] 5.1.2 使用 `\dt` 和 `\d table_name` 验证所有表创建成功
- [x] 5.1.3 验证所有字段类型、默认值、NOT NULL 约束正确
- [x] 5.1.4 使用 `\di` 验证所有索引创建成功
- [x] 5.1.5 验证唯一索引和组合索引的正确性

### 5.2 数据完整性验证
- [x] 5.2.1 插入测试数据验证唯一索引生效(尝试插入重复 ICCID 应失败)
- [x] 5.2.2 插入测试数据验证 NOT NULL 约束生效
- [x] 5.2.3 插入测试数据验证 CHECK 约束生效(如金额 >= 0)
- [x] 5.2.4 查询测试数据验证组合索引生效(使用 EXPLAIN ANALYZE)
- [x] 5.2.5 验证运营商初始数据插入成功

### 5.3 回滚验证
- [x] 5.3.1 执行迁移脚本 down
- [x] 5.3.2 验证所有表和索引删除成功
- [x] 5.3.3 重新执行 up 验证迁移脚本可重复执行

---

## 6. 代码质量检查

### 6.1 代码格式化
- [x] 6.1.1 使用 `go fmt` 格式化所有模型代码
- [x] 6.1.2 使用 `goimports` 整理导入语句
- [x] 6.1.3 使用 `golangci-lint` 检查代码质量

### 6.2 命名规范检查
- [x] 6.2.1 验证所有 Go 字段名遵循驼峰命名法(PascalCase)
- [x] 6.2.2 验证所有数据库字段名遵循下划线命名法(snake_case)
- [x] 6.2.3 验证所有常量命名遵循 Go 规范(如 IotCardStatusInStock)
- [x] 6.2.4 验证所有模型文件名遵循 Go 规范(snake_case，如 iot_card.go)

### 6.3 GORM 标签检查
- [x] 6.3.1 验证所有字段都有 `gorm:"column:字段名"` 标签
- [x] 6.3.2 验证所有字段都有 `json:"字段名"` 标签
- [x] 6.3.3 验证所有字段的 `comment` 标签包含中文说明
- [x] 6.3.4 验证字符串字段的 `type` 标签指定了长度(如 `type:varchar(100)`)
- [x] 6.3.5 验证数值字段的 `type` 标签指定了精度(如 `type:decimal(10,2)`)

---

## 完成标准

本阶段任务完成后，应该具备：

1. ✅ 完整的数据库迁移脚本(up 和 down)
2. ✅ 完整的 GORM 模型定义(所有表对应的 Go 结构体)
3. ✅ 完整的常量定义(所有枚举值)
4. ✅ 完整的数据库设计文档(ERD 图 + 表结构说明)
5. ✅ 完整的模型使用说明文档
6. ✅ 完整的轮询机制说明文档
7. ✅ 数据库迁移在本地测试通过
8. ✅ 所有代码遵循项目开发规范(命名、注释、格式)

**不包含**：业务逻辑实现、API 接口、Service 层、Store 层、DTO、错误码、Redis Key 等。

---

## 关键设计说明

### 运营商表 (carriers)
- 存储运营商基础信息（中国移动、中国联通、中国电信）
- IoT 卡表通过 `carrier_id` 关联运营商表

### IoT 卡表 (iot_cards)
- `card_category` 字段：枚举值 "normal"(普通卡) | "industry"(行业卡),默认 "normal"
  - **普通卡**: 需要实名认证才能激活使用
  - **行业卡**: 不需要实名认证,可以在 `real_name_status` 为 0 的情况下激活使用
- `carrier_id` 关联运营商表（替代原来的 carrier 字符串字段）
- `enable_polling` 控制是否参与轮询（默认 true，可手动禁用）
- `last_data_check_at` 记录卡流量检查时间
- `last_real_name_check_at` 记录实名检查时间

### 套餐使用情况表 (package_usages)
- 核心业务表，跟踪套餐的激活、使用、过期情况
- 单卡套餐：`usage_type` = "single_card"，`iot_card_id` 有值
- 设备级套餐：`usage_type` = "device"，`device_id` 有值
- `data_usage_mb` 通过汇总卡的流量计算（不是实时轮询，而是定期统计）

### 轮询配置表 (polling_configs)
- 支持梯度配置（未实名卡、实名卡使用不同的轮询策略）
- 支持按运营商配置不同的轮询频率
- 独立配置三种轮询：实名检查、卡流量检查、套餐流量检查
- `priority` 数字越小优先级越高

### 流量使用记录表 (data_usage_records)
- 记录每次卡流量检查的结果
- 支持按卡、按时间范围查询流量历史
- 数据量会快速增长，建议定期清理 90 天前的记录或使用分区表

### 轮询逻辑（概念说明）
1. **卡流量轮询**：只轮询有生效套餐的卡，`enable_polling = true`
2. **套餐流量检查**：定期汇总卡的流量，判断套餐是否超额
3. **实名状态轮询**：定期检查卡的实名状态，实名后降低轮询频率
   - **行业卡特殊处理**: 行业卡的实名状态检查应该被禁用或设置为低优先级
4. **三个流程独立运行**：互不干扰，通过轮询配置表动态控制

### 分佣解冻逻辑（概念说明）
1. **一次性分佣**: 普通卡需要实名认证后才能解冻;行业卡无需实名认证,只需满足激活和充值条件
2. **长期分佣**: 普通卡需要实名认证后才能开始长期分佣;行业卡无需实名认证,满足其他条件即可
3. **组合分佣**: 行业卡的时间点条件从激活时开始计算(不是实名时)
