# Draft: Gateway Integration 工作计划

## 用户需求确认

**目标**: 封装 Gateway API 为统一的能力模块，提供类型安全的接口、统一的错误处理和配置管理。

**核心交付物**:
- Gateway 客户端封装（`internal/gateway/` 包）
- 14 个 API 接口（流量卡 7 个 + 设备 7 个）
- AES-128-ECB 加密 + MD5 签名机制
- 配置集成（环境变量）
- 错误码定义（1110-1119）
- 依赖注入（Bootstrap）
- 完整测试覆盖

**总任务数**: 51 个实施任务 + 10 个验收标准

## 初步任务分组

### Phase 1: 基础结构搭建（13 个任务）
- 目录结构创建
- 加密/签名工具实现
- 客户端基础结构
- DTO 定义

### Phase 2: API 接口封装（17 个任务）
- 流量卡 API（7 个接口）
- 设备 API（7 个接口）
- 单元测试

### Phase 3: 配置和错误码集成（7 个任务）
- Gateway 配置
- Gateway 错误码

### Phase 4: 依赖注入和集成（6 个任务）
- Bootstrap 初始化
- Service 层集成

### Phase 5: 集成测试和文档（8 个任务）
- 集成测试
- 文档更新

## 用户决策（已确认）

### 1. Gateway 测试环境配置 ✅
- **BaseURL**: `https://lplan.whjhft.com/openapi`
- **AppID**: `60bgt1X8i7AvXqkd`
- **AppSecret**: `BZeQttaZQt0i73moF`
- **测试 ICCID**: `8986062580006141710`
- **设备测试**: 不需要测试

### 2. 加密/签名算法验证 ✅
- **文档来源**: Apifox 文档（https://omp5mq28pq.apifox.cn/7819761m0）
- **加密方案**: AES-128-ECB + PKCS5Padding + Base64（密钥为 AppSecret 的 MD5）
- **签名方案**: MD5(排序参数&key=AppSecret)，大写输出
- **安全警告**: ⚠️ 遗留系统，添加安全警告注释（ECB 模式泄漏 + MD5 碰撞风险）

### 3. Service 层集成范围 ✅
- **集成位置**: `internal/service/iot_card/service.go`（已存在）
- **集成方法**: 新增 `SyncCardStatus(ctx, iccid)` 方法作为示例
- **范围**: 仅提供一个集成示例

### 4. 批量查询接口 ✅
- **决定**: ❌ 完全不实施（连预留接口都不需要）
- **理由**: 用户明确表示"根本就不会有批量查询接口"

### 5. 错误处理策略 ✅
- **重试逻辑**: ✅ 需要自动重试（最多 3 次，指数退避：1s, 2s, 4s）
- **降级策略**: ❌ 不需要
- **超时处理**: 超时错误不重试，直接返回
- **实现方式**: 在 `doRequest` 内置简单循环重试（无需第三方库）

## 研究发现

### 项目现有架构
- **分层结构**: Handler → Service → Store → Model（严格分离）
- **依赖注入**: Bootstrap 按顺序初始化（Stores → Services → Handlers）
- **配置管理**: Viper 加载，支持环境变量覆盖（前缀 `JUNHONG_`）
- **错误处理**: 统一错误码系统（1000-1999: 4xx, 2000-2999: 5xx）
- **测试模式**: Table-driven tests + testutils（全局单例 DB/Redis）
- **HTTP 客户端参考**: `/pkg/sms/` 使用接口 + 依赖注入模式

### 加密/签名安全警告
- **AES-128-ECB**: ⚠️ 密码学上已被破解（模式泄漏），仅用于遗留系统
- **MD5 签名**: ⚠️ 存在碰撞攻击漏洞，建议使用 HMAC-SHA256
- **理由**: 如果 Gateway API 是遗留系统且无法更改，则必须使用 ECB + MD5

### 最佳实践建议
1. **HTTP 客户端**: 使用 `http.Transport` 精细配置超时（Dial、TLS、ResponseHeader）
2. **API 客户端**: 导出接口而非具体类型（可测试性）
3. **集成测试**: 使用真实 Gateway 环境 + 测试 ICCID
4. **错误处理**: 区分超时错误 vs 其他网络错误
5. **重试策略**: 内置简单循环重试（无需第三方库）

### 现有代码结构
- **iot_card Service**: 已存在于 `internal/service/iot_card/service.go`
  - 当前方法: ListStandalone, GetByICCID, AllocateCards, RecallCards, BatchSetSeriesBinding
  - 新增方法: SyncCardStatus（Gateway 集成示例）
- **HTTP 客户端参考**: `pkg/sms/http_client.go`（无重试逻辑，使用 context 超时）
- **重试模式**: 项目使用 Asynq 任务队列重试（常量：`DefaultRetryMax = 5`）

## 任务调整

### 删除任务
- **Task 20**: "预留 BatchQuery（批量查询，未来扩展）" → ❌ 删除

### 新增任务
- **Task 1.5**: "在 doRequest 中实现 HTTP 重试逻辑（3 次，指数退避）"
- **Task 4.3**: "在 iot_card Service 中新增 SyncCardStatus 方法"

### 修改任务
- **Task 5.1**: 使用真实配置进行集成测试（测试 ICCID: `8986062580006141710`）
- **Task 2.1**: 移除 BatchQuery 实现
- **Task 2.2**: 设备 API 只实现方法签名（测试时跳过真实调用）

### 调整后任务数
- **实施任务**: 51 个（原 51 - 1 个删除 + 1 个新增 = 51）
- **验收标准**: 10 个（保留但不作为实施任务）
