From c4d67154431c94aa04c7f3e8f2fadf48fbdeed20 Mon Sep 17 00:00:00 2001 From: liuxiongfeng Date: Tue, 10 Feb 2026 20:59:54 +0800 Subject: [PATCH] chore: squash merge customizations from develop-old-0.1.77 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 定制文档: CLAUDE.md, AGENTS.md - UI定制: 微信客服按钮, 首页改造, 移除GitHub链接 - 部署运维: docker-compose.yml, 压测脚本 - CI/gitignore 小改动 --- .github/workflows/backend-ci.yml | 2 + .gitignore | 1 + AGENTS.md | 723 ++++++++++++++++++ CLAUDE.md | 723 ++++++++++++++++++ deploy/docker-compose.yml | 41 +- frontend/public/wechat-qr.jpg | Bin 0 -> 151392 bytes .../components/common/WechatServiceButton.vue | 104 +++ frontend/src/components/layout/AppHeader.vue | 17 - frontend/src/views/HomeView.vue | 173 ++++- stress_test_gemini_session.sh | 127 +++ 10 files changed, 1832 insertions(+), 79 deletions(-) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 frontend/public/wechat-qr.jpg create mode 100644 frontend/src/components/common/WechatServiceButton.vue create mode 100644 stress_test_gemini_session.sh diff --git a/.github/workflows/backend-ci.yml b/.github/workflows/backend-ci.yml index 2596a18c..84575a96 100644 --- a/.github/workflows/backend-ci.yml +++ b/.github/workflows/backend-ci.yml @@ -17,6 +17,7 @@ jobs: go-version-file: backend/go.mod check-latest: false cache: true + cache-dependency-path: backend/go.sum - name: Verify Go version run: | go version | grep -q 'go1.25.7' @@ -36,6 +37,7 @@ jobs: go-version-file: backend/go.mod check-latest: false cache: true + cache-dependency-path: backend/go.sum - name: Verify Go version run: | go version | grep -q 'go1.25.7' diff --git a/.gitignore b/.gitignore index 48172982..2f2bfbdf 100644 --- a/.gitignore +++ b/.gitignore @@ -78,6 +78,7 @@ Desktop.ini # =================== tmp/ temp/ +logs/ *.tmp *.temp *.log diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..a7a3e34a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,723 @@ +# Sub2API 开发说明 + +## 版本管理策略 + +### 版本号规则 + +我们在官方版本号后面添加自己的小版本号: + +- 官方版本:`v0.1.68` +- 我们的版本:`v0.1.68.1`、`v0.1.68.2`(递增) + +### 分支策略 + +| 分支 | 说明 | +|------|------| +| `main` | 我们的主分支,包含所有定制功能 | +| `release/custom-X.Y.Z` | 基于官方 `vX.Y.Z` 的发布分支 | +| `upstream/main` | 上游官方仓库 | + +--- + +## 发布流程(基于新官方版本) + +当官方发布新版本(如 `v0.1.69`)时: + +### 1. 同步上游并创建发布分支 + +```bash +# 获取上游最新代码 +git fetch upstream --tags + +# 基于官方标签创建新的发布分支 +git checkout v0.1.69 -b release/custom-0.1.69 + +# 合并我们的 main 分支(包含所有定制功能) +git merge main --no-edit + +# 解决可能的冲突后继续 +``` + +### 2. 更新版本号并打标签 + +```bash +# 更新版本号文件 +echo "0.1.69.1" > backend/cmd/server/VERSION +git add backend/cmd/server/VERSION +git commit -m "chore: bump version to 0.1.69.1" + +# 打上我们自己的标签 +git tag v0.1.69.1 + +# 推送分支和标签 +git push origin release/custom-0.1.69 +git push origin v0.1.69.1 +``` + +### 3. 更新 main 分支 + +```bash +# 将发布分支合并回 main,保持 main 包含最新定制功能 +git checkout main +git merge release/custom-0.1.69 +git push origin main +``` + +--- + +## 热修复发布(在现有版本上修复) + +当需要在当前版本上发布修复时: + +```bash +# 在当前发布分支上修复 +git checkout release/custom-0.1.68 +# ... 进行修复 ... +git commit -m "fix: 修复描述" + +# 递增小版本号 +echo "0.1.68.2" > backend/cmd/server/VERSION +git add backend/cmd/server/VERSION +git commit -m "chore: bump version to 0.1.68.2" + +# 打标签并推送 +git tag v0.1.68.2 +git push origin release/custom-0.1.68 +git push origin v0.1.68.2 + +# 同步修复到 main +git checkout main +git cherry-pick +git push origin main +``` + +--- + +## 服务器部署流程 + +### 前置条件 + +- 本地已配置 SSH 别名 `clicodeplus` 连接到服务器 +- 服务器部署目录:`/root/sub2api`(正式)、`/root/sub2api-beta`(测试) +- 服务器使用 Docker Compose 部署 + +### 部署环境说明 + +| 环境 | 目录 | 端口 | 数据库 | 容器名 | +|------|------|------|--------|--------| +| 正式 | `/root/sub2api` | 8080 | `sub2api` | `sub2api` | +| Beta | `/root/sub2api-beta` | 8084 | `beta` | `sub2api-beta` | + +### 外部数据库 + +正式和 Beta 环境**共用外部 PostgreSQL 数据库**(非容器内数据库),配置在 `.env` 文件中: +- `DATABASE_HOST`:外部数据库地址 +- `DATABASE_SSLMODE`:SSL 模式(通常为 `require`) +- `POSTGRES_USER` / `POSTGRES_DB`:用户名和数据库名 + +#### 数据库操作命令 + +通过 SSH 在服务器上执行数据库操作: + +```bash +# 正式环境 - 查询迁移记录 +ssh clicodeplus "source /root/sub2api/deploy/.env && PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h \$DATABASE_HOST -U \$POSTGRES_USER -d \$POSTGRES_DB -c 'SELECT * FROM schema_migrations ORDER BY applied_at DESC LIMIT 5;'" + +# Beta 环境 - 查询迁移记录 +ssh clicodeplus "source /root/sub2api-beta/deploy/.env && PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h \$DATABASE_HOST -U \$POSTGRES_USER -d \$POSTGRES_DB -c 'SELECT * FROM schema_migrations ORDER BY applied_at DESC LIMIT 5;'" + +# Beta 环境 - 清除指定迁移记录(重新执行迁移) +ssh clicodeplus "source /root/sub2api-beta/deploy/.env && PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h \$DATABASE_HOST -U \$POSTGRES_USER -d \$POSTGRES_DB -c \"DELETE FROM schema_migrations WHERE filename LIKE '%049%';\"" + +# Beta 环境 - 更新账号数据 +ssh clicodeplus "source /root/sub2api-beta/deploy/.env && PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h \$DATABASE_HOST -U \$POSTGRES_USER -d \$POSTGRES_DB -c \"UPDATE accounts SET credentials = credentials - 'model_mapping' WHERE platform = 'antigravity';\"" +``` + +> **注意**:使用 `source .env` 加载环境变量,避免在命令行中暴露密码。 + +### 部署步骤 + +**重要:每次部署都必须递增版本号!** + +#### 0. 递增版本号(本地操作) + +每次部署前,先在本地递增小版本号: + +```bash +# 查看当前版本号 +cat backend/cmd/server/VERSION +# 假设当前是 0.1.69.1 + +# 递增版本号 +echo "0.1.69.2" > backend/cmd/server/VERSION +git add backend/cmd/server/VERSION +git commit -m "chore: bump version to 0.1.69.2" +git push origin release/custom-0.1.69 +``` + +#### 1. 服务器拉取代码 + +```bash +ssh clicodeplus "cd /root/sub2api && git fetch fork && git checkout -B release/custom-0.1.69 fork/release/custom-0.1.69" +``` + +#### 2. 服务器构建镜像 + +```bash +ssh clicodeplus "cd /root/sub2api && docker build --no-cache -t sub2api:latest -f Dockerfile ." +``` + +#### 3. 更新镜像标签并重启服务 + +```bash +ssh clicodeplus "docker tag sub2api:latest weishaw/sub2api:latest" +ssh clicodeplus "cd /root/sub2api/deploy && docker compose up -d --force-recreate sub2api" +``` + +#### 4. 验证部署 + +```bash +# 查看启动日志 +ssh clicodeplus "docker logs sub2api --tail 20" + +# 确认版本号(必须与步骤 0 中设置的版本号一致) +ssh clicodeplus "cat /root/sub2api/backend/cmd/server/VERSION" + +# 检查容器状态 +ssh clicodeplus "docker ps | grep sub2api" +``` + +--- + +## Beta 并行部署(不影响现网) + +目标:在同一台服务器上并行启动一个 beta 实例(例如端口 `8084`),**严禁改动/重启**现网实例(默认目录 `/root/sub2api`)。 + +### 设计原则 + +- **新目录**:beta 使用独立目录,例如 `/root/sub2api-beta`。 +- **敏感信息只放 `.env`**:beta 的数据库密码、JWT_SECRET 等只写入 `/root/sub2api-beta/deploy/.env`,不要提交到 git。 +- **独立 Compose Project**:通过 `docker compose -p sub2api-beta ...` 启动,确保 network/volume 隔离。 +- **独立端口**:通过 `.env` 的 `SERVER_PORT` 映射宿主机端口(例如 `8084:8080`)。 + +### 前置检查 + +```bash +# 1) 确保 8084 未被占用 +ssh clicodeplus "ss -ltnp | grep :8084 || echo '8084 is free'" + +# 2) 确认现网容器还在(只读检查) +ssh clicodeplus "docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}' | sed -n '1,200p'" +``` + +### 首次部署步骤 + +```bash +# 0) 进入服务器 +ssh clicodeplus + +# 1) 克隆代码到新目录(示例使用你的 fork) +cd /root +git clone https://github.com/touwaeriol/sub2api.git sub2api-beta +cd /root/sub2api-beta +git checkout release/custom-0.1.71 + +# 2) 准备 beta 的 .env(敏感信息只写这里) +cd /root/sub2api-beta/deploy + +# 推荐:从现网 .env 复制,保证除 DB 名/用户/端口外完全一致 +cp -f /root/sub2api/deploy/.env ./.env + +# 仅修改以下三项(其他保持不变) +perl -pi -e 's/^SERVER_PORT=.*/SERVER_PORT=8084/' ./.env +perl -pi -e 's/^POSTGRES_USER=.*/POSTGRES_USER=beta/' ./.env +perl -pi -e 's/^POSTGRES_DB=.*/POSTGRES_DB=beta/' ./.env + +# 3) 写 compose override(避免与现网容器名冲突,镜像使用本地构建的 sub2api:beta) +cat > docker-compose.override.yml <<'YAML' +services: + sub2api: + image: sub2api:beta + container_name: sub2api-beta + redis: + container_name: sub2api-beta-redis +YAML + +# 4) 构建 beta 镜像(基于当前代码) +cd /root/sub2api-beta +docker build -t sub2api:beta -f Dockerfile . + +# 5) 启动 beta(独立 project,确保不影响现网) +cd /root/sub2api-beta/deploy +docker compose -p sub2api-beta --env-file .env -f docker-compose.yml -f docker-compose.override.yml up -d + +# 6) 验证 beta +curl -fsS http://127.0.0.1:8084/health +docker logs sub2api-beta --tail 50 +``` + +### 数据库配置约定(beta) + +- 数据库地址/SSL/密码:与现网一致(从现网 `.env` 复制即可)。 +- 仅修改: + - `POSTGRES_USER=beta` + - `POSTGRES_DB=beta` + +注意:需要数据库侧已存在 `beta` 用户与 `beta` 数据库,并授予权限;否则容器会启动失败并不断重启。 + +### 更新 beta(拉代码 + 仅重建 beta 容器) + +```bash +ssh clicodeplus "set -e; cd /root/sub2api-beta && git fetch --all --tags && git checkout -f release/custom-0.1.71 && git reset --hard origin/release/custom-0.1.71" +ssh clicodeplus "cd /root/sub2api-beta && docker build -t sub2api:beta -f Dockerfile ." +ssh clicodeplus "cd /root/sub2api-beta/deploy && docker compose -p sub2api-beta --env-file .env -f docker-compose.yml -f docker-compose.override.yml up -d --no-deps --force-recreate sub2api" +ssh clicodeplus "curl -fsS http://127.0.0.1:8084/health" +``` + +### 停止/回滚 beta(只影响 beta) + +```bash +ssh clicodeplus "cd /root/sub2api-beta/deploy && docker compose -p sub2api-beta -f docker-compose.yml -f docker-compose.override.yml down" +``` + +--- + +## 服务器首次部署 + +### 1. 克隆代码并配置远程仓库 + +```bash +ssh clicodeplus +cd /root +git clone https://github.com/Wei-Shaw/sub2api.git +cd sub2api + +# 添加 fork 仓库 +git remote add fork https://github.com/touwaeriol/sub2api.git +``` + +### 2. 切换到定制分支并配置环境 + +```bash +git fetch fork +git checkout -B release/custom-0.1.69 fork/release/custom-0.1.69 + +cd deploy +cp .env.example .env +vim .env # 配置 DATABASE_URL, REDIS_URL, JWT_SECRET 等 +``` + +### 3. 构建并启动 + +```bash +cd /root/sub2api +docker build -t sub2api:latest -f Dockerfile . +docker tag sub2api:latest weishaw/sub2api:latest +cd deploy && docker compose up -d +``` + +### 6. 启动服务 + +```bash +# 进入 deploy 目录 +cd deploy + +# 启动所有服务(PostgreSQL、Redis、sub2api) +docker compose up -d + +# 查看服务状态 +docker compose ps +``` + +### 7. 验证部署 + +```bash +# 查看应用日志 +docker logs sub2api --tail 50 + +# 检查健康状态 +curl http://localhost:8080/health + +# 确认版本号 +cat /root/sub2api/backend/cmd/server/VERSION +``` + +### 8. 常用运维命令 + +```bash +# 查看实时日志 +docker logs -f sub2api + +# 重启服务 +docker compose restart sub2api + +# 停止所有服务 +docker compose down + +# 停止并删除数据卷(慎用!会删除数据库数据) +docker compose down -v + +# 查看资源使用情况 +docker stats sub2api +``` + +--- + +## 定制功能说明 + +当前定制分支包含以下功能(相对于官方版本): + +### UI/UX 定制 + +| 功能 | 说明 | +|------|------| +| 首页优化 | 面向用户的价值主张设计 | +| 移除 GitHub 链接 | 用户菜单中不显示 GitHub 导航 | +| 微信客服按钮 | 首页悬浮微信客服入口 | +| 限流时间精确显示 | 账号限流时间显示精确到秒 | + +### Antigravity 平台增强 + +| 功能 | 说明 | +|------|------| +| Scope 级别限流 | 按配额域(claude/gemini_text/gemini_image)独立限流,避免整个账号被锁定 | +| 模型级别限流 | 按具体模型(如 claude-opus-4-5)独立限流,更精细的限流控制 | +| 限流预检查 | 调度时预检查账号/模型限流状态,避免选中已限流账号 | +| 秒级冷却时间 | 支持 429 响应的秒级精确冷却时间 | +| 身份注入优化 | 模型身份信息注入 + 静默边界防止身份泄露 | +| thoughtSignature 修复 | Gemini 3 函数调用 400 错误修复 | +| max_tokens 自动修正 | 自动修正 max_tokens <= budget_tokens 导致的 400 错误 | + +### 调度算法优化 + +| 功能 | 说明 | +|------|------| +| 分层过滤选择 | 调度算法从全排序改为分层过滤,提升性能 | +| LRU 随机选择 | 相同 LRU 时间时随机选择,避免账号集中 | +| 限流等待阈值配置化 | 可配置的限流等待阈值 | + +### 运维增强 + +| 功能 | 说明 | +|------|------| +| Scope 限流统计 | 运维界面展示 Antigravity 账号 scope 级别限流统计 | +| 账号限流状态显示 | 账号列表显示 scope 和模型级别限流状态 | +| 清除限流按钮增强 | 有 scope/模型限流时也显示清除限流按钮 | + +### 其他修复 + +| 功能 | 说明 | +|------|------| +| .gitattributes | 确保迁移文件使用 LF 换行符(解决 Windows 下 SQL 摘要不一致) | +| 部署配置优化 | DATABASE_HOST 和 DATABASE_SSLMODE 可通过 .env 配置 | + +--- + +## 注意事项 + +1. **前端必须打包进镜像**:使用 `docker build` 在服务器上构建,Dockerfile 会自动编译前端并 embed 到后端二进制中 + +2. **镜像标签**:docker-compose.yml 使用 `weishaw/sub2api:latest`,本地构建后需要 `docker tag` 覆盖 + +3. **Windows 换行符问题**:已通过 `.gitattributes` 解决,确保 `*.sql` 文件始终使用 LF + +4. **版本号管理**:每次发布必须更新 `backend/cmd/server/VERSION` 并打标签 + +5. **合并冲突**:合并上游新版本时,重点关注以下文件可能的冲突: + - `backend/internal/service/antigravity_gateway_service.go` + - `backend/internal/service/gateway_service.go` + - `backend/internal/pkg/antigravity/request_transformer.go` + +--- + +## Go 代码规范 + +### 1. 函数设计 + +#### 单一职责原则 +- **函数行数**:单个函数常规不应超过 **30 行**,超过时应拆分为子函数。若某段逻辑确实不可拆分(如复杂的状态机、协议解析等),可以例外,但需添加注释说明原因 +- **嵌套层级**:避免超过 3 层嵌套,使用 early return 减少嵌套 + +```go +// ❌ 不推荐:深层嵌套 +func process(data []Item) { + for _, item := range data { + if item.Valid { + if item.Type == "A" { + if item.Status == "active" { + // 业务逻辑... + } + } + } + } +} + +// ✅ 推荐:early return +func process(data []Item) { + for _, item := range data { + if !item.Valid { + continue + } + if item.Type != "A" { + continue + } + if item.Status != "active" { + continue + } + // 业务逻辑... + } +} +``` + +#### 复杂逻辑提取 +将复杂的条件判断或处理逻辑提取为独立函数: + +```go +// ❌ 不推荐:内联复杂逻辑 +if resp.StatusCode == 429 || resp.StatusCode == 503 { + // 80+ 行处理逻辑... +} + +// ✅ 推荐:提取为独立函数 +result := handleRateLimitResponse(resp, params) +switch result.action { +case actionRetry: + continue +case actionBreak: + return result.resp, nil +} +``` + +### 2. 重复代码消除 + +#### 配置获取模式 +将重复的配置获取逻辑提取为方法: + +```go +// ❌ 不推荐:重复代码 +logBody := s.settingService != nil && s.settingService.cfg != nil && s.settingService.cfg.Gateway.LogUpstreamErrorBody +maxBytes := 2048 +if s.settingService != nil && s.settingService.cfg != nil && s.settingService.cfg.Gateway.LogUpstreamErrorBodyMaxBytes > 0 { + maxBytes = s.settingService.cfg.Gateway.LogUpstreamErrorBodyMaxBytes +} + +// ✅ 推荐:提取为方法 +func (s *Service) getLogConfig() (logBody bool, maxBytes int) { + maxBytes = 2048 + if s.settingService == nil || s.settingService.cfg == nil { + return false, maxBytes + } + cfg := s.settingService.cfg.Gateway + if cfg.LogUpstreamErrorBodyMaxBytes > 0 { + maxBytes = cfg.LogUpstreamErrorBodyMaxBytes + } + return cfg.LogUpstreamErrorBody, maxBytes +} +``` + +### 3. 常量管理 + +#### 避免魔法数字 +所有硬编码的数值都应定义为常量: + +```go +// ❌ 不推荐 +if retryDelay >= 10*time.Second { + resetAt := time.Now().Add(30 * time.Second) +} + +// ✅ 推荐 +const ( + rateLimitThreshold = 10 * time.Second + defaultRateLimitDuration = 30 * time.Second +) + +if retryDelay >= rateLimitThreshold { + resetAt := time.Now().Add(defaultRateLimitDuration) +} +``` + +#### 注释引用常量名 +在注释中引用常量名而非硬编码值: + +```go +// ❌ 不推荐 +// < 10s: 等待后重试 + +// ✅ 推荐 +// < rateLimitThreshold: 等待后重试 +``` + +### 4. 错误处理 + +#### 使用结构化日志 +优先使用 `slog` 进行结构化日志记录: + +```go +// ❌ 不推荐 +log.Printf("%s status=%d model_rate_limit_failed model=%s error=%v", prefix, statusCode, modelName, err) + +// ✅ 推荐 +slog.Error("failed to set model rate limit", + "prefix", prefix, + "status_code", statusCode, + "model", modelName, + "error", err, +) +``` + +### 5. 测试规范 + +#### Mock 函数签名同步 +修改函数签名时,必须同步更新所有测试中的 mock 函数: + +```go +// 如果修改了 handleError 签名 +handleError func(..., groupID int64, sessionHash string) *Result + +// 必须同步更新测试中的 mock +handleError: func(..., groupID int64, sessionHash string) *Result { + return nil +}, +``` + +#### 测试构建标签 +统一使用测试构建标签: + +```go +//go:build unit + +package service +``` + +### 6. 时间格式解析 + +#### 使用标准库 +优先使用 `time.ParseDuration`,支持所有 Go duration 格式: + +```go +// ❌ 不推荐:手动限制格式 +if !strings.HasSuffix(delay, "s") || strings.Contains(delay, "m") { + continue +} + +// ✅ 推荐:使用标准库 +dur, err := time.ParseDuration(delay) // 支持 "0.5s", "4m50s", "1h30m" 等 +``` + +### 7. 接口设计 + +#### 接口隔离原则 +定义最小化接口,只包含必需的方法: + +```go +// ❌ 不推荐:使用过于宽泛的接口 +type AccountRepository interface { + // 20+ 个方法... +} + +// ✅ 推荐:定义最小化接口 +type ModelRateLimiter interface { + SetModelRateLimit(ctx context.Context, id int64, modelKey string, resetAt time.Time) error +} +``` + +### 8. 并发安全 + +#### 共享数据保护 +访问可能被并发修改的数据时,确保线程安全: + +```go +// 如果 Account.Extra 可能被并发修改 +// 需要使用互斥锁或原子操作保护读取 +func (a *Account) GetRateLimitRemainingTime(model string) time.Duration { + a.mu.RLock() + defer a.mu.RUnlock() + // 读取 Extra 字段... +} +``` + +### 9. 命名规范 + +#### 一致的命名风格 +- 常量使用 camelCase:`rateLimitThreshold` +- 类型使用 PascalCase:`AntigravityQuotaScope` +- 同一概念使用统一命名:`Threshold` 或 `Limit`,不要混用 + +```go +// ❌ 不推荐:命名不一致 +antigravitySmartRetryMinWait // 使用 Min +antigravityRateLimitThreshold // 使用 Threshold + +// ✅ 推荐:统一风格 +antigravityMinRetryWait +antigravityRateLimitThreshold +``` + +### 10. 代码审查清单 + +在提交代码前,检查以下项目: + +- [ ] 函数是否超过 30 行?(不可拆分的逻辑除外,需注释说明) +- [ ] 嵌套是否超过 3 层? +- [ ] 是否有重复代码可以提取? +- [ ] 是否使用了魔法数字? +- [ ] Mock 函数签名是否与实际函数一致? +- [ ] 测试是否覆盖了新增逻辑? +- [ ] 日志是否包含足够的上下文信息? +- [ ] 是否考虑了并发安全? + +--- + +## CI 检查与发布门禁 + +### GitHub Actions 检查项 + +本项目有 4 个 CI 任务,**任何代码推送或发布前都必须全部通过**: + +| Workflow | Job | 说明 | 本地验证命令 | +|----------|-----|------|-------------| +| CI | `test` | 单元测试 + 集成测试 | `cd backend && make test-unit && make test-integration` | +| CI | `golangci-lint` | Go 代码静态检查(golangci-lint v2.7) | `cd backend && golangci-lint run --timeout=5m` | +| Security Scan | `backend-security` | govulncheck + gosec 安全扫描 | `cd backend && govulncheck ./... && gosec -severity high -confidence high ./...` | +| Security Scan | `frontend-security` | pnpm audit 前端依赖安全检查 | `cd frontend && pnpm audit --prod --audit-level=high` | + +### 向上游提交 PR + +PR 目标是上游官方仓库,**只包含通用功能改动**(bug fix、新功能、性能优化等)。 + +**以下文件禁止出现在 PR 中**(属于我们 fork 的定制化内容): +- `CLAUDE.md`、`AGENTS.md` — 我们的开发文档 +- `backend/cmd/server/VERSION` — 我们的版本号文件 +- UI 定制改动(GitHub 链接移除、微信客服按钮、首页定制等) +- 部署配置(`deploy/` 目录下的定制修改) + +**PR 流程**: +1. 从 `develop` 创建功能分支,只包含要提交给上游的改动 +2. 推送分支后,**等待 4 个 CI job 全部通过** +3. 确认通过后再创建 PR +4. 使用 `gh run list --repo touwaeriol/sub2api --branch ` 检查状态 + +### 自有分支推送(develop / main) + +推送到我们自己的 `develop` 或 `main` 分支时,包含所有改动(定制化 + 通用功能)。 + +**推送流程**: +1. 本地运行 `cd backend && make test-unit` 确保单元测试通过 +2. 本地运行 `cd backend && gofmt -l ./...` 确保格式正确 +3. 推送后确认 CI 和 Security Scan 两个 workflow 的 4 个 job 全部绿色 ✅ +4. 任何 job 失败必须立即修复,**禁止在 CI 未通过的状态下继续后续操作** + +### 发布版本 + +1. 确保 `main` 分支最新提交的 4 个 CI job 全部通过 +2. 递增 `backend/cmd/server/VERSION`,提交并推送 +3. 打 tag 推送后,确认 tag 触发的 3 个 workflow(CI、Security Scan、Release)全部通过 +4. **Release workflow 失败时禁止部署** — 必须先修复问题,删除旧 tag,重新打 tag +5. 使用 `gh run list --repo touwaeriol/sub2api --limit 10` 确认状态 + +### 常见 CI 失败原因及修复 +- **gofmt**:struct 字段对齐不一致 → 运行 `gofmt -w ` 修复 +- **golangci-lint**:未使用的变量/导入 → 删除或使用 `_` 忽略 +- **test 失败**:mock 函数签名不一致 → 同步更新 mock +- **gosec**:安全漏洞 → 根据提示修复或添加例外 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..a7a3e34a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,723 @@ +# Sub2API 开发说明 + +## 版本管理策略 + +### 版本号规则 + +我们在官方版本号后面添加自己的小版本号: + +- 官方版本:`v0.1.68` +- 我们的版本:`v0.1.68.1`、`v0.1.68.2`(递增) + +### 分支策略 + +| 分支 | 说明 | +|------|------| +| `main` | 我们的主分支,包含所有定制功能 | +| `release/custom-X.Y.Z` | 基于官方 `vX.Y.Z` 的发布分支 | +| `upstream/main` | 上游官方仓库 | + +--- + +## 发布流程(基于新官方版本) + +当官方发布新版本(如 `v0.1.69`)时: + +### 1. 同步上游并创建发布分支 + +```bash +# 获取上游最新代码 +git fetch upstream --tags + +# 基于官方标签创建新的发布分支 +git checkout v0.1.69 -b release/custom-0.1.69 + +# 合并我们的 main 分支(包含所有定制功能) +git merge main --no-edit + +# 解决可能的冲突后继续 +``` + +### 2. 更新版本号并打标签 + +```bash +# 更新版本号文件 +echo "0.1.69.1" > backend/cmd/server/VERSION +git add backend/cmd/server/VERSION +git commit -m "chore: bump version to 0.1.69.1" + +# 打上我们自己的标签 +git tag v0.1.69.1 + +# 推送分支和标签 +git push origin release/custom-0.1.69 +git push origin v0.1.69.1 +``` + +### 3. 更新 main 分支 + +```bash +# 将发布分支合并回 main,保持 main 包含最新定制功能 +git checkout main +git merge release/custom-0.1.69 +git push origin main +``` + +--- + +## 热修复发布(在现有版本上修复) + +当需要在当前版本上发布修复时: + +```bash +# 在当前发布分支上修复 +git checkout release/custom-0.1.68 +# ... 进行修复 ... +git commit -m "fix: 修复描述" + +# 递增小版本号 +echo "0.1.68.2" > backend/cmd/server/VERSION +git add backend/cmd/server/VERSION +git commit -m "chore: bump version to 0.1.68.2" + +# 打标签并推送 +git tag v0.1.68.2 +git push origin release/custom-0.1.68 +git push origin v0.1.68.2 + +# 同步修复到 main +git checkout main +git cherry-pick +git push origin main +``` + +--- + +## 服务器部署流程 + +### 前置条件 + +- 本地已配置 SSH 别名 `clicodeplus` 连接到服务器 +- 服务器部署目录:`/root/sub2api`(正式)、`/root/sub2api-beta`(测试) +- 服务器使用 Docker Compose 部署 + +### 部署环境说明 + +| 环境 | 目录 | 端口 | 数据库 | 容器名 | +|------|------|------|--------|--------| +| 正式 | `/root/sub2api` | 8080 | `sub2api` | `sub2api` | +| Beta | `/root/sub2api-beta` | 8084 | `beta` | `sub2api-beta` | + +### 外部数据库 + +正式和 Beta 环境**共用外部 PostgreSQL 数据库**(非容器内数据库),配置在 `.env` 文件中: +- `DATABASE_HOST`:外部数据库地址 +- `DATABASE_SSLMODE`:SSL 模式(通常为 `require`) +- `POSTGRES_USER` / `POSTGRES_DB`:用户名和数据库名 + +#### 数据库操作命令 + +通过 SSH 在服务器上执行数据库操作: + +```bash +# 正式环境 - 查询迁移记录 +ssh clicodeplus "source /root/sub2api/deploy/.env && PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h \$DATABASE_HOST -U \$POSTGRES_USER -d \$POSTGRES_DB -c 'SELECT * FROM schema_migrations ORDER BY applied_at DESC LIMIT 5;'" + +# Beta 环境 - 查询迁移记录 +ssh clicodeplus "source /root/sub2api-beta/deploy/.env && PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h \$DATABASE_HOST -U \$POSTGRES_USER -d \$POSTGRES_DB -c 'SELECT * FROM schema_migrations ORDER BY applied_at DESC LIMIT 5;'" + +# Beta 环境 - 清除指定迁移记录(重新执行迁移) +ssh clicodeplus "source /root/sub2api-beta/deploy/.env && PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h \$DATABASE_HOST -U \$POSTGRES_USER -d \$POSTGRES_DB -c \"DELETE FROM schema_migrations WHERE filename LIKE '%049%';\"" + +# Beta 环境 - 更新账号数据 +ssh clicodeplus "source /root/sub2api-beta/deploy/.env && PGPASSWORD=\"\$POSTGRES_PASSWORD\" psql -h \$DATABASE_HOST -U \$POSTGRES_USER -d \$POSTGRES_DB -c \"UPDATE accounts SET credentials = credentials - 'model_mapping' WHERE platform = 'antigravity';\"" +``` + +> **注意**:使用 `source .env` 加载环境变量,避免在命令行中暴露密码。 + +### 部署步骤 + +**重要:每次部署都必须递增版本号!** + +#### 0. 递增版本号(本地操作) + +每次部署前,先在本地递增小版本号: + +```bash +# 查看当前版本号 +cat backend/cmd/server/VERSION +# 假设当前是 0.1.69.1 + +# 递增版本号 +echo "0.1.69.2" > backend/cmd/server/VERSION +git add backend/cmd/server/VERSION +git commit -m "chore: bump version to 0.1.69.2" +git push origin release/custom-0.1.69 +``` + +#### 1. 服务器拉取代码 + +```bash +ssh clicodeplus "cd /root/sub2api && git fetch fork && git checkout -B release/custom-0.1.69 fork/release/custom-0.1.69" +``` + +#### 2. 服务器构建镜像 + +```bash +ssh clicodeplus "cd /root/sub2api && docker build --no-cache -t sub2api:latest -f Dockerfile ." +``` + +#### 3. 更新镜像标签并重启服务 + +```bash +ssh clicodeplus "docker tag sub2api:latest weishaw/sub2api:latest" +ssh clicodeplus "cd /root/sub2api/deploy && docker compose up -d --force-recreate sub2api" +``` + +#### 4. 验证部署 + +```bash +# 查看启动日志 +ssh clicodeplus "docker logs sub2api --tail 20" + +# 确认版本号(必须与步骤 0 中设置的版本号一致) +ssh clicodeplus "cat /root/sub2api/backend/cmd/server/VERSION" + +# 检查容器状态 +ssh clicodeplus "docker ps | grep sub2api" +``` + +--- + +## Beta 并行部署(不影响现网) + +目标:在同一台服务器上并行启动一个 beta 实例(例如端口 `8084`),**严禁改动/重启**现网实例(默认目录 `/root/sub2api`)。 + +### 设计原则 + +- **新目录**:beta 使用独立目录,例如 `/root/sub2api-beta`。 +- **敏感信息只放 `.env`**:beta 的数据库密码、JWT_SECRET 等只写入 `/root/sub2api-beta/deploy/.env`,不要提交到 git。 +- **独立 Compose Project**:通过 `docker compose -p sub2api-beta ...` 启动,确保 network/volume 隔离。 +- **独立端口**:通过 `.env` 的 `SERVER_PORT` 映射宿主机端口(例如 `8084:8080`)。 + +### 前置检查 + +```bash +# 1) 确保 8084 未被占用 +ssh clicodeplus "ss -ltnp | grep :8084 || echo '8084 is free'" + +# 2) 确认现网容器还在(只读检查) +ssh clicodeplus "docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}' | sed -n '1,200p'" +``` + +### 首次部署步骤 + +```bash +# 0) 进入服务器 +ssh clicodeplus + +# 1) 克隆代码到新目录(示例使用你的 fork) +cd /root +git clone https://github.com/touwaeriol/sub2api.git sub2api-beta +cd /root/sub2api-beta +git checkout release/custom-0.1.71 + +# 2) 准备 beta 的 .env(敏感信息只写这里) +cd /root/sub2api-beta/deploy + +# 推荐:从现网 .env 复制,保证除 DB 名/用户/端口外完全一致 +cp -f /root/sub2api/deploy/.env ./.env + +# 仅修改以下三项(其他保持不变) +perl -pi -e 's/^SERVER_PORT=.*/SERVER_PORT=8084/' ./.env +perl -pi -e 's/^POSTGRES_USER=.*/POSTGRES_USER=beta/' ./.env +perl -pi -e 's/^POSTGRES_DB=.*/POSTGRES_DB=beta/' ./.env + +# 3) 写 compose override(避免与现网容器名冲突,镜像使用本地构建的 sub2api:beta) +cat > docker-compose.override.yml <<'YAML' +services: + sub2api: + image: sub2api:beta + container_name: sub2api-beta + redis: + container_name: sub2api-beta-redis +YAML + +# 4) 构建 beta 镜像(基于当前代码) +cd /root/sub2api-beta +docker build -t sub2api:beta -f Dockerfile . + +# 5) 启动 beta(独立 project,确保不影响现网) +cd /root/sub2api-beta/deploy +docker compose -p sub2api-beta --env-file .env -f docker-compose.yml -f docker-compose.override.yml up -d + +# 6) 验证 beta +curl -fsS http://127.0.0.1:8084/health +docker logs sub2api-beta --tail 50 +``` + +### 数据库配置约定(beta) + +- 数据库地址/SSL/密码:与现网一致(从现网 `.env` 复制即可)。 +- 仅修改: + - `POSTGRES_USER=beta` + - `POSTGRES_DB=beta` + +注意:需要数据库侧已存在 `beta` 用户与 `beta` 数据库,并授予权限;否则容器会启动失败并不断重启。 + +### 更新 beta(拉代码 + 仅重建 beta 容器) + +```bash +ssh clicodeplus "set -e; cd /root/sub2api-beta && git fetch --all --tags && git checkout -f release/custom-0.1.71 && git reset --hard origin/release/custom-0.1.71" +ssh clicodeplus "cd /root/sub2api-beta && docker build -t sub2api:beta -f Dockerfile ." +ssh clicodeplus "cd /root/sub2api-beta/deploy && docker compose -p sub2api-beta --env-file .env -f docker-compose.yml -f docker-compose.override.yml up -d --no-deps --force-recreate sub2api" +ssh clicodeplus "curl -fsS http://127.0.0.1:8084/health" +``` + +### 停止/回滚 beta(只影响 beta) + +```bash +ssh clicodeplus "cd /root/sub2api-beta/deploy && docker compose -p sub2api-beta -f docker-compose.yml -f docker-compose.override.yml down" +``` + +--- + +## 服务器首次部署 + +### 1. 克隆代码并配置远程仓库 + +```bash +ssh clicodeplus +cd /root +git clone https://github.com/Wei-Shaw/sub2api.git +cd sub2api + +# 添加 fork 仓库 +git remote add fork https://github.com/touwaeriol/sub2api.git +``` + +### 2. 切换到定制分支并配置环境 + +```bash +git fetch fork +git checkout -B release/custom-0.1.69 fork/release/custom-0.1.69 + +cd deploy +cp .env.example .env +vim .env # 配置 DATABASE_URL, REDIS_URL, JWT_SECRET 等 +``` + +### 3. 构建并启动 + +```bash +cd /root/sub2api +docker build -t sub2api:latest -f Dockerfile . +docker tag sub2api:latest weishaw/sub2api:latest +cd deploy && docker compose up -d +``` + +### 6. 启动服务 + +```bash +# 进入 deploy 目录 +cd deploy + +# 启动所有服务(PostgreSQL、Redis、sub2api) +docker compose up -d + +# 查看服务状态 +docker compose ps +``` + +### 7. 验证部署 + +```bash +# 查看应用日志 +docker logs sub2api --tail 50 + +# 检查健康状态 +curl http://localhost:8080/health + +# 确认版本号 +cat /root/sub2api/backend/cmd/server/VERSION +``` + +### 8. 常用运维命令 + +```bash +# 查看实时日志 +docker logs -f sub2api + +# 重启服务 +docker compose restart sub2api + +# 停止所有服务 +docker compose down + +# 停止并删除数据卷(慎用!会删除数据库数据) +docker compose down -v + +# 查看资源使用情况 +docker stats sub2api +``` + +--- + +## 定制功能说明 + +当前定制分支包含以下功能(相对于官方版本): + +### UI/UX 定制 + +| 功能 | 说明 | +|------|------| +| 首页优化 | 面向用户的价值主张设计 | +| 移除 GitHub 链接 | 用户菜单中不显示 GitHub 导航 | +| 微信客服按钮 | 首页悬浮微信客服入口 | +| 限流时间精确显示 | 账号限流时间显示精确到秒 | + +### Antigravity 平台增强 + +| 功能 | 说明 | +|------|------| +| Scope 级别限流 | 按配额域(claude/gemini_text/gemini_image)独立限流,避免整个账号被锁定 | +| 模型级别限流 | 按具体模型(如 claude-opus-4-5)独立限流,更精细的限流控制 | +| 限流预检查 | 调度时预检查账号/模型限流状态,避免选中已限流账号 | +| 秒级冷却时间 | 支持 429 响应的秒级精确冷却时间 | +| 身份注入优化 | 模型身份信息注入 + 静默边界防止身份泄露 | +| thoughtSignature 修复 | Gemini 3 函数调用 400 错误修复 | +| max_tokens 自动修正 | 自动修正 max_tokens <= budget_tokens 导致的 400 错误 | + +### 调度算法优化 + +| 功能 | 说明 | +|------|------| +| 分层过滤选择 | 调度算法从全排序改为分层过滤,提升性能 | +| LRU 随机选择 | 相同 LRU 时间时随机选择,避免账号集中 | +| 限流等待阈值配置化 | 可配置的限流等待阈值 | + +### 运维增强 + +| 功能 | 说明 | +|------|------| +| Scope 限流统计 | 运维界面展示 Antigravity 账号 scope 级别限流统计 | +| 账号限流状态显示 | 账号列表显示 scope 和模型级别限流状态 | +| 清除限流按钮增强 | 有 scope/模型限流时也显示清除限流按钮 | + +### 其他修复 + +| 功能 | 说明 | +|------|------| +| .gitattributes | 确保迁移文件使用 LF 换行符(解决 Windows 下 SQL 摘要不一致) | +| 部署配置优化 | DATABASE_HOST 和 DATABASE_SSLMODE 可通过 .env 配置 | + +--- + +## 注意事项 + +1. **前端必须打包进镜像**:使用 `docker build` 在服务器上构建,Dockerfile 会自动编译前端并 embed 到后端二进制中 + +2. **镜像标签**:docker-compose.yml 使用 `weishaw/sub2api:latest`,本地构建后需要 `docker tag` 覆盖 + +3. **Windows 换行符问题**:已通过 `.gitattributes` 解决,确保 `*.sql` 文件始终使用 LF + +4. **版本号管理**:每次发布必须更新 `backend/cmd/server/VERSION` 并打标签 + +5. **合并冲突**:合并上游新版本时,重点关注以下文件可能的冲突: + - `backend/internal/service/antigravity_gateway_service.go` + - `backend/internal/service/gateway_service.go` + - `backend/internal/pkg/antigravity/request_transformer.go` + +--- + +## Go 代码规范 + +### 1. 函数设计 + +#### 单一职责原则 +- **函数行数**:单个函数常规不应超过 **30 行**,超过时应拆分为子函数。若某段逻辑确实不可拆分(如复杂的状态机、协议解析等),可以例外,但需添加注释说明原因 +- **嵌套层级**:避免超过 3 层嵌套,使用 early return 减少嵌套 + +```go +// ❌ 不推荐:深层嵌套 +func process(data []Item) { + for _, item := range data { + if item.Valid { + if item.Type == "A" { + if item.Status == "active" { + // 业务逻辑... + } + } + } + } +} + +// ✅ 推荐:early return +func process(data []Item) { + for _, item := range data { + if !item.Valid { + continue + } + if item.Type != "A" { + continue + } + if item.Status != "active" { + continue + } + // 业务逻辑... + } +} +``` + +#### 复杂逻辑提取 +将复杂的条件判断或处理逻辑提取为独立函数: + +```go +// ❌ 不推荐:内联复杂逻辑 +if resp.StatusCode == 429 || resp.StatusCode == 503 { + // 80+ 行处理逻辑... +} + +// ✅ 推荐:提取为独立函数 +result := handleRateLimitResponse(resp, params) +switch result.action { +case actionRetry: + continue +case actionBreak: + return result.resp, nil +} +``` + +### 2. 重复代码消除 + +#### 配置获取模式 +将重复的配置获取逻辑提取为方法: + +```go +// ❌ 不推荐:重复代码 +logBody := s.settingService != nil && s.settingService.cfg != nil && s.settingService.cfg.Gateway.LogUpstreamErrorBody +maxBytes := 2048 +if s.settingService != nil && s.settingService.cfg != nil && s.settingService.cfg.Gateway.LogUpstreamErrorBodyMaxBytes > 0 { + maxBytes = s.settingService.cfg.Gateway.LogUpstreamErrorBodyMaxBytes +} + +// ✅ 推荐:提取为方法 +func (s *Service) getLogConfig() (logBody bool, maxBytes int) { + maxBytes = 2048 + if s.settingService == nil || s.settingService.cfg == nil { + return false, maxBytes + } + cfg := s.settingService.cfg.Gateway + if cfg.LogUpstreamErrorBodyMaxBytes > 0 { + maxBytes = cfg.LogUpstreamErrorBodyMaxBytes + } + return cfg.LogUpstreamErrorBody, maxBytes +} +``` + +### 3. 常量管理 + +#### 避免魔法数字 +所有硬编码的数值都应定义为常量: + +```go +// ❌ 不推荐 +if retryDelay >= 10*time.Second { + resetAt := time.Now().Add(30 * time.Second) +} + +// ✅ 推荐 +const ( + rateLimitThreshold = 10 * time.Second + defaultRateLimitDuration = 30 * time.Second +) + +if retryDelay >= rateLimitThreshold { + resetAt := time.Now().Add(defaultRateLimitDuration) +} +``` + +#### 注释引用常量名 +在注释中引用常量名而非硬编码值: + +```go +// ❌ 不推荐 +// < 10s: 等待后重试 + +// ✅ 推荐 +// < rateLimitThreshold: 等待后重试 +``` + +### 4. 错误处理 + +#### 使用结构化日志 +优先使用 `slog` 进行结构化日志记录: + +```go +// ❌ 不推荐 +log.Printf("%s status=%d model_rate_limit_failed model=%s error=%v", prefix, statusCode, modelName, err) + +// ✅ 推荐 +slog.Error("failed to set model rate limit", + "prefix", prefix, + "status_code", statusCode, + "model", modelName, + "error", err, +) +``` + +### 5. 测试规范 + +#### Mock 函数签名同步 +修改函数签名时,必须同步更新所有测试中的 mock 函数: + +```go +// 如果修改了 handleError 签名 +handleError func(..., groupID int64, sessionHash string) *Result + +// 必须同步更新测试中的 mock +handleError: func(..., groupID int64, sessionHash string) *Result { + return nil +}, +``` + +#### 测试构建标签 +统一使用测试构建标签: + +```go +//go:build unit + +package service +``` + +### 6. 时间格式解析 + +#### 使用标准库 +优先使用 `time.ParseDuration`,支持所有 Go duration 格式: + +```go +// ❌ 不推荐:手动限制格式 +if !strings.HasSuffix(delay, "s") || strings.Contains(delay, "m") { + continue +} + +// ✅ 推荐:使用标准库 +dur, err := time.ParseDuration(delay) // 支持 "0.5s", "4m50s", "1h30m" 等 +``` + +### 7. 接口设计 + +#### 接口隔离原则 +定义最小化接口,只包含必需的方法: + +```go +// ❌ 不推荐:使用过于宽泛的接口 +type AccountRepository interface { + // 20+ 个方法... +} + +// ✅ 推荐:定义最小化接口 +type ModelRateLimiter interface { + SetModelRateLimit(ctx context.Context, id int64, modelKey string, resetAt time.Time) error +} +``` + +### 8. 并发安全 + +#### 共享数据保护 +访问可能被并发修改的数据时,确保线程安全: + +```go +// 如果 Account.Extra 可能被并发修改 +// 需要使用互斥锁或原子操作保护读取 +func (a *Account) GetRateLimitRemainingTime(model string) time.Duration { + a.mu.RLock() + defer a.mu.RUnlock() + // 读取 Extra 字段... +} +``` + +### 9. 命名规范 + +#### 一致的命名风格 +- 常量使用 camelCase:`rateLimitThreshold` +- 类型使用 PascalCase:`AntigravityQuotaScope` +- 同一概念使用统一命名:`Threshold` 或 `Limit`,不要混用 + +```go +// ❌ 不推荐:命名不一致 +antigravitySmartRetryMinWait // 使用 Min +antigravityRateLimitThreshold // 使用 Threshold + +// ✅ 推荐:统一风格 +antigravityMinRetryWait +antigravityRateLimitThreshold +``` + +### 10. 代码审查清单 + +在提交代码前,检查以下项目: + +- [ ] 函数是否超过 30 行?(不可拆分的逻辑除外,需注释说明) +- [ ] 嵌套是否超过 3 层? +- [ ] 是否有重复代码可以提取? +- [ ] 是否使用了魔法数字? +- [ ] Mock 函数签名是否与实际函数一致? +- [ ] 测试是否覆盖了新增逻辑? +- [ ] 日志是否包含足够的上下文信息? +- [ ] 是否考虑了并发安全? + +--- + +## CI 检查与发布门禁 + +### GitHub Actions 检查项 + +本项目有 4 个 CI 任务,**任何代码推送或发布前都必须全部通过**: + +| Workflow | Job | 说明 | 本地验证命令 | +|----------|-----|------|-------------| +| CI | `test` | 单元测试 + 集成测试 | `cd backend && make test-unit && make test-integration` | +| CI | `golangci-lint` | Go 代码静态检查(golangci-lint v2.7) | `cd backend && golangci-lint run --timeout=5m` | +| Security Scan | `backend-security` | govulncheck + gosec 安全扫描 | `cd backend && govulncheck ./... && gosec -severity high -confidence high ./...` | +| Security Scan | `frontend-security` | pnpm audit 前端依赖安全检查 | `cd frontend && pnpm audit --prod --audit-level=high` | + +### 向上游提交 PR + +PR 目标是上游官方仓库,**只包含通用功能改动**(bug fix、新功能、性能优化等)。 + +**以下文件禁止出现在 PR 中**(属于我们 fork 的定制化内容): +- `CLAUDE.md`、`AGENTS.md` — 我们的开发文档 +- `backend/cmd/server/VERSION` — 我们的版本号文件 +- UI 定制改动(GitHub 链接移除、微信客服按钮、首页定制等) +- 部署配置(`deploy/` 目录下的定制修改) + +**PR 流程**: +1. 从 `develop` 创建功能分支,只包含要提交给上游的改动 +2. 推送分支后,**等待 4 个 CI job 全部通过** +3. 确认通过后再创建 PR +4. 使用 `gh run list --repo touwaeriol/sub2api --branch ` 检查状态 + +### 自有分支推送(develop / main) + +推送到我们自己的 `develop` 或 `main` 分支时,包含所有改动(定制化 + 通用功能)。 + +**推送流程**: +1. 本地运行 `cd backend && make test-unit` 确保单元测试通过 +2. 本地运行 `cd backend && gofmt -l ./...` 确保格式正确 +3. 推送后确认 CI 和 Security Scan 两个 workflow 的 4 个 job 全部绿色 ✅ +4. 任何 job 失败必须立即修复,**禁止在 CI 未通过的状态下继续后续操作** + +### 发布版本 + +1. 确保 `main` 分支最新提交的 4 个 CI job 全部通过 +2. 递增 `backend/cmd/server/VERSION`,提交并推送 +3. 打 tag 推送后,确认 tag 触发的 3 个 workflow(CI、Security Scan、Release)全部通过 +4. **Release workflow 失败时禁止部署** — 必须先修复问题,删除旧 tag,重新打 tag +5. 使用 `gh run list --repo touwaeriol/sub2api --limit 10` 确认状态 + +### 常见 CI 失败原因及修复 +- **gofmt**:struct 字段对齐不一致 → 运行 `gofmt -w ` 修复 +- **golangci-lint**:未使用的变量/导入 → 删除或使用 `_` 忽略 +- **test 失败**:mock 函数签名不一致 → 同步更新 mock +- **gosec**:安全漏洞 → 根据提示修复或添加例外 diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index 033731ac..f1d19f84 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -47,13 +47,15 @@ services: # ======================================================================= # Database Configuration (PostgreSQL) + # Default: uses local postgres container + # External DB: set DATABASE_HOST and DATABASE_SSLMODE in .env # ======================================================================= - - DATABASE_HOST=postgres - - DATABASE_PORT=5432 + - DATABASE_HOST=${DATABASE_HOST:-postgres} + - DATABASE_PORT=${DATABASE_PORT:-5432} - DATABASE_USER=${POSTGRES_USER:-sub2api} - DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} - DATABASE_DBNAME=${POSTGRES_DB:-sub2api} - - DATABASE_SSLMODE=disable + - DATABASE_SSLMODE=${DATABASE_SSLMODE:-disable} # ======================================================================= # Redis Configuration @@ -128,8 +130,6 @@ services: # Examples: http://host:port, socks5://host:port - UPDATE_PROXY_URL=${UPDATE_PROXY_URL:-} depends_on: - postgres: - condition: service_healthy redis: condition: service_healthy networks: @@ -141,35 +141,6 @@ services: retries: 3 start_period: 30s - # =========================================================================== - # PostgreSQL Database - # =========================================================================== - postgres: - image: postgres:18-alpine - container_name: sub2api-postgres - restart: unless-stopped - ulimits: - nofile: - soft: 100000 - hard: 100000 - volumes: - - postgres_data:/var/lib/postgresql/data - environment: - - POSTGRES_USER=${POSTGRES_USER:-sub2api} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required} - - POSTGRES_DB=${POSTGRES_DB:-sub2api} - - TZ=${TZ:-Asia/Shanghai} - networks: - - sub2api-network - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-sub2api} -d ${POSTGRES_DB:-sub2api}"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 10s - # 注意:不暴露端口到宿主机,应用通过内部网络连接 - # 如需调试,可临时添加:ports: ["127.0.0.1:5433:5432"] - # =========================================================================== # Redis Cache # =========================================================================== @@ -209,8 +180,6 @@ services: volumes: sub2api_data: driver: local - postgres_data: - driver: local redis_data: driver: local diff --git a/frontend/public/wechat-qr.jpg b/frontend/public/wechat-qr.jpg new file mode 100644 index 0000000000000000000000000000000000000000..659068d835e86ccd58f5a429f270cce802590ec9 GIT binary patch literal 151392 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 literal 0 HcmV?d00001 diff --git a/frontend/src/components/common/WechatServiceButton.vue b/frontend/src/components/common/WechatServiceButton.vue new file mode 100644 index 00000000..9ee8d3d5 --- /dev/null +++ b/frontend/src/components/common/WechatServiceButton.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/frontend/src/components/layout/AppHeader.vue b/frontend/src/components/layout/AppHeader.vue index a6b4030f..53a0c01e 100644 --- a/frontend/src/components/layout/AppHeader.vue +++ b/frontend/src/components/layout/AppHeader.vue @@ -121,23 +121,6 @@ {{ t('nav.apiKeys') }} - - - - - - {{ t('nav.github') }} - diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue index 6a3753f1..babcf046 100644 --- a/frontend/src/views/HomeView.vue +++ b/frontend/src/views/HomeView.vue @@ -122,8 +122,11 @@ > {{ siteName }} -

