package support import "errors" var ( ErrNotFound = errors.New("ticket not found") ErrSubjectRequired = errors.New("subject required") ErrBodyRequired = errors.New("message body required") ErrInvalidCategory = errors.New("invalid category") ErrInvalidStatus = errors.New("invalid status") ErrInvalidPriority = errors.New("invalid priority") ErrInvalidTag = errors.New("invalid tag") ErrTooManyTags = errors.New("too many tags") ErrInvalidRelatedSKU = errors.New("invalid related_sku") ErrInvalidRelatedProduct = errors.New("invalid related_product_id") ErrTicketClosed = errors.New("ticket is closed") ErrForbidden = errors.New("forbidden") ErrAlreadyClaimed = errors.New("already_claimed") ErrNotClaimable = errors.New("not_claimable") ErrInvalidScope = errors.New("invalid scope") ErrInvalidAssignee = errors.New("invalid assignee") ErrNotificationGone = errors.New("notification not found") ErrAIAutoReplyDisabled = errors.New("support AI auto-reply is disabled") ErrAutoReplyDisabled = errors.New("auto-reply disabled for ticket") ErrAutoReplyAlreadyPosted = errors.New("auto-reply already posted") ErrAIRateLimited = errors.New("support AI auto-reply rate limited") ErrAIAutoReplyTimeout = errors.New("support AI auto-reply timed out") ErrNoAIDraft = errors.New("no AI draft to approve") ErrCSATNotEligible = errors.New("ticket not eligible for rating") ErrAlreadyRated = errors.New("ticket already rated") ErrInvalidCSATScore = errors.New("invalid csat score") ErrInvalidScore = ErrInvalidCSATScore ErrCSATCommentTooLong = errors.New("csat comment too long") ErrKBSlugRequired = errors.New("kb slug required") ErrInvalidKBSlug = errors.New("invalid kb slug") ErrKBTitleRequired = errors.New("kb title required") ErrKBBodyRequired = errors.New("kb body required") ErrKBNotFound = errors.New("kb article not found") ErrKBSlugTaken = errors.New("kb slug taken") ErrTemplateNameRequired = errors.New("template name required") ErrTemplateBodyRequired = errors.New("template body required") ErrTemplateNotFound = errors.New("reply template not found") ErrInvalidMatchThreshold = errors.New("invalid match confidence threshold") ErrInvalidAIThreshold = errors.New("invalid AI confidence threshold") ErrInvalidAIDelivery = errors.New("invalid AI delivery mode") ) // ClientError reports whether err is a known client-facing support validation error. func ClientError(err error) (msg string, ok bool) { switch { case err == nil: return "", false case errors.Is(err, ErrSubjectRequired), errors.Is(err, ErrBodyRequired), errors.Is(err, ErrInvalidCategory), errors.Is(err, ErrInvalidStatus), errors.Is(err, ErrInvalidPriority), errors.Is(err, ErrInvalidTag), errors.Is(err, ErrTooManyTags), errors.Is(err, ErrInvalidRelatedSKU), errors.Is(err, ErrInvalidRelatedProduct), errors.Is(err, ErrNoAIDraft), errors.Is(err, ErrTicketClosed), errors.Is(err, ErrForbidden), errors.Is(err, ErrInvalidAssignee), errors.Is(err, ErrAlreadyClaimed), errors.Is(err, ErrNotClaimable), errors.Is(err, ErrInvalidScope), errors.Is(err, ErrInvalidCSATScore), errors.Is(err, ErrCSATNotEligible), errors.Is(err, ErrAlreadyRated), errors.Is(err, ErrCSATCommentTooLong), errors.Is(err, ErrKBSlugRequired), errors.Is(err, ErrInvalidKBSlug), errors.Is(err, ErrKBTitleRequired), errors.Is(err, ErrKBBodyRequired), errors.Is(err, ErrKBNotFound), errors.Is(err, ErrKBSlugTaken), errors.Is(err, ErrTemplateNameRequired), errors.Is(err, ErrTemplateBodyRequired), errors.Is(err, ErrTemplateNotFound), errors.Is(err, ErrInvalidMatchThreshold), errors.Is(err, ErrInvalidAIThreshold), errors.Is(err, ErrInvalidAIDelivery), errors.Is(err, ErrAutoReplyDisabled), errors.Is(err, ErrAutoReplyAlreadyPosted), errors.Is(err, ErrNoAIDraft), errors.Is(err, ErrKBImageInvalidType), errors.Is(err, ErrKBImageTooLarge), errors.Is(err, ErrKBImageInvalidName), errors.Is(err, ErrKBImageBadSig), errors.Is(err, ErrKBUploadDirMissing): return err.Error(), true default: return "", false } }