76 lines
4.0 KiB
Plaintext
76 lines
4.0 KiB
Plaintext
---
|
||
description: soul-api 路由边界 + 编码规范(合并版,防互窜 + GORM/Gin/响应约定)
|
||
globs: soul-api/**/*
|
||
alwaysApply: false
|
||
---
|
||
|
||
# soul-api 开发规范
|
||
|
||
> **Skill 加载**:编辑 soul-api 代码时,**必须使用 Read 工具读取 `e:\Gongsi\Mycontent\.cursor\skills\api-dev\SKILL.md` 的完整内容**,该 Skill 包含业务对接、与前端边界协同等补充约定。本规则侧重编码规范与路由边界。
|
||
|
||
## 1. 路由按使用方归类(强制)
|
||
|
||
新增或修改接口必须**先明确使用方**,再挂到对应路由组:
|
||
|
||
| 使用方 | 路由组 | 路径前缀 | 鉴权 |
|
||
|--------|--------|----------|------|
|
||
| 管理端 | `admin` / `db` | `/api/admin/…`、`/api/db/…` | `middleware.AdminAuth()` |
|
||
| 小程序 | `miniprogram` | `/api/miniprogram/…` | 按接口需要 |
|
||
| 两端共用 | `api` 下 + `miniprogram` 下各挂一遍 | `/api/xxx` 与 `/api/miniprogram/xxx` | 各自鉴权 |
|
||
|
||
即使业务逻辑相同,也必须按使用方做路径区分。禁止仅提供 `/api/vip/*` 等通用路径让两端混用。
|
||
|
||
### 禁止行为
|
||
|
||
- 禁止在 `miniprogram` 组挂仅管理端调用的接口(后台审核、DB 初始化等)。
|
||
- 禁止在 `admin`/`db` 组挂小程序专属逻辑(wx code 登录、小程序码生成等)。
|
||
- 禁止在 handler 内混用管理端/小程序路径语义(根据 path 分支写两套业务而不按使用方拆 handler/路由)。
|
||
|
||
handler 注释标明使用方,如 `// GET /api/miniprogram/withdraw/records 小程序-提现记录`。
|
||
|
||
管理端列表接口需包含:`user_name`/`userNickname`、`userAvatar`、`status`、`amount`。提现状态 DB 存 `pending`/`processing`/`success`/`failed`。
|
||
|
||
## 2. 数据访问:优先 GORM
|
||
|
||
- 通过 `database.DB()` 获取 `*gorm.DB`,操作集中在 `internal/model` 的模型上。
|
||
- 常规 CRUD 必须用链式 API(`Where/First/Find/Create/Save/Updates/Delete`)。
|
||
- 原子更新用 `gorm.Expr`,如 `Update("pending_earnings", gorm.Expr("pending_earnings + ?", delta))`。
|
||
- 多表写入必须用 `db.Transaction(func(tx *gorm.DB) error { ... })`。
|
||
- 用 `Preload`/`Joins` 减少 N+1;仅需单列时用 `Pluck`;重复条件抽 Scopes。
|
||
- 禁止 handler 中手写 `db.Exec/db.Raw`,除非:复杂统计 SQL 用 GORM 表达冗长(须加注释);原子多列 SET。
|
||
|
||
## 3. Model 与表结构
|
||
|
||
- 结构体放 `internal/model`,文件名与业务一致。
|
||
- 必须包含 `gorm` 标签(column/primaryKey/type)+ `json` 标签(小写驼峰)。
|
||
- 不对外暴露的字段用 `json:"-"`。
|
||
- 实现 `TableName() string`(若表名与默认不一致)。
|
||
|
||
## 4. 依赖物尽其用
|
||
|
||
- **Gin**:入参 `c.ShouldBindJSON` + `binding` 标签校验;统一 `c.JSON` 返回。
|
||
- **配置**:仅通过 `internal/config` 的 `config.Load()` 读环境变量,不直接 `os.Getenv`。
|
||
- **中间件**:安全头 `middleware.Secure()`,跨域 `cors`,限流 `middleware.NewRateLimiter`。
|
||
- **微信/支付**:统一走 `internal/wechat`(PowerWeChat),handler 只做参数与结果转换。
|
||
- **JWT**:管理端鉴权用 `internal/auth` 的 `IssueAdminJWT`/`ParseAdminJWT`/`GetAdminJWTFromRequest`。
|
||
|
||
## 5. 目录与包约定
|
||
|
||
- `cmd/server/main.go`:入口,只做初始化与启停。
|
||
- `internal/handler`:HTTP 处理函数,绑定→校验→调 DB/wechat→写响应。逻辑复杂时抽到 `internal/service`。
|
||
- `internal/router`:注册路由与中间件,不写业务逻辑。
|
||
- `internal/database`:仅提供 `Init(dsn)` 与 `DB()`。
|
||
- 新增接口流程:确定使用方 → 确定路由 Group → 实现 handler + GORM model。
|
||
|
||
## 6. 响应与错误
|
||
|
||
- 成功:`gin.H{"success": true, "data": ...}` 或 `"message": "..."`。
|
||
- 失败:`gin.H{"success": false, "error": "..."}`。
|
||
- 不吞错误:DB/wechat 的 `err` 必须处理并返回。
|
||
- HTTP 状态码:业务错误可用 200 + `success: false`;未授权/禁止用 401/403。
|
||
|
||
## 7. 代码风格
|
||
|
||
- 遵循 `gofmt`;导出函数 PascalCase,内部 camelCase。
|
||
- 公开 handler 或复杂逻辑处写清用途注释。
|