- 14 Apr, 2026 29 commits
-
-
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
-
erio authored
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).
-
erio authored
M5: New composable frontend/src/composables/useQuotaNotifyState.ts - Replaces 9 individual refs in both Create/Edit modals with reactive state - Provides loadFromExtra/writeToExtra/reset helpers - Eliminates ~120 lines of duplicated code across the two modals H14: Vue file length violations fixed - AdminPaymentPlansView.vue: 325 → 183 lines (extracted PlanEditDialog.vue) - QuotaLimitCard.vue: 327 → 268 lines (extracted QuotaDimensionRow.vue) - PlanEditDialog.vue: 181 lines (new, plan create/edit form) - QuotaDimensionRow.vue: 108 lines (new, single quota dimension row)
-
erio authored
refactor: batch 3 — decompose CheckBalanceAfterDeduction, merge crossing checks, add QuotaNotifyConfig M1: CheckBalanceAfterDeduction (63→18 lines) decomposed into: canNotifyBalance, resolveUserEffectiveThreshold, crossedDownward, dispatchBalanceLowEmail M3: New Account.QuotaNotifyConfig(dim) method replaces 9 hardcoded getters (getters kept as thin wrappers for backward compatibility) M4: checkQuotaDimCrossings + checkQuotaDimCrossingsFromState merged into one function taking pre-built []quotaDim; caller builds dims conditionally -
erio authored
H5: diffSettings now tracks 5 balance/quota notify fields in audit log M15: log.Printf audit log migrated to slog.Info, removed "log" import M14: New frontend/src/constants/account.ts with shared constants QuotaNotifyToggle.vue uses QUOTA_THRESHOLD_TYPE_FIXED/PERCENTAGE L2: UsageTable.vue uses BILLING_MODE_TOKEN/IMAGE from billingMode.ts -
erio authored
fix: batch 1 audit fixes — quota SQL fixed mode, public recharge URL, WebSearch bool fallback, UpdatePlan validation H1: incrementUsageBillingAccountQuota now uses shared dailyExpiredExpr/weeklyExpiredExpr constants (supporting fixed reset mode) instead of hardcoded '24 hours'/'168 hours' H4: public settings endpoint now maps balance_low_notify_recharge_url H6: GetWebSearchEmulationMode tolerates legacy bool values (true→enabled) H7: UpdatePlan validates non-nil patch fields (rejects negative price, empty name, etc.) H8: UsageTable accountBilled() helper with total_cost ?? 0 null guard H9: AdminUsageLog TS type adds channel_id + billing_tier M2: account.go "fixed" literals replaced with thresholdTypeFixed constant M13: SystemSettings TS type adds web_search_emulation_enabled UI: QuotaLimitCard title labels now use flex-1 to align with flex-1 input boxes -
erio authored
- 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
-
erio authored
-
erio authored
-
erio authored
-
erio authored
- 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
-
erio authored
-
erio authored
Threshold now represents remaining quota instead of usage amount: - Fixed ($): threshold=400, limit=1000 → alert when remaining drops to $400 (i.e., usage reaches $600) - Percentage (%): threshold=30%, limit=1000 → alert when remaining drops to 30% (i.e., usage reaches $700) Also: - Rename 告警阈值 → 提醒阈值 in i18n - Widen type dropdown to w-16 for proper $ / % display
-
erio authored
Move QuotaNotifyToggle to the same row as the limit $ input for all three dimensions (daily/weekly/total), significantly reducing card height.
-
erio authored
- QuotaLimitCard: add collapse/expand toggle (chevron icon + click header) - QuotaNotifyToggle: show $ or % suffix in threshold input - Reduce vertical spacing between reset mode hint and notify toggle
-
erio authored
- QuotaNotifyToggle: add $ or % suffix to threshold input based on type - QuotaLimitCard: combine reset mode and notify toggle on same row to reduce vertical height for daily/weekly sections - Remove redundant ml-4 indentation from QuotaNotifyToggle
-
erio authored
Priority was wrong: - Before: custom rules → LiteLLM (when ApplyPricingToAccountStats) → nil - After: custom rules → totalCost (when ApplyPricingToAccountStats) → LiteLLM → nil When ApplyPricingToAccountStats is enabled, use the request's actual client billing cost (before multiplier) as account_stats_cost, instead of recalculating from LiteLLM per-token prices which produced incorrect values for per-request billing mode. LiteLLM model pricing is now the final fallback (priority 3), used only when neither custom rules nor ApplyPricingToAccountStats apply.
-
erio authored
The field was present in SystemSettings response DTO and service layer but missing from: - UpdateSettingsRequest (admin handler) - saves were silently ignored - GET/PUT response mapping in admin handler - UpdateSettingsRequest (non-admin dto) This caused the toggle to always revert to off after saving.
-
erio authored
QuotaLimitCard now requires quotaNotifyGlobalEnabled prop to control visibility of QuotaNotifyToggle components. When the global account quota notification is disabled in admin settings, per-account threshold toggles are hidden in both Edit and Create account modals.
-
erio authored
- Move sanitizeEmailHeader to SendEmailWithConfig entry point, covering all email senders (verify code, password reset, ops alerts, notifications) - Add panic recovery to UpdateBalance goroutine - Fix stale comment in getAccountQuotaNotifyEmails (email="" no longer used) - Log error instead of silently discarding verifyNotifyCode cache update failure
-
erio authored
P0: fix wildcard matching test assertion (config order, not longest prefix) P0: add TotalRecharged to auth cache snapshot (v5) for percentage threshold P1: move pricing rules into per-platform sections in ChannelsView P1: populate account name cache when editing existing channel rules P1: sanitize email subject headers to prevent SMTP injection P1: make Redis INCR+EXPIRE idempotent for rate limiting P1: deep copy FeaturesConfig in Channel.Clone() P2: clean up stale email="" placeholder comments P2: replace log.Printf with slog in email_service.go
-
erio authored
WebSearch tri-state switch: - Account-level web_search_emulation changed from bool to tri-state string: "default" (follow channel) / "enabled" / "disabled" - shouldEmulateWebSearch checks channel config when account is "default" - SQL migration converts old bool values - Frontend select replaces toggle in Edit/CreateAccountModal Account stats pricing: - resolveAccountStatsCost uses upstream model (post-mapping) for matching - Priority: custom rules → model pricing file (when toggle on) → default - Custom rules always configurable, independent of toggle - Account ID field changed to searchable selector filtered by platform - Description updated to reflect new behavior Quota notification cache fix: - CheckAccountQuotaAfterIncrement fetches real-time account from DB - Reconstructs pre-increment usage for accurate threshold crossing detection - New AccountQuotaReader interface (minimal: GetByID only) Usage tooltip: - Per-request/image billing shows per-request price instead of $0 token price - Token billing continues to show input/output price per million tokens
-
erio authored
- API Key show/copy buttons moved inside input field (inline icons) - Proxy selector and test button on same row to save vertical space - Test opens a dialog modal instead of inline display - Hide all websearch config in channels/accounts when global toggle is off
-
erio authored
- Fix GetByKeyForAuth not selecting balance notify fields (notifications never triggered in gateway path) - Fix provider-level ProxyURL never resolved: inject ProxyRepository into SettingService, resolve proxy URLs when building Manager - Fix admin manual balance adjustment not updating total_recharged - Add threshold_type input validation (reject invalid values) - Fix user threshold_type inheritance: custom threshold defaults to "fixed" instead of inheriting global type (prevents $5 being treated as 5%) - Add try-catch for clipboard.writeText (fails on non-HTTPS) - Add SetTotalRecharged to user Update for admin balance operations
-
erio authored
- User balance low notification: email alert when balance drops below configurable threshold (user email + verified extra emails) - Account quota notification: broadcast email to admin-configured recipients when daily/weekly/total quota usage exceeds alert threshold - Admin settings: global enable/disable, default threshold, quota notification email list (Email Settings tab) - User profile: enable/disable, custom threshold, add/remove extra notification emails with verification code flow - Account quota: per-dimension alert toggle and threshold in quota control card - Trigger logic: first-crossing only (old >= threshold && new < threshold for balance; old < threshold && new >= threshold for quota), naturally prevents duplicate notifications without Redis dedup
-
erio authored
Backend: - Define OrderTypeBalance/Subscription, EntityStatusActive, DeductionType*, NotificationStatus* constants in payment/types.go - Replace all magic strings in payment_order, payment_fulfillment, payment_refund - Add local constants in easypay.go (tradeStatusSuccess, signTypeMD5) - Add 27 unit tests for load balancer (filterByLimits, pickLeastAmount, getInstanceChannelLimits, startOfDay) Frontend: - Remove all `any` types in SettingsView.vue (18 catch blocks + 1 payload) - Fix bare catch blocks in PaymentResultView, PaymentView - Add `unknown` type annotation to all catch blocks chore: bump version to 0.1.108.140
-
erio authored
Backend: - Extract YuanToFen/FenToYuan to payment/amount.go using shopspring/decimal - Require alipay publicKey in config validation - Fix wxpay webhook response to return JSON per V3 spec - Remove wxpay certSerial fallback to publicKeyId - Define magic strings as named constants in wxpay/alipay providers - Add slog warning for wxpay H5→Native payment downgrade - Make EncryptionKey validation return error on invalid (non-empty) key - Make decryptConfig propagate errors instead of returning nil - Add idempotency check in doBalance to prevent stuck FAILED retries Frontend: - Fix dashboard currency symbol from $ to ¥ - Fix AdminPaymentPlansView any type to proper SubscriptionPlan type - Make quick amount buttons follow selected payment method limits - Center help image with larger height and text below
-
erio authored
The paginated List query was selecting 9 columns but scanning 10 fields, missing c.features. GetByID and ListAll already included it correctly.
-
erio authored
-
- 13 Apr, 2026 1 commit
-
-
github-actions[bot] authored
-
- 12 Apr, 2026 1 commit
-
-
github-actions[bot] authored
-
- 11 Apr, 2026 2 commits
-
-
erio authored
Upstream removed sora feature (090_drop_sora.sql) but left i18n keys and wire.go references. Clean up: - Remove entire sora i18n block from en.ts and zh.ts (~190 lines) - Remove sora nav key and unused 'data' settings tab key - Remove sora_client_enabled from settings (fork-specific) - Remove SoraMediaCleanupService from wire.go
-
erio authored
Add a full payment and subscription system supporting EasyPay (Alipay/WeChat), Stripe, and direct Alipay/WeChat Pay providers with multi-instance load balancing.
-
- 08 Apr, 2026 2 commits
-
-
ius authored
-
github-actions[bot] authored
-
- 07 Apr, 2026 1 commit
-
-
github-actions[bot] authored
-
- 05 Apr, 2026 4 commits
-
-
github-actions[bot] authored
-
erio authored
-
erio authored
-
github-actions[bot] authored
-