Files
xuanzhi-service/server/.ai-specs/coding-specs/vo-model-request-response.md

67 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Model / Request / Response 组织规范
## 适用范围
- 判断实体、API 入参、API 出参、`vo` 的落点时,使用本文。
- 新增或修改 `model/<module>``model/<module>/request``model/<module>/response` 时,使用本文。
## 结论基线
- 不建顶层 `vo` 目录;所有数据载体统一归入 `model` 体系。
- 实体只承载表结构和业务实体字段;禁止承载分页、筛选、排序、展示聚合字段。
| 类型 | 固定落点 | 用途 |
|:---|:---|:---|
| 实体 | `model/<module>` | GORM 映射、业务实体 |
| 入参 | `model/<module>/request` | 查询、分页、排序、保存、动作参数 |
| 出参 | `model/<module>/response` | 详情包装、列表项、聚合字段、展示转换 |
| 通用结构 | `model/common/request``model/common/response` | 跨模块稳定复用 |
## 判定规则
| 场景 | 结论 |
|:---|:---|
| 入参 = 可公开写入的实体字段,且无额外语义 | 可复用实体 |
| 入参只开放部分字段,或需要屏蔽敏感/系统字段 | 必须使用 `request` |
| 入参包含分页、筛选、排序、动作语义、组合参数 | 必须使用 `request` |
| 返回实体原样或实体列表 | 可直接返回实体 |
| 返回包含展示、聚合、联表、树、嵌套结构 | 必须使用 `response` |
| 关联表列表/详情需要给前端展示关联对象名称、标题、label | 必须使用 `response` 联表展示字段,实体只保留外键 ID |
| 多个接口 contract 完全一致 | 复用同一个 `request/response` |
| `admin/app` 字段、校验、分页、展示口径不同 | 按端拆分 `request/response` |
## 强制规则
- 新增实体必须放 `model/<module>`;正式 API contract 必须放 `request``response`
- 禁止在 `API` 文件中长期维护正式 contract 的匿名结构体。
- 新增 `request/response` 前,必须先检查同模块现有结构是否可复用。
- `request/response` 只有字段、校验语义、返回语义明显不同,才允许新增。
- 同一业务模块存在 `admin/app` 两套接口时,实体只保留一份;仅 `request/response` 按端拆分。
- 改实体字段时,必须同步检查 `doc-sql``Service` 查询/写入、`API` 绑定/返回。
-`request/response` 或接口 contract 时,必须同步检查并更新 `doc-api``API``Service`
- 关联表实体只能承载自身字段和外键 ID禁止把关联对象的 `name/title/label` 等展示字段写入实体或 `doc-sql`
- 关联表的 admin 列表响应默认必须补充主要关联对象展示字段,字段名使用 `<关联对象语义><Name/Title/Label>`,例如 `authorName``bookTitle``typeLabel`
- 关联表详情响应如果用于前端详情页、编辑弹窗或审阅页面,也必须返回与列表一致的关联展示字段;纯内部读取接口可只返回实体。
- 展示字段来源必须由 `Service` 通过 `JOIN`、预加载或批量查询组装到 `response`,禁止要求前端拿到 ID 后再逐条反查名称。
- 关联展示字段只读;`Create/Update` 请求仍只接收外键 ID 和可编辑业务字段,禁止接收或信任前端传入的展示名称。
- 若列表支持按关联展示字段搜索或排序,`total` 统计查询必须同步使用等价关联条件,避免分页总数和列表数据不一致。
## 推荐做法
| 对象 | 模板 | 示例 |
|:---|:---|:---|
| 列表查询入参 | `<StructName>Search` | `BookSearch` |
| 动作入参 | `<Action><StructName>Req` | `ChangePasswordReq` |
| 详情出参 | `<StructName>Response` | `BookResponse` |
| 列表项出参 | `<StructName>ListItem` | `BookListItem` |
| 关联展示字段 | `<Related> + Name/Title/Label` | `authorName``bookTitle` |
| 选项出参 | `<StructName>Option` | `AuthorOption` |
| 文件 | `model/<module>/<resource>.go``model/<module>/request/<resource>.go``model/<module>/response/<resource>.go` | `model/book/book.go` |
## 禁止事项
- 禁止新建顶层 `vo` 目录,与 `model` 并行维护数据结构。
- 禁止为每个 API 机械复制字段几乎相同的 `request/response`
- 禁止把分页、排序、筛选、展示、聚合、临时返回字段塞进实体。
- 禁止用 `map[string]interface{}``gin.H` 作为正式业务出参。