feat: websearch quota enhancements and balance notify hint
- QuotaLimit changed to *int64 (null=unlimited, >0=limited) - Add reset-usage endpoint (POST /admin/settings/web-search-emulation/reset-usage) - Show quota usage in header always (collapsed and expanded) - Add reset quota button in expanded provider view - Quota input: empty=unlimited with ∞ placeholder, must be >0 if set - Add email verification hint on balance notify card
This commit is contained in:
@@ -24,7 +24,7 @@ type WebSearchProviderConfig struct {
|
||||
Type string `json:"type"` // websearch.ProviderTypeBrave | Tavily
|
||||
APIKey string `json:"api_key,omitempty"` // secret — omitted in API responses
|
||||
APIKeyConfigured bool `json:"api_key_configured"` // read-only mask
|
||||
QuotaLimit int64 `json:"quota_limit"` // 0 = unlimited
|
||||
QuotaLimit *int64 `json:"quota_limit"` // nil = unlimited, >0 = limited
|
||||
SubscribedAt *int64 `json:"subscribed_at,omitempty"` // subscription start (unix seconds); quota resets monthly
|
||||
QuotaUsed int64 `json:"quota_used,omitempty"` // read-only: current usage from Redis
|
||||
ProxyID *int64 `json:"proxy_id"` // optional proxy association
|
||||
@@ -52,8 +52,8 @@ func validateWebSearchConfig(cfg *WebSearchEmulationConfig) error {
|
||||
if !validProviderTypes[p.Type] {
|
||||
return fmt.Errorf("provider[%d]: invalid type %q", i, p.Type)
|
||||
}
|
||||
if p.QuotaLimit < 0 {
|
||||
return fmt.Errorf("provider[%d]: quota_limit must be >= 0", i)
|
||||
if p.QuotaLimit != nil && *p.QuotaLimit < 0 {
|
||||
return fmt.Errorf("provider[%d]: quota_limit must be > 0 or null", i)
|
||||
}
|
||||
if seen[p.Type] {
|
||||
return fmt.Errorf("provider[%d]: duplicate type %q", i, p.Type)
|
||||
@@ -299,6 +299,15 @@ func PopulateWebSearchUsage(ctx context.Context, cfg *WebSearchEmulationConfig)
|
||||
return &out
|
||||
}
|
||||
|
||||
// ResetWebSearchUsage deletes the Redis quota key for the given provider type.
|
||||
func ResetWebSearchUsage(ctx context.Context, providerType string) error {
|
||||
mgr := getWebSearchManager()
|
||||
if mgr == nil {
|
||||
return fmt.Errorf("web search manager not initialized")
|
||||
}
|
||||
return mgr.ResetUsage(ctx, providerType)
|
||||
}
|
||||
|
||||
// SanitizeWebSearchConfig returns a copy with api_key fields masked and quota usage populated.
|
||||
func SanitizeWebSearchConfig(ctx context.Context, cfg *WebSearchEmulationConfig) *WebSearchEmulationConfig {
|
||||
if cfg == nil {
|
||||
|
||||
Reference in New Issue
Block a user