## MODIFIED Requirements

### Requirement: polling_realname_handler.go——实名数据采集

**文件**：`internal/task/polling_realname_handler.go`（< 220行）

**构造函数依赖**（通过构造函数注入，禁止全局变量）：
```go
func NewPollingRealnameHandler(
    base                  *PollingBase,
    gateway               *gateway.Client,
    iotCardStore          *postgres.IotCardStore,
    asynqClient           *asynq.Client,
    stopResumeSvc         iot_card_svc.StopResumeServiceInterface,
    deviceSimBindingStore *postgres.DeviceSimBindingStore,  // 新增：用于查询卡所属设备
) *PollingRealnameHandler
```

**方法列表**：
- `Handle(ctx, task) error`：Asynq 任务入口
- `triggerFirstRealnameActivation(ctx, cardID)`：提交卡级首次实名激活任务（已有，不变）
- `triggerDeviceRealnameActivation(ctx, cardID)`：**新增**，查询卡所属设备并提交设备级激活任务

**处理流程（0→1 路径新增步骤）**：
1. 调 `base.acquireConcurrency("realname")`，获取失败则 requeue 后返回
2. 调 `base.getCardWithCache(ctx, cardID)` 获取卡信息
3. 调 Gateway 查询实名状态
4. 写 Store（更新 `real_name_status`、`last_real_name_check_at`，首次实名时写 `first_realname_at`）
5. 若实名状态变为已实名（0→1）：
   a. 调 `triggerFirstRealnameActivation(ctx, cardID)` — 提交卡级激活任务
   b. **调 `triggerDeviceRealnameActivation(ctx, cardID)` — 提交设备级激活任务（新增）**
   c. 调 `stopResumeService.EvaluateAndAct(ctx, freshCard)` — 触发复机判断
6. 调 `base.requeueCard(ctx, cardID, "realname")` 重新入队
7. 调 `base.releaseConcurrency("realname")`

#### Scenario: 实名状态由未实名变为已实名——同时触发卡级和设备级激活
- **GIVEN** cardID=4，`real_name_status=0`，该卡通过 `tb_device_sim_binding` 绑定于设备 ID=2
- **WHEN** Gateway 返回实名已完成，Handler 检测到 0→1 变化
- **THEN** Store 更新 `real_name_status=1, first_realname_at=NOW()`
- **AND** 提交卡级 Asynq 任务（`carrier_type=iot_card, carrier_id=4`）
- **AND** 提交设备级 Asynq 任务（`carrier_type=device, carrier_id=2`）
- **AND** 调用 `EvaluateAndAct` 触发复机评估

#### Scenario: 独立卡实名——仅触发卡级激活
- **GIVEN** cardID=10，`real_name_status=0`，未绑定任何设备
- **WHEN** Gateway 返回实名已完成，Handler 检测到 0→1 变化
- **THEN** 提交卡级 Asynq 任务（`carrier_type=iot_card, carrier_id=10`）
- **AND** `triggerDeviceRealnameActivation` 调用 `GetActiveBindingByCardID` 返回 not found，静默跳过，不报错

#### Scenario: 实名状态未变化——不触发任何激活
- **GIVEN** cardID=200，`real_name_status=1`（已实名），Gateway 返回仍已实名
- **WHEN** Handler 执行
- **THEN** Store 不执行实名更新；不提交任何激活任务；按正常间隔 requeue

## ADDED Requirements

### Requirement: PollingRealnameHandler 注入 DeviceSimBindingStore

`PollingRealnameHandler` 结构体 SHALL 包含 `deviceSimBindingStore *postgres.DeviceSimBindingStore` 字段，由 `NewPollingRealnameHandler` 构造函数注入。`pkg/queue/handler.go` 的 `registerPollingHandlers` SHALL 将已可用的 `h.workerResult.Stores.DeviceSimBinding` 作为最后一个参数传入。

#### Scenario: Worker 启动时 DeviceSimBindingStore 正确注入
- **WHEN** Worker 进程启动，调用 `registerPollingHandlers()`
- **THEN** `NewPollingRealnameHandler` 接收 6 个参数，第 6 个为 `h.workerResult.Stores.DeviceSimBinding`
- **AND** handler 的 `deviceSimBindingStore` 字段非 nil

#### Scenario: DeviceSimBindingStore 为 nil 时 triggerDeviceRealnameActivation 静默跳过
- **GIVEN** handler 的 `deviceSimBindingStore` 为 nil（测试或未注入场景）
- **WHEN** 调用 `triggerDeviceRealnameActivation`
- **THEN** 函数立即返回，不 panic，不报错
