# Stack Research

**Domain:** IoT 卡管理平台 — SIM 卡全生命周期 + 代理分销 + 分佣结算
**Researched:** 2026-03-27
**Confidence:** MEDIUM-HIGH（核心技术栈 HIGH，外围选项 MEDIUM）

---

## 结论先行：当前技术栈评估

**整体结论：当前技术选型对于该领域是合理的，无需大规模替换。**
存在 3 个明确的技术债和 1 个值得关注的升级时机。

| 组件 | 当前版本 | 最新版本 | 状态 | 建议 |
|------|---------|---------|------|------|
| Fiber | v2.52.9 | **v3.1.0** | ⚠️ 大版本落后 | 保持 v2，不升级（见分析） |
| GORM | v1.31.1 | v1.31.x | ✅ 最新 | 继续使用 |
| Asynq | v0.25.1 | **v0.26.0** | ⚠️ 落后一个版本 | 可选升级（安全依赖升级） |
| go-redis | v9.7.0 | v9.18.0 | ⚠️ 落后较多 | 建议升级（无 API 破坏性变更） |
| sonic | v1.14.2 | v1.14.x | ✅ 近期版本 | 继续使用 |
| PowerWeChat | v3.4.38 | v3.4.38 | ✅ 最新 | 继续使用 |
| Go runtime | 1.25.x | 1.25.x | ✅ 最新 | 继续使用 |

---

## 核心技术栈

### 一、HTTP 框架 — Fiber v2（**继续坚守**）

| 项目 | 内容 |
|------|------|
| 当前版本 | v2.52.9（已是 v2.x 最新） |
| 最新大版本 | v3.1.0（2026-02-02 正式发布） |
| **不升级的原因** | v3 有重大破坏性变更，迁移成本高，且本项目有大量存量代码 |

**v3 核心破坏性变更（对本项目影响分析）：**

1. **`c.UserContext()` 被移除** → `Ctx` 本身现在实现 `context.Context`，直接传 `c` 即可。
   - **影响：**本项目全代码库大量使用 `c.UserContext()` 传递用户 Context 到 Service/Store 层，这是最大的迁移成本。
   - **估算：**全局搜索 `UserContext()` 调用点，预估 100+ 处改动。

2. **`c.BodyParser()` 移除** → 改用 `c.Bind().Body()`
   - **影响：**所有 Handler 层的请求解析代码需要改写。

3. **路由注册 `Add` 方法签名变更** → 影响 `internal/routes/registry.go` 的统一注册逻辑。

4. **`app.Mount()` 移除** → 使用 `app.Use()`。

**置信度：HIGH**（官方文档 https://docs.gofiber.io/whats_new/ 已确认）

**建议：** 保持 v2.52.x，待 v2 EOL 公告或下一个重大重构机会再考虑升级。v2 安全维护至少到 2026 年底，风险可控。

---

### 二、ORM — GORM v2（**继续使用，无更好替代方案**）

**2026 年 Go ORM 格局：**

| ORM | 定位 | 适合本项目 |
|-----|------|-----------|
| **GORM** | 全功能 ORM，code-first，ActiveRecord 风格 | ✅ **最适合** |
| sqlc | 编译时类型安全，从 SQL 生成 Go 代码 | ❌ 需要从头重写所有查询 |
| sqlx | SQL 轻量封装，接近原生 database/sql | ❌ 需要全部改写，收益有限 |
| ent | 图模型 ORM，compile-time type safety | ❌ 学习成本高，编译慢，不适合现有代码库 |

**为什么 GORM 对本项目是正确选择：**
- CRUD 密集型应用（卡管理、套餐管理、订单、佣金），GORM 的约定优于配置大幅减少样板代码
- 软删除、钩子（Hooks）、事务等特性本项目大量依赖
- 当前 v1.31.x 已是最新，无需升级

**GORM 的已知性能问题（针对本项目的建议）：**
- 多级代理佣金树查询（最深 7 层）不应使用 GORM `Preload`，而应使用原生 `WITH RECURSIVE` CTE
- 批量导入（ICCID Excel）应使用 `db.CreateInBatches()` 而非逐行 `Create()`

**置信度：HIGH**（多个 2026 年对比文章，主流观点一致）

---

### 三、任务队列 — Asynq（**继续使用，考虑升级到 v0.26.0**）

