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.
ClosesWei-Shaw/sub2api#1021
Add dailyResetMode, dailyResetHour, weeklyResetMode, weeklyResetDay,
weeklyResetHour, and resetTimezone bindings to the apikey/bedrock
QuotaLimitCard instances in CreateAccountModal and EditAccountModal.
Consolidate two separate channel types (bedrock + bedrock-apikey) into
a single "AWS Bedrock" channel. Authentication mode is now distinguished
by credentials.auth_mode ("sigv4" | "apikey") instead of separate types.
Backend:
- Remove AccountTypeBedrockAPIKey constant
- IsBedrock() simplified; IsBedrockAPIKey() checks auth_mode
- Add IsAPIKeyOrBedrock() helper to eliminate repeated type checks
- Extend pool mode, quota scheduling, and billing to bedrock
- Add RetryableOnSameAccount to handleBedrockUpstreamErrors
- Add "bedrock" scope to Beta Policy for independent control
Frontend:
- Merge two buttons into one "AWS Bedrock" with auth mode radio
- Badge displays "Anthropic | AWS"
- Pool mode and quota limit UI available for bedrock
- Quota display in account list (usage bars, capacity badges, reset)
- Remove all bedrock-apikey type references
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
Add a dedicated modal in group management for viewing, adding, editing,
and deleting per-user rate multipliers within a group.
Backend:
- GET /admin/groups/:id/rate-multipliers - list entries with user details
- PUT /admin/groups/:id/rate-multipliers - batch sync (full replace)
- DELETE /admin/groups/:id/rate-multipliers - clear all entries
- Repository: GetByGroupID, SyncGroupRateMultipliers methods on
user_group_rate_multipliers table (same table as user-side rates)
Frontend:
- New GroupRateMultipliersModal component with:
- User search and add with email autocomplete
- Editable rate column with local edit mode (cancel/save)
- Batch adjust: multiply all rates by a factor
- Clear all (local operation, requires save to persist)
- Pagination (10/20/50 per page)
- Platform icon with brand colors in group info bar
- Unsaved changes indicator with revert option
- Unit tests for all three backend endpoints
- Always show close button at bottom
- Add "revert changes" link when dirty
- Save now closes dialog on success
- Button styles match group edit dialog
chore: bump version to 0.1.96.8
Recovers features lost during 0.1.91->0.1.95 merge (0.1.92-0.1.94
customizations were skipped because main branch was not updated).
Recovered features:
- Antigravity 403 forbidden/validation/ban status detection and display
- Subscription tier badge in account list
- Client affinity scheduling for Anthropic accounts
- Sora async task API and GDrive storage backend
- Swipe-to-select for admin tables
- OpenAI passthrough account selection fix
- Various quota and usage enhancements
- Rate column is now editable input (local state, not auto-saved)
- Add/delete/clear-all are local operations until Save is clicked
- Batch adjust shows "最终倍率" preview column before applying
- Bottom cancel/save bar appears when there are unsaved changes
- Save sends all entries at once via batch API
- Move clear-all button next to add button
- Always show pagination bar (not hidden when entries <= pageSize)
- Change page size options to 10/20/50, default 10
- Move email column to first position
- Add sticky table header with scrollable body
- Add page size selector (20/50/100)
- Use ConfirmDialog for clear all confirmation
- Disable browser autocomplete on inputs
- Enlarge clear all button styling
- Widen modal to 'wide' size for table layout
- Separate columns: ID, username, email, notes, status, rate
- Use standard Pagination component for consistent style
- Add user_notes and user_status to backend GroupRateMultiplierEntry
- Add unit tests for GetGroupRateMultipliers and ClearGroupRateMultipliers
- Allow duplicate user add (overwrites existing rate)
Remove duplicate handleResetQuota, dead reset-status/clear-rate-limit
event bindings (no buttons emit these events - upstream unified into
recover-state). Keep isRateLimited customization in hasRecoverableState.
Add a system-wide "Backend Mode" that disables user self-registration
and self-service while keeping admin panel and API gateway fully
functional. When enabled, only admin can log in; all user-facing
routes return 403.
Backend:
- New setting key `backend_mode_enabled` with atomic cached reads (60s TTL)
- BackendModeUserGuard middleware blocks non-admin authenticated routes
- BackendModeAuthGuard middleware blocks registration/password-reset auth routes
- Login/Login2FA/RefreshToken handlers reject non-admin when enabled
- TokenPairWithUser struct for role-aware token refresh
- 20 unit tests (middleware + service layer)
Frontend:
- Router guards redirect unauthenticated users to /login
- Admin toggle in Settings page
- Login page hides register link and footer in backend mode
- 9 unit tests for router guard logic
- i18n support (en/zh)
27 files changed, 833 insertions(+), 17 deletions(-)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>