1. 05 Mar, 2026 1 commit
    • yangjianbo's avatar
      feat(openai-ws): 合并 WS v2 透传模式与前端 ws mode · 1d0872e7
      yangjianbo authored
      
      
      新增 OpenAI WebSocket v2 passthrough relay 数据面与服务适配层,
      支持按账号 ws mode 在 ctx_pool 与 passthrough 间路由。
      
      同步调整前端 OpenAI ws mode 选项为 off/ctx_pool/passthrough,
      并补充 i18n 文案与对应单测。
      
      新增 Caddyfile.dmit 与 docker-compose-aicodex.yml 部署配置,
      用于宿主机场景下的反向代理与服务编排。
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      1d0872e7
  2. 04 Mar, 2026 8 commits
  3. 03 Mar, 2026 9 commits
    • shaw's avatar
      feat: 重构 /v1/usage 端点,支持 quota_limited 和 unrestricted 双模式 · 838dad87
      shaw authored
      - quota_limited 模式:返回 Key 级别的总额度、速率限制窗口用量和过期时间
      - unrestricted 模式:返回订阅限额或钱包余额信息(向后兼容)
      - 新增 model_stats 字段,支持 start_date/end_date 参数查询按模型用量统计
      - 提取 buildUsageData/parseUsageDateRange 等辅助方法,减少主函数复杂度
      - 新增 APIKeyService.GetRateLimitData 和 UsageService.GetAPIKeyModelStats
      838dad87
    • QTom's avatar
      feat(gateway): 系统设置控制未分组 Key 调度 — Handler 层中间件拦截 · 0c7cbe35
      QTom authored
      新增系统设置 allow_ungrouped_key_scheduling(默认关闭),
      未分组的 API Key 在网关请求时直接返回 403,
      由 RequireGroupAssignment 中间件统一拦截,
      支持 Anthropic / Google 两种错误格式响应。
      
      全栈实现:常量 → 结构体 → 解析/更新/初始化 → DTO → 管理接口 →
      中间件 → 路由注册 → 前端设置界面 + i18n。
      0c7cbe35
    • alfadb's avatar
      style: fix gofmt formatting in ops_settings.go · 832b0185
      alfadb authored
      
      
      Remove extra space before inline comment to pass golangci-lint gofmt check.
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      832b0185
    • alfadb's avatar
      fix(ops): 默认忽略 count_tokens 404 错误 · b1719b26
      alfadb authored
      
      
      将 IgnoreCountTokensErrors 默认值从 false 改为 true。
      
      count_tokens 返回 404 是预期业务行为(上游不支持 endpoint,
      客户端应 fallback 到本地 tokenizer 估算),不应被视为错误。
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      b1719b26
    • shaw's avatar
      fix: 修复 PR #723 引入的 CI lint 和 test 编译错误 · ccf6a921
      shaw authored
      - wire_gen_test.go: 补充 NewTokenRefreshService 缺失的 tempUnschedCache 参数
      - config.go, token_refresh_service.go: 修复 gofmt 格式问题
      ccf6a921
    • shaw's avatar
      fix: correct migration 061 checksum and add missing BillingCache mock methods · 4a919545
      shaw authored
      - Fix fileChecksum for 061 migration: use TrimSpace hash (66207e7a) instead
        of raw sha256sum (97bdd9a3), matching the actual runtime computation
      - Add 222b4a09 as accepted DB checksum for 061 migration
      - Add missing GetAPIKeyRateLimit/SetAPIKeyRateLimit/UpdateAPIKeyRateLimitUsage/
        InvalidateAPIKeyRateLimit methods to mock BillingCache in test stubs
      - Fix NewBillingCacheService call in singleflight test (add apiKeyRepo param)
      4a919545
    • 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 10 commits
    • erio's avatar
      fix: remove unused sanitizeCustomMenuItemsJSON function · 451a8511
      erio authored
      
      
      Replaced by filterUserVisibleMenuItems which includes both array
      validation and admin-item filtering.
      Co-Authored-By: default avatarClaude Opus 4.6 <noreply@anthropic.com>
      451a8511
    • 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
      style: fix gofmt alignment in setting_service.go · 7541e243
      erio authored
      7541e243
    • erio's avatar
      e4f87993
    • erio's avatar
    • 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
    • QTom's avatar
      feat(gateway): 双模式用户消息队列 — 串行队列 + 软性限速 · a9285b8a
      QTom authored
      新增 UMQ (User Message Queue) 双模式支持:
      - serialize: 账号级分布式串行锁 + RPM 自适应延迟(严格限流)
      - throttle: 仅 RPM 自适应前置延迟,不阻塞并发(软性限速)
      
      后端:
      - config: 新增 Mode 字段,保留 Enabled 向后兼容
      - service: 新增 UserMessageQueueService(Lua 锁/延迟算法/清理 worker)
      - repository: 新增 UserMsgQueueCache(Redis Lua acquire/release/force-release)
      - handler: 新增 UserMsgQueueHelper(SSE ping + 等待循环 + throttle)
      - gateway: 按 mode 分支集成 serialize/throttle 逻辑
      - lint: 修复 gofmt rewrite rules、errcheck 类型断言、staticcheck QF1012
      
      前端:
      - 三态选择器 UI(关闭/软性限速/串行队列)替代 toggle 开关
      - BulkEdit 支持 null 语义(不修改)
      - i18n 中英文文案
      
      通过 6 轮专家评审(42 次 review)、golangci-lint、单元测试、集成测试。
      a9285b8a
    • zqq61's avatar
      fix: OAuth 401 不再永久锁死账号,改用临时不可调度实现自动恢复 · ec6bcfeb
      zqq61 authored
      OAuth 账号收到 401 时,原逻辑同时设置 expires_at=now() 和 SetError(),
      但刷新服务只查询 status=active 的账号,导致 error 状态的账号永远无法
      被刷新服务拾取,expires_at=now() 实际上是死代码。
      
      修复:
      - OAuth 401 使用 SetTempUnschedulable 替代 SetError,保持 status=active
      - 新增 oauth_401_cooldown_minutes 配置项(默认 10 分钟)
      - 刷新成功后同步清除 DB 和 Redis 中的临时不可调度状态
      - 不可重试错误检查(invalid_grant 等)从 Antigravity 推广到所有平台
      - 可重试错误耗尽后不再标记 error,下个刷新周期继续重试
      
      恢复流程:
      OAuth 401 → temp_unschedulable + expires_at=now → 刷新服务拾取
        → 成功: 清除 temp_unschedulable → 自动恢复
        → invalid_grant: SetError → 永久禁用
        → 网络错误: 仅记日志 → 下周期重试
      ec6bcfeb
    • QTom's avatar
      feat(proxy): 集中代理 URL 验证并实现全局 fail-fast · fdcbf7aa
      QTom authored
      提取 proxyurl.Parse() 公共包,将分散在 6 处的代理 URL 验证逻辑
      统一收敛,确保无效代理配置在创建时立即失败,永不静默回退直连。
      
      主要变更:
      - 新增 proxyurl 包:统一 TrimSpace → url.Parse → Host 校验 → Scheme 白名单
      - socks5:// 自动升级为 socks5h://,防止 DNS 泄漏(大小写不敏感)
      - antigravity: http.ProxyURL → proxyutil.ConfigureTransportProxy 支持 SOCKS5
      - openai_oauth: 删除 newOpenAIOAuthHTTPClient,收编至 httpclient.GetClient
      - 移除未使用的 ProxyStrict 字段(fail-fast 已是全局默认行为)
      - 补充 15 个 proxyurl 测试 + pricing/usage fail-fast 测试
      fdcbf7aa
    • PMExtra's avatar
  5. 01 Mar, 2026 10 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
    • QTom's avatar
      feat(identity): 指纹缓存 TTL 懒续期机制 · d869ac95
      QTom authored
      - TTL 改为 7 天,配合 24 小时自动续期保持活跃账号永不过期
      - 版本升级时采用合并语义,仅更新请求中实际存在的字段
      - 添加产品名验证防止浏览器 UA 误判为更新版本
      d869ac95
    • 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
    • QTom's avatar
      feat(gateway): 添加 Claude Code 客户端最低版本检查功能 · 4280aca8
      QTom authored
      - 通过 User-Agent 识别 Claude Code 客户端并提取版本号
      - 在网关层验证客户端版本是否满足管理员配置的最低要求
      - 在管理后台提供版本要求配置选项(英文/中文双语)
      - 实现原子缓存 + singleflight 防止并发问题和 thundering herd
      - 使用 context.WithoutCancel 隔离 DB 查询,避免客户端断连影响缓存
      - 双 TTL 策略:60s 正常、5s 错误恢复,保证性能与可用性
      - 仅检查 Claude Code 客户端,其他客户端不受影响
      - 添加完整单元测试覆盖版本提取、比对、上下文操作
      4280aca8
    • erio's avatar
      c08889b0
    • erio's avatar
      57ebe382
    • erio's avatar
      fix: use i18n for mixed-channel warning messages and improve bulk pre-check · 3a04552f
      erio authored
      - BulkUpdate handler: add structured details to 409 response
      - BulkUpdateAccounts: simplify to global pre-check before any DB write;
        remove per-account snapshot tracking which is no longer needed
      - MixedChannelError.Error(): restore English message for API compatibility
      - BulkEditAccountModal: use t() with details for both pre-check and 409
        fallback paths instead of displaying raw backend strings
      - Update test to verify pre-check blocks on existing group conflicts
      3a04552f
    • erio's avatar
      fix: update mixed channel warning message · b67bf222
      erio authored
      b67bf222
    • erio's avatar
      feat: bulk update accounts pre-check mixed channel risk with confirm dialog · 7aa4c083
      erio authored
      - Move mixed channel check before any DB writes in BulkUpdateAccounts
      - Return 409 from BulkUpdate handler for MixedChannelError
      - Add ConfirmDialog to BulkEditAccountModal for mixed channel warning
      - Update mixed channel warning message to Chinese
      7aa4c083
  6. 28 Feb, 2026 2 commits