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:
erio
2026-04-14 08:03:27 +08:00
parent 1e6912ea2e
commit 7c7292935e
12 changed files with 121 additions and 28 deletions

View File

@@ -17,8 +17,8 @@ func TestValidateWebSearchConfig_Valid(t *testing.T) {
cfg := &WebSearchEmulationConfig{
Enabled: true,
Providers: []WebSearchProviderConfig{
{Type: "brave", QuotaLimit: 1000},
{Type: "tavily", QuotaLimit: 500},
{Type: "brave", QuotaLimit: int64Ptr(1000)},
{Type: "tavily", QuotaLimit: int64Ptr(500)},
},
}
require.NoError(t, validateWebSearchConfig(cfg))
@@ -42,9 +42,9 @@ func TestValidateWebSearchConfig_InvalidType(t *testing.T) {
func TestValidateWebSearchConfig_NegativeQuotaLimit(t *testing.T) {
cfg := &WebSearchEmulationConfig{
Providers: []WebSearchProviderConfig{{Type: "brave", QuotaLimit: -1}},
Providers: []WebSearchProviderConfig{{Type: "brave", QuotaLimit: int64Ptr(-1)}},
}
require.ErrorContains(t, validateWebSearchConfig(cfg), "quota_limit must be >= 0")
require.ErrorContains(t, validateWebSearchConfig(cfg), "quota_limit must be > 0 or null")
}
func TestValidateWebSearchConfig_DuplicateType(t *testing.T) {
@@ -57,9 +57,9 @@ func TestValidateWebSearchConfig_DuplicateType(t *testing.T) {
require.ErrorContains(t, validateWebSearchConfig(cfg), "duplicate type")
}
func TestValidateWebSearchConfig_ZeroQuotaLimit(t *testing.T) {
func TestValidateWebSearchConfig_NilQuotaLimit(t *testing.T) {
cfg := &WebSearchEmulationConfig{
Providers: []WebSearchProviderConfig{{Type: "brave", QuotaLimit: 0}},
Providers: []WebSearchProviderConfig{{Type: "brave", QuotaLimit: nil}},
}
require.NoError(t, validateWebSearchConfig(cfg))
}
@@ -92,7 +92,7 @@ func TestParseWebSearchConfigJSON_BackwardCompatibility(t *testing.T) {
cfg := parseWebSearchConfigJSON(raw)
require.True(t, cfg.Enabled)
require.Len(t, cfg.Providers, 1)
require.Equal(t, int64(1000), cfg.Providers[0].QuotaLimit)
require.Equal(t, int64(1000), *cfg.Providers[0].QuotaLimit)
}
// --- SanitizeWebSearchConfig ---
@@ -126,12 +126,12 @@ func TestSanitizeWebSearchConfig_PreservesOtherFields(t *testing.T) {
cfg := &WebSearchEmulationConfig{
Enabled: true,
Providers: []WebSearchProviderConfig{
{Type: "brave", APIKey: "secret", QuotaLimit: 1000},
{Type: "brave", APIKey: "secret", QuotaLimit: int64Ptr(1000)},
},
}
out := SanitizeWebSearchConfig(context.Background(), cfg)
require.True(t, out.Enabled)
require.Equal(t, int64(1000), out.Providers[0].QuotaLimit)
require.Equal(t, int64(1000), *out.Providers[0].QuotaLimit)
}
func TestSanitizeWebSearchConfig_DoesNotMutateOriginal(t *testing.T) {