129 lines
3.2 KiB
Markdown
129 lines
3.2 KiB
Markdown
|
|
# Competition Management System - Agent Instructions
|
|||
|
|
|
|||
|
|
这是一个多租户的竞赛管理系统,采用 NestJS + Vue 3 技术栈。
|
|||
|
|
|
|||
|
|
## 🚨 最重要的规则
|
|||
|
|
|
|||
|
|
### 多租户数据隔离
|
|||
|
|
|
|||
|
|
**所有数据库查询必须包含 `tenantId` 条件!** 这是系统安全的核心。
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// ✅ 正确
|
|||
|
|
const users = await prisma.user.findMany({
|
|||
|
|
where: { tenantId, validState: 1 }
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// ❌ 错误 - 绝对不允许
|
|||
|
|
const users = await prisma.user.findMany();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 后端开发
|
|||
|
|
|
|||
|
|
### 模块结构
|
|||
|
|
- 使用 NestJS 标准模块结构:module、controller、service、dto
|
|||
|
|
- 所有数据操作通过 Prisma,禁止直接 SQL
|
|||
|
|
- 使用 `@Injectable()`、`@Controller()` 装饰器
|
|||
|
|
|
|||
|
|
### 权限控制
|
|||
|
|
- 使用 `@RequirePermission('module:action')` 装饰器
|
|||
|
|
- 格式:`user:create`、`contest:update`、`role:delete`
|
|||
|
|
- 所有路由默认需要认证,公开接口使用 `@Public()`
|
|||
|
|
|
|||
|
|
### DTO 验证
|
|||
|
|
```typescript
|
|||
|
|
export class CreateUserDto {
|
|||
|
|
@IsString()
|
|||
|
|
username: string;
|
|||
|
|
|
|||
|
|
@IsEmail()
|
|||
|
|
@IsOptional()
|
|||
|
|
email?: string;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 错误处理
|
|||
|
|
- 使用 NestJS 内置异常,消息用中文
|
|||
|
|
- `NotFoundException`、`BadRequestException`、`ForbiddenException`
|
|||
|
|
|
|||
|
|
## 前端开发
|
|||
|
|
|
|||
|
|
### 组件开发
|
|||
|
|
- 使用 Vue 3 `<script setup lang="ts">` 语法
|
|||
|
|
- 页面组件放在 `views/` 目录,按模块组织
|
|||
|
|
- 使用 Ant Design Vue 组件库
|
|||
|
|
|
|||
|
|
### API 调用
|
|||
|
|
- API 文件放在 `api/` 目录,按模块组织
|
|||
|
|
- 函数命名:`getXxx`、`createXxx`、`updateXxx`、`deleteXxx`
|
|||
|
|
- 使用 TypeScript 类型定义
|
|||
|
|
|
|||
|
|
### 路由
|
|||
|
|
- 路由路径必须包含租户编码:`/:tenantCode/users`
|
|||
|
|
- 使用动态路由(基于菜单权限)
|
|||
|
|
|
|||
|
|
### 状态管理
|
|||
|
|
- 使用 Pinia,store 命名:`useAuthStore`、`useUserStore`
|
|||
|
|
|
|||
|
|
## 数据库设计
|
|||
|
|
|
|||
|
|
### 必需字段
|
|||
|
|
所有业务表必须包含:
|
|||
|
|
```prisma
|
|||
|
|
model YourModel {
|
|||
|
|
id Int @id @default(autoincrement())
|
|||
|
|
tenantId Int @map("tenant_id")
|
|||
|
|
validState Int @default(1) @map("valid_state")
|
|||
|
|
creator Int?
|
|||
|
|
modifier Int?
|
|||
|
|
createTime DateTime @default(now()) @map("create_time")
|
|||
|
|
modifyTime DateTime @updatedAt @map("modify_time")
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 性能优化
|
|||
|
|
- 使用 `include` 预加载,避免 N+1 查询
|
|||
|
|
- 使用 `select` 精简字段
|
|||
|
|
- 实现分页查询
|
|||
|
|
|
|||
|
|
## 代码风格
|
|||
|
|
|
|||
|
|
- TypeScript 严格模式
|
|||
|
|
- 使用 async/await,避免 Promise.then()
|
|||
|
|
- 使用中文注释
|
|||
|
|
- Git 提交信息:`类型: 描述`(如 `feat: 添加用户管理`)
|
|||
|
|
|
|||
|
|
## 快速参考
|
|||
|
|
|
|||
|
|
### 创建新模块
|
|||
|
|
1. 在 Prisma schema 定义模型
|
|||
|
|
2. 运行 `pnpm prisma:migrate:dev`
|
|||
|
|
3. 创建 NestJS 模块(module、controller、service、dto)
|
|||
|
|
4. 在 `app.module.ts` 注册
|
|||
|
|
5. 创建前端 API 和页面
|
|||
|
|
|
|||
|
|
### 常用装饰器
|
|||
|
|
- `@CurrentTenantId()` - 获取租户ID
|
|||
|
|
- `@CurrentUser()` - 获取当前用户
|
|||
|
|
- `@RequirePermission()` - 权限检查
|
|||
|
|
- `@Public()` - 公开接口
|
|||
|
|
|
|||
|
|
### 开发命令
|
|||
|
|
```bash
|
|||
|
|
# 后端
|
|||
|
|
cd backend
|
|||
|
|
pnpm start:dev # 启动开发服务器
|
|||
|
|
pnpm prisma:migrate:dev # 数据库迁移
|
|||
|
|
pnpm init:admin # 初始化管理员
|
|||
|
|
|
|||
|
|
# 前端
|
|||
|
|
cd frontend
|
|||
|
|
pnpm dev # 启动开发服务器
|
|||
|
|
pnpm build # 构建生产版本
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
💡 **记住**:租户隔离是系统的核心安全机制,所有数据操作都必须验证 `tenantId`!
|
|||
|
|
|