feat: add brand library management features

- Introduced BrandLibrarySummary type to encapsulate brand library limits and usage.
- Updated Brand interface to include keyword_count and question_count fields.
- Implemented brand library limits in the backend, including max brands, keywords, and questions per keyword.
- Added API endpoint to retrieve brand library summary.
- Enhanced BrandsView.vue to display brand library usage and limits.
- Implemented computed properties to manage brand, keyword, and question limits in the UI.
- Updated mutation handlers to invalidate relevant queries upon creating/updating brands, keywords, and questions.
- Added visual indicators for brand, keyword, and question limits in the UI.
- Enhanced error handling for exceeding brand and keyword limits during creation.
This commit is contained in:
2026-04-16 21:01:40 +08:00
parent 27389164b0
commit 41f3060e00
15 changed files with 731 additions and 44 deletions
@@ -89,6 +89,30 @@ retrieval:
}
}
func TestLoadAppliesBrandLibraryDefaults(t *testing.T) {
configPath := writeTestConfig(t, `
brand_library: {}
`)
cfg, err := Load(configPath)
if err != nil {
t.Fatalf("Load() error = %v", err)
}
if cfg.BrandLibrary.FreeBrandLimit != 1 {
t.Fatalf("expected default free brand limit 1, got %d", cfg.BrandLibrary.FreeBrandLimit)
}
if cfg.BrandLibrary.PaidBrandLimit != 2 {
t.Fatalf("expected default paid brand limit 2, got %d", cfg.BrandLibrary.PaidBrandLimit)
}
if cfg.BrandLibrary.MaxKeywords != 5 {
t.Fatalf("expected default max keywords 5, got %d", cfg.BrandLibrary.MaxKeywords)
}
if cfg.BrandLibrary.MaxQuestionsPerKeyword != 5 {
t.Fatalf("expected default max questions per keyword 5, got %d", cfg.BrandLibrary.MaxQuestionsPerKeyword)
}
}
func writeTestConfig(t *testing.T, body string) string {
t.Helper()