fix: resolve 5 audit findings in channel/credits/scheduling

P0-1: Credits degraded response retry + fail-open
- Add isAntigravityDegradedResponse() to detect transient API failures
- Retry up to 3 times with exponential backoff (500ms/1s/2s)
- Invalidate singleflight cache between retries
- Fail-open after exhausting retries instead of 5h circuit break

P1-1: Fix channel restriction pre-check timing conflict
- Swap checkClaudeCodeRestriction before checkChannelPricingRestriction
- Ensures channel restriction is checked against final fallback groupID

P1-2: Add interval pricing validation (frontend + backend)
- Backend: ValidateIntervals() with boundary, price, overlap checks
- Frontend: validateIntervals() with Chinese error messages
- Rules: MinTokens>=0, MaxTokens>MinTokens, prices>=0, no overlap

P2: Fix cross-platform same-model pricing/mapping override
- Store cache keys using original platform instead of group platform
- Lookup across matching platforms (antigravity→anthropic→gemini)
- Prevents anthropic/gemini same-name models from overwriting each other
This commit is contained in:
erio
2026-04-02 20:28:04 +08:00
parent 6d3ea64a35
commit 71f61bbc47
12 changed files with 1028 additions and 48 deletions

View File

@@ -855,6 +855,13 @@ func (s *AccountUsageService) GetAntigravityCredits(ctx context.Context, account
return s.getAntigravityUsage(ctx, account)
}
// InvalidateAntigravityCreditsCache 清除指定账号的 Antigravity 用量缓存,
// 使下次调用 GetAntigravityCredits 时强制重新拉取。
// 用于 credits 降级响应重试场景:避免重试命中同一个降级缓存。
func (s *AccountUsageService) InvalidateAntigravityCreditsCache(accountID int64) {
s.cache.antigravityCache.Delete(accountID)
}
// recalcAntigravityRemainingSeconds 重新计算 Antigravity UsageInfo 中各窗口的 RemainingSeconds
// 用于从缓存取出时更新倒计时,避免返回过时的剩余秒数
func recalcAntigravityRemainingSeconds(info *UsageInfo) {