一、超管端设计优化 - 文档管理SOP体系建立,docs目录重组 - 统一用户管理:跨租户全局视角,合并用户管理+公众用户 - 活动监管全模块重构:全部活动(统计卡片+阶段筛选+SuperDetail详情页)、报名数据/作品数据/评审进度(两层合一扁平列表)、成果发布(去Tab+统计+隐藏写操作) - 菜单精简:移除评委管理/评审规则/通知管理 - Bug修复:租户编辑丢失隐藏菜单、pageSize限制、主色统一 二、UGC绘本创作社区P0 - 数据库:10张新表(user_works/user_work_pages/work_tags等) - 子女账号独立化:Child升级为独立User,家长切换+独立登录 - 用户作品库:CRUD+发布审核,8个API - AI创作流程:提交→生成→保存到作品库,4个API - 作品广场:首页改造为推荐流,标签+搜索+排序 - 内容审核(超管端):作品审核+作品管理+标签管理 - 活动联动:WorkSelector作品选择器 - 布局改造:底部5Tab(发现/创作/活动/作品库/我的) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
294 lines
8.9 KiB
Plaintext
294 lines
8.9 KiB
Plaintext
# 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` 字段
|
||
|