1. 05 Feb, 2026 3 commits
    • shaw's avatar
      feat: 支持用户专属分组倍率配置 · 2b192f7d
      shaw authored
      2b192f7d
    • shaw's avatar
      feat(auth): 实现 Refresh Token 机制 · 49a3c437
      shaw authored
      - 新增 Access Token + Refresh Token 双令牌认证
      - 支持 Token 自动刷新和轮转
      - 添加登出和撤销所有会话接口
      - 前端实现无感刷新和主动刷新定时器
      49a3c437
    • JIA-ss's avatar
      feat(gateway): filter /v1/usage stats by API Key instead of UserID · fa3ea5ee
      JIA-ss authored
      
      
      Previously the /v1/usage endpoint aggregated usage stats (today/total
      tokens, cost, RPM/TPM) across all API Keys belonging to the user.
      This made it impossible to distinguish usage from different API Keys
      (e.g. balance vs subscription keys).
      
      Now the usage stats are filtered by the current request's API Key ID,
      so each key only sees its own usage data. The balance/remaining fields
      are unaffected and still reflect the user-level wallet balance.
      
      Changes:
      - Add GetAPIKeyDashboardStats to repository interface and implementation
      - Add getPerformanceStatsByAPIKey helper (also fixes TPM to include
        cache_creation_tokens and cache_read_tokens)
      - Add GetAPIKeyDashboardStats to UsageService
      - Update Usage handler to call GetAPIKeyDashboardStats(apiKey.ID)
      Co-Authored-By: default avatarClaude Opus 4.5 <noreply@anthropic.com>
      fa3ea5ee
  2. 03 Feb, 2026 4 commits
    • bayma888's avatar
      feat(api-key): add independent quota and expiration support · 6146be14
      bayma888 authored
      This feature allows API Keys to have their own quota limits and expiration
      times, independent of the user's balance.
      
      Backend:
      - Add quota, quota_used, expires_at fields to api_key schema
      - Implement IsExpired() and IsQuotaExhausted() checks in middleware
      - Add ResetQuota and ClearExpiration API endpoints
      - Integrate quota billing in gateway handlers (OpenAI, Anthropic, Gemini)
      - Include quota/expiration fields in auth cache for performance
      - Expiration check returns 403, quota exhausted returns 429
      
      Frontend:
      - Add quota and expiration inputs to key create/edit dialog
      - Add quick-select buttons for expiration (+7, +30, +90 days)
      - Add reset quota confirmation dialog
      - Add expires_at column to keys list
      - Add i18n translations for new features (en/zh)
      
      Migration:
      - Add 045_add_api_key_quota.sql for new columns
      6146be14
    • JIA-ss's avatar
      fix(proxy): 增加代理探测的多 URL 回退机制 · df7a3e65
      JIA-ss authored
      
      
      某些 AI API 专用代理只允许访问特定域名(如 anthropic.com、openai.com),
      会拦截对 ip-api.com 的请求。本次修改增加了多 URL 回退机制:
      
      1. 优先使用 ip-api.com(可获取详细地理信息:城市、地区、国家)
      2. 若失败则回退到 httpbin.org/ip(仅获取 IP 地址,速度快)
      
      主要变更:
      - 新增 probeURLs 列表支持多个探测 URL
      - 重构 ProbeProxy() 实现回退逻辑
      - 新增 parseHTTPBin() 解析 httpbin.org 响应
      - 优化错误信息,JSON 解析失败时显示响应体前 200 字符
      Co-Authored-By: default avatarClaude <noreply@anthropic.com>
      df7a3e65
    • ducky's avatar
      feat(usage): add reasoning effort column · 53ee6383
      ducky authored
      53ee6383
    • liuxiongfeng's avatar
      fix: jsonb_set 嵌套路径无法创建多层 key 的问题 · f5884d16
      liuxiongfeng authored
      PostgreSQL jsonb_set 在 create_if_missing=true 时无法一次性创建多层嵌套路径。
      例如设置 {antigravity_quota_scopes,gemini_image} 时,如果 antigravity_quota_scopes 不存在,
      jsonb_set 不会自动创建外层 key,导致更新静默失败(affected=1 但数据未变)。
      
      修复方案:嵌套两次 jsonb_set,先确保外层 key 存在,再设置内层值。
      同时在设置限流时更新 last_used_at,使刚触发 429 的账号调度优先级降低。
      
      Cherry-picked from slovx2/sub2api: 4b57e80e
      f5884d16
  3. 02 Feb, 2026 6 commits
    • bayma888's avatar
      feat(admin): add user balance/concurrency history modal · 606e29d3
      bayma888 authored
      - Add new API endpoint GET /admin/users/:id/balance-history with pagination and type filter
      - Add SumPositiveBalanceByUser for calculating total recharged amount
      - Create UserBalanceHistoryModal component with:
        - User info header (email, username, created_at, current balance, notes, total recharged)
        - Type filter dropdown (all/balance/admin_balance/concurrency/admin_concurrency/subscription)
        - Quick deposit/withdraw buttons
        - Paginated history list with icons and colored values
      - Add instant tooltip on balance column for better UX
      - Add z-index prop to BaseDialog for modal stacking control
      - Update i18n translations (zh/en)
      606e29d3
    • song's avatar
      chore: apply stashed changes · 3ecadf4a
      song authored
      3ecadf4a
    • song's avatar
      merge upstream main · 0170d19f
      song authored
      0170d19f
    • liuxiongfeng's avatar
      test: 为测试 stub 添加缺失的 GroupRepository 接口方法 · ce1d2904
      liuxiongfeng authored
      新增 BindAccountsToGroup 和 GetAccountIDsByGroupIDs 方法的 stub 实现,
      确保测试文件中的 mock 类型满足 GroupRepository 接口要求。
      ce1d2904
    • liuxiongfeng's avatar
      feat(groups): 添加从其他分组复制账号功能 · e1a4a7b8
      liuxiongfeng authored
      - 创建分组时可选择从已有分组复制账号
      - 编辑分组时支持同步账号(全量替换操作)
      - 仅允许选择相同平台的源分组
      - 添加完整的数据校验:去重、自引用检查、平台一致性检查
      - 前端支持多选源分组,带提示说明操作行为
      e1a4a7b8
    • 小北's avatar
      feat: 支持在用户搜索中使用备注字段 · 426ce616
      小北 authored
      - 在用户仓库的搜索过滤器中添加备注字段
      - 管理员现在可以通过备注/标记搜索用户
      - 使用不区分大小写的搜索(ContainsFold)
      
      Changes:
      - backend/internal/repository/user_repo.go: 添加 NotesContainsFold 到搜索条件
      426ce616
  4. 31 Jan, 2026 1 commit
  5. 30 Jan, 2026 3 commits
  6. 28 Jan, 2026 1 commit
    • shaw's avatar
      修复调度器空缓存导致的竞态条件bug · e12dd079
      shaw authored
      当新分组创建后立即绑定账号时,调度器会错误地将空快照视为有效缓存命中,
      导致返回没有可调度的账号。现在空快照会触发数据库回退查询。
      e12dd079
  7. 27 Jan, 2026 3 commits
  8. 26 Jan, 2026 2 commits
    • song's avatar
      fix: jsonb_set 嵌套路径无法创建多层 key 的问题 · 4b57e80e
      song authored
      PostgreSQL jsonb_set 在 create_if_missing=true 时无法一次性创建多层嵌套路径。
      例如设置 {antigravity_quota_scopes,gemini_image} 时,如果 antigravity_quota_scopes 不存在,
      jsonb_set 不会自动创建外层 key,导致更新静默失败(affected=1 但数据未变)。
      
      修复方案:嵌套两次 jsonb_set,先确保外层 key 存在,再设置内层值。
      
      影响范围:
      - SetAntigravityQuotaScopeLimit: Antigravity 平台按模型 scope 限流
      - SetModelRateLimit: Anthropic 平台 Sonnet 模型限流
      4b57e80e
    • shaw's avatar
      feat(auth): 实现 TOTP 双因素认证功能 · 1245f07a
      shaw authored
      新增功能:
      - 支持 Google Authenticator 等应用进行 TOTP 二次验证
      - 用户可在个人设置中启用/禁用 2FA
      - 登录时支持 TOTP 验证流程
      - 管理后台可全局开关 TOTP 功能
      
      安全增强:
      - TOTP 密钥使用 AES-256-GCM 加密存储
      - 添加 TOTP_ENCRYPTION_KEY 配置项,必须手动配置才能启用功能
      - 防止服务重启导致加密密钥变更使用户无法登录
      - 验证失败次数限制,防止暴力破解
      
      配置说明:
      - Docker 部署:在 .env 中设置 TOTP_ENCRYPTION_KEY
      - 非 Docker 部署:在 config.yaml 中设置 totp.encryption_key
      - 生成密钥命令:openssl rand -hex 32
      1245f07a
  9. 24 Jan, 2026 3 commits
    • shaw's avatar
      feat(auth): 密码重置邮件队列化与限流优化 · 9cc83525
      shaw authored
      - 邮件发送改为异步队列处理,避免并发导致发送失败
      - 新增 Email 维度限流(30秒冷却期),防止邮件轰炸
      - Token 验证使用常量时间比较,防止时序攻击
      - 重构代码消除冗余,提取公共验证逻辑
      9cc83525
    • shaw's avatar
      fix(test): 修复订阅相关测试失败问题 · 43a1031e
      shaw authored
      1. 使用未来日期(2099年)作为测试订阅的过期时间,避免
         normalizeSubscriptionStatus 将测试数据标记为过期
      2. 修复 List 方法调用参数不足的问题(新增 sortBy/sortOrder 参数)
      43a1031e
    • shaw's avatar
      feat(subscription): 订阅过期状态自动更新与服务端排序 · b0aa2354
      shaw authored
      - 新增 SubscriptionExpiryService 定时任务,每分钟更新过期订阅状态
      - 订阅列表支持服务端排序(按过期时间、状态、创建时间)
      - 实时显示正确的过期状态,无需等待定时任务
      - 允许对已过期订阅进行续期操作
      - DataTable 组件支持 serverSideSort 模式
      b0aa2354
  10. 23 Jan, 2026 4 commits
  11. 21 Jan, 2026 1 commit
    • song's avatar
      fix: 429 限流时更新账号 last_used_at · 3a31fa47
      song authored
      在设置限流标记时同时更新 last_used_at,使得刚触发 429 的账号
      在后续调度中优先级降低,让其他账号有更多被选中的机会。
      3a31fa47
  12. 20 Jan, 2026 4 commits
  13. 19 Jan, 2026 5 commits