style(project): silence remaining lint findings (stutter, max shadow, gosec)

This commit is contained in:
2026-05-01 10:33:16 +08:00
parent 76a1461f4b
commit 1567f21a82
4 changed files with 23 additions and 20 deletions
+7 -1
View File
@@ -17,6 +17,7 @@ import (
// 字符串常量保持与 DB CHECK 约束一致。
type Phase string
// 五阶段枚举值,与 migrations/0002 的 CHECK 约束完全一致。
const (
PhasePlanning Phase = "planning"
PhaseAuditing Phase = "auditing"
@@ -41,6 +42,7 @@ func (p Phase) IsValid() bool {
// Status 是 Requirement / Issue 通用的开/关状态。
type Status string
// 开/关状态枚举值,与 DB CHECK 约束一致。
const (
StatusOpen Status = "open"
StatusClosed Status = "closed"
@@ -50,6 +52,7 @@ const (
// internal 所有登录用户可读;写权限两者都仅限 owner+admin。
type Visibility string
// 可见性枚举值,与 DB CHECK 约束一致。
const (
VisibilityPrivate Visibility = "private"
VisibilityInternal Visibility = "internal"
@@ -111,7 +114,10 @@ type Caller struct {
IsAdmin bool
}
// ProjectService 暴露 Project 聚合根的应用服务方法。
// ProjectService 暴露 Project 聚合根的应用服务方法。包内有三个并列服务
// (Project/Requirement/Issue),这里保留聚合名前缀以避免歧义。
//
//nolint:revive // 名字带聚合根前缀比 "Service" 更准确:包里有 3 个并列服务接口
type ProjectService interface {
Create(ctx context.Context, c Caller, in CreateProjectInput) (*Project, error)
Get(ctx context.Context, c Caller, slug string) (*Project, error)
+3 -3
View File
@@ -45,7 +45,7 @@ func assertReadable(p *Project, c Caller) error {
// assertWritable 是 write 类操作的鉴权门面:仅 owner+admin。已归档项目额外
// 拒绝;调用方应在执行写入前调用此函数。
func assertWritable(p *Project, c Caller) error {
if !(c.IsAdmin || p.OwnerID == c.UserID) {
if !c.IsAdmin && p.OwnerID != c.UserID {
// stranger 对 private 看不见;对 internal 也不能写。统一 not_found 防探测。
if p.Visibility == VisibilityPrivate {
return errs.New(errs.CodeNotFound, "project 不存在")
@@ -148,7 +148,7 @@ func (s *projectService) Archive(ctx context.Context, c Caller, slug string) err
return err
}
// 归档/取消归档仍要 owner+admin 校验,但已归档不再额外阻塞 archive。
if !(c.IsAdmin || p.OwnerID == c.UserID) {
if !c.IsAdmin && p.OwnerID != c.UserID {
if p.Visibility == VisibilityPrivate {
return errs.New(errs.CodeNotFound, "project 不存在")
}
@@ -169,7 +169,7 @@ func (s *projectService) Unarchive(ctx context.Context, c Caller, slug string) e
if err != nil {
return err
}
if !(c.IsAdmin || p.OwnerID == c.UserID) {
if !c.IsAdmin && p.OwnerID != c.UserID {
if p.Visibility == VisibilityPrivate {
return errs.New(errs.CodeNotFound, "project 不存在")
}
+10 -13
View File
@@ -120,13 +120,13 @@ func (r *fakeRepo) UnarchiveProject(_ context.Context, id uuid.UUID) error {
// ===== Requirement =====
func (r *fakeRepo) nextRequirementNumber(projectID uuid.UUID) int {
max := 0
maxNum := 0
for _, x := range r.requirements {
if x.ProjectID == projectID && x.Number > max {
max = x.Number
if x.ProjectID == projectID && x.Number > maxNum {
maxNum = x.Number
}
}
return max + 1
return maxNum + 1
}
func (r *fakeRepo) CreateRequirement(_ context.Context, in *Requirement) (*Requirement, error) {
@@ -235,13 +235,13 @@ func (r *fakeRepo) ReopenRequirement(_ context.Context, id uuid.UUID) error {
// ===== Issue =====
func (r *fakeRepo) nextIssueNumber(projectID uuid.UUID) int {
max := 0
maxNum := 0
for _, x := range r.issues {
if x.ProjectID == projectID && x.Number > max {
max = x.Number
if x.ProjectID == projectID && x.Number > maxNum {
maxNum = x.Number
}
}
return max + 1
return maxNum + 1
}
func (r *fakeRepo) CreateIssue(_ context.Context, in *Issue) (*Issue, error) {
@@ -280,17 +280,14 @@ func (r *fakeRepo) ListIssues(_ context.Context, projectID uuid.UUID, filter Iss
continue
}
if filter.Requirement != nil {
switch {
case *filter.Requirement == 0:
if *filter.Requirement == 0 {
if x.RequirementID != nil {
continue
}
default:
if x.RequirementID == nil || *x.RequirementID != *requirementID {
} else if x.RequirementID == nil || *x.RequirementID != *requirementID {
continue
}
}
}
if filter.AssigneeID != nil {
if x.AssigneeID == nil || *x.AssigneeID != *filter.AssigneeID {
continue
+2 -2
View File
@@ -232,7 +232,7 @@ func (r *pgRepo) CreateRequirement(ctx context.Context, in *Requirement) (*Requi
func (r *pgRepo) GetRequirementByNumber(ctx context.Context, projectID uuid.UUID, number int) (*Requirement, error) {
row, err := r.q.GetRequirementByNumber(ctx, projectsqlc.GetRequirementByNumberParams{
ProjectID: toPgUUID(projectID),
Number: int32(number),
Number: int32(number), //nolint:gosec // number 来自 service 层 number int 字段,原值即来自 DB int32,溢出不可达
})
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
@@ -364,7 +364,7 @@ func (r *pgRepo) CreateIssue(ctx context.Context, in *Issue) (*Issue, error) {
func (r *pgRepo) GetIssueByNumber(ctx context.Context, projectID uuid.UUID, number int) (*Issue, error) {
row, err := r.q.GetIssueByNumber(ctx, projectsqlc.GetIssueByNumberParams{
ProjectID: toPgUUID(projectID),
Number: int32(number),
Number: int32(number), //nolint:gosec // 同上:number 原始来自 DB int32
})
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {