feat(antigravity): add 403 forbidden status detection, classification and display

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
This commit is contained in:
erio
2026-03-13 00:10:01 +08:00
parent 1ee984478f
commit 6344fa2a86
11 changed files with 1113 additions and 50 deletions

View File

@@ -1980,6 +1980,15 @@ export default {
},
ineligibleWarning:
'该账号无 Antigravity 使用权限,但仍能进行 API 转发。继续使用请自行承担风险。',
forbidden: '已封禁',
forbiddenValidation: '需要验证',
forbiddenViolation: '违规封禁',
openVerification: '打开验证链接',
copyLink: '复制链接',
linkCopied: '链接已复制',
needsReauth: '需要重新授权',
rateLimited: '限流中',
usageError: '获取失败',
form: {
nameLabel: '账号名称',
namePlaceholder: '请输入账号名称',