fix(db): add multi-tenancy migration for knowledge-service tables

Adds tenant_id UUID column to user_memories, system_experiences,
knowledge_articles, and knowledge_chunks tables with default tenant
backfill and indexes. Migration already applied to production DB.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-06 09:23:13 -08:00
parent 20001277ff
commit dc6311f050
1 changed files with 125 additions and 0 deletions

View File

@ -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<void> {
// ========== 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<void> {
// 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"`,
);
}
}