Claude Code Hub - Go 重写方案
一、项目概况
1.1 原项目分析
| 维度 |
现状 (Node.js) |
说明 |
| 前端 |
Next.js 16 + React 19 |
管理后台 UI |
| 后端 |
Hono 4 |
API 服务 |
| 数据库 |
PostgreSQL + Drizzle ORM |
完整的表结构 |
| 缓存 |
Redis + ioredis |
限流、会话缓存 |
| 代码量 |
~997 文件 |
包含前端 |
1.2 核心功能
- 代理网关: 转发 AI API 请求到多个供应商
- 多协议支持: Claude API、OpenAI 兼容 API、Codex API
- 用户管理: 用户、API Key、权限控制
- 供应商管理: 多供应商、权重分配、熔断器
- 配额限流: 多维度限流(RPM、日限额、周限额等)
- 会话管理: Session 跟踪、并发控制
- 费用统计: Token 计费、成本追踪
- 通知系统: Webhook 通知
二、技术栈选型
2.1 确定的技术栈
| 层级 |
选型 |
说明 |
| Web 框架 |
Gin |
高性能,HTTP/2 + SSE 支持 |
| 数据库 |
PostgreSQL |
复用现有数据库 |
| ORM |
Bun + pgdriver |
SQL-first,开发体验好 |
| Redis |
go-redis/v9 |
限流、缓存、会话 |
| 日志 |
zerolog |
高性能结构化日志 |
| 配置 |
viper |
环境变量 + 配置文件 |
| 验证 |
validator/v10 |
请求参数验证 |
| HTTP 客户端 |
resty/v2 |
代理上游请求 |
| 金额计算 |
quagmt/udecimal |
高性能、零分配精确金额计算 |
| 并发控制 |
golang.org/x/sync |
errgroup 等 |
2.2 Go 模块依赖
// go.mod
module github.com/yourorg/claude-code-hub
go 1.23
require (
// Web 框架
github.com/gin-gonic/gin v1.10+
// 数据库
github.com/uptrace/bun v1.2+
github.com/uptrace/bun/driver/pgdriver v1.2+
github.com/uptrace/bun/dialect/pgdialect v1.2+
// Redis
github.com/redis/go-redis/v9 v9+
// 配置 & 验证
github.com/spf13/viper v1.19+
github.com/go-playground/validator/v10 v10+
// 日志
github.com/rs/zerolog v1.33+
// HTTP 客户端
github.com/go-resty/resty/v2 v2.15+
// 工具
github.com/google/uuid v1.6+
github.com/quagmt/udecimal v1.3+
golang.org/x/sync v0.10+
)
2.3 前端策略
当前决定: 暂不考虑前端,先完成后端 API。
后续选项:
- A. 保留 Next.js 前端,Go 只负责后端 API
- B. 前端静态化,Go 服务内嵌静态文件
- C. 使用 Vue/Svelte 重写轻量级前端
三、项目目录结构
claude-code-hub/
├── cmd/
│ └── server/
│ └── main.go # 应用入口
│
├── internal/ # 内部包
│ ├── config/ # 配置管理
│ │ ├── config.go # 配置结构体
│ │ └── loader.go # viper 加载
│ │
│ ├── database/ # 数据库连接
│ │ ├── postgres.go # Bun 初始化
│ │ ├── redis.go # go-redis 客户端
│ │ └── migrations/ # SQL 迁移文件
│ │
│ ├── model/ # 数据模型 (对应 schema.ts)
│ │ ├── user.go
│ │ ├── key.go
│ │ ├── provider.go
│ │ ├── message_request.go
│ │ ├── model_price.go
│ │ └── ...
│ │
│ ├── repository/ # 数据访问层
│ │ ├── user_repo.go
│ │ ├── key_repo.go
│ │ ├── provider_repo.go
│ │ ├── statistics_repo.go
│ │ └── ...
│ │
│ ├── service/ # 业务逻辑层
│ │ ├── auth/
│ │ │ └── auth.go # API Key 认证
│ │ ├── ratelimit/
│ │ │ ├── service.go # 多维度限流
│ │ │ ├── lua_scripts.go # Redis Lua 脚本
│ │ │ └── time_utils.go
│ │ ├── circuitbreaker/
│ │ │ ├── breaker.go # 熔断器状态机
│ │ │ └── state.go # Redis 状态持久化
│ │ ├── session/
│ │ │ ├── manager.go # Session 管理
│ │ │ └── tracker.go # 并发追踪
│ │ ├── cost/
│ │ │ └── calculator.go # Token 计费
│ │ ├── cache/
│ │ │ ├── provider_cache.go # 供应商缓存
│ │ │ └── session_cache.go
│ │ └── notification/
│ │ ├── queue.go # 通知队列
│ │ └── webhook.go # Webhook 发送
│ │
│ ├── proxy/ # 代理核心 (最重要)
│ │ ├── handler.go # 代理主逻辑
│ │ ├── session.go # ProxySession 上下文
│ │ ├── forwarder.go # 上游请求转发
│ │ ├── sse.go # SSE 流处理
│ │ ├── provider_selector.go # 供应商选择 (权重/优先级)
│ │ ├── guard/ # Guard 链
│ │ │ ├── pipeline.go
│ │ │ ├── auth_guard.go
│ │ │ ├── ratelimit_guard.go
│ │ │ ├── provider_guard.go
│ │ │ └── ...
│ │ └── converter/ # 格式转换器
│ │ ├── claude.go
│ │ ├── openai.go
│ │ ├── gemini.go
│ │ └── codex.go
│ │
│ ├── handler/ # HTTP 处理器
│ │ ├── v1/ # 代理 API
│ │ │ ├── messages.go # /v1/messages
│ │ │ ├── chat.go # /v1/chat/completions
│ │ │ ├── responses.go # /v1/responses
│ │ │ └── models.go # /v1/models
│ │ ├── api/ # 管理 API
│ │ │ ├── users.go
│ │ │ ├── keys.go
│ │ │ ├── providers.go
│ │ │ └── ...
│ │ └── middleware/
│ │ ├── auth.go
│ │ ├── cors.go
│ │ ├── logger.go
│ │ └── recovery.go
│ │
│ └── pkg/ # 内部工具包
│ ├── logger/
│ ├── errors/
│ ├── validator/
│ └── utils/
│
├── pkg/ # 可导出的包
│ └── types/ # 公共类型定义
│
├── scripts/
│ └── migrate/ # 迁移工具
│
├── docs/ # 文档
│ ├── REWRITE.md # 本文档
│ └── SPEC.md # 技术规范
│
├── go.mod
├── go.sum
├── Makefile
└── README.md
四、模块依赖关系
┌─────────────────┐
│ cmd/server │
│ (入口) │
└────────┬────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ config │ │ logger │ │ database│
│ (配置) │ │ (日志) │ │ (DB连接) │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└──────────────┼──────────────┘
▼
┌───────────────┐
│ repository │
│ (数据访问) │
└───────┬───────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ auth │ │ cache │ │ cost │
│ (认证) │ │ (缓存) │ │ (计费) │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
└──────────────────┼──────────────────┘
▼
┌───────────────────────┐
│ ratelimit │
│ (限流) │
└───────────┬───────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ breaker │ │ session │ │ webhook │
│ (熔断) │ │ (会话) │ │ (通知) │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
└────────────┼────────────┘
▼
┌───────────────┐
│ proxy │
│ (代理核心) │
└───────┬───────┘
│
▼
┌───────────────┐
│ handler │
│ (HTTP处理器) │
└───────────────┘
五、核心模块映射
| Node.js 模块 |
Go 模块 |
优先级 |
复杂度 |
| drizzle/schema.ts |
internal/model/ |
P0 |
中 |
| lib/auth.ts |
internal/service/auth/ |
P0 |
低 |
| lib/rate-limit/service.ts |
internal/service/ratelimit/ |
P0 |
高 |
| lib/circuit-breaker.ts |
internal/service/circuitbreaker/ |
P0 |
中 |
| lib/session-manager.ts |
internal/service/session/ |
P0 |
高 |
| v1/_lib/proxy-handler.ts |
internal/proxy/handler.go |
P0 |
高 |
| v1/_lib/proxy/forwarder.ts |
internal/proxy/forwarder.go |
P0 |
高 |
| v1/_lib/proxy/guard-pipeline.ts |
internal/proxy/guard/ |
P0 |
中 |
| lib/utils/cost-calculation.ts |
internal/service/cost/ |
P1 |
低 |
| lib/cache/provider-cache.ts |
internal/service/cache/ |
P1 |
低 |
| lib/notification/ |
internal/service/notification/ |
P2 |
中 |
| lib/redis/lua-scripts.ts |
internal/service/ratelimit/lua_scripts.go |
P0 |
中 |
六、分阶段实现计划
Phase 1:基础设施 (Week 1) [已完成]
| 序号 |
任务 |
对应 Node.js |
状态 |
| 1.1 |
项目初始化 (go mod, Makefile) |
- |
已完成 |
| 1.2 |
config/ 配置加载 |
lib/config/ |
已完成 |
| 1.3 |
pkg/logger/ 日志 |
lib/logger.ts |
已完成 |
| 1.4 |
database/postgres.go |
drizzle/db.ts |
已完成 |
| 1.5 |
database/redis.go |
lib/redis/ |
已完成 |
| 1.6 |
model/ 数据模型 |
drizzle/schema.ts |
已完成 |
| 1.7 |
pkg/errors/ 错误处理 |
lib/error-* |
已完成 |
交付物: 可运行的空服务,连接 PostgreSQL + Redis
Phase 2:数据访问层 (Week 2) ✅ 已完成
| 序号 |
任务 |
对应 Node.js |
状态 |
| 2.1 |
repository/user_repo.go |
repository/user.ts |
✅ 已完成 |
| 2.2 |
repository/key_repo.go |
repository/key.ts |
✅ 已完成 |
| 2.3 |
repository/provider_repo.go |
repository/provider.ts |
✅ 已完成 |
| 2.4 |
repository/statistics_repo.go |
repository/statistics.ts |
✅ 已完成 |
| 2.5 |
repository/price_repo.go |
actions/model-prices.ts |
✅ 已完成 |
交付物: 完整的 CRUD 操作层
Phase 3:核心服务层 (Week 3-4)
| 序号 |
任务 |
对应 Node.js |
状态 |
| 3.1 |
service/auth/ API Key 认证 |
lib/auth.ts |
待开始 |
| 3.2 |
service/cache/ 供应商缓存 |
lib/cache/ |
待开始 |
| 3.3 |
service/cost/ Token 计费 |
lib/utils/cost-calculation.ts |
待开始 |
| 3.4 |
service/ratelimit/ 多维度限流 |
lib/rate-limit/ |
待开始 |
| 3.5 |
service/circuitbreaker/ 熔断器 |
lib/circuit-breaker.ts |
待开始 |
| 3.6 |
service/session/ 会话管理 |
lib/session-manager.ts |
待开始 |
交付物: 核心业务逻辑可独立测试
Phase 4:代理核心 (Week 5-6) ⭐ 最重要
| 序号 |
任务 |
对应 Node.js |
状态 |
| 4.1 |
proxy/session.go ProxySession |
v1/_lib/proxy/session.ts |
待开始 |
| 4.2 |
proxy/guard/ Guard 链 |
v1/_lib/proxy/guards/ |
待开始 |
| 4.3 |
proxy/provider_selector.go |
v1/_lib/proxy/provider-selector.ts |
待开始 |
| 4.4 |
proxy/forwarder.go 请求转发 |
v1/_lib/proxy/forwarder.ts |
待开始 |
| 4.5 |
proxy/sse.go SSE 流处理 |
lib/utils/sse.ts |
待开始 |
| 4.6 |
proxy/handler.go 主处理器 |
v1/_lib/proxy-handler.ts |
待开始 |
| 4.7 |
proxy/converter/ 格式转换 |
v1/_lib/converters/ |
待开始 |
交付物: 完整的代理功能,可处理 Claude/OpenAI 请求
Phase 5:HTTP 层 (Week 7)
| 序号 |
任务 |
对应 Node.js |
状态 |
| 5.1 |
handler/middleware/ 中间件 |
各中间件 |
待开始 |
| 5.2 |
handler/v1/messages.go |
/v1/messages |
待开始 |
| 5.3 |
handler/v1/chat.go |
/v1/chat/completions |
待开始 |
| 5.4 |
handler/v1/responses.go |
/v1/responses |
待开始 |
| 5.5 |
handler/v1/models.go |
/v1/models |
待开始 |
| 5.6 |
handler/api/ 管理 API |
/api/actions/* |
待开始 |
交付物: 完整的 API 端点,兼容现有客户端
Phase 6:辅助功能 (Week 8+)
| 序号 |
任务 |
对应 Node.js |
状态 |
| 6.1 |
service/notification/ 通知 |
lib/notification/ |
待开始 |
| 6.2 |
Webhook 渲染器 |
lib/webhook/renderers/ |
待开始 |
| 6.3 |
敏感词检测 |
lib/sensitive-word-detector.ts |
待开始 |
| 6.4 |
请求过滤 |
lib/request-filter-engine.ts |
待开始 |
七、测试与验证策略
7.1 测试层级
┌─────────────────────────────────────────────────┐
│ E2E 测试 (端到端) │
│ - 完整 API 请求流程 │
│ - 与 Node.js 版本行为对比 │
├─────────────────────────────────────────────────┤
│ 集成测试 (Integration) │
│ - Repository + 真实数据库 │
│ - Service + Redis │
│ - HTTP Handler + 完整服务栈 │
├─────────────────────────────────────────────────┤
│ 单元测试 (Unit) │
│ - 纯函数逻辑 │
│ - Mock 外部依赖 │
│ - 边界条件覆盖 │
└─────────────────────────────────────────────────┘
7.2 关键验证点
| 模块 |
验证内容 |
方法 |
| 代理 API |
请求/响应格式兼容性 |
对比测试 |
| SSE 流 |
流式响应正确性 |
抓包对比 |
| 限流 |
多维度限流精度 |
压力测试 |
| 熔断器 |
状态切换正确性 |
故障注入 |
| 成本计算 |
计费精度 |
单元测试 |
| 并发 |
高并发稳定性 |
压力测试 |
7.3 兼容性测试脚本
# 同时运行两个服务,对比响应
# scripts/compare_test.sh
NODE_URL="http://localhost:3000"
GO_URL="http://localhost:8080"
# 对比 API 响应
curl -s "$NODE_URL/v1/models" | jq -S > /tmp/node_models.json
curl -s "$GO_URL/v1/models" | jq -S > /tmp/go_models.json
diff /tmp/node_models.json /tmp/go_models.json
7.4 灰度发布策略
阶段 1: 开发测试 (Dev)
└── 仅内部测试环境
阶段 2: 影子模式 (Shadow)
└── 复制生产流量到 Go 服务,不返回响应
└── 对比日志和指标
阶段 3: 金丝雀发布 (Canary)
└── 5% → 20% → 50% 流量切换
阶段 4: 全量发布 (Production)
└── 100% 流量切换
└── 保留 Node.js 服务作为回滚备份
八、API 兼容性要求
目标: 100% 兼容现有 Node.js 版本的 API
代理 API
| 端点 |
方法 |
说明 |
| /v1/messages |
POST |
Claude 原生 API |
| /v1/chat/completions |
POST |
OpenAI 兼容 API |
| /v1/responses |
POST |
Codex API |
| /v1/models |
GET |
模型列表 |
管理 API
| 端点 |
方法 |
说明 |
| /api/actions/users/* |
CRUD |
用户管理 |
| /api/actions/keys/* |
CRUD |
Key 管理 |
| /api/actions/providers/* |
CRUD |
供应商管理 |
| /api/actions/statistics/* |
GET |
统计数据 |
九、开发规范
9.1 代码风格
- 遵循 Go 官方代码规范
- 使用 golangci-lint 进行代码检查
- 错误处理使用
errors.Wrap 添加上下文
- 日志使用结构化字段
9.2 命名规范
- 包名使用小写单词
- 接口名以
er 结尾 (如 UserRepository)
- 私有方法/变量使用小写开头
- 常量使用驼峰式
9.3 测试规范
- 每个包必须有对应的
_test.go 文件
- 测试函数命名:
Test<Function>_<Scenario>
- 使用 table-driven tests
- Mock 使用
mockgen 生成
十、风险与应对
| 风险 |
影响 |
应对策略 |
| SSE 流处理复杂 |
高 |
详细研究 Gin SSE 实现,增加测试覆盖 |
| Lua 脚本迁移 |
中 |
保持与 Node.js 版本一致的脚本逻辑 |
| 供应商 API 变更 |
低 |
使用 adapter 模式隔离变更 |
| 性能回归 |
中 |
建立基准测试,持续监控 |
十一、里程碑检查点