- {{ siteSubtitle }} +

+ {{ t('home.heroSubtitle') }} +

+

+ {{ t('home.heroDescription') }}

@@ -177,7 +180,7 @@ -
+
@@ -204,6 +207,63 @@
+ +
+

+ {{ t('home.painPoints.title') }} +

+
+ +
+
+ + + +
+

{{ t('home.painPoints.items.expensive.title') }}

+

{{ t('home.painPoints.items.expensive.desc') }}

+
+ +
+
+ + + +
+

{{ t('home.painPoints.items.complex.title') }}

+

{{ t('home.painPoints.items.complex.desc') }}

+
+ +
+
+ + + +
+

{{ t('home.painPoints.items.unstable.title') }}

+

{{ t('home.painPoints.items.unstable.desc') }}

+
+ +
+
+ + + +
+

{{ t('home.painPoints.items.noControl.title') }}

+

{{ t('home.painPoints.items.noControl.desc') }}

+
+
+
+ + +
+

+ {{ t('home.solutions.title') }} +

+

{{ t('home.solutions.subtitle') }}

+
+
@@ -369,6 +429,77 @@ >
+ + +
+

+ {{ t('home.comparison.title') }} +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ t('home.comparison.headers.feature') }}{{ t('home.comparison.headers.official') }}{{ t('home.comparison.headers.us') }}
{{ t('home.comparison.items.pricing.feature') }}{{ t('home.comparison.items.pricing.official') }}{{ t('home.comparison.items.pricing.us') }}
{{ t('home.comparison.items.models.feature') }}{{ t('home.comparison.items.models.official') }}{{ t('home.comparison.items.models.us') }}
{{ t('home.comparison.items.management.feature') }}{{ t('home.comparison.items.management.official') }}{{ t('home.comparison.items.management.us') }}
{{ t('home.comparison.items.stability.feature') }}{{ t('home.comparison.items.stability.official') }}{{ t('home.comparison.items.stability.us') }}
{{ t('home.comparison.items.control.feature') }}{{ t('home.comparison.items.control.official') }}{{ t('home.comparison.items.control.us') }}
+
+
+ + +
+

