1. 20 Apr, 2026 12 commits
  2. 17 Apr, 2026 2 commits
  3. 16 Apr, 2026 3 commits
  4. 15 Apr, 2026 3 commits
  5. 14 Apr, 2026 20 commits
    • erio's avatar
      fix: gofmt payment_service.go and payment_order.go · c2108421
      erio authored
      c2108421
    • erio's avatar
      fix(payment): use original recharge amount in product name, not pay_amount · 342dbd2e
      erio authored
      Product name (e.g. "快代码科技工作室 100 元") should show the user's
      original recharge amount (limitAmount), not the fee-inclusive pay amount.
      The gateway receives payAmount separately for actual charging.
      342dbd2e
    • erio's avatar
      fix: gofmt formatting and update API contract test for new fields · 60614e6f
      erio authored
      - Fix gofmt alignment in setting_handler.go, settings.go, payment_config_service.go
      - Add payment_balance_recharge_multiplier and payment_recharge_fee_rate
        to API contract test expected JSON
      60614e6f
    • erio's avatar
      fix(payment): enhance fee rate input validation and UI · d149dbc9
      erio authored
      Backend:
      - Validate recharge_fee_rate: 0 ≤ rate ≤ 100, max 2 decimal places
      
      Frontend settings:
      - Add % suffix icon to fee rate input
      - Enforce max=100, min=0, step=0.01 with 2 decimal precision
      d149dbc9
    • erio's avatar
      fix(payment): integrate recharge fee rate in order flow and fix UI display · e761d38f
      erio authored
      Backend:
      - Use cfg.RechargeFeeRate in order creation instead of hardcoded 0
      - Remove dead getFeeRate stub method
      - All amounts computed server-side: order_amount, pay_amount, fee_rate
      
      Frontend - PaymentView:
      - Read recharge_fee_rate from checkout-info API (not per-method)
      - Show fee breakdown only when fee_rate > 0
      - Show credited amount only when multiplier ≠ 1
      
      Frontend - Order display (user + admin):
      - Fix fee_rate * 100 bug (fee_rate is already a percentage)
      - OrderTable: show pay_amount as primary, fee/credited as sub-lines
      - AdminOrderDetail: full breakdown (base/fee/paid/credited)
      - AdminRefundDialog: label "到账金额" for clarity
      - PaymentResultView: show pay_amount with fee info
      
      Types + i18n:
      - Add recharge_fee_rate to CheckoutInfoResponse
      - Add fee_rate to CreateOrderResult
      - Add translations: creditedAmount, fee, baseAmount, includedInPayAmount
      e761d38f
    • erio's avatar
      feat(payment): add recharge fee rate setting and fix provider card UI · 98140f6c
      erio authored
      - Add recharge_fee_rate system setting (percentage fee on top of recharge amount)
      - Full backend chain: config constant, PaymentConfig struct, update validation,
        read/write persistence, DTO, handler GET/PUT responses
      - Frontend: settings input with preview, i18n (zh/en), API types
      - Fix provider card toggle layout: labels above switches to save width
      - Fix Chinese translation: "EasyPay" → "易支付" in provider description
      98140f6c
    • erio's avatar
      feat(payment): balance recharge multiplier and refund amount separation · 60a4b931
      erio authored
      - Add balance_recharge_multiplier system setting (e.g. 1.2 = charge 100 get 120)
      - Separate order_amount (credited balance) from pay_amount (actual payment)
      - Refund calculates gateway amount proportionally from pay_amount
      - Frontend shows both amounts in order details, payment status, refund dialog
      - Admin settings UI for configuring recharge multiplier
      60a4b931
    • erio's avatar
      fix: Messages() routing refactor and subscription group test coverage · 8548a130
      erio authored
      - Refactor OpenAI Messages() routing: pre-compute dispatch model using
        resolveOpenAIMessagesDispatchMappedModel + NormalizeOpenAICompatRequestedModel
        instead of try-fail-retry pattern with gin context passing
      - Remove openai_messages_fallback_model context anti-pattern
      - Use effectiveMappedModel directly for forward default mapped model
      - Add 3 subscription group tests covering all branch paths:
        _Blocked (no active subscription → SUBSCRIPTION_REQUIRED),
        _RequiresRepo (nil repo → SUBSCRIPTION_REPOSITORY_UNAVAILABLE),
        _AllowsActiveSubscription (valid subscription → success)
      8548a130
    • erio's avatar
      fix: flaky WebSocket test, usage request queue, and test improvements · 3fa5b8bc
      erio authored
      - Fix flaky WebSocket passthrough test: allow StatusNormalClosure after
        client close instead of requiring NoError (race condition fix)
      - Fix ratelimit 401 test: use PlatformOpenAI instead of PlatformGemini
        for OAuth token cache invalidation scenario (more accurate)
      - Add usageLoadQueue: Anthropic OAuth/setup-token accounts sharing the
        same proxy exit are serialized with 1-2s jitter to prevent upstream 429
      - AccountUsageCell: add module-level usage cache (5min TTL), unmounted
        safety guard, and integrate enqueueUsageRequest for throttled fetching
      3fa5b8bc
    • erio's avatar
      fix: merge general improvements from release branch · 63f539b3
      erio authored
      Backend:
      - gateway_handler: pass subject.UserID instead of int64(0) for user-level routing
      - setting_handler: add missing BalanceLowNotifyRechargeURL to UpdateSettings response
      - openai_gateway_service: use applyAccountStatsCost for account stats pricing integration
      - embed_on: add local file override (data/public/) for embedded frontend assets
      
      Frontend:
      - useTableSelection: add batchUpdate method for batch operations
      - AccountsView: virtual scrolling params, Set-based isSelected, swipe virtualization
      - ProxiesView: add batchUpdate to selection and swipe-select
      - BulkEditAccountModal: fix submit handler to prevent event object as argument
      - SettingsView: move payload construction outside try block
      - i18n: add general translation keys (saved, deleted, view, validation, allowUserRefund)
      - api/client: reorder error fields for consistency
      - stores/payment: clarify pollOrderStatus JSDoc
      63f539b3
    • erio's avatar
      fix: resolve 3 code review issues in allow_user_refund · c14d7393
      erio authored
      1. PrepareRefund: block refund on provider instance lookup failure
         instead of silently skipping permission check (medium severity)
      
      2. UpdateProviderInstance: allow enabling refund_enabled and
         allow_user_refund in the same request by checking req.RefundEnabled
         value before falling back to DB read
      
      3. ExecuteRefund: only revoke subscription on ErrAdjustWouldExpire,
         abort on other errors (DB failure, not found) instead of
         unconditionally revoking
      c14d7393
    • erio's avatar
      fix: merge 30 general improvements from release branch · 6ac8ccde
      erio authored
      Bug fixes:
      - Detached context for GetAccountConcurrencyBatch (prevent all-zero on request cancel)
      - Filter soft-deleted users in GetByGroupID
      - Stripe CSP policy (allow Stripe.js in script-src and frame-src)
      - WebSearch API key validation on save
      - RECHARGING status in payment result success check
      - Windows test fixes (logger Sync deadlock, config path escaping)
      
      Feature enhancements:
      - Webhook multi-instance dispatch (extractOutTradeNo + GetWebhookProvider)
      - EasyPay mobile H5 payment (device param + PayURL2)
      - SSE error propagation in WebSearch emulation
      - AccountStatsCost DTO field for admin usage logs
      - Plans sort by sort_order instead of created_at
      - UsageMapHook for streaming response usage data
      - apicompat Instructions field passthrough
      - EffectiveLoadFactor for ops concurrency/metrics
      - Usage billing RETURNING balance for notify system
      - BulkUpdate mixed channel warning with details
      - println to slog migration in auth cache
      - Wire ProviderSet cleanup
      - CI cache-dependency-path optimization
      
      Frontend:
      - Refund eligibility check per provider (canRequestRefund)
      - Plan sort_order editing
      - Dead code cleanup (simulate_claude_max, client_affinity)
      - GroupsView platform switch guard
      - channels features_config API type
      - UsageView account_stats_cost export
      6ac8ccde
    • erio's avatar
      feat: add per-provider allow_user_refund control and align wildcard matching · f1297a36
      erio authored
      allow_user_refund:
      - Add allow_user_refund field to PaymentProviderInstance ent schema
      - Migration 103: ALTER TABLE payment_provider_instances ADD COLUMN
      - Cascade logic: disabling refund_enabled auto-disables allow_user_refund
      - User refund validation: check provider instance allows user refund
      - Admin refund validation: check provider instance allows admin refund
      - Subscription refund: deduct days on refund, rollback on failure
      - New endpoint: GET /payment/orders/refund-eligible-providers
      - Frontend: ToggleSwitch in ProviderCard/Dialog, cascade in SettingsView
      
      Wildcard matching:
      - Change findPricingForModel from "longest prefix wins" to "config order
        priority (first match wins)", aligning with channel service behavior
      f1297a36
    • erio's avatar
      fix: resolve remaining lint errors for upstream CI · e8ee400a
      erio authored
      - Fix errcheck: brave.go resp.Body.Close, manager_test.go Encode
      - Fix gofmt: payment_config_service.go
      - Fix unused: use shouldFallbackGeminiModel (with modelName param) in handler
      e8ee400a
    • erio's avatar
      fix: resolve upstream CI failures (lint, test, gofmt) · 6a08efee
      erio authored
      - Fix errcheck: handle Write/Encode return values in brave_test.go
      - Fix errcheck: defer resp.Body.Close() with _ assignment in tavily.go
      - Fix gofmt: payment.go, channel.go, payment_config_providers.go
      - Fix unused: remove dead decodeURLValue in easypay.go
      - Restore shouldFallbackGeminiModel function (deleted during cherry-pick)
      - Add missing balanceNotifyService param to NewGatewayService in test
      - Fix platform default test expectation (empty stays empty)
      - Fix wildcard pricing test (longest prefix wins, not config order)
      - Fix subscription group test (SUBSCRIPTION_REPOSITORY_UNAVAILABLE)
      6a08efee
    • erio's avatar
      fix: resolve test compilation errors and restore upstream VERSION · b42f34c3
      erio authored
      - Add missing interface methods to test stubs (RemoveGroupFromUserAllowedGroups,
        GetNotifyCodeUserRate, IncrNotifyCodeUserRate, UpdateGroupIDByUserAndGroup)
      - Fix NewUserService call signatures (add 4th param)
      - Fix GetAccountCount return signature (3 values)
      - Update api_contract_test.go snapshots for balance_notify fields
      - Restore resolveOpenAIMessagesDispatchMappedModel function
      - Reset VERSION to upstream 0.1.112
      b42f34c3
    • erio's avatar
      fix: resolve cherry-pick conflicts and restore compilation · d6965b06
      erio authored
      - Restore gateway_cache.go to upstream (no lua embeds)
      - Restore payment_order.go to upstream (use out_trade_no lookup)
      - Restore payment_fulfillment.go to upstream (same reason)
      - Add FeaturesConfig field and IsWebSearchEmulationEnabled to Channel
      - Add applyAccountStatsCost wrapper function
      - Add SettingKeyWebSearchEmulationConfig constant
      - Add WebSearchEmulationEnabled to SystemSettings
      - Add notify code rate limiting methods to EmailCache interface
      - Remove AllowUserRefund references (ent schema not present)
      - Fix duplicate import in payment_handler.go
      - Fix wire_gen.go argument mismatches
      d6965b06
    • erio's avatar
      test: add unit tests for billing, websearch, and notify systems · 9028d208
      erio authored
      Billing (25 tests):
      - CalculateCostUnified: nil resolver fallback, token/per_request/image modes
      - GetModelPricingWithChannel: nil/partial/full channel overrides
      - resolveAccountStatsCost: four-level priority chain integration tests
      
      WebSearch (18 tests):
      - PopulateWebSearchUsage: nil input, manager states, QuotaLimit nil/*int64
      - ResetWebSearchUsage: nil manager error
      - Manager.ResetUsage: nil Redis
      - shouldEmulateWebSearch: full decision chain (8 scenarios)
      
      Notify (36 tests):
      - ParseNotifyEmails/MarshalNotifyEmails: old/new format, roundtrip
      - crossedDownward: boundary values, threshold semantics
      - checkQuotaDimCrossings: mixed dimensions, disabled/zero skip
      9028d208
    • erio's avatar
      feat: websearch quota enhancements and balance notify hint · 7c729293
      erio authored
      - QuotaLimit changed to *int64 (null=unlimited, >0=limited)
      - Add reset-usage endpoint (POST /admin/settings/web-search-emulation/reset-usage)
      - Show quota usage in header always (collapsed and expanded)
      - Add reset quota button in expanded provider view
      - Quota input: empty=unlimited with ∞ placeholder, must be >0 if set
      - Add email verification hint on balance notify card
      7c729293
    • erio's avatar
      fix: gofmt formatting across all Go source files · 1e6912ea
      erio authored
      1e6912ea