1. 14 Apr, 2026 6 commits
    • erio's avatar
      feat(websearch): settings UI overhaul and quota improvements · d0674e0f
      erio authored
      - Remove Priority field, auto load-balance by quota remaining
      - Replace QuotaRefreshInterval (daily/weekly/monthly) with SubscribedAt
        (subscription date, monthly lazy refresh via Redis TTL)
      - Add collapsible provider cards, API key show/copy, usage progress bar
      - Add test endpoint (POST /web-search-emulation/test) bypassing quota
      - Wire WebSearchManagerBuilder on startup (was never called before)
      - Fix nextMonthlyReset day-of-month overflow (Jan 31 → Feb 28)
      - Fix non-deterministic sort in selectByQuotaWeight
      - Map ProxyID in builder for provider-level proxy tracking
      - Fix frontend timezone drift in subscribed_at date picker
      - Fix provider deletion index shift for expandedProviders state
      d0674e0f
    • erio's avatar
      feat(notify): add balance low & account quota notification system · b32d1a2c
      erio authored
      - User balance low notification: email alert when balance drops below
        configurable threshold (user email + verified extra emails)
      - Account quota notification: broadcast email to admin-configured
        recipients when daily/weekly/total quota usage exceeds alert threshold
      - Admin settings: global enable/disable, default threshold, quota
        notification email list (Email Settings tab)
      - User profile: enable/disable, custom threshold, add/remove extra
        notification emails with verification code flow
      - Account quota: per-dimension alert toggle and threshold in quota
        control card
      - Trigger logic: first-crossing only (old >= threshold && new < threshold
        for balance; old < threshold && new >= threshold for quota), naturally
        prevents duplicate notifications without Redis dedup
      b32d1a2c
    • erio's avatar
      fix(test): add web_search_emulation_enabled to API contract test · 7fad9f60
      erio authored
      The settings API response now includes the new field; update the
      expected snapshot in TestAPIContracts to match.
      7fad9f60
    • erio's avatar
      feat(gateway): add web search emulation for Anthropic API Key accounts · 1b53ffca
      erio authored
      Inject web search capability for Claude Console (API Key) accounts that
      don't natively support Anthropic's web_search tool. When a pure
      web_search request is detected, the gateway calls Brave Search or Tavily
      API directly and constructs an Anthropic-protocol-compliant SSE/JSON
      response without forwarding to upstream.
      
      Backend:
      - New `pkg/websearch/` SDK: Brave and Tavily provider implementations
        with io.LimitReader, proxy support, and Redis-based quota tracking
        (Lua atomic INCR + TTL, DECR rollback on failure)
      - Global config via `settings.web_search_emulation_config` (JSON) with
        in-process cache + singleflight, input validation, API key merge on
        save, and sanitized API responses
      - Channel-level toggle via `channels.features_config` JSONB column
        (DB migration 101)
      - Account-level toggle via `accounts.extra.web_search_emulation`
      - Request interception in `Forward()` with SSE streaming response
        construction using json.Marshal (no manual string concatenation)
      - Manager hot-reload: `RebuildWebSearchManager()` called on config save
        and startup via `SetWebSearchRedisClient()`
      - 70 unit tests covering providers, manager, config validation,
        sanitization, tool detection, query extraction, and response building
      
      Frontend:
      - Settings → Gateway tab: Web Search Emulation config card with global
        toggle, provider list (add/remove, API key, priority, quota, proxy)
      - Channels → Anthropic tab: web search emulation toggle with global
        state linkage (disabled when global off)
      - Account Create/Edit modals: web search emulation toggle for API Key
        type with Toggle component
      - Full i18n coverage (zh + en)
      1b53ffca
    • erio's avatar
      fix(payment): critical audit fixes for security, idempotency and correctness · c738cfec
      erio authored
      Backend fixes:
      - #1: doSub subscription idempotency via audit log check
      - #2: markFailed only when status=RECHARGING (prevents overwriting COMPLETED)
      - #3: ExpireTimedOutOrders checks upstream payment before expiring
      - #4: Public verify endpoint for payment result page (no auth required)
      - #5: EasyPay QueryOrder returns amount, confirmPayment handles zero amount
      - #6: WxPay notifyUrl priority: request-first, config-fallback
      - #7: EasyPay remove double URL decode in VerifyNotification
      - #8: checkPaid/cancelUpstreamPayment use order's provider instance
      - #9: Amount NaN/Inf/negative validation in order creation and refund
      - #10: Refund amount comparison uses tolerance instead of float64 ==
      - #11: Skip balance deduction on retry when previous rollback failed
      - #12: checkPaid logs fulfillment errors instead of silently ignoring
      - #13: WxPay certSerial added to required config fields
      
      Frontend fixes:
      - Payment result page no longer requires authentication
      - Public verify API fallback for expired sessions
      c738cfec
    • erio's avatar
      refactor: remove PaymentChannel, reuse upstream Channel with features field · 794e8172
      erio authored
      - Delete payment_channels table and PaymentChannel Ent schema
      - Add `features` column to upstream channels table (migration 095)
      - Add Features field to Channel struct, input types, handler request/response
      - Payment user/admin handlers now use ChannelService directly
      - Remove Channel CRUD from PaymentConfigService and admin payment routes
      - Remove "渠道管理" tab from admin orders page (use /admin/channels)
      794e8172
  2. 11 Apr, 2026 1 commit
  3. 10 Apr, 2026 1 commit
  4. 09 Apr, 2026 2 commits
  5. 08 Apr, 2026 1 commit
  6. 05 Apr, 2026 4 commits
  7. 04 Apr, 2026 2 commits
  8. 31 Mar, 2026 1 commit
  9. 27 Mar, 2026 1 commit
    • shaw's avatar
      feat(tls-fingerprint): 新增 TLS 指纹 Profile 数据库管理及代码质量优化 · 1854050d
      shaw authored
      新增功能:
      - 新增 TLS 指纹 Profile CRUD 管理(Ent schema + 迁移 + Admin API + 前端管理界面)
      - 支持账号绑定数据库中的自定义 TLS Profile,或随机选择(profile_id=-1)
      - HTTPUpstream.DoWithTLS 接口从 bool 改为 *tlsfingerprint.Profile,支持按账号指定 Profile
      - AccountUsageService 注入 TLSFingerprintProfileService,统一 usage 场景与网关的 Profile 解析逻辑
      
      代码优化:
      - 删除已被 TLSFingerprintProfileService 完全取代的 registry.go 死代码(418 行)
      - 提取 3 个 dialer 的重复 TLS 握手逻辑为 performTLSHandshake() 共用函数
      - 修复 GetTLSFingerprintProfileID 缺少 json.Number 处理的 bug
      - gateway_service.Forward 中 ResolveTLSProfile 从重试循环内重复调用改为预解析局部变量
      - 删除冗余的 buildClientHelloSpec() 单行 wrapper 和 int64(e.ID) 无效转换
      - tls_fingerprint_profile_cache.go 日志从 log.Printf 改为 slog 结构化日志
      - dialer_capture_test.go 添加 //go:build integration 标签,防止 CI 失败
      - 去重 TestProfileExpectation 类型至共享 test_types_test.go
      - 修复 9 个测试文件缺少 tlsfingerprint import 的编译错误
      - 修复 error_policy_integration_test.go 中 handleError 回调签名被错误替换的问题
      1854050d
  10. 26 Mar, 2026 1 commit
    • shaw's avatar
      feat: 网关请求头 wire casing 保持、转发行为开关、调试日志增强及 accept-encoding 恢复 · b20e1422
      shaw authored
      - 新增 header_util.go,通过 setHeaderRaw/getHeaderRaw/addHeaderRaw 绕过
        Go 的 canonical-case 规范化,保持真实 Claude CLI 抓包的请求头大小写
        (如 "x-app" 而非 "X-App","X-Stainless-OS" 而非 "X-Stainless-Os")
      - 新增管理后台开关:指纹统一化(默认开启)和 metadata 透传(默认关闭),
        使用 atomic.Value + singleflight 缓存模式,60s TTL
      - 调试日志从控制台 body 打印升级为文件级完整快照
        (按真实 wire 顺序输出 headers + 格式化 JSON body + 上下文元数据)
      - 恢复 accept-encoding 到白名单,在 http_upstream.go 新增 decompressResponseBody
        处理 gzip/brotli/deflate 解压(Go 显式设置 Accept-Encoding 时不会自动解压)
      - OAuth 服务 axios UA 从 1.8.4 更新至 1.13.6
      - 测试断言改用 getHeaderRaw 适配 raw header 存储方式
      b20e1422
  11. 25 Mar, 2026 1 commit
    • QTom's avatar
      feat(antigravity): 自动设置隐私并支持后台手动重试 · c2965c0f
      QTom authored
      新增 Antigravity OAuth 隐私设置能力,在账号创建、刷新、导入和后台
      Token 刷新路径自动调用 setUserSettings + fetchUserInfo 关闭遥测;
      持久化后同步内存 Extra,错误处理改为日志记录。
      
      Made-with: Cursor
      c2965c0f
  12. 24 Mar, 2026 1 commit
  13. 23 Mar, 2026 2 commits
  14. 20 Mar, 2026 1 commit
  15. 19 Mar, 2026 1 commit
    • QTom's avatar
      feat(admin): 用户管理新增分组列、分组筛选与专属分组一键替换 · ba7d2aec
      QTom authored
      - 新增分组列:展示用户的专属/公开分组,支持 hover 查看详情
      - 新增分组筛选:下拉选择或模糊搜索分组名过滤用户
      - 专属分组替换:点击专属分组弹出操作菜单,选择目标分组后
        自动授予新分组权限、迁移绑定的 Key、移除旧分组权限
      - 后端新增 POST /admin/users/:id/replace-group 端点,事务内
        完成分组替换并失效认证缓存
      ba7d2aec
  16. 18 Mar, 2026 4 commits
  17. 16 Mar, 2026 1 commit
    • erio's avatar
      feat(dashboard): add per-user drill-down for group, model, and endpoint distributions · 4b41e898
      erio authored
      Click on a group name, model name, or endpoint name in the distribution
      tables to expand and show per-user usage breakdown (requests, tokens,
      actual cost, standard cost).
      
      Backend: new GET /admin/dashboard/user-breakdown API with group_id,
      model, endpoint, endpoint_type filters.
      Frontend: clickable rows with expand/collapse sub-table in all three
      distribution charts.
      4b41e898
  18. 15 Mar, 2026 3 commits
  19. 13 Mar, 2026 1 commit
    • Rose Ding's avatar
      feat: 数据库定时备份与恢复(S3 兼容存储,支持 Cloudflare R2) · 53ad1645
      Rose Ding authored
      
      
      新增管理员专属的数据库备份与恢复功能:
      - 全量 PostgreSQL 备份(pg_dump),gzip 压缩后上传到 S3 兼容存储
      - 支持手动备份和 cron 定时备份
      - 支持从备份恢复(psql --single-transaction)
      - 备份文件自动过期清理(默认 14 天)
      - 前端完整管理页面(S3 配置、定时配置、备份列表、恢复/下载/删除)
      - 内置 Cloudflare R2 配置教程弹窗
      - Dockerfile 从 postgres 镜像多阶段复制 pg_dump/psql,确保版本一致
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      53ad1645
  20. 12 Mar, 2026 3 commits
    • Peter's avatar
      80d8d6c3
    • erio's avatar
      feat(groups): add rate multipliers management modal · d6488112
      erio authored
      Add a dedicated modal in group management for viewing, adding, editing,
      and deleting per-user rate multipliers within a group.
      
      Backend:
      - GET /admin/groups/:id/rate-multipliers - list entries with user details
      - PUT /admin/groups/:id/rate-multipliers - batch sync (full replace)
      - DELETE /admin/groups/:id/rate-multipliers - clear all entries
      - Repository: GetByGroupID, SyncGroupRateMultipliers methods on
        user_group_rate_multipliers table (same table as user-side rates)
      
      Frontend:
      - New GroupRateMultipliersModal component with:
        - User search and add with email autocomplete
        - Editable rate column with local edit mode (cancel/save)
        - Batch adjust: multiply all rates by a factor
        - Clear all (local operation, requires save to persist)
        - Pagination (10/20/50 per page)
        - Platform icon with brand colors in group info bar
        - Unsaved changes indicator with revert option
      - Unit tests for all three backend endpoints
      d6488112
    • QTom's avatar
      a63de121
  21. 11 Mar, 2026 2 commits
    • John Doe's avatar
      feat: add Backend Mode toggle to disable user self-service · 6826149a
      John Doe authored
      
      
      Add a system-wide "Backend Mode" that disables user self-registration
      and self-service while keeping admin panel and API gateway fully
      functional. When enabled, only admin can log in; all user-facing
      routes return 403.
      
      Backend:
      - New setting key `backend_mode_enabled` with atomic cached reads (60s TTL)
      - BackendModeUserGuard middleware blocks non-admin authenticated routes
      - BackendModeAuthGuard middleware blocks registration/password-reset auth routes
      - Login/Login2FA/RefreshToken handlers reject non-admin when enabled
      - TokenPairWithUser struct for role-aware token refresh
      - 20 unit tests (middleware + service layer)
      
      Frontend:
      - Router guards redirect unauthenticated users to /login
      - Admin toggle in Settings page
      - Login page hides register link and footer in backend mode
      - 9 unit tests for router guard logic
      - i18n support (en/zh)
      
      27 files changed, 833 insertions(+), 17 deletions(-)
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      6826149a
    • 7976723's avatar
      fix: 修复 Chat Completions 编译错误和运行时 panic · a17ac501
      7976723 authored
      1. 修复 WriteFilteredHeaders API 不兼容(2处):
         将 s.cfg.Security.ResponseHeaders 改为 s.responseHeaderFilter,
         因为 main 分支已将函数签名改为接受 *responseheaders.CompiledHeaderFilter
      
      2. 修复 writer 生命周期导致的 nil pointer panic:
         ChatCompletions handler 替换了 c.Writer 但未恢复,导致
         OpsErrorLogger 中间件的 defer 释放 opsCaptureWriter 后,
         Logger 中间件调用 c.Writer.Status() 触发空指针解引用。
         通过保存并恢复 originalWriter 修复。
      
      3. 为 chatCompletionsResponseWriter 添加防御性 Status() 和
         Written() 方法,包含 nil 安全检查
      
      4. 恢复 gateway.go 中被误删的 net/http import
      a17ac501