+ {{ t('home.cta.title') }} +

+

+ {{ t('home.cta.description') }} +

+ + {{ t('home.cta.button') }} + + + + {{ t('home.goToDashboard') }} + + +
@@ -380,27 +511,20 @@

© {{ currentYear }} {{ siteName }}. {{ t('home.footer.allRightsReserved') }}

- + + {{ t('home.docs') }} + + + + @@ -410,6 +534,7 @@ import { useI18n } from 'vue-i18n' import { useAuthStore, useAppStore } from '@/stores' import LocaleSwitcher from '@/components/common/LocaleSwitcher.vue' import Icon from '@/components/icons/Icon.vue' +import WechatServiceButton from '@/components/common/WechatServiceButton.vue' const { t } = useI18n() @@ -419,7 +544,6 @@ const appStore = useAppStore() // Site settings - directly from appStore (already initialized from injected config) const siteName = computed(() => appStore.cachedPublicSettings?.site_name || appStore.siteName || 'Sub2API') const siteLogo = computed(() => appStore.cachedPublicSettings?.site_logo || appStore.siteLogo || '') -const siteSubtitle = computed(() => appStore.cachedPublicSettings?.site_subtitle || 'AI API Gateway Platform') const docUrl = computed(() => appStore.cachedPublicSettings?.doc_url || appStore.docUrl || '') const homeContent = computed(() => appStore.cachedPublicSettings?.home_content || '') @@ -432,9 +556,6 @@ const isHomeContentUrl = computed(() => { // Theme const isDark = ref(document.documentElement.classList.contains('dark')) -// GitHub URL -const githubUrl = 'https://github.com/Wei-Shaw/sub2api' - // Auth state const isAuthenticated = computed(() => authStore.isAuthenticated) const isAdmin = computed(() => authStore.isAdmin) diff --git a/stress_test_gemini_session.sh b/stress_test_gemini_session.sh new file mode 100644 index 00000000..1f2aca57 --- /dev/null +++ b/stress_test_gemini_session.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +# Gemini 粘性会话压力测试脚本 +# 测试目标:验证不同会话分配不同账号,同一会话保持同一账号 + +BASE_URL="http://host.clicodeplus.com:8080" +API_KEY="sk-32ad0a3197e528c840ea84f0dc6b2056dd3fead03526b5c605a60709bd408f7e" +MODEL="gemini-2.5-flash" + +# 创建临时目录存放结果 +RESULT_DIR="/tmp/gemini_stress_test_$(date +%s)" +mkdir -p "$RESULT_DIR" + +echo "==========================================" +echo "Gemini 粘性会话压力测试" +echo "结果目录: $RESULT_DIR" +echo "==========================================" + +# 函数:发送请求并记录 +send_request() { + local session_id=$1 + local round=$2 + local system_prompt=$3 + local contents=$4 + local output_file="$RESULT_DIR/session_${session_id}_round_${round}.json" + + local request_body=$(cat < "$output_file" 2>&1 + + echo "[Session $session_id Round $round] 完成" +} + +# 会话1:数学计算器(累加序列) +run_session_1() { + local sys_prompt="你是一个数学计算器,只返回计算结果数字,不要任何解释" + + # Round 1: 1+1=? + send_request 1 1 "$sys_prompt" '[{"role":"user","parts":[{"text":"1+1=?"}]}]' + + # Round 2: 继续 2+2=?(累加历史) + send_request 1 2 "$sys_prompt" '[{"role":"user","parts":[{"text":"1+1=?"}]},{"role":"model","parts":[{"text":"2"}]},{"role":"user","parts":[{"text":"2+2=?"}]}]' + + # Round 3: 继续 3+3=? + send_request 1 3 "$sys_prompt" '[{"role":"user","parts":[{"text":"1+1=?"}]},{"role":"model","parts":[{"text":"2"}]},{"role":"user","parts":[{"text":"2+2=?"}]},{"role":"model","parts":[{"text":"4"}]},{"role":"user","parts":[{"text":"3+3=?"}]}]' + + # Round 4: 批量计算 10+10, 20+20, 30+30 + send_request 1 4 "$sys_prompt" '[{"role":"user","parts":[{"text":"1+1=?"}]},{"role":"model","parts":[{"text":"2"}]},{"role":"user","parts":[{"text":"2+2=?"}]},{"role":"model","parts":[{"text":"4"}]},{"role":"user","parts":[{"text":"3+3=?"}]},{"role":"model","parts":[{"text":"6"}]},{"role":"user","parts":[{"text":"计算: 10+10=? 20+20=? 30+30=?"}]}]' +} + +# 会话2:英文翻译器(不同系统提示词 = 不同会话) +run_session_2() { + local sys_prompt="你是一个英文翻译器,将中文翻译成英文,只返回翻译结果" + + send_request 2 1 "$sys_prompt" '[{"role":"user","parts":[{"text":"你好"}]}]' + send_request 2 2 "$sys_prompt" '[{"role":"user","parts":[{"text":"你好"}]},{"role":"model","parts":[{"text":"Hello"}]},{"role":"user","parts":[{"text":"世界"}]}]' + send_request 2 3 "$sys_prompt" '[{"role":"user","parts":[{"text":"你好"}]},{"role":"model","parts":[{"text":"Hello"}]},{"role":"user","parts":[{"text":"世界"}]},{"role":"model","parts":[{"text":"World"}]},{"role":"user","parts":[{"text":"早上好"}]}]' +} + +# 会话3:日文翻译器 +run_session_3() { + local sys_prompt="你是一个日文翻译器,将中文翻译成日文,只返回翻译结果" + + send_request 3 1 "$sys_prompt" '[{"role":"user","parts":[{"text":"你好"}]}]' + send_request 3 2 "$sys_prompt" '[{"role":"user","parts":[{"text":"你好"}]},{"role":"model","parts":[{"text":"こんにちは"}]},{"role":"user","parts":[{"text":"谢谢"}]}]' + send_request 3 3 "$sys_prompt" '[{"role":"user","parts":[{"text":"你好"}]},{"role":"model","parts":[{"text":"こんにちは"}]},{"role":"user","parts":[{"text":"谢谢"}]},{"role":"model","parts":[{"text":"ありがとう"}]},{"role":"user","parts":[{"text":"再见"}]}]' +} + +# 会话4:乘法计算器(另一个数学会话,但系统提示词不同) +run_session_4() { + local sys_prompt="你是一个乘法专用计算器,只计算乘法,返回数字结果" + + send_request 4 1 "$sys_prompt" '[{"role":"user","parts":[{"text":"2*3=?"}]}]' + send_request 4 2 "$sys_prompt" '[{"role":"user","parts":[{"text":"2*3=?"}]},{"role":"model","parts":[{"text":"6"}]},{"role":"user","parts":[{"text":"4*5=?"}]}]' + send_request 4 3 "$sys_prompt" '[{"role":"user","parts":[{"text":"2*3=?"}]},{"role":"model","parts":[{"text":"6"}]},{"role":"user","parts":[{"text":"4*5=?"}]},{"role":"model","parts":[{"text":"20"}]},{"role":"user","parts":[{"text":"计算: 10*10=? 20*20=?"}]}]' +} + +# 会话5:诗人(完全不同的角色) +run_session_5() { + local sys_prompt="你是一位诗人,用简短的诗句回应每个话题,每次只写一句诗" + + send_request 5 1 "$sys_prompt" '[{"role":"user","parts":[{"text":"春天"}]}]' + send_request 5 2 "$sys_prompt" '[{"role":"user","parts":[{"text":"春天"}]},{"role":"model","parts":[{"text":"春风拂面花满枝"}]},{"role":"user","parts":[{"text":"夏天"}]}]' + send_request 5 3 "$sys_prompt" '[{"role":"user","parts":[{"text":"春天"}]},{"role":"model","parts":[{"text":"春风拂面花满枝"}]},{"role":"user","parts":[{"text":"夏天"}]},{"role":"model","parts":[{"text":"蝉鸣蛙声伴荷香"}]},{"role":"user","parts":[{"text":"秋天"}]}]' +} + +echo "" +echo "开始并发测试 5 个独立会话..." +echo "" + +# 并发运行所有会话 +run_session_1 & +run_session_2 & +run_session_3 & +run_session_4 & +run_session_5 & + +# 等待所有后台任务完成 +wait + +echo "" +echo "==========================================" +echo "所有请求完成,结果保存在: $RESULT_DIR" +echo "==========================================" + +# 显示结果摘要 +echo "" +echo "响应摘要:" +for f in "$RESULT_DIR"/*.json; do + filename=$(basename "$f") + response=$(cat "$f" | head -c 200) + echo "[$filename]: ${response}..." +done + +echo "" +echo "请检查服务器日志确认账号分配情况"