You've already forked agentic-coding-workflow
style(project): silence remaining lint findings (stutter, max shadow, gosec)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 不存在")
|
||||
}
|
||||
|
||||
@@ -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,15 +280,12 @@ 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 {
|
||||
continue
|
||||
}
|
||||
} else if x.RequirementID == nil || *x.RequirementID != *requirementID {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if filter.AssigneeID != nil {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user