Checkout page aggregates Stripe sub-types (card,link,alipay,wxpay) under
"stripe", but SelectInstance matched against supported_types literally,
which doesn't contain "stripe". Now matches by provider_key for Stripe.
- 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
The buttons were hidden because v-if only checked provider.api_key,
which is always empty for saved providers (backend sanitizes it).
Now also checks api_key_configured. Copy button is disabled when
no actual key is available (only configured placeholder shown).
- Add missing balanceNotifyService param to NewGatewayService in warmup test
- Fix config_test YAML path escaping on Windows (use filepath.ToSlash)
- Update pricingRequestToService test: empty platform no longer defaults
smtp.SendMail automatically upgrades to STARTTLS when the server
supports it. Our replacement sendMailPlain skipped this, causing
credentials to be sent in plaintext on port 587. Add STARTTLS
negotiation before Auth to restore the original security behavior.
- Skip websearch provider when ProxyID is set but proxy not found (prevent
silent direct connection bypass)
- Fix sortByStableRandomWeight: pair factors with items so sort.Slice swap
keeps weights aligned
- Allow empty platform in account_stats_pricing_rules (wildcard matching),
only force anthropic default for main model_pricing
- Add channel_account_stats_pricing_intervals table and repo layer support
for interval-based pricing in account stats rules
- calculateTokenStatsCost now uses interval pricing when available
- Replace smtp.SendMail/tls.Dial with net.Dialer timeout (10s dial, 20s IO)
to prevent goroutine leak on SMTP hang
- Fix gofmt formatting issues
- Web Search label: black text with red warning hint
- Fix web_search_emulation toggle: explicitly write false for disabled
platforms instead of leaving stale true from cloned features_config
- Extract validatePricingEntries from validateChannelConfig for reuse
- Validate account_stats_pricing_rules[].pricing in both Create and
Update paths (negative prices, bad intervals, missing per_request price)
- Fix websearch provider failover: proxy error from provider-specific proxy
now continues to next provider instead of aborting the entire loop
- Fix SMTP failure locking users out: send email first, then write cache
and increment rate counter
- Fix notify email cache key case sensitivity: normalize to lowercase
- Add OriginalPrice validation to validatePlanPatch and validatePlanRequired
- Add empty scope validation for channel pricing rules (group_ids/account_ids)
- Add platform color to account search dropdown in channel pricing rules
Legacy instances created the settings table via ent auto-migration,
which emits Go-level defaults only. Migration 005 uses CREATE TABLE
IF NOT EXISTS, so the missing SQL DEFAULT was never backfilled. This
caused 098's raw INSERT to fail with a NOT NULL violation on
updated_at. The new migration is idempotent and safe for fresh
installs (no-op) and historical instances (backfills the default).
M6: New applyAccountStatsCost() helper in account_stats_pricing.go replaces
identical upstream-model-fallback + resolveAccountStatsCost() call sites
in both gateway_service.go and openai_gateway_service.go
M11: postUsageBilling legacy path no longer calls finalizePostUsageBilling,
fixing the double-queue bug (QueueDeductBalance was called twice if the
fallback path was ever reached). Added NOTE comment documenting the split.
- Limit input and notify threshold now share flex-1 equally (was w-28 fixed)
- Reset schedule hint text moved inline after the selectors (same row)
- Timezone dropdown shows GMT offset, e.g. "Asia/Shanghai (GMT+8)"
In "custom account stats pricing rule" section, group checkbox labels and
selected account chips now use the platform text color (matching the top
"associated groups" header), making it visually consistent across the modal.
- EditAccountModal width changed from "normal" to "wide" (match CreateAccountModal)
- CreateAccountModal now passes all quota notify props to QuotaLimitCard
- QuotaLimitCard: when global notify disabled, hide title row, input takes full width
- Quota alert email: show remaining quota + threshold (fixed/$, percentage/%) instead of usage trigger point
- Add BalanceLowNotifyRechargeURL to admin PUT response (fixes save-then-stale)
- Add ?? 1 guard for account_rate_multiplier in UsageTable else branch
- Downgrade high-frequency notify logs from Info to Debug
- Extract "Sub2API" magic string to defaultSiteName constant
- Quota alert email now shows account ID and platform
- Balance low email includes a "Top Up Now" button when recharge URL is configured
- New setting: balance_low_notify_recharge_url in admin settings
- Fix toFixed crash when price is undefined
- Remove sort_order field, order by created_at instead
- Fix group selector showing blank when nothing selected
- Add required field markers (*) and backend validation
- Add i18n groupRequired key for both zh/en