Files
tiku-backend.net/docs/migration/phase-2-engineering-foundation.md

4.5 KiB
Raw Blame History

第二阶段:.NET 工程底座

完成日期2026-07-27。

本阶段按 greenfield 项目建设,不承担旧 Supabase / NestJS 数据兼容。数据库结构以 EF Core 实体、Fluent Configuration 和 Migration 为唯一权威来源API 运行时不自动修改数据库。

数据库开发与发布边界

  • 开发采用 code first修改实体或 Fluent Configuration 后生成 EF Core Migration。
  • Migration 统一保存在 Tiku.Infrastructure/Persistence/Migrations/
  • Tiku.DbMigrator 是执行 Migration 的独立入口。
  • Tiku.ApiTiku.Worker 不调用 Database.Migrate(),避免多实例启动时争抢 DDL也避免应用进程持有结构变更权限。
  • 发布前生成并审查 SQL生产环境由部署流程显式执行 DbMigrator 或审核后的 SQL。
  • Development 未配置连接串时默认连接本机 tiku 数据库,并使用当前系统用户名,不内置密码。
  • 非 Development 环境必须显式配置 ConnectionStrings:DatabaseDATABASE_URL,缺失时启动失败。

常用命令:

dotnet ef migrations add <MigrationName> \
  --project Tiku.Infrastructure \
  --startup-project Tiku.DbMigrator

dotnet ef migrations script \
  --project Tiku.Infrastructure \
  --startup-project Tiku.DbMigrator

dotnet run --project Tiku.DbMigrator

真实 PostgreSQL 测试基线

Tiku.IntegrationTests 已移除 EF Core InMemory provider全部集成测试连接真实 PostgreSQL

  • 管理连接可通过 TIKU_TEST_POSTGRES_ADMIN 覆盖。
  • 默认管理连接为 Host=localhost;Database=postgres;Username=<当前系统用户>
  • 测试进程创建一次已执行完整 Migration 的模板数据库。
  • 每个 ApiTestFactory 从模板克隆独立 tiku_it_* 数据库,测试之间不共享业务数据。
  • Factory 释放时终止连接并删除克隆库;进程退出时删除模板库。
  • 测试只允许管理 tiku_it_* 命名空间,不访问或清理已有 tiku 业务数据库。

真实关系型测试暴露并修正了以下 InMemory 无法可靠验证的问题:

  • 测试夹具缺失的 Region、School、Subject、Category、Question 等外键实体。
  • QuestionQuestionVersion 当前版本引用形成的插入循环,改为事务内分阶段保存。
  • ReferralLead.FirstTrackIdReferralTrack.LeadId 形成的插入循环,改为事务内分阶段保存。
  • PostgreSQL JSON 映射不能将未定义的 default(JsonElement) 生成为 SQL literal缺省数组改为有效的 []
  • 徽章发放不再伪造超长 legacy ID通知使用新记录 ID 生成独立、稳定的去重键。

配置与密钥安全

  • 根配置不再提交可用于生产的 JWT signing key。
  • Development 只使用明确标识的开发 JWT keyProduction 拒绝该 key。
  • 租户第三方凭据使用 AES-256-GCM envelope 保存。
  • 每条密文使用 12-byte nonce、16-byte authentication tag。
  • AAD 绑定 tenantIdsecretRefkeyId,密文不能跨租户或跨引用替换。
  • 主密钥必须是 Base64 编码的 32 字节值Production 拒绝仓库内的开发测试 key。
  • 运行时配置键为 Security:TenantSecrets:KeyIdSecurity:TenantSecrets:MasterKey;环境变量可使用 TIKU_TENANT_SECRET_KEY_IDTIKU_TENANT_SECRET_MASTER_KEY
  • 新 schema 只保留 encryption_key_idencrypted_payloadencryption_nonceencryption_tag,不保留明文字段或明文回退读取路径。

本阶段的 EncryptTenantSecretPayloads Migration 会直接删除旧 secret_payload 字段。这是 greenfield 决策,不提供旧数据转换或兼容窗口。

验证结果

2026-07-27 在本机 PostgreSQL 18.4、.NET SDK 10.0.301 上完成:

dotnet build通过0 warning / 0 error
dotnet test通过265/265
  UnitTests16/16
  IntegrationTests真实 PostgreSQL249/249
dotnet format --verify-no-changes通过
git diff --check通过
EF Core migration script通过生成 4184 行 SQL
测试数据库清理:通过,无 tiku_it_* 残留

第二阶段退出条件

  • EF Core Migration 成为 code-first schema 的唯一版本历史。
  • API 与 Worker 不在启动时自动执行 Migration。
  • 生产数据库、JWT 和租户密钥配置缺失时 fail fast。
  • 租户第三方凭据只保存 AES-GCM 密文 envelope。
  • 集成测试完全切换到隔离的真实 PostgreSQL 数据库。
  • 修复真实数据库暴露的外键、循环依赖、JSON 和字段长度问题。
  • 全量构建、测试、格式与 Migration SQL 验证通过。