Files
junhong_cmp_fiber/.claude/skills/dto-standards/SKILL.md
huang e9ff14df0e
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
规范: 新增枚举与状态字段规范并修复代理充值状态描述错误
- 新增 docs/enum-status-standards.md:完整的枚举/状态规范,涵盖 int vs string 选择、起始值约定、description 格式统一、constants 唯一真相来源、Response DTO 必须提供 status_name
- 更新 dto-standards SKILL.md:加入枚举规范要点,AI 写 DTO 时自动触发
- 更新 AGENTS.md:常量管理章节和 Code Review 检查清单各加入枚举检查项
- 修复 agent_recharge_dto.go:description 从错误的 3 个状态改为正确的 5 个状态(原 3:已取消 实为 3:已完成)
- 修复 agent_recharge service:toResponse 补充 StatusName 中文字段,防止前端映射出错
2026-04-11 11:25:58 +08:00

7.9 KiB
Raw Blame History

name, description
name description
dto-standards DTO 数据传输对象规范。创建或修改 DTO 文件、请求/响应结构时使用。包含 description 标签、枚举字段、验证标签等规范。

DTO 规范

所有 DTO 文件必须遵循以下规范,这是 API 文档生成的基础。

触发条件

在以下情况下必须遵守本规范:

  • 创建或修改 internal/model/ 下的请求/响应 DTO
  • 创建 XXXRequestXXXResponseXXXReqXXXResp 结构体
  • 添加或修改 API 接口的输入输出参数

必须项MUST

1. Description 标签规范

所有字段必须使用 description 标签,禁止使用行内注释

错误

type CreateUserRequest struct {
    Username string `json:"username"` // 用户名
    Status   int    `json:"status"`   // 状态
}

正确

type CreateUserRequest struct {
    Username string `json:"username" description:"用户名"`
    Status   int    `json:"status" description:"状态 (0:禁用, 1:启用)"`
}

2. 枚举字段int vs string 选择

必须按以下规则选择类型,禁止混用:

场景 类型 示例
状态类(生命周期阶段) int 待支付→已完成→已关闭
布尔状态(启用/禁用) int 0=禁用, 1=启用
类型/方式类(种类) string "wechat", "single_card"
平台/标识符类 string "web", "h5", "all"
// ✅ 状态 → int
Status        int    `json:"status"`
PaymentStatus int    `json:"payment_status"`

// ✅ 类型/方式 → string
PaymentMethod string `json:"payment_method" validate:"required,oneof=wechat offline"`
OrderType     string `json:"order_type"     validate:"required,oneof=single_card device"`

3. Int 状态值约定

3.1 通用禁用/启用

必须用全局常量,禁止自定义(尤其禁止 1=启用 2=禁用 这种反向写法)

// pkg/constants/constants.go 已定义,直接使用
StatusDisabled = 0 // 禁用
StatusEnabled  = 1 // 启用

正确:description:"状态 (0:禁用, 1:启用)" 禁止:description:"状态 (1:启用, 2:禁用)"

3.2 生命周期状态

1 开始递增0 不使用(避免与 Go 零值混淆):

const (
    RechargeStatusPending   = 1 // 待支付
    RechargeStatusPaid      = 2 // 已支付
    RechargeStatusCompleted = 3 // 已完成
    RechargeStatusClosed    = 4 // 已关闭
)

4. 枚举列表必须从 constants 原文抄写

DTO description 的枚举列表必须与 pkg/constants/ 定义完全一致,不可凭记忆填写。

操作步骤:

  1. 先查/定义 pkg/constants/ 中的枚举常量
  2. 将常量注释原文抄写到 description
// constants.go 中:
RechargeStatusPending   = 1 // 待支付
RechargeStatusPaid      = 2 // 已支付
RechargeStatusCompleted = 3 // 已完成
RechargeStatusClosed    = 4 // 已关闭
RechargeStatusRefunded  = 5 // 已退款

// DTO description 从上面抄:
Status int `json:"status" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`

禁止description 与 constants 不一致,是历史 bug 的根因):

// constants 说 3=已完成description 却写 3:已取消
Status int `json:"status" description:"状态 (1:待支付, 2:已完成, 3:已取消)"`

5. description 格式标准

统一格式字段含义 (值1:中文含义1, 值2:中文含义2)

  • 值与含义之间用冒号 :(禁止用等号 =
  • 多个值之间用逗号加空格 ,
  • 含义必须是中文
// ✅ 统一格式
Status       int    `description:"状态 (1:待支付, 2:已支付, 3:已完成)"`
Platform     string `description:"适用端口 (all:全部, web:Web后台, h5:H5端)"`

// ❌ 格式混乱
Status int `description:"状态 (0=禁用, 1=启用)"`     // 用等号
Status int `description:"0=禁用 1=启用"`             // 无括号无逗号

6. Response DTO 的状态字段必须同时返回 int 和 text

所有 Response DTO 中的 int 状态字段,必须同时提供对应的 _name 文字字段。

原因:防止前端维护映射表出错(历史上已有因此产生 bug 的案例)。

// ✅ Response DTO 标准写法
type XxxResponse struct {
    Status     int    `json:"status"      description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"`
    StatusName string `json:"status_name" description:"状态名称(中文)"`
}

// toResponse 函数中赋值
func rechargeStatusName(status int) string {
    switch status {
    case constants.RechargeStatusPending:
        return "待支付"
    case constants.RechargeStatusCompleted:
        return "已完成"
    // ...
    default:
        return "未知"
    }
}

字段命名约定:statusstatus_namepayment_statuspayment_status_name

例外Request DTO查询过滤、创建请求不需要 _name 字段。

7. 验证标签与 OpenAPI 标签一致

Username string `json:"username" validate:"required,min=3,max=50" required:"true" minLength:"3" maxLength:"50" description:"用户名"`
validate 标签 OpenAPI 标签
required required:"true"
min=N,max=M(数值) minimum:"N" maximum:"M"
min=N,max=M(字符串) minLength:"N" maxLength:"M"
oneof=A B C description 中说明枚举值

8. 请求参数类型标签

// Query 参数
type ListRequest struct {
    Page   int  `json:"page"  query:"page"  validate:"omitempty,min=1" minimum:"1" description:"页码"`
    Status *int `json:"status" query:"status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭)"`
}

// Path 参数
type IDReq struct {
    ID uint `path:"id" description:"ID" required:"true"`
}

9. 响应 DTO 完整性

type AccountResponse struct {
    ID         uint   `json:"id"          description:"账号ID"`
    Username   string `json:"username"    description:"用户名"`
    UserType   int    `json:"user_type"   description:"用户类型 (1:超级管理员, 2:平台用户, 3:代理账号, 4:企业账号)"`
    Status     int    `json:"status"      description:"状态 (0:禁用, 1:启用)"`
    StatusName string `json:"status_name" description:"状态名称(中文)"`
    CreatedAt  string `json:"created_at"  description:"创建时间"`
    UpdatedAt  string `json:"updated_at"  description:"更新时间"`
}

AI 助手必须执行的检查

在创建或修改任何 DTO 文件后,必须执行以下检查:

  1. 所有字段有 description 标签(无行内注释)
  2. 枚举类型选择正确(状态用 int类型/方式用 string
  3. 禁用/启用使用 0=禁用, 1=启用(禁止 1=启用 2=禁用)
  4. description 枚举列表已从 pkg/constants/ 原文抄写,无遗漏
  5. description 格式统一(冒号 :,括号,逗号)
  6. Response DTO 有 _name 伴生字段
  7. validate 标签与 OpenAPI 标签一致
  8. 重新生成 OpenAPI 文档验证:go run cmd/gendocs/main.go

完整枚举规范: 参见 docs/enum-status-standards.md


常见枚举字段标准值

// 用户类型(从 constants.UserType* 抄)
description:"用户类型 (1:超级管理员, 2:平台用户, 3:代理账号, 4:企业账号)"

// 通用启用/禁用(从 constants.StatusEnabled/Disabled 抄)
description:"状态 (0:禁用, 1:启用)"

// 充值状态(从 constants.RechargeStatus* 抄)
description:"状态 (1:待支付, 2:已支付, 3:已完成, 4:已关闭, 5:已退款)"

// 权限类型
description:"权限类型 (1:菜单, 2:按钮)"

// 适用端口
description:"适用端口 (all:全部, web:Web后台, h5:H5端)"

// 店铺层级
description:"店铺层级 (1-7级)"