feat: 添加租户隔离保护触发器的管理方法,并更新迁移文档

This commit is contained in:
2026-07-28 14:45:33 +08:00
parent 99e4e43122
commit 5e993298e7
5 changed files with 61 additions and 4 deletions

View File

@@ -218,6 +218,24 @@ Tiku.Infrastructure/Persistence/Migrations/20260728031410_InitialSchema.cs
- 不新增 Supabase provider、Supabase URL 拼接、Supabase Storage bucket 逻辑或 Supabase Auth 兼容层。
- EF Core 管实体和 migration 生命周期;跨表租户不变量不能指望 ORM 自动推导。比如“题目引用只能指向平台或本租户”“分类父节点只能属于平台或本租户”,必须用集中 PostgreSQL trigger / constraint trigger SQL helper + migration 调用 + 真实 PostgreSQL 测试兜底,禁止去数据库手工补。
## 数据库边界与 ORM 分工
本项目仍然采用 EF Core code-first migration 管理数据库基线:实体、索引、外键、普通唯一约束和普通 check constraint 都应优先通过 `IEntityTypeConfiguration` 表达,并随 migration 进入代码库。
但 EF Core 不会、也不应该自动推导跨表业务不变量。以下规则必须保留为 PostgreSQL guard
- `TenantQuestionReference` 只能引用平台主体公共题或当前租户私题,不能引用其他租户私题。
- `TaxonomyNode` 的父节点只能属于平台主体或当前租户,不能挂到其他租户节点。
- 需要读取 `tenants.mode` 或按 owner 关系做条件判断的规则。
这些 guard 的维护约定固定如下:
1. 触发器 SQL 只放在 `Tiku.Infrastructure/Persistence/PostgreSqlTenantConstraintSql.cs`
2. Migration 不直接复制触发器 SQL只调用 `migrationBuilder.EnsureTenantIsolationGuards()``migrationBuilder.DropTenantIsolationGuards()`
3. 重建或压缩 `InitialSchema` 后,必须在 `Up()` 末尾调用 `EnsureTenantIsolationGuards()`,在 `Down()` 开头调用 `DropTenantIsolationGuards()`
4. 新增类似规则时,先判断能否用 EF FK / unique index / check constraint 表达;表达不了才新增 PostgreSQL guard。
5. 每个 guard 必须同时有 migration script 断言和真实 PostgreSQL 越权测试。
## 还剩多少待迁移
运行时契约基线显示,旧 NestJS 有 342 个操作,当前 .NET 有 237 个操作: