1. 05 Mar, 2026 3 commits
    • erio's avatar
    • erio's avatar
      feat: add quota limit for API key accounts · 05527b13
      erio authored
      - Add configurable spending limit (quota_limit) for apikey-type accounts
      - Atomic quota accumulation via PostgreSQL JSONB operations on TotalCost
      - Scheduler filters out over-quota accounts with outbox-triggered snapshot refresh
      - Display quota usage ($used / $limit) in account capacity column
      - Add "Reset Quota" action in account menu to reset usage to zero
      - Editing account settings preserves quota_used (no accidental reset)
      - Covers all 3 billing paths: Anthropic, Gemini, OpenAI RecordUsage
      
      chore: bump version to 0.1.90.4
      05527b13
    • guoyongchang's avatar
      feat: 支持基于 crontab 的定时账号测试 · 3a089242
      guoyongchang authored
      
      
      每个测试计划绑定一个账号和一个模型,按 cron 表达式定期执行测试,
      保存历史结果并在前端账号管理页面中提供完整的增删改查和结果查看功能。
      
      主要变更:
      - 新增 scheduled_test_plans / scheduled_test_results 两张表及迁移
      - 后端 service 层:CRUD 服务 + 后台 cron runner(每分钟扫描到期计划并发执行)
      - RunTestBackground 方法通过 httptest 在内存中执行账号测试并解析 SSE 输出
      - Redis leader lock + pg_try_advisory_lock 双重保障多实例部署只执行一次
      - REST API:5 个管理端点(计划 CRUD + 结果查询)
      - 前端 ScheduledTestsPanel 组件:计划管理、启用开关、内联编辑、结果展开查看
      - 中英文 i18n 支持
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      3a089242
  2. 04 Mar, 2026 3 commits
  3. 03 Mar, 2026 5 commits
    • shaw's avatar
      refactor: 重构 api_key_auth 中间件,用 skipBilling 替代 7 处散落的 isUsageQuery · a728dfe0
      shaw authored
      将中间件职责拆分为鉴权(Authentication)和计费执行(Billing Enforcement)两层:
      - 鉴权层(disabled/IP/用户状态)始终执行
      - 计费层(过期/配额/订阅/余额)用单一 skipBilling 守卫整块控制
      
      /v1/usage 端点只需鉴权不需计费,skipBilling 仅出现 2 处(订阅加载错误处理 + 计费块守卫),
      取代了之前 isUsageQuery 散布在 7 个 if 分支中的控制流。
      a728dfe0
    • QTom's avatar
      feat(gateway): 系统设置控制未分组 Key 调度 — Handler 层中间件拦截 · 0c7cbe35
      QTom authored
      新增系统设置 allow_ungrouped_key_scheduling(默认关闭),
      未分组的 API Key 在网关请求时直接返回 403,
      由 RequireGroupAssignment 中间件统一拦截,
      支持 Anthropic / Google 两种错误格式响应。
      
      全栈实现:常量 → 结构体 → 解析/更新/初始化 → DTO → 管理接口 →
      中间件 → 路由注册 → 前端设置界面 + i18n。
      0c7cbe35
    • shaw's avatar
      fix: resolve CI lint errors and test compilation failures for rate limit feature · b8b5cec3
      shaw authored
      - Fix errcheck: properly handle rows.Close() error via named return + defer closure
      - Fix gofmt: auto-format billing_cache.go, api_key_service.go, billing_cache_service.go
      - Add missing rate limit interface methods to 4 test stubs (GetRateLimitData, IncrementRateLimitUsage, ResetRateLimitWindows)
      - Fix NewBillingCacheService calls missing the new apiKeyRepo parameter
      b8b5cec3
    • shaw's avatar
      feat: apikey支持5h/1d/7d速率控制 · a80ec5d8
      shaw authored
      a80ec5d8
    • QTom's avatar
      fix(gateway): 分组隔离 — 禁止未分组账号被跨组调度 · 530a1629
      QTom authored
      当 API Key 无分组时,调度仅从未分组账号池中选取。
      修复 isAccountInGroup 在 groupID==nil 时的逻辑,
      同时补全 scheduler_snapshot_service 和 gemini_compat_service
      中的 SimpleMode 保护,确保分组隔离在所有调度路径生效。
      
      新增 ListSchedulableUngroupedByPlatform/s 方法,
      使用 Ent 的 Not(HasAccountGroups()) 谓词实现未分组账号隔离。
      新增 17 个单元和端到端隔离测试,覆盖所有分支和边界条件。
      530a1629
  4. 02 Mar, 2026 4 commits
    • erio's avatar
      fix: security hardening and architectural improvements for custom menu · e97c3766
      erio authored
      
      
      1. (Critical) Filter admin-only menu items from public API responses -
         both GetPublicSettings handler and GetPublicSettingsForInjection now
         exclude visibility=admin items, preventing unauthorized access to
         admin menu URLs.
      
      2. (Medium) Validate JSON array structure in sanitizeCustomMenuItemsJSON -
         use json.Unmarshal into []json.RawMessage instead of json.Valid to
         reject non-array JSON values that would cause frontend runtime errors.
      
      3. (Medium) Decouple router from business JSON parsing - move origin
         extraction logic from router.go to SettingService.GetFrameSrcOrigins,
         eliminating direct JSON parsing of custom_menu_items in the routing
         layer.
      
      4. (Low) Restrict custom menu item ID charset to [a-zA-Z0-9_-] via
         regex validation, preventing route-breaking characters like / ? # or
         spaces.
      
      5. (Low) Handle crypto/rand error in generateMenuItemID - return error
         instead of silently ignoring, preventing potential duplicate IDs.
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      e97c3766
    • erio's avatar
      50a8116a
    • erio's avatar
      fix: custom menu security hardening and code quality improvements · bf6fe5e9
      erio authored
      
      
      - Add admin menu permission check in CustomPageView (visibility + role)
      - Sanitize SVG content with DOMPurify before v-html rendering (XSS prevention)
      - Decouple router.go from dto package using anonymous struct
      - Consolidate duplicate parseCustomMenuItems into dto.ParseCustomMenuItems
      - Enhance menu item validation (count, length, ID uniqueness limits)
      - Add audit logging for purchase_subscription and custom_menu_items changes
      - Update API contract test to include custom_menu_items field
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      bf6fe5e9
    • erio's avatar
      feat: custom menu pages with iframe embedding and CSP injection · 067810fa
      erio authored
      
      
      Add configurable custom menu items that appear in sidebar, each rendering
      an iframe-embedded external page. Includes shared URL builder with
      src_host/src_url tracking, CSP frame-src multi-origin deduplication,
      admin settings UI, and i18n support.
      
      chore: bump version to 0.1.87.19
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      067810fa
  5. 01 Mar, 2026 3 commits
    • PMExtra's avatar
      feat(settings): add default subscriptions for new users · 7e020822
      PMExtra authored
      - add default subscriptions to admin settings
      
      - auto-assign subscriptions on register and admin user creation
      
      - add validation/tests and align settings UI with subscription selector patterns
      7e020822
    • erio's avatar
      feat(dashboard): add group usage distribution chart to usage page · 65459a99
      erio authored
      Add a doughnut chart showing usage statistics broken down by group on
      the admin usage records page. The chart appears alongside the existing
      model distribution chart (2-column grid), with the token usage trend
      chart moved to a separate full-width row below.
      
      Changes:
      - backend/pkg/usagestats: add GroupStat type
      - backend/service: add GetGroupStatsWithFilters interface method and implementation
      - backend/repository: implement GetGroupStatsWithFilters with LEFT JOIN groups
      - backend/handler: add GetGroupStats handler with full filter support
      - backend/routes: register GET /admin/dashboard/groups route
      - backend/tests: add GetGroupStatsWithFilters stubs to contract/sora tests
      - frontend/types: add GroupStat interface
      - frontend/api: add getGroupStats API function and types
      - frontend/components: add GroupDistributionChart.vue doughnut chart
      - frontend/views: update UsageView layout and load group stats in parallel
      - frontend/i18n: add groupDistribution, group, noGroup keys (zh + en)
      65459a99
    • QTom's avatar
      fix(ci): 修复 golangci-lint 和 API 合约测试失败 · b2141a96
      QTom authored
      - 修复 errcheck: singleflight 返回值类型断言添加 ok 检查
      - 修复 gofmt: 格式化 setting_service.go 和 claude_code_validator_test.go
      - 修复 TestAPIContracts: 在 GET /admin/settings 期望中添加 min_claude_code_version 字段
      b2141a96
  6. 28 Feb, 2026 5 commits
    • erio's avatar
    • QTom's avatar
      fix: sync test constructor calls with new rpmCache parameter · e135435c
      QTom authored
      Add missing nil argument for rpmCache to NewAccountHandler (5 sites)
      and NewGatewayService (2 sites) after RPM feature expanded their
      signatures.
      e135435c
    • QTom's avatar
      feat(admin): 完整实现管理员修改用户 API Key 分组的功能 · 9a91815b
      QTom authored
      ## 核心功能
      - 添加 AdminUpdateAPIKeyGroupID 服务方法,支持绑定/解绑/保持不变三态语义
      - 实现 UserRepository.AddGroupToAllowedGroups 接口,自动同步专属分组权限
      - 添加 HTTP PUT /api-keys/:id handler 端点,支持管理员直接修改 API Key 分组
      
      ## 事务一致性
      - 使用 ent Tx 保证专属分组绑定时「添加权限」和「更新 Key」的原子性
      - Repository 方法支持 clientFromContext,兼容事务内调用
      - 事务失败时自动回滚,避免权限孤立
      
      ## 业务逻辑
      - 订阅类型分组阻断,需通过订阅管理流程
      - 非活跃分组拒绝绑定
      - 负 ID 和非法 ID 验证
      - 自动授权响应,告知管理员成功授权的分组
      
      ## 代码质量
      - 16 个单元测试覆盖所有业务路径和边界用例
      - 7 个 handler 集成测试覆盖 HTTP 层
      - GroupRepo stub 返回克隆副本,防止测试间数据泄漏
      - API 类型安全修复(PaginatedResponse<ApiKey>)
      - 前端 ref 回调类型对齐 Vue 规范
      
      ## 国际化支持
      - 中英文提示信息完整
      - 自动授权成功/失败提示
      9a91815b
    • QTom's avatar
      feat(admin): 添加管理员直接修改用户 API Key 分组的功能 · 000e621e
      QTom authored
      - 新增 PUT /api/v1/admin/api-keys/:id 端点,允许管理员修改任意用户 API Key 的分组绑定
      - 跳过用户级权限校验但保留分组有效性验证,修改后触发认证缓存失效
      - Service 层支持三态语义:nil=不修改,0=解绑,>0=绑定,<0=拒绝
      - 指针值拷贝保证安全隔离,负数 groupID 返回 400 INVALID_GROUP_ID
      - 前端 UserApiKeysModal 新增可点击的分组选择下拉框,支持多 Key 并发更新
      - 下拉支持视口翻转和滚动关闭,按钮有 disabled 和加载状态
      - 覆盖:后端 20 个单元测试 (Service 11 + Handler 9) + 前端 16 个 E2E 测试
      - golangci-lint 0 issues, make test-unit 全部通过
      000e621e
    • yangjianbo's avatar
      feat(sync): full code sync from release · bb664d9b
      yangjianbo authored
      bb664d9b
  7. 24 Feb, 2026 1 commit
    • erio's avatar
      feat: add mixed-channel precheck API for account-group binding · aaac1aac
      erio authored
      Add a dedicated CheckMixedChannel endpoint that allows the frontend
      to pre-validate mixed channel risk before submitting create/update
      requests. This improves UX by showing warnings earlier in the flow
      instead of only after form submission.
      
      Backend changes:
      - Add CheckMixedChannelRequest struct and CheckMixedChannel handler
      - Register POST /check-mixed-channel route
      - Expose CheckMixedChannelRisk as public method on AdminService
      - Simplify Create/Update 409 responses (remove details/require_confirmation)
      - Add comprehensive handler tests and stub methods
      
      Frontend changes:
      - Add checkMixedChannelRisk API function and TypeScript types
      - Refactor CreateAccountModal to precheck before step transition and submission
      - Refactor EditAccountModal to precheck before update submission
      - Replace pendingPayload pattern with action-based dialog flow
      aaac1aac
  8. 22 Feb, 2026 1 commit
  9. 21 Feb, 2026 1 commit
  10. 19 Feb, 2026 2 commits
  11. 17 Feb, 2026 1 commit
  12. 14 Feb, 2026 3 commits
  13. 13 Feb, 2026 1 commit
    • yangjianbo's avatar
      fix(ops): 修复日志级别过滤并增强OpenAI错误诊断日志 · f96acf6e
      yangjianbo authored
      - 移除 warn 级别下 access info 的强制入库补写,确保运行时日志级别真实生效
      
      - 将 OpenAI fallback matched 与 passthrough 断流提示按需求降级为 info
      
      - 为 codex_cli_only 与 instructions required 场景补充请求诊断字段(含 User-Agent)
      
      - 出于安全考虑移除请求体预览,仅保留 request_body_size 与白名单头信息
      
      - 新增/更新回归测试,覆盖 Forward 入口到日志落库链路
      f96acf6e
  14. 12 Feb, 2026 3 commits
  15. 11 Feb, 2026 1 commit
    • kyx236's avatar
      feat(admin): Add group filtering for account listings · fe1d46a8
      kyx236 authored
      - Add groupID parameter to ListAccounts and ListWithFilters methods
      - Implement account filtering by group ID in repository query
      - Add group query parameter parsing in account handler
      - Update all ListAccounts/ListWithFilters call sites with groupID parameter
      - Add group filter UI component to AccountTableFilters
      - Add i18n translations for group filter label in English and Chinese
      - Update API contract and test stubs to reflect new signature
      - Enable filtering accounts by their assigned groups in admin panel
      fe1d46a8
  16. 10 Feb, 2026 1 commit
    • Tian's avatar
      feat(antigravity): 支持 Refresh Token 批量导入创建 OAuth 账号 · c8f87a9c
      Tian authored
      后端新增 ValidateRefreshToken service 方法和 POST /oauth/refresh-token 端点,
      前端新增 API/Composable/UI 集成,OAuthAuthorizationFlow i18n 动态化,
      支持在 Antigravity 创建账号时批量粘贴 Refresh Token 自动验证并创建账号。
      c8f87a9c
  17. 09 Feb, 2026 2 commits