diff --git a/packages/services/knowledge-service/src/migrations/AddMultiTenancyToKnowledgeService.ts b/packages/services/knowledge-service/src/migrations/AddMultiTenancyToKnowledgeService.ts new file mode 100644 index 0000000..bc4928b --- /dev/null +++ b/packages/services/knowledge-service/src/migrations/AddMultiTenancyToKnowledgeService.ts @@ -0,0 +1,125 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +/** + * 为 knowledge-service 的四张表添加 tenant_id 列 + * + * 影响的表: + * - user_memories + * - system_experiences + * - knowledge_articles + * - knowledge_chunks + * + * 使用默认租户 ID 回填现有数据 + */ +export class AddMultiTenancyToKnowledgeService1738900100000 + implements MigrationInterface +{ + name = 'AddMultiTenancyToKnowledgeService1738900100000'; + + private readonly DEFAULT_TENANT_ID = + '00000000-0000-0000-0000-000000000001'; + + public async up(queryRunner: QueryRunner): Promise { + // ========== 1. user_memories 表 ========== + await queryRunner.query( + `ALTER TABLE "user_memories" ADD COLUMN IF NOT EXISTS "tenant_id" UUID`, + ); + await queryRunner.query( + `UPDATE "user_memories" SET "tenant_id" = '${this.DEFAULT_TENANT_ID}' WHERE "tenant_id" IS NULL`, + ); + await queryRunner.query( + `ALTER TABLE "user_memories" ALTER COLUMN "tenant_id" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "user_memories" ALTER COLUMN "tenant_id" SET DEFAULT '${this.DEFAULT_TENANT_ID}'`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "idx_user_memories_tenant" ON "user_memories" ("tenant_id")`, + ); + + // ========== 2. system_experiences 表 ========== + await queryRunner.query( + `ALTER TABLE "system_experiences" ADD COLUMN IF NOT EXISTS "tenant_id" UUID`, + ); + await queryRunner.query( + `UPDATE "system_experiences" SET "tenant_id" = '${this.DEFAULT_TENANT_ID}' WHERE "tenant_id" IS NULL`, + ); + await queryRunner.query( + `ALTER TABLE "system_experiences" ALTER COLUMN "tenant_id" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "system_experiences" ALTER COLUMN "tenant_id" SET DEFAULT '${this.DEFAULT_TENANT_ID}'`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "idx_system_experiences_tenant" ON "system_experiences" ("tenant_id")`, + ); + + // ========== 3. knowledge_articles 表 ========== + await queryRunner.query( + `ALTER TABLE "knowledge_articles" ADD COLUMN IF NOT EXISTS "tenant_id" UUID`, + ); + await queryRunner.query( + `UPDATE "knowledge_articles" SET "tenant_id" = '${this.DEFAULT_TENANT_ID}' WHERE "tenant_id" IS NULL`, + ); + await queryRunner.query( + `ALTER TABLE "knowledge_articles" ALTER COLUMN "tenant_id" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "knowledge_articles" ALTER COLUMN "tenant_id" SET DEFAULT '${this.DEFAULT_TENANT_ID}'`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "idx_knowledge_articles_tenant" ON "knowledge_articles" ("tenant_id")`, + ); + + // ========== 4. knowledge_chunks 表 ========== + await queryRunner.query( + `ALTER TABLE "knowledge_chunks" ADD COLUMN IF NOT EXISTS "tenant_id" UUID`, + ); + await queryRunner.query( + `UPDATE "knowledge_chunks" SET "tenant_id" = '${this.DEFAULT_TENANT_ID}' WHERE "tenant_id" IS NULL`, + ); + await queryRunner.query( + `ALTER TABLE "knowledge_chunks" ALTER COLUMN "tenant_id" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "knowledge_chunks" ALTER COLUMN "tenant_id" SET DEFAULT '${this.DEFAULT_TENANT_ID}'`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "idx_knowledge_chunks_tenant" ON "knowledge_chunks" ("tenant_id")`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + // knowledge_chunks + await queryRunner.query( + `DROP INDEX IF EXISTS "idx_knowledge_chunks_tenant"`, + ); + await queryRunner.query( + `ALTER TABLE "knowledge_chunks" DROP COLUMN IF EXISTS "tenant_id"`, + ); + + // knowledge_articles + await queryRunner.query( + `DROP INDEX IF EXISTS "idx_knowledge_articles_tenant"`, + ); + await queryRunner.query( + `ALTER TABLE "knowledge_articles" DROP COLUMN IF EXISTS "tenant_id"`, + ); + + // system_experiences + await queryRunner.query( + `DROP INDEX IF EXISTS "idx_system_experiences_tenant"`, + ); + await queryRunner.query( + `ALTER TABLE "system_experiences" DROP COLUMN IF EXISTS "tenant_id"`, + ); + + // user_memories + await queryRunner.query( + `DROP INDEX IF EXISTS "idx_user_memories_tenant"`, + ); + await queryRunner.query( + `ALTER TABLE "user_memories" DROP COLUMN IF EXISTS "tenant_id"`, + ); + } +}