1. 15 Mar, 2026 7 commits
    • shaw's avatar
      ae44a943
    • Elysia's avatar
      增加测试 · 359e5675
      Elysia authored
      359e5675
    • erio's avatar
      fix(billing): allow clearing group quota limits and treat 0 as zero-limit · 5899784a
      erio authored
      Previously, v-model.number produced "" when input was cleared, causing
      JSON decode errors on the backend. Also, normalizeLimit treated 0 as
      "unlimited" which prevented setting a zero quota. Now "" is converted
      to null (unlimited) in frontend, and 0 is preserved as a valid limit.
      
      Closes Wei-Shaw/sub2api#1021
      5899784a
    • erio's avatar
      fix(billing): treat nil rate limit window as expired to prevent usage accumulation · 9e8959c5
      erio authored
      When Redis cache is populated from DB with a NULL window_1d_start, the
      Lua increment script only updates usage counters without setting window
      timestamps. IsWindowExpired(nil) previously returned false, so the
      accumulated usage was never reset across time windows, effectively
      turning usage_1d into a lifetime counter. Once this exceeded
      rate_limit_1d the key was incorrectly blocked with "日限额已用完".
      
      Fixes Wei-Shaw/sub2api#1022
      9e8959c5
    • YanzheL's avatar
      fix: extract and log Claude output_config.effort in usage records · 1bff2292
      YanzheL authored
      Claude's output_config.effort parameter (low/medium/high/max) was not
      being extracted from requests or logged in the reasoning_effort column
      of usage logs. Only the OpenAI path populated this field.
      
      Changes:
      - Extract output_config.effort in ParseGatewayRequest
      - Add ReasoningEffort field to ForwardResult
      - Populate reasoning_effort in both RecordUsage and RecordUsageWithLongContext
      - Guard against overwriting service-set effort values in handler
      - Update stale comments that described reasoning_effort as OpenAI-only
      - Add unit tests for extraction, normalization, and persistence
      1bff2292
    • Ethan0x0000's avatar
      test: fix usage repo stubs for unit builds · cf924775
      Ethan0x0000 authored
      cf924775
    • Ethan0x0000's avatar
      feat: 完善使用记录端点可观测性与分布统计 · eefab159
      Ethan0x0000 authored
      将入站、上游与路径三类端点分布统一到使用记录页的一致化卡片交互中,并补齐端点元数据与统计链路,提升排障与流量分析效率。
      eefab159
  2. 14 Mar, 2026 16 commits
  3. 13 Mar, 2026 12 commits
    • erio's avatar
      fix: restore OAuth 401 temp-unschedulable for Gemini, update Antigravity tests · 45456fa2
      erio authored
      The 403 detection PR changed the 401 handler condition from
      `account.Type == AccountTypeOAuth` to
      `account.Type == AccountTypeOAuth && account.Platform == PlatformOpenAI`,
      which accidentally excluded Gemini OAuth from the temp-unschedulable path.
      
      Fix: use `!= PlatformAntigravity` instead, preserving Gemini behavior
      while correctly excluding Antigravity (whose 401 is handled by
      applyErrorPolicy's temp_unschedulable_rules).
      
      Update tests to reflect Antigravity's new 401 semantics:
      - HandleUpstreamError: Antigravity OAuth 401 now uses SetError
      - CheckErrorPolicy: Antigravity 401 second hit stays TempUnscheduled
      - DB fallback: split into Gemini (escalates) and Antigravity (stays temp)
      45456fa2
    • erio's avatar
      feat(redeem): support subscription type in create-and-redeem API · 05edb551
      erio authored
      Add group_id and validity_days fields to CreateAndRedeemCodeRequest,
      enabling subscription-type redemption codes to be created and redeemed
      in a single API call.
      
      - Type defaults to "balance" when omitted for backward compatibility
      - Subscription type requires group_id (non-nil) and validity_days (>0)
      - Existing balance/concurrency callers are unaffected
      05edb551
    • Ylarod's avatar
      fix lint · e90ec847
      Ylarod authored
      e90ec847
    • erio's avatar
      feat(antigravity): add 403 forbidden status detection, classification and display · 6344fa2a
      erio authored
      Backend:
      - Detect and classify 403 responses into three types:
        validation (account needs Google verification),
        violation (terms of service / banned),
        forbidden (generic 403)
      - Extract verification/appeal URLs from 403 response body
        (structured JSON parsing with regex fallback)
      - Add needs_verify, is_banned, needs_reauth, error_code fields
        to UsageInfo (omitempty for zero impact on other platforms)
      - Handle 403 in request path: classify and permanently set account error
      - Save validation_url in error_message for degraded path recovery
      - Enrich usage with account error on both success and degraded paths
      - Add singleflight dedup for usage requests with independent context
      - Differentiate cache TTL: success/403 → 3min, errors → 1min
      - Return degraded UsageInfo instead of HTTP 500 on quota fetch errors
      
      Frontend:
      - Display forbidden status badges with color coding (red for banned,
        amber for needs verification, gray for generic)
      - Show clickable verification/appeal URL links
      - Display needs_reauth and degraded error states in usage cell
      - Add Antigravity tier label badge next to platform type
      
      Tests:
      - Comprehensive unit tests for classifyForbiddenType (7 cases)
      - Unit tests for extractValidationURL (8 cases including unicode escapes)
      - Integration test for FetchQuota forbidden path
      6344fa2a
    • Peter's avatar
      feat(ops): allow hiding alert events · 29b0e4a8
      Peter authored
      29b0e4a8
    • Ylarod's avatar
      sub2api: add bedrock support · 11f7b835
      Ylarod authored
      11f7b835
    • Rose Ding's avatar
    • Rose Ding's avatar
    • wucm667's avatar
      refactor: 将 ComputeQuotaResetAt 和 ValidateQuotaResetConfig 函数中的 map 类型从... · 2573107b
      wucm667 authored
      refactor: 将 ComputeQuotaResetAt 和 ValidateQuotaResetConfig 函数中的 map 类型从 map[string]interface{} 修改为 map[string]any
      2573107b
    • wucm667's avatar
      feat: 账号配额支持固定时间重置模式 · 5b850059
      wucm667 authored
      - 后端新增 rolling/fixed 两种配额重置模式,支持日配额和周配额
      - fixed 模式下可配置重置时刻(小时)、重置星期几(周配额)及时区(IANA)
      - 在 account_repo.go 中使用 SQL 表达式适配两种模式的过期判断与重置时间推进
      - 新增 ComputeQuotaResetAt / ValidateQuotaResetConfig 等辅助函数
      - DTO 层新增相关字段并在 mappers 中完整映射
      - 前端 QuotaLimitCard 新增 rolling/fixed 切换 UI、时区选择器
      - CreateAccountModal / EditAccountModal 透传新配置字段
      - i18n(zh/en)同步新增相关翻译词条
      5b850059
    • haruka's avatar
      fix: 管理员重置配额补全 monthly 字段并修复 ristretto 缓存异步问题 · e73531ce
      haruka authored
      
      
      - 后端 handler:ResetSubscriptionQuotaRequest 新增 Monthly 字段,
        验证逻辑扩展为 daily/weekly/monthly 至少一项为 true
      - 后端 service:AdminResetQuota 新增 resetMonthly 参数,
        调用 ResetMonthlyUsage;重置后追加 subCacheL1.Wait(),
        保证 ristretto Del() 的异步删除立即生效,消除重置后
        /v1/usage 返回旧用量数据的竞态窗口
      - 后端测试:更新存量测试用例匹配新签名,补充
        TestAdminResetQuota_ResetMonthlyOnly /
        TestAdminResetQuota_ResetMonthlyUsageError 两个新用例
      - 前端 API:resetQuota options 类型新增 monthly: boolean
      - 前端视图:confirmResetQuota 改为同时重置 daily/weekly/monthly
      - i18n:中英文确认提示文案更新,提及每月配额
      Co-Authored-By: default avatarClaude Sonnet 4.6 <noreply@anthropic.com>
      e73531ce
    • 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
  4. 12 Mar, 2026 5 commits