library-picturebook-activity/.cursorrules

294 lines
8.6 KiB
Plaintext
Raw Permalink Normal View History

2025-12-09 11:10:36 +08:00
# Competition Management System - Cursor User Rules (DEPRECATED)
⚠️ **此文件已废弃** - 请使用新的规则系统:
- 项目规则:`.cursor/rules/*.mdc`
- 快速参考:`AGENTS.md`
- 说明文档:`.cursor/RULES_README.md`
---
以下内容保留作为备份,但不再使用:
# Competition Management System - Cursor User Rules
## 项目概述
这是一个多租户的竞赛管理系统,采用前后端分离架构:
- **后端**: NestJS + TypeScript + Prisma + MySQL
- **前端**: Vue 3 + TypeScript + Vite + Ant Design Vue + Pinia
- **认证**: JWT + RBAC (基于角色的访问控制)
- **架构**: 多租户架构,数据完全隔离
## 后端开发规范
### 1. 模块结构
- 每个功能模块应包含:`module.ts`, `controller.ts`, `service.ts`, `dto/` 目录
- 模块命名使用复数形式(如 `users`, `roles`, `contests`
- 子模块放在父模块目录下(如 `contests/works/`, `contests/teams/`
### 2. 服务层 (Service)
- 所有数据库操作必须通过 PrismaService禁止直接使用 SQL
- 服务方法必须处理租户隔离:所有查询必须包含 `tenantId` 条件
- 使用 `@Injectable()` 装饰器
- 构造函数注入依赖,使用 private readonly
- 方法命名:`create`, `findAll`, `findOne`, `update`, `remove`
- 查询方法应支持分页:使用 `skip` 和 `take` 参数
### 3. 控制器层 (Controller)
- 使用 `@Controller()` 装饰器,路径使用复数形式
- 所有路由默认需要认证(除非使用 `@Public()` 装饰器)
- 使用 `@Get()`, `@Post()`, `@Put()`, `@Delete()`, `@Patch()` 装饰器
- 从请求中获取租户ID使用 `@CurrentTenantId()` 装饰器或从 JWT token 中提取
- 使用 `@CurrentUser()` 装饰器获取当前用户信息
- 权限控制:使用 `@RequirePermission()` 装饰器
- 返回统一响应格式:使用 TransformInterceptor自动处理
### 4. DTO (Data Transfer Object)
- 所有 DTO 放在 `dto/` 目录下
- 使用 `class-validator` 进行验证
- 命名规范:
- 创建:`CreateXxxDto`
- 更新:`UpdateXxxDto`
- 查询:`QueryXxxDto`
- 必填字段使用验证装饰器(如 `@IsString()`, `@IsNumber()`
- 可选字段使用 `@IsOptional()`
- 数组字段使用 `@IsArray()` 和 `@IsNumber({}, { each: true })`
### 5. 数据库操作 (Prisma)
- 所有表必须包含 `tenantId` 字段(租户隔离)
- 所有表必须包含审计字段:`creator`, `modifier`, `createTime`, `modifyTime`
- 使用 Prisma 的 `include` 和 `select` 优化查询
- 关联查询使用嵌套 include避免 N+1 问题
- 删除操作使用软删除(`validState` 字段)或级联删除
- 事务操作使用 `prisma.$transaction()`
### 6. 多租户处理
- **必须**:所有业务数据查询必须包含 `tenantId` 条件
- 从 JWT token 或请求头中获取租户ID
- 创建数据时自动设置 `tenantId`
- 更新/删除时验证数据属于当前租户
- 超级租户(`isSuper = 1`)可以访问所有租户数据
### 7. 权限控制
- 使用 `@RequirePermission()` 装饰器进行权限检查
- 权限字符串格式:`模块:操作`(如 `contest:create`, `user:update`
- 角色权限通过 RolesGuard 自动检查
- 权限验证失败返回 403 Forbidden
### 8. 错误处理
- 使用 NestJS 内置异常:`NotFoundException`, `BadRequestException`, `UnauthorizedException`, `ForbiddenException`
- 自定义异常消息使用中文
- 错误信息要清晰明确,便于调试
### 9. 代码风格
- 使用 TypeScript 严格模式
- 使用 ESLint 和 Prettier 格式化代码
- 导入顺序NestJS 核心 → 第三方库 → 本地模块
- 使用 async/await避免 Promise.then()
- 使用解构赋值提高代码可读性
## 前端开发规范
### 1. 组件结构
- 页面组件放在 `views/` 目录下,按模块组织
- 公共组件放在 `components/` 目录下
- 使用 `<script setup lang="ts">` 语法
- 组件命名使用 PascalCase
### 2. API 调用
- 所有 API 调用放在 `api/` 目录下,按模块组织
- 使用 axios 实例(已配置拦截器)
- API 函数命名:`getXxx`, `createXxx`, `updateXxx`, `deleteXxx`
- 使用 TypeScript 类型定义请求和响应
### 3. 状态管理 (Pinia)
- Store 文件放在 `stores/` 目录下
- 使用 `defineStore()` 定义 store
- Store 命名使用 camelCase + Store 后缀(如 `authStore`
### 4. 路由管理
- 路由配置在 `router/index.ts`
- 支持动态路由(基于菜单权限)
- 路由路径包含租户编码:`/:tenantCode/xxx`
- 路由 meta 包含权限信息:`permissions`, `roles`
### 5. 表单验证
- 使用 VeeValidate + Zod 进行表单验证
- 验证规则定义在组件内或单独的 schema 文件
- 错误提示使用中文
### 6. UI 组件
- 使用 Ant Design Vue 组件库
- 样式使用 Tailwind CSS + SCSS
- 响应式设计:移动端优先
- 组件要有 loading 和 error 状态
### 7. 类型定义
- TypeScript 类型定义放在 `types/` 目录下
- 接口类型使用 `interface`,数据模型使用 `type`
- 导出类型供其他模块使用
## 数据库设计规范
### 1. 表结构
- 所有业务表必须包含 `tenantId` 字段
- 所有表必须包含审计字段:
- `creator`: Int? - 创建人ID
- `modifier`: Int? - 修改人ID
- `createTime`: DateTime @default(now()) - 创建时间
- `modifyTime`: DateTime @updatedAt - 修改时间
- 状态字段使用 `validState`: Int @default(1)1-有效2-失效)
- 表名使用复数形式,映射使用 `@@map("table_name")`
### 2. 关系设计
- 使用 Prisma 关系定义外键
- 级联删除:`onDelete: Cascade`
- 可选关联:`onDelete: SetNull`
- 一对一关系:使用 `?` 标记可选
### 3. 索引
- 主键自动索引
- 外键字段自动索引
- 查询频繁的字段添加索引
- 唯一约束使用 `@unique`
### 4. 迁移
- 使用 Prisma Migrate 管理数据库迁移
- 迁移文件命名:`YYYYMMDDHHMMSS_description`
- 迁移前备份数据库
- 生产环境使用 `prisma migrate deploy`
## 通用开发规范
### 1. Git 提交
- 提交信息使用中文
- 格式:`类型: 描述`(如 `feat: 添加竞赛管理功能`
- 类型:`feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
### 2. 注释
- 复杂逻辑必须添加注释
- 函数注释说明参数和返回值
- 使用中文注释
### 3. 测试
- 单元测试文件命名:`*.spec.ts`
- 测试覆盖率要求:核心业务逻辑 > 80%
- 使用 Jest 进行测试
### 4. 环境配置
- 使用 `.env.development` 和 `.env.production`
- 敏感信息不要提交到 Git
- 配置项通过 `@nestjs/config` 管理
### 5. 日志
- 使用 NestJS Logger
- 日志级别:`error`, `warn`, `log`, `debug`, `verbose`
- 记录关键操作和错误信息
## 安全规范
### 1. 认证授权
- 所有 API 默认需要 JWT 认证
- 密码使用 bcrypt 加密salt rounds: 10
- Token 过期时间合理设置
- 敏感操作需要额外验证
### 2. 数据验证
- 前端和后端都要进行数据验证
- 使用 DTO 和 class-validator 验证输入
- 防止 SQL 注入:使用 Prisma参数化查询
- 防止 XSS前端转义用户输入
### 3. 权限控制
- 最小权限原则
- 前端显示控制 + 后端权限验证
- 租户数据隔离必须严格检查
## 性能优化
### 1. 数据库查询
- 避免 N+1 查询,使用 `include` 预加载
- 使用 `select` 只查询需要的字段
- 分页查询必须实现
- 大表查询添加索引
### 2. API 响应
- 响应数据精简,避免返回不必要字段
- 使用分页减少单次数据量
- 长时间操作使用异步处理
### 3. 前端优化
- 路由懒加载
- 组件按需加载
- 图片使用 CDN 或压缩
- 避免不必要的重新渲染
## 代码审查检查清单
- [ ] 所有数据库查询包含 `tenantId` 条件
- [ ] DTO 验证规则完整
- [ ] 错误处理完善
- [ ] 权限检查正确
- [ ] 代码格式符合规范
- [ ] 注释清晰
- [ ] 无硬编码配置
- [ ] 类型定义完整
- [ ] 无控制台日志(生产环境)
## 常见问题
### Q: 如何获取当前租户ID
A: 在控制器中使用 `@CurrentTenantId()` 装饰器,或在服务中从 JWT token 提取。
### Q: 如何创建新的业务模块?
A:
1. 在 Prisma schema 中定义模型
2. 运行 `prisma migrate dev`
3. 创建模块目录和文件module, controller, service, dto
4. 在 `app.module.ts` 中注册模块
5. 创建前端 API 和页面
### Q: 如何处理多租户数据隔离?
A:
- 查询时始终包含 `where: { tenantId }`
- 创建时自动设置 `tenantId`
- 更新/删除前验证数据属于当前租户
### Q: 如何添加新的权限?
A:
1. 在数据库中创建权限记录
2. 在路由或控制器方法上使用 `@RequirePermission('module:action')`
3. 在前端路由 meta 中添加 `permissions` 字段