library-picturebook-activity/.cursorrules
aid 418aa57ea8 Day4: 超管端设计优化 + UGC绘本创作社区P0实现
一、超管端设计优化
- 文档管理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>
2026-03-27 22:20:25 +08:00

294 lines
8.9 KiB
Plaintext
Raw Permalink 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.

# 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` 字段