## MODIFIED Requirements

### Requirement: Device Handler 分层修复

Device Handler SHALL 不再直接持有 `gateway.Client` 引用。所有 Gateway API 调用 SHALL 通过 Device Service 层发起。

#### Scenario: DeviceHandler 不持有 gatewayClient

- **WHEN** 创建 `DeviceHandler` 实例
- **THEN** `NewDeviceHandler` 构造函数不接收 `gateway.Client` 参数
- **AND** Handler 结构体不包含 `gatewayClient` 字段

#### Scenario: 查询设备网关信息通过 Service 调用

- **WHEN** Handler 的 `GetGatewayInfo` 方法被调用
- **THEN** Handler 调用 `service.GetGatewayInfo(ctx, identifier)`

#### Scenario: 查询设备卡槽信息通过 Service 调用

- **WHEN** Handler 的 `GetGatewaySlots` 方法被调用
- **THEN** Handler 调用 `service.GetGatewaySlots(ctx, identifier)`

#### Scenario: 设置设备限速通过 Service 调用

- **WHEN** Handler 的 `SetSpeedLimit` 方法被调用
- **THEN** Handler 调用 `service.SetGatewaySpeedLimit(ctx, identifier, speedLimit)`

#### Scenario: 设置设备 WiFi 通过 Service 调用

- **WHEN** Handler 的 `SetWiFi` 方法被调用
- **THEN** Handler 调用 `service.SetGatewayWiFi(ctx, identifier, req)`

#### Scenario: 切换设备卡通过 Service 调用

- **WHEN** Handler 的 `SwitchCard` 方法被调用
- **THEN** Handler 调用 `service.GatewaySwitchCard(ctx, identifier, targetICCID)`

#### Scenario: 重启设备通过 Service 调用

- **WHEN** Handler 的 `RebootDevice` 方法被调用
- **THEN** Handler 调用 `service.GatewayRebootDevice(ctx, identifier)`

#### Scenario: 恢复出厂设置通过 Service 调用

- **WHEN** Handler 的 `ResetDevice` 方法被调用
- **THEN** Handler 调用 `service.GatewayResetDevice(ctx, identifier)`

### Requirement: Device Service Gateway 代理方法

Device Service SHALL 提供 Gateway API 的代理方法，封装设备标识符解析、IMEI 检查和 Gateway 调用。

#### Scenario: GetGatewayInfo 方法

- **WHEN** 调用 `service.GetGatewayInfo(ctx, identifier)`
- **THEN** 先通过 `GetDeviceByIdentifier` 查找设备并验证权限
- **AND** 检查设备 IMEI 不为空
- **AND** 调用 `gatewayClient.GetDeviceInfo` 传入设备 IMEI
- **AND** 返回 `*gateway.DeviceInfoResp`

#### Scenario: GetGatewaySlots 方法

- **WHEN** 调用 `service.GetGatewaySlots(ctx, identifier)`
- **THEN** 先查找设备、验证 IMEI 不为空
- **AND** 调用 `gatewayClient.GetSlotInfo`
- **AND** 返回 `*gateway.SlotInfoResp`

#### Scenario: SetGatewaySpeedLimit 方法

- **WHEN** 调用 `service.SetGatewaySpeedLimit(ctx, identifier, speedLimit)`
- **THEN** 先查找设备、验证 IMEI
- **AND** 调用 `gatewayClient.SetSpeedLimit` 传入设备 IMEI 和限速值

#### Scenario: SetGatewayWiFi 方法

- **WHEN** 调用 `service.SetGatewayWiFi(ctx, identifier, cardNo, ssid, password string, enabled bool)`
- **THEN** 先查找设备、验证 IMEI
- **AND** 调用 `gatewayClient.SetWiFi` 传入设备 IMEI、cardNo（ICCID）、ssid、password、enabled

#### Scenario: GatewaySwitchCard 方法

- **WHEN** 调用 `service.GatewaySwitchCard(ctx, identifier, targetICCID)`
- **THEN** 先查找设备、验证 IMEI
- **AND** 调用 `gatewayClient.SwitchCard` 传入设备 IMEI 作为 cardNo 和目标 ICCID

#### Scenario: GatewayRebootDevice 方法

- **WHEN** 调用 `service.GatewayRebootDevice(ctx, identifier)`
- **THEN** 先查找设备、验证 IMEI
- **AND** 调用 `gatewayClient.RebootDevice` 传入设备 IMEI

#### Scenario: GatewayResetDevice 方法

- **WHEN** 调用 `service.GatewayResetDevice(ctx, identifier)`
- **THEN** 先查找设备、验证 IMEI
- **AND** 调用 `gatewayClient.ResetDevice` 传入设备 IMEI

#### Scenario: 设备 IMEI 为空

- **WHEN** 调用任意 Gateway 代理方法且设备的 IMEI 字段为空
- **THEN** 返回 `CodeInvalidParam` 错误
- **AND** 错误信息说明该设备未配置 IMEI

#### Scenario: 设备不存在或无权限

- **WHEN** 调用任意 Gateway 代理方法且标识符无法匹配到设备
- **THEN** 返回对应的错误（由 `GetDeviceByIdentifier` 返回）

### Requirement: Device Service 接收 Gateway Client

Device Service SHALL 在构造函数中接收 `*gateway.Client` 依赖。

#### Scenario: Device Service 初始化

- **WHEN** 创建 Device Service 实例
- **THEN** 构造函数接收 `gatewayClient *gateway.Client` 参数
- **AND** 存储为 Service 的内部字段
- **AND** `gatewayClient` 可以为 nil（Gateway 配置缺失时）

#### Scenario: Gateway Client 为 nil 时调用 Gateway 方法

- **WHEN** `gatewayClient` 为 nil 且调用任意 Gateway 代理方法
- **THEN** 返回 `CodeGatewayError` 错误
- **AND** 错误信息为 "Gateway 客户端未配置"
