Skip to content

Commit b6a8a51

Browse files
committed
refactor: enhance tag sanitization and user validation logic
1 parent dec8c53 commit b6a8a51

2 files changed

Lines changed: 45 additions & 35 deletions

File tree

‎apps/product-query-svc/domain/product.go‎

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,29 @@ func (p *Product) RemoveTag(tag string) {
9191

9292
// replaceTags 重建标签列表(调用方负责去重复构建)。
9393
func (p *Product) replaceTags(tags []string) error {
94+
sanitized, err := sanitizeTags(tags)
95+
if err != nil {
96+
return err
97+
}
98+
p.Tags = sanitized
99+
return nil
100+
}
101+
102+
// errValidation 构造带细节的校验错误。
103+
func errValidation(msg string) error {
104+
return errors.Join(ErrValidation, errors.New(msg))
105+
}
106+
107+
func equalFold(a, b string) bool {
108+
return strings.EqualFold(strings.TrimSpace(a), strings.TrimSpace(b))
109+
}
110+
111+
func sanitizeTags(tags []string) ([]string, error) {
94112
if len(tags) == 0 {
95-
p.Tags = nil
96-
return nil
113+
return nil, nil
97114
}
98115
seen := make(map[string]struct{}, len(tags))
99-
out := outBuffer(len(tags))
116+
sanitized := make([]string, 0, len(tags))
100117
for _, raw := range tags {
101118
cleaned := strings.TrimSpace(raw)
102119
if cleaned == "" {
@@ -107,27 +124,13 @@ func (p *Product) replaceTags(tags []string) error {
107124
continue
108125
}
109126
seen[key] = struct{}{}
110-
out = append(out, cleaned)
111-
if len(out) > maxTags {
112-
return errValidation("tags exceed limit")
127+
sanitized = append(sanitized, cleaned)
128+
if len(sanitized) > maxTags {
129+
return nil, errValidation("tags exceed limit")
113130
}
114131
}
115-
p.Tags = out
116-
return nil
117-
}
118-
119-
// errValidation 构造带细节的校验错误。
120-
func errValidation(msg string) error {
121-
return errors.Join(ErrValidation, errors.New(msg))
122-
}
123-
124-
func equalFold(a, b string) bool {
125-
return strings.EqualFold(strings.TrimSpace(a), strings.TrimSpace(b))
126-
}
127-
128-
func outBuffer(capacity int) []string {
129-
if capacity < 0 {
130-
capacity = 0
132+
if len(sanitized) == 0 {
133+
return nil, nil
131134
}
132-
return make([]string, 0, capacity)
135+
return sanitized, nil
133136
}
Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
package domain
22

33
import (
4-
"errors"
54
"regexp"
5+
"strings"
66
"time"
77
)
88

9-
var (
10-
ErrEmailValidation = errors.New("email validation error")
11-
)
9+
var emailRegexp = regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
1210

1311
func IsValidEmail(email string) bool {
14-
// 这是一个常用的简化正则,够用 90% 场景
15-
re := regexp.MustCompile(`^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$`)
16-
return re.MatchString(email)
12+
return emailRegexp.MatchString(strings.TrimSpace(email))
1713
}
1814

1915
type User struct {
@@ -24,25 +20,36 @@ type User struct {
2420
}
2521

2622
func NewUser(name string, email string) (*User, error) {
27-
u := &User{Name: name, Email: email, CreatedAt: time.Now()}
23+
u := &User{
24+
Name: strings.TrimSpace(name),
25+
Email: strings.TrimSpace(email),
26+
CreatedAt: time.Now().UTC(),
27+
}
2828

2929
if err := u.Validate(); err != nil {
30-
return nil, ErrValidation
30+
return nil, err
3131
}
3232

3333
return u, nil
3434
}
3535

3636
func (u *User) Validate() error {
37-
if IsValidEmail(u.Email) {
38-
return ErrValidation
37+
if u.Name == "" {
38+
return errValidation("name required")
39+
}
40+
if !IsValidEmail(u.Email) {
41+
return errValidation("invalid email format")
3942
}
4043
return nil
4144
}
4245

4346
//TODO how to avoid a same email could create several account
4447

4548
func (u *User) ChangeName(newName string) error {
46-
u.Name = newName
49+
cleaned := strings.TrimSpace(newName)
50+
if cleaned == "" {
51+
return errValidation("name required")
52+
}
53+
u.Name = cleaned
4754
return nil
4855
}

0 commit comments

Comments
 (0)