library-picturebook-activity/.cursor/rules/multi-tenant.mdc
2025-12-09 11:10:36 +08:00

102 lines
2.1 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.

---
description: 多租户数据隔离规范(所有涉及数据库操作的代码必须遵守)
globs:
alwaysApply: true
---
# 多租户处理规范
⚠️ **极其重要**:所有业务数据查询必须包含 `tenantId` 条件!
## 核心原则
### 1. 数据库查询
- **必须**:所有业务表查询必须包含 `tenantId` 条件
- 超级租户(`isSuper = 1`)可以访问所有租户数据
```typescript
// ✅ 正确示例
const users = await this.prisma.user.findMany({
where: {
tenantId,
validState: 1,
},
});
// ❌ 错误示例 - 缺少 tenantId
const users = await this.prisma.user.findMany({
where: {
validState: 1,
},
});
```
### 2. 获取租户ID
在控制器中使用 `@CurrentTenantId()` 装饰器:
```typescript
@Get()
async findAll(@CurrentTenantId() tenantId: number) {
return this.service.findAll(tenantId);
}
```
### 3. 创建数据
创建数据时自动设置 `tenantId`
```typescript
async create(createDto: CreateDto, tenantId: number) {
return this.prisma.model.create({
data: {
...createDto,
tenantId,
},
});
}
```
### 4. 更新/删除数据
更新或删除前验证数据属于当前租户:
```typescript
async update(id: number, updateDto: UpdateDto, tenantId: number) {
// 先验证数据属于当前租户
const existing = await this.prisma.model.findFirst({
where: { id, tenantId },
});
if (!existing) {
throw new NotFoundException('数据不存在或不属于当前租户');
}
return this.prisma.model.update({
where: { id },
data: updateDto,
});
}
```
## 数据库表设计
所有业务表必须包含:
- `tenantId`: Int - 租户ID必填
- `creator`: Int? - 创建人ID
- `modifier`: Int? - 修改人ID
- `createTime`: DateTime @default(now())
- `modifyTime`: DateTime @updatedAt
- `validState`: Int @default(1) - 有效状态1-有效2-失效)
## 审查清单
在代码审查时,重点检查:
- [ ] 所有 `findMany`、`findFirst`、`findUnique` 包含 `tenantId` 条件
- [ ] 创建操作设置了 `tenantId`
- [ ] 更新/删除操作验证了 `tenantId`
- [ ] 新的 Prisma 模型包含了 `tenantId` 字段