Merge pull request #738 from DaydreamCoding/feat/ungrouped-key-setting

feat(gateway): 系统设置控制未分组 Key 调度 — Handler 层中间件拦截
This commit is contained in:
Wesley Liddick
2026-03-03 21:03:31 +08:00
committed by GitHub
13 changed files with 150 additions and 7 deletions

View File

@@ -201,6 +201,9 @@ const (
// SettingKeyMinClaudeCodeVersion 最低 Claude Code 版本号要求 (semver, 如 "2.1.0",空值=不检查)
SettingKeyMinClaudeCodeVersion = "min_claude_code_version"
// SettingKeyAllowUngroupedKeyScheduling 允许未分组 API Key 调度(默认 false未分组 Key 返回 403
SettingKeyAllowUngroupedKeyScheduling = "allow_ungrouped_key_scheduling"
)
// AdminAPIKeyPrefix is the prefix for admin API keys (distinct from user "sk-" keys).

View File

@@ -438,6 +438,9 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet
// Claude Code version check
updates[SettingKeyMinClaudeCodeVersion] = settings.MinClaudeCodeVersion
// 分组隔离
updates[SettingKeyAllowUngroupedKeyScheduling] = strconv.FormatBool(settings.AllowUngroupedKeyScheduling)
err = s.settingRepo.SetMultiple(ctx, updates)
if err == nil {
// 先使 inflight singleflight 失效,再刷新缓存,缩小旧值覆盖新值的竞态窗口
@@ -646,6 +649,9 @@ func (s *SettingService) InitializeDefaultSettings(ctx context.Context) error {
// Claude Code version check (default: empty = disabled)
SettingKeyMinClaudeCodeVersion: "",
// 分组隔离(默认不允许未分组 Key 调度)
SettingKeyAllowUngroupedKeyScheduling: "false",
}
return s.settingRepo.SetMultiple(ctx, defaults)
@@ -776,6 +782,9 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin
// Claude Code version check
result.MinClaudeCodeVersion = settings[SettingKeyMinClaudeCodeVersion]
// 分组隔离
result.AllowUngroupedKeyScheduling = settings[SettingKeyAllowUngroupedKeyScheduling] == "true"
return result
}
@@ -1098,6 +1107,15 @@ func (s *SettingService) GetStreamTimeoutSettings(ctx context.Context) (*StreamT
return &settings, nil
}
// IsUngroupedKeySchedulingAllowed 查询是否允许未分组 Key 调度
func (s *SettingService) IsUngroupedKeySchedulingAllowed(ctx context.Context) bool {
value, err := s.settingRepo.GetValue(ctx, SettingKeyAllowUngroupedKeyScheduling)
if err != nil {
return false // fail-closed: 查询失败时默认不允许
}
return value == "true"
}
// GetMinClaudeCodeVersion 获取最低 Claude Code 版本号要求
// 使用进程内 atomic.Value 缓存60 秒 TTL热路径零锁开销
// singleflight 防止缓存过期时 thundering herd

View File

@@ -65,6 +65,9 @@ type SystemSettings struct {
// Claude Code version check
MinClaudeCodeVersion string
// 分组隔离:允许未分组 Key 调度(默认 false → 403
AllowUngroupedKeyScheduling bool
}
type DefaultSubscriptionSetting struct {