- Create model/errors.go to centralize all sentinel errors
- ValidateAccessToken now returns error to distinguish DB failures
- ValidateUserToken uses unified ErrTokenInvalid for all auth failures
(expired/exhausted/disabled/not-found) to prevent token enumeration
- authHelper and TokenAuthReadOnly use i18n messages instead of
hardcoded Chinese strings
- All err.Error() removed from user-facing responses; DB errors logged
server-side and return generic "contact admin" message (HTTP 500)
- Migrate ErrRedeemFailed, ErrTwoFANotEnabled to model/errors.go
ValidateAndFill now checks the DB query result and returns sentinel errors
(ErrDatabase, ErrInvalidCredentials, ErrUserEmptyCredentials) instead of
hardcoded Chinese strings. The controller maps each sentinel to the
appropriate i18n message, so users see "please contact admin" on DB errors
instead of a misleading "wrong password" message. Non-DB errors still
return a unified vague response to avoid leaking user existence.
- Backend: differentiate error messages for admin vs regular users in price.go
- Backend: include error_code in channel test response for structured error handling
- Frontend: render model_price_error as a styled card in Playground with admin nav button
- Frontend: show inline error details and settings link in channel test modal
- Frontend: parse error codes from both SSE and non-streaming API responses
- i18n: remove redundant "Settings" suffix from setting tab translations (en/fr/ru/ja/vi)
- i18n: update "Group & Model Pricing" translations across all locales
- Refactor token, redemption, and user quota inputs to prioritize monetary
amount entry, with raw quota input collapsed by default
- Add atomic quota adjustment modal for users with add/subtract/override modes,
bypassing batch update queue for immediate DB consistency
- Make user quota fields readonly in edit form; all modifications go through
the dedicated adjust-quota modal via POST /api/user/manage
- Add DecreaseUserQuota `db` parameter for direct DB writes, matching
IncreaseUserQuota behavior
- Support negative quota display in amount conversion helpers
- Add i18n keys for all new UI strings across all locales
Rewrite GroupGroupRatioRules and GroupSpecialUsableRules to group rules
by user group in collapsible sections instead of a flat table. Default
collapsed to reduce visual clutter when many rules exist. Fix i18n
translations for ja, zh-TW with proper native text; add missing keys.
- Add GET /api/data/users endpoint for user-grouped quota data (admin only)
- Add user consumption ranking (horizontal bar, top 10) and user consumption
trend (area chart) tabs visible only to admin users
- Fix mislabeled "消耗趋势" tab to "调用趋势" (shows call counts, not quota)
- Add processUserData helper for user ranking and trend data extraction
- Add i18n keys for new tabs across all 7 locales
- Replaced ModelRatioSettings with ModelPricingCombined in the RatioSetting component.
- Updated tab structure to prioritize pricing settings over model settings.
- Removed unused imports for ModelRatioSettings and ModelSettingsVisualEditor.
Add new endpoint POST /api/token/batch/keys to fetch multiple
token keys in a single request, improving performance when
exporting or copying multiple tokens.
- Backend: Add GetTokenKeysBatch controller and GetTokenKeysByIds model
- Backend: Add route with CriticalRateLimit and DisableCache middleware
- Frontend: Add fetchTokenKeysBatch helper function
- Frontend: Update useTokensData to use batch API for token export
- Added `EstimateBilling` function to check for video input in request metadata and return corresponding discount ratios.
- Updated `ModelPriceHelperPerCall` to incorporate new pricing logic based on model ratios and video input.
- Enhanced task billing logs to include model ratio information and adjusted calculations for actual quota based on additional multipliers.
- Introduced `renderTaskBillingProcess` to improve rendering of task billing information in the UI.
- Deleted the `playgroundMaxTokens` helper functions and their associated tests.
- Updated `loadConfig` and `usePlaygroundState` to handle `max_tokens` directly without sanitization.
- Simplified input handling in `usePlaygroundState` to directly set values without normalization.
- Introduced `sanitizePlaygroundInputs` to normalize `max_tokens` input values.
- Updated `loadConfig` to utilize the new sanitization function.
- Replaced `Input` with `InputNumber` for `max_tokens` in `ParameterControl` for better user experience.
- Modified API payload building logic to handle `max_tokens` more robustly.
- Added tests for new helper functions in `playgroundMaxTokens.js` to ensure correct behavior.