fix(brand-questions): surface seed topic min length as actionable error

Reject AI seed topics shorter than 2 characters on both client and server with
a dedicated invalid_seed_topic error code, and render an inline hint listing
the offending terms so users know exactly what to fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 10:18:28 +08:00
parent 7d8e82c69f
commit 2c4f7d6fcf
6 changed files with 112 additions and 2 deletions
@@ -218,7 +218,7 @@ func (s *QuestionExpansionService) GenerateByAIDistill(ctx context.Context, bran
actor := auth.MustActor(ctx)
seedTopic := normalizeQuestionText(req.SeedTopic)
if utf8.RuneCountInString(seedTopic) < 2 {
return nil, response.ErrBadRequest(40091, "invalid_params", "seed_topic is required")
return nil, response.ErrBadRequest(40091, "invalid_seed_topic", "seed_topic must contain at least 2 characters")
}
brandCtx, err := s.loadQuestionBrandContext(ctx, actor.TenantID, brandID)
@@ -2,6 +2,7 @@ package transport
import (
"strconv"
"strings"
"github.com/gin-gonic/gin"
@@ -61,6 +62,10 @@ func (h *QuestionExpansionHandler) AIDistill(c *gin.Context) {
}
var req app.QuestionDistillRequest
if err := c.ShouldBindJSON(&req); err != nil {
if isInvalidSeedTopicBindError(err) {
response.Error(c, response.ErrBadRequest(40091, "invalid_seed_topic", "seed_topic must contain at least 2 characters"))
return
}
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
return
}
@@ -118,3 +123,12 @@ func parseBrandIDParam(c *gin.Context) (int64, bool) {
}
return brandID, true
}
func isInvalidSeedTopicBindError(err error) bool {
if err == nil {
return false
}
message := err.Error()
return strings.Contains(message, "QuestionDistillRequest.SeedTopic") ||
strings.Contains(message, "seed_topic")
}