1. 09 Feb, 2026 6 commits
    • QTom's avatar
      04cedce9
    • QTom's avatar
      feat(admin): 新增 CRS 同步预览和账号选择功能 · 5e0d7894
      QTom authored
      - 后端新增 PreviewFromCRS 接口,允许用户先预览 CRS 中的账号
      - 后端支持在同步时选择特定账号,不选中的账号将被跳过
      - 前端重构 SyncFromCrsModal 为三步向导:输入凭据 → 预览账号 → 执行同步
      - 改进表单无障碍性:添加 for/id 关联和 required 属性
      - 修复 Back 按钮返回时的状态清理
      - 新增 buildSelectedSet 和 shouldCreateAccount 的单元测试
      - 完整的向后兼容性:旧客户端不发送 selected_account_ids 时行为不变
      5e0d7894
    • yangjianbo's avatar
      fix: 修复代码审核发现的安全和质量问题 · d7011163
      yangjianbo authored
      
      
      安全修复(P0):
      - 移除硬编码的 OAuth client_secret(Antigravity、Gemini CLI),
        改为通过环境变量注入(ANTIGRAVITY_OAUTH_CLIENT_SECRET、
        GEMINI_CLI_OAUTH_CLIENT_SECRET)
      - 新增 logredact.RedactText() 对非结构化文本做敏感信息脱敏,
        覆盖 GOCSPX-*/AIza* 令牌和常见 key=value 模式
      - 日志中不再打印 org_uuid、account_uuid、email_address 等敏感值
      
      安全修复(P1):
      - URL 验证增强:新增 ValidateHTTPURL 统一入口,支持 allowlist 和
        私网地址阻断(localhost/内网 IP)
      - 代理回退安全:代理初始化失败时默认阻止直连回退,防止 IP 泄露,
        可通过 security.proxy_fallback.allow_direct_on_error 显式开启
      - Gemini OAuth 配置校验:client_id 与 client_secret 必须同时
        设置或同时留空
      
      其他改进:
      - 新增 tools/secret_scan.py 密钥扫描工具和 Makefile secret-scan 目标
      - 更新所有 docker-compose 和部署配置,传递 OAuth secret 环境变量
      - google_one OAuth 类型使用固定 redirectURI,与 code_assist 对齐
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      d7011163
    • yangjianbo's avatar
      test: 删除CI工作流,大幅提升后端单元测试覆盖率至50%+ · fc8a39e0
      yangjianbo authored
      
      
      删除因GitHub计费锁定而失败的CI工作流。
      为6个核心Go源文件补充单元测试,全部达到50%以上覆盖率:
      - response/response.go: 97.6%
      - antigravity/oauth.go: 90.1%
      - antigravity/client.go: 88.6% (新增27个HTTP客户端测试)
      - geminicli/oauth.go: 91.8%
      - service/oauth_service.go: 61.2%
      - service/gemini_oauth_service.go: 51.9%
      
      新增/增强8个测试文件,共计5600+行测试代码。
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      fc8a39e0
    • erio's avatar
      fix: resolve CI failures from scope removal refactor · 9a479d1b
      erio authored
      - Fix gofmt alignment in ops_realtime_models.go
      - Remove SetAntigravityQuotaScopeLimit mock from api_contract_test.go
      - Add UpdateSortOrders mock to mockGroupRepoForGateway
      9a479d1b
    • erio's avatar
      refactor: replace scope-level rate limiting with model-level rate limiting · fc095bf0
      erio authored
      Merge functional changes from develop branch:
      - Remove AntigravityQuotaScope system (claude/gemini_text/gemini_image)
      - Replace with per-model rate limiting using resolveAntigravityModelKey
      - Remove model load statistics (IncrModelCallCount/GetModelLoadBatch)
      - Simplify account selection to unified priority→load→LRU algorithm
      - Remove SetAntigravityQuotaScopeLimit from AccountRepository
      - Clean up scope-related UI indicators and API fields
      fc095bf0
  2. 08 Feb, 2026 22 commits
  3. 07 Feb, 2026 12 commits
    • erio's avatar
      fix(gateway): restore upstream account forwarding with dedicated methods · 77b66653
      erio authored
      v0.1.74 merged upstream accounts into the OAuth path, causing requests
      to hit the wrong protocol and endpoint. Add three upstream-specific
      methods (testUpstreamConnection, ForwardUpstream, ForwardUpstreamGemini)
      that use base_url + apiKey auth and passthrough the original body, while
      reusing the existing response handling and error/retry logic.
      77b66653
    • yangjianbo's avatar
      perf(日志): 降噪优化,将常规成功日志降级为 Debug 级别 · 53e1c8b2
      yangjianbo authored
      
      
      - GIN Logger 中间件跳过 /health 和 /setup/status 的请求日志
      - UsageCleanup 空闲轮询(no_task)日志降级为 slog.Debug
      - Scheduler 常规 rebuild ok 日志降级为 slog.Debug
      - DashboardAggregation 常规聚合完成日志降级为 slog.Debug
      - TokenRefresh 无刷新活动时周期日志降级为 slog.Debug
      
      生产环境(Info 级别)下自动静默,debug 模式下仍可见。
      错误、警告类日志保持原有级别不变。
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      53e1c8b2
    • yangjianbo's avatar
      test: 为代码审核修复添加详细单元测试(7个测试文件,50+测试用例) · 00caf0bc
      yangjianbo authored
      
      
      新增测试文件:
      - cors_test.go: CORS 条件化头部测试(12个测试,覆盖白名单/黑名单/通配符/凭证/多源/Vary)
      - gateway_helper_backoff_test.go: nextBackoff 退避测试(6个测试+基准,验证指数增长/边界/抖动/收敛)
      - billing_cache_jitter_test.go: jitteredTTL 抖动测试(5个测试+基准,验证范围/上界/方差/均值)
      - subscription_calculate_progress_test.go: calculateProgress 纯函数测试(9个测试,覆盖日/周/月限额/超限截断/过期)
      - openai_gateway_handler_test.go: SSE JSON 转义测试(7个子用例,验证双引号/反斜杠/换行符安全)
      
      更新测试文件:
      - response_transformer_test.go: 增强 generateRandomID 测试(7个测试,含并发/字符集/降级计数器)
      - security_headers_test.go: 适配 GenerateNonce 新签名
      - api_key_auth_test.go: 适配 NewSubscriptionService 新参数
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      00caf0bc
    • yangjianbo's avatar
      fix: 修复代码审核发现的10个问题(P0安全+P1数据一致性+P2性能优化) · 9634494b
      yangjianbo authored
      
      
      P0: OpenAI SSE 错误消息 JSON 注入 — 使用 json.Marshal 替代 fmt.Sprintf
      P1: subscription 续期包裹 Ent 事务确保原子性
      P1: CSP nonce 生成处理 crypto/rand 错误,失败降级为 unsafe-inline
      P1: singleflight 透传数据库真实错误,不再吞没为 not found
      P1: GetUserSubscriptionsWithProgress 提取 calculateProgress 消除 N+1
      P2: billing_cache/gateway_helper 迁移到 math/rand/v2 消除全局锁争用
      P2: generateRandomID 降级分支增加原子计数器防碰撞
      P2: CORS 非白名单 origin 不再设置 Allow-Headers/Methods/Max-Age
      P2: Turnstile 验证移除 VerifyCode 空值跳过条件防绕过
      P2: Redis Cluster Lua 脚本空 KEYS 添加兼容性警告注释
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      9634494b
    • yangjianbo's avatar
      fix: 修复批量更新凭证明细与缓存TTL抖动 · 4a20a2a8
      yangjianbo authored
      - BatchUpdateCredentials 返回 success/failed/results 及 success_ids/failed_ids
      
      - billing jitteredTTL 改为只减不增,确保TTL不超上界
      
      - crypto/rand 失败时随机ID降级避免 panic
      
      - OpenAI SelectAccount 失败日志去重并补充字段
      
      - 修复两处类型断言以通过 errcheck
      4a20a2a8
    • yangjianbo's avatar
      fix: 修复函数签名变更后的调用参数不匹配 · 836ba14b
      yangjianbo authored
      
      
      - handleUpstreamError 补齐新增的三个参数 (0, "", false)
      - handleStreamingResponse 移除已删除的 nil 参数
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      836ba14b
    • yangjianbo's avatar
      fix(audit): 第二批审计修复 — P0 生产 Bug、安全加固、性能优化、缓存一致性、代码质量 · 2588fa6a
      yangjianbo authored
      
      
      基于 backend-code-audit 审计报告,修复剩余 P0/P1/P2 共 34 项问题:
      
      P0 生产 Bug:
      - 修复 time.Since(time.Now()) 计时逻辑错误 (P0-03)
      - generateRandomID 改用 crypto/rand 替代固定索引 (P0-04)
      - IncrementQuotaUsed 重写为 Ent 原子操作消除 TOCTOU 竞态 (P0-05)
      
      安全加固:
      - gateway/openai handler 错误响应替换为泛化消息,防止内部信息泄露 (P1-14)
      - usage_log_repo dateFormat 参数改用白名单映射,防止 SQL 注入 (P1-16)
      - 默认配置安全加固:sslmode=prefer、response_headers=true、mode=release (P1-18/19, P2-15)
      
      性能优化:
      - gateway handler 循环内 defer 替换为显式 releaseWait 闭包 (P1-02)
      - group_repo/promo_code_repo Count 前 Clone 查询避免状态污染 (P1-03)
      - usage_log_repo 四个查询添加 LIMIT 10000 防止 OOM (P1-07)
      - GetBatchUsageStats 添加时间范围参数,默认最近 30 天 (P1-10)
      - ip.go CIDR 预编译为包级变量 (P1-11)
      - BatchUpdateCredentials 重构为先验证后更新 (P1-13)
      
      缓存一致性:
      - billing_cache 添加 jitteredTTL 防止缓存雪崩 (P2-10)
      - DeductUserBalance/UpdateSubscriptionUsage 错误传播修复 (P2-12)
      - UserService.UpdateBalance 成功后异步失效 billingCache (P2-13)
      
      代码质量:
      - search 截断改为按 rune 处理,支持多字节字符 (P2-01)
      - TLS Handshake 改为 HandshakeContext 支持 context 取消 (P2-07)
      - CORS 预检添加 Access-Control-Max-Age: 86400 (P2-16)
      
      测试覆盖:
      - 新增 user_service_test.go(UpdateBalance 缓存失效 6 个用例)
      - 新增 batch_update_credentials_test.go(fail-fast + 类型验证 7 个用例)
      - 新增 response_transformer_test.go、ip_test.go、usage_log_repo_unit_test.go、search_truncate_test.go
      - 集成测试:IncrementQuotaUsed 并发测试、billing_cache 错误传播测试
      - config_test.go 补充 server.mode/sslmode 默认值断言
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      2588fa6a
    • erio's avatar
      feat: smart retry max 1 attempt + clear sticky session on failure · 3077fd27
      erio authored
      - Change antigravitySmartRetryMaxAttempts from 3 to 1 to prevent
        repeated rate limiting and long waits
      - Clear sticky session binding (DeleteSessionAccountID) after smart
        retry exhaustion, so subsequent requests don't hit the same
        rate-limited account
      - Add flow diagrams to Forward/ForwardGemini doc comments
      - Add comprehensive unit tests covering:
        - Sticky session cleared on retry failure (429, 503, network error)
        - Sticky session NOT cleared on retry success
        - Sticky session NOT cleared for non-sticky requests (empty hash)
        - Sticky session NOT cleared on long delay path (handled by handler)
        - Nil cache safety (no panic)
        - MaxAttempts constant verification
        - End-to-end retryLoop → switchError propagation with session clear
      3077fd27
    • shaw's avatar
      6aaa4aee
    • erio's avatar
      e3748da8
    • erio's avatar
      refactor: remove Anthropic digest chain from Messages handler · 86b503f8
      erio authored
      The digest chain fallback is only needed for Gemini endpoints, not
      for the Anthropic Messages API path. Remove the handler integration
      while keeping the reusable service/repository layer for future use.
      86b503f8
    • erio's avatar
      feat: add Anthropic sticky session digest chain matching via Trie · 50a783ff
      erio authored
      The previous fallback (step 3) in GenerateSessionHash hashed system +
      all messages together, producing a different hash each round as the
      conversation grew ([a] -> [a,b] -> [a,b,c]). This made fallback sticky
      sessions ineffective for multi-turn conversations.
      
      Implement per-message Trie digest chain matching (reusing Gemini's Trie
      infrastructure) so that the previous round's chain is always a prefix
      of the current round's chain, enabling reliable session affinity.
      50a783ff