更新项目文档,添加会话启动自检说明,强化 GORM 使用规范,确保数据操作遵循事务管理和预加载原则。修正多个处理函数以使用链式查询和数据验证,提升代码一致性和可维护性。
This commit is contained in:
@@ -11,9 +11,13 @@ alwaysApply: false
|
||||
- **一律使用 GORM 进行数据读写**,通过 `database.DB()` 获取 `*gorm.DB`,操作集中在 `internal/model` 中定义的模型上。
|
||||
- **禁止**在 handler 中手写 `db.Exec("INSERT ...")`、`db.Raw("SELECT ...")` 等裸 SQL,除非满足下方「例外」。
|
||||
- 常规 CRUD 必须用 GORM 链式 API:
|
||||
- 查询:`db.Where(...).First/Find/Count`、`db.Preload`、`db.Select`、`db.Order`
|
||||
- 查询:`db.Where(...).First/Find/Count`、`db.Preload`、`db.Select`、`db.Order`、`db.Pluck`(单列)、`db.Joins`(关联)
|
||||
- 写入:`db.Create`、`db.Save`、`db.Model(...).Updates(map/struct)`、`db.Where(...).Delete`
|
||||
- 原子更新:用 `gorm.Expr`,例如 `Update("pending_earnings", gorm.Expr("pending_earnings + ?", delta))`,而不是多行 Raw/Exec。
|
||||
- **事务(必用)**:涉及多表写入(如支付回调、分佣、订单+用户同时更新)必须用 `db.Transaction(func(tx *gorm.DB) error { ... })` 包裹,避免部分成功导致数据不一致。
|
||||
- **Preload**:列表返回关联数据(如 orders 带 user)时,优先用 `db.Preload("User").Find(&orders)` 或 `db.Joins` 减少 N+1;无 GORM 关联定义时可用 `Joins` 或 `Where("id IN ?", ids).Find(&users)` 批量查。
|
||||
- **Pluck**:仅需单列时用 `db.Model(&Order{}).Where(...).Pluck("product_id", &ids)`,不写 Raw。
|
||||
- **Scopes**:复杂或重复的查询条件可抽成 `func(db *gorm.DB) *gorm.DB` 的 Scopes,便于复用。
|
||||
- **例外**(允许少量 Raw/Exec):
|
||||
- 单条复杂统计 SQL 且用 GORM 表达冗长时,可用 `db.Raw(...).Scan(&struct)`,并加简短注释说明原因。
|
||||
- 必须用原生 SQL 的原子多列更新(如多字段 `SET a=a+?, b=b+?`)可保留 `db.Exec`,其余尽量改为 `Model().Update(Expr(...))`。
|
||||
@@ -29,11 +33,15 @@ alwaysApply: false
|
||||
|
||||
## 3. 依赖物尽其用
|
||||
|
||||
- **Gin**:入参用 `c.ShouldBindJSON(&req)` + `binding:"required"` 等做校验;统一用 `c.JSON(status, gin.H{...})` 或结构体返回;路由按功能挂在 `router.Setup` 的对应 Group(如 `/admin` 用 `middleware.AdminAuth()`)。
|
||||
- **GORM**:能用链式条件、Scopes、预加载完成的,不写 Raw;事务用 `db.Transaction(func(tx *gorm.DB) error { ... })`。
|
||||
- **Gin**:入参用 `c.ShouldBindJSON(&req)` + `binding` 标签做校验;统一用 `c.JSON(status, gin.H{...})` 或结构体返回;路由按功能挂在 `router.Setup` 的对应 Group(如 `/admin` 用 `middleware.AdminAuth()`)。
|
||||
- **binding 标签**:`required`、`min=N`、`max=N`、`len=N`、`email`、`gte`、`lte` 等(go-playground/validator);金额可用 `binding:"required,gte=0"`,手机号可用 `binding:"required,len=11"`。
|
||||
- **GORM**:能用链式条件、Scopes、Preload、Pluck、Joins 完成的,不写 Raw;多表写入必须用 `db.Transaction`。
|
||||
- **配置**:仅通过 `internal/config` 的 `config.Load()` 读环境变量;业务代码不直接 `os.Getenv`;新配置项加到 `Config` 结构体并在 `Load()` 中解析。
|
||||
- **中间件**:安全头用 `middleware.Secure()`,跨域用 `cors`,限流用 `middleware.NewRateLimiter(...).Middleware()`;新路由按需挂到已有或新 Group,避免重复造轮子。
|
||||
- **微信/支付**:小程序、支付、转账相关统一走 `internal/wechat` 封装,handler 只做参数与结果转换。
|
||||
- **微信/支付**:小程序、支付、转账相关统一走 `internal/wechat` 封装(PowerWeChat),handler 只做参数与结果转换。
|
||||
- **JWT**:管理端鉴权用 `internal/auth` 的 `IssueAdminJWT`、`ParseAdminJWT`、`GetAdminJWTFromRequest`,不手写 token 解析。
|
||||
- **godotenv**:配置加载在 `config.Load()` 内完成,业务代码不直接调。
|
||||
- **Redis**:当前为间接依赖(PowerWeChat 引入),未直接使用;若需分布式缓存或限流,可显式引入并统一封装,避免各处散落。
|
||||
|
||||
## 4. 接口按使用方归类(小程序 vs 管理端)
|
||||
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
---
|
||||
description: Soul 创业派对项目整体边界与 Skill 索引,防止子项目互窜
|
||||
description: Soul 创业派对项目整体边界与 Skill 索引,防止子项目互窜;含会话启动自检
|
||||
globs: ["**"]
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Soul 创业派对 - 项目边界与开发约束
|
||||
|
||||
## 会话启动自检(新 Cursor 打开本项目时优先执行)
|
||||
|
||||
当新的 Cursor 会话打开本项目时,**先进行自检**,确保仅沿用本项目的开发风格与配置:
|
||||
|
||||
1. **Rules 与 Skills 范围**:仅使用本项目 `.cursor/rules/` 与 `.cursor/skills/` 下的规则与技能;不套用与本项目无关的全局或其它项目的 rules/skills(如存客宝AI、React 转 Vue、Next 全栈拆分等与本项目无关的能力)。
|
||||
2. **开发风格**:按当前编辑目录遵守对应 boundary 与 Skill(miniprogram → 小程序规范;soul-admin → 管理端规范;soul-api → API 规范);API 路径、路由分组、变更检查清单等均以本规则与 `.cursor/README.md` 为准。
|
||||
3. **配置参数**:baseUrl、鉴权方式、路由前缀(`/api/miniprogram/*`、`/api/admin/*`、`/api/db/*`)等以项目内实际配置为准,不引入外部项目的默认值或约定。
|
||||
4. **清理无关项**:若发现会话上下文中存在与本项目无关的 rules 或 skills 引用,应忽略或排除,仅以本项目 `.cursor` 为准。
|
||||
|
||||
自检通过后,再按「项目组成」「防互窜原则」「开发时」执行后续开发。
|
||||
|
||||
---
|
||||
|
||||
## 项目组成
|
||||
|
||||
| 子项目 | 目录 | 用途 | 后端对接 |
|
||||
|
||||
Reference in New Issue
Block a user