**最新版本：** v0.26.0（2026-02-03 发布）

| 版本 | 关键变更 |
|------|---------|
| v0.25.1（当前） | 安全依赖升级 + 增加 `RedisUniversalClient` 支持 |
| **v0.26.0** | 增加 Task Headers 支持（PR #1070）+ TLS 选项 + 最低 Go 版本升至 1.24 |

**为什么不替换 Asynq：**
在 IoT 卡管理场景中，Asynq 的优势：
- 基于 Redis（与现有基础设施共享，无额外运维成本）
- 内置定时任务调度（Scheduler）适合轮询任务场景
- 任务可视化（Asynqmon Web UI）在生产调试中有价值
- 竞品（Machinery、Watermill）依赖更重，对单节点场景没有额外收益

**建议：** 升级到 v0.26.0（`go get github.com/hibiken/asynq@v0.26.0`），主要收益是上游安全依赖修复，API 完全兼容。

**置信度：HIGH**（GitHub Releases 直接验证）

---

### 四、Redis 客户端 — go-redis v9（**建议升级**）

**当前版本：** v9.7.0
**最新版本：** v9.18.0（2026-02-16）

v9.7.0 → v9.18.0 跨越 11 个 patch 版本，均为向后兼容。建议升级原因：
- 包含若干 bug 修复和性能改进
- 升级命令：`go get github.com/redis/go-redis/v9@v9.18.0`

**置信度：MEDIUM**（pkg.go.dev 直接确认版本）

---

### 五、JSON 序列化 — sonic（**继续使用**）

**sonic（bytedance/sonic）** 在 2025 年基准测试中仍是 Go 生态最快的 JSON 库：

| 库 | 相对速度 | 适用场景 |
|----|---------|---------|
| **sonic** | ~3-4x 快于 std | 高并发 API，大 payload（如 Excel 导入响应） |
| encoding/json v2（Go 1.25 内置） | ~1.8x 快于 std | 标准库，无需引入依赖 |
| encoding/json（std） | 1x 基线 | 无额外依赖场景 |

**注意：** Go 1.25 引入了 `encoding/json/v2`，性能约为 sonic 的 50%，但消除了历史行为不一致问题。对于本项目，sonic 仍是正确选择：本项目已集成且使用 Fiber 的 sonic 替换，迁移收益不大。

**置信度：HIGH**（2025-09 Reddit benchmark + Trendyol 生产迁移案例）

---

## 领域特有技术栈缺口分析

### 缺口 1：金融精度问题 ⚠️（**重大技术债**）

**问题描述：**
IoT 卡管理平台涉及两类精度敏感计算：
1. **货币金额**：钱包余额、佣金金额（差价佣金、一次性佣金）、套餐价格
2. **流量计费**：MB/GB 流量用量计算、按比例退款

**当前实现风险：**
- 余额字段使用 `int64`（存储"分"）—— **钱包余额做法正确**
- 但佣金链计算（差价 = 上层价格 - 下层成本）中，如果涉及百分比分佣（如"提成 15%"），用 `float64` 计算后再转 `int64` 会有精度损失

**标准做法（2025 年行业共识）：**

```
选项 A：纯整数（分/厘）存储，避免所有浮点运算
  - 适合固定金额计算
  - 本项目钱包余额已是此做法 ✅
  
选项 B：shopspring/decimal（用于百分比/比例计算）
  - 适合佣金比例计算、退款按比例扣减
  - 7000+ GitHub stars，已是 Go 社区财务计算标准库
  
选项 C：go-money（Rhymond/go-money）
  - 适合多币种场景，本项目不需要
```

**建议：**
引入 `github.com/shopspring/decimal` v1.4.0，**仅用于**：
- 佣金比例计算（如方案 I-3：退款按比例扣减代理佣金）
- 流量按比例计费（方案 E 的流量体系改革）

不需要全局替换 int64 余额字段，仅在需要乘除法的计算环节使用 decimal，最终结果转 int64 存储。

**置信度：HIGH**（Modern Treasury 官方博客 2025-08 + shopspring/decimal 7286 stars）

---

### 缺口 2：多级代理查询性能 ⚠️（**架构风险**）

**问题描述：**
本项目代理层级最多 7 层，`GetSubordinateShopIDs()` 使用 PostgreSQL `WITH RECURSIVE` CTE 查询，结果缓存 30 分钟。这个架构是正确的。

**潜在风险：**
- 佣金链计算时，N 层递归分佣可能退化为 N 次单独 DB 查询（N+1 问题）
- 7 层 × 每层查询 = 最坏 7 次 DB 往返，而 DB 查询要求 < 50ms

**2025 年标准方案：**
对于多级分佣树计算，行业标准是一次性将整条链路数据加载到内存，而非逐层查询：

```sql
-- 一次性获取完整佣金链（从叶子节点到根节点）
WITH RECURSIVE commission_chain AS (
  SELECT shop_id, parent_id, level, 0 AS depth
  FROM tb_shop WHERE id = $1
  UNION ALL
  SELECT s.shop_id, s.parent_id, s.level, cc.depth + 1
  FROM tb_shop s
  INNER JOIN commission_chain cc ON s.id = cc.parent_id
)
SELECT * FROM commission_chain ORDER BY depth;
```

当前代码已经有 `WITH RECURSIVE` 基础，但需要确认佣金计算是否利用了这个能力。

**置信度：MEDIUM**（基于代码库 PROJECT.md 分析 + PostgreSQL 官方文档）

---

### 缺口 3：可观测性 ⚠️（**生产上线前需解决**）

**问题描述：**
当前技术栈的可观测性仅有：
- 应用日志（Zap）
- 访问日志
- Asynq 任务状态（via Asynqmon 可选）
- 健康检查 `GET /health`

**缺失：**
- 没有指标（Metrics）收集
- 没有链路追踪（Tracing）
- 没有告警（Alerting）

**对于当前阶段（MVP 修复上线）：** 可以暂时接受，PROJECT.md 的 Out of Scope 已明确 "P2-6 告警通知渠道 — 无关紧要，暂不做"。

**但如果平台上线后扩展：**
- 轻量级方案：Prometheus + Grafana（已是 Go 社区标准）
- 零侵入方案：OpenTelemetry Go SDK（标准化，支持后续接入任意后端）

**置信度：MEDIUM**（基于 Go 社区 2025 年可观测性实践）

---

### 缺口 4（IoT 领域特有）：运营商网关客户端 — 无通用标准库

**问题描述：**
本项目有 `internal/gateway/client.go`（外部 Gateway 服务 HTTP 客户端）。IoT SIM 卡管理平台通常需要对接：
- GSMA M2M 标准（SM-DP+/SM-DS for eSIM）
- 运营商私有 API（中国联通、移动、电信）

**2025 年实际情况：**
国内运营商 IoT 平台（移动 OneNET、电信 CTWing、联通 Open）均为私有 REST/SOAP API，**没有标准化的 Go SDK**。

当前项目自研 `internal/gateway/client.go` 是唯一可行路径，符合行业惯例。

**置信度：HIGH**（行业调研确认，无通用 Go SDK 存在）

---

## 当前栈中已弃用/有问题的依赖

| 依赖 | 问题 | 建议 |
|------|------|------|
| `aws/aws-sdk-go` (v1) | AWS SDK Go v1 已于 2025-07-31 进入 Maintenance Mode，不再接收功能更新 | 低优先级，当前对接联通云 OSS，可继续使用；如有大范围重构可迁移到 `aws/aws-sdk-go-v2` |
| `excelize/v2` | 无严重问题，版本跟进即可 | — |

**AWS SDK v1 注意：** 仅 Maintenance Mode，不是 End of Life，安全补丁仍会发布。迁移到 v2 需要较大代码改动，不建议在当前 MVP 阶段操作。

**置信度：MEDIUM**（AWS 官方公告，2025-07-31）

---

## 可选补充库

以下库不在当前技术栈中，但对特定需求有价值：

| 库 | 版本 | 用途 | 引入时机 |
|----|------|------|---------|
| `shopspring/decimal` | v1.4.0 | 佣金比例计算、退款按比例计算 | **方案 I（退款）实现时** |
| `golang-migrate/migrate` | v4.18.x | 数据库迁移（已在项目使用） | — 已用 |
| `hibiken/asynqmon` | latest | Asynq 任务可视化 Web UI | 生产环境调试时 |

---

## 替代方案对比

| 类别 | 当前选择 | 备选 | 不替换的理由 |
|------|---------|------|------------|
| HTTP 框架 | Fiber v2 | Gin, Echo, Chi, Fiber v3 | 大量存量代码；v3 破坏性变更成本高 |
| ORM | GORM | sqlc, sqlx, ent | 项目已深度集成，CRUD 场景 GORM 是最优解 |
| 任务队列 | Asynq | Machinery, Watermill, Temporal | Redis 复用优势；Temporal 对单节点过重 |
| 消息队列 | 无（Asynq 兼任） | NATS, Kafka | 当前规模不需要独立 MQ |
| 缓存 | Redis | Memcached | Redis 功能更丰富，已是基础设施 |
| 数据库 | PostgreSQL | MySQL, CockroachDB | PostgreSQL 的递归 CTE 对层级数据有优势 |
| JSON | sonic | encoding/json, json/v2 | sonic 性能优势在高并发场景显著 |

---

## 版本兼容性注意事项

| 依赖组合 | 状态 | 注意 |
|---------|------|------|
| Fiber v2 + Go 1.25 | ✅ 兼容 | Fiber v2.52.9 已适配 Go 1.25 |
| Fiber v3 + Go 1.25 | ⚠️ 要求 Go 1.25+ | v3 以 Go 1.25 为最低版本 |
| Asynq v0.26.0 + Go 1.25 | ✅ 兼容 | v0.26.0 要求 Go 1.24+，1.25 满足 |
| GORM v1.31.1 + PostgreSQL 14+ | ✅ 兼容 | — |
| PowerWeChat v3.4.38 + Go 1.25 | ✅ 兼容 | 官方声明 Go 1.23+ |

---

## 关键技术债总结（优先级排序）

### P0：必须在上线前解决

**金融精度风险**（佣金计算）
- 检查所有涉及百分比/比例的佣金计算代码，确认没有 `float64` 中间步骤
- 方案 I（退款按比例扣减佣金）实现时必须引入 `shopspring/decimal`

### P1：上线后尽快处理

**go-redis 版本落后**
- 从 v9.7.0 升级到 v9.18.0，无 API 破坏性变更，安全隐患修复

**Asynq 版本落后**
- 从 v0.25.1 升级到 v0.26.0，获得安全修复

### P2：中期规划

**AWS SDK v1 → v2 迁移**（对象存储）
- 不紧急，v1 仍有安全支持，规划下一个重大重构时处理

**Fiber v2 → v3 迁移评估**
- v2 仍在维护，不需要立即升级
- 建议在明年底（2027）重新评估是否升级

---

## 安装/升级命令参考

```bash
# 升级 Asynq（推荐）
go get github.com/hibiken/asynq@v0.26.0

# 升级 go-redis（推荐）
go get github.com/redis/go-redis/v9@v9.18.0

# 引入 decimal（P0 佣金精度修复时）
go get github.com/shopspring/decimal@v1.4.0

# 升级所有兼容依赖（谨慎，逐一验证）
go get -u ./...
```

---

## Sources

| 来源 | 内容 | 置信度 |
|------|------|--------|
| https://docs.gofiber.io/whats_new/ | Fiber v3 破坏性变更完整列表 | HIGH |
| https://newreleases.io/project/github/hibiken/asynq/release/v0.26.0 | Asynq v0.26.0 发布说明 | HIGH |
| https://pkg.go.dev/github.com/redis/go-redis/v9 | go-redis 最新版本 v9.18.0 | HIGH |
| https://reintech.io/blog/sqlc-vs-gorm-vs-sqlx-go-database-libraries-compared-2026 | GORM vs sqlc vs sqlx 2026 深度对比 | MEDIUM |
| https://encore.cloud/resources/go-orms | Go ORM 2026 对比（GORM/sqlc/ent）| MEDIUM |
| https://pkg.go.dev/github.com/shopspring/decimal@v1.4.0 | shopspring/decimal v1.4.0 | HIGH |
| https://www.moderntreasury.com/journal/floats-dont-work-for-storing-cents | 金融精度使用整数的行业实践 | HIGH |
| Reddit r/golang 2025-09 JSON benchmark | sonic vs std vs json/v2 基准 | MEDIUM |
| https://pkg.go.dev/github.com/ArtisanCloud/PowerWeChat/v3@v3.4.38 | PowerWeChat 最新版本确认 | HIGH |

---

*Stack research for: IoT SIM 卡管理平台（Go + Fiber + GORM + Asynq + PostgreSQL + Redis）*
*Researched: 2026-03-27*
