From 5267b759bee1427f0d090a430bb9ad9a6ba708d8 Mon Sep 17 00:00:00 2001 From: ttipo Date: Tue, 30 Jun 2026 19:43:23 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=93=9C=EB=9D=BC=EC=9D=B4=EB=B8=8C=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EB=A9=B1=EB=93=B1=C2=B7=EA=B2=AC=EA=B3=A0?= =?UTF-8?q?=ED=99=94=20(=EC=9A=B4=EC=98=81=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=20=EB=B0=A9=EC=A7=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADD COLUMN IF NOT EXISTS, project_attachments 는 제약 이름 비의존 DROP TABLE IF EXISTS ... CASCADE 로 변경. 과거 synchronize 로 만들어진 운영 DB나 부분 적용 상태에서도 실패하지 않도록 함 Co-Authored-By: Claude Opus 4.8 (1M context) --- ...dDriveFileExtractDropProjectAttachments.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/backend/src/migrations/1783000000000-AddDriveFileExtractDropProjectAttachments.ts b/backend/src/migrations/1783000000000-AddDriveFileExtractDropProjectAttachments.ts index 6853e7b..7e54240 100644 --- a/backend/src/migrations/1783000000000-AddDriveFileExtractDropProjectAttachments.ts +++ b/backend/src/migrations/1783000000000-AddDriveFileExtractDropProjectAttachments.ts @@ -5,35 +5,35 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; // → 연동 폴더 문서를 NCP 에서 받아 텍스트 추출·캐싱(AI 업무 추천 주입) // - 프로젝트 직접 업로드(project_attachments) 폐기 → 테이블 제거(완전 대체) // 운영(migrationsRun)에서만 실행되며, dev 는 synchronize 로 자동 반영된다. +// +// 멱등·견고하게 작성: 과거 synchronize 로 만들어진 운영 DB(제약 이름 상이)나 +// 부분 적용 상태에서도 실패하지 않도록 IF [NOT] EXISTS / CASCADE 를 사용한다. export class AddDriveFileExtractDropProjectAttachments1783000000000 implements MigrationInterface { name = 'AddDriveFileExtractDropProjectAttachments1783000000000'; public async up(queryRunner: QueryRunner): Promise { - // 1) drive_files AI 추출 캐시 컬럼 + // 1) drive_files AI 추출 캐시 컬럼 (이미 있으면 건너뜀) await queryRunner.query( - `ALTER TABLE "drive_files" ADD "extracted_text" text`, + `ALTER TABLE "drive_files" ADD COLUMN IF NOT EXISTS "extracted_text" text`, ); await queryRunner.query( - `ALTER TABLE "drive_files" ADD "extract_status" character varying NOT NULL DEFAULT 'pending'`, + `ALTER TABLE "drive_files" ADD COLUMN IF NOT EXISTS "extract_status" character varying NOT NULL DEFAULT 'pending'`, ); // 2) project_attachments 폐기 (드라이브 연동으로 대체) + // 제약 이름에 의존하지 않도록 CASCADE 로 테이블·FK 를 한 번에 제거. await queryRunner.query( - `ALTER TABLE "project_attachments" DROP CONSTRAINT "FK_project_attachments_uploader"`, + `DROP TABLE IF EXISTS "project_attachments" CASCADE`, ); - await queryRunner.query( - `ALTER TABLE "project_attachments" DROP CONSTRAINT "FK_project_attachments_project"`, - ); - await queryRunner.query(`DROP TABLE "project_attachments"`); } public async down(queryRunner: QueryRunner): Promise { // 1) project_attachments 복원 (AddProjectAttachments + ExtractedText 와 동일 스키마) await queryRunner.query( - `CREATE TABLE "project_attachments" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying NOT NULL, "stored_name" character varying NOT NULL, "size" integer NOT NULL, "mime" character varying NOT NULL, "kind" character varying NOT NULL, "extracted_text" text, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "project_id" uuid, "uploader_id" uuid, CONSTRAINT "PK_project_attachments" PRIMARY KEY ("id"))`, + `CREATE TABLE IF NOT EXISTS "project_attachments" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying NOT NULL, "stored_name" character varying NOT NULL, "size" integer NOT NULL, "mime" character varying NOT NULL, "kind" character varying NOT NULL, "extracted_text" text, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "project_id" uuid, "uploader_id" uuid, CONSTRAINT "PK_project_attachments" PRIMARY KEY ("id"))`, ); await queryRunner.query( - `CREATE INDEX "IDX_project_attachments_project" ON "project_attachments" ("project_id")`, + `CREATE INDEX IF NOT EXISTS "IDX_project_attachments_project" ON "project_attachments" ("project_id")`, ); await queryRunner.query( `ALTER TABLE "project_attachments" ADD CONSTRAINT "FK_project_attachments_project" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, @@ -44,10 +44,10 @@ export class AddDriveFileExtractDropProjectAttachments1783000000000 implements M // 2) drive_files 추출 캐시 컬럼 제거 await queryRunner.query( - `ALTER TABLE "drive_files" DROP COLUMN "extract_status"`, + `ALTER TABLE "drive_files" DROP COLUMN IF EXISTS "extract_status"`, ); await queryRunner.query( - `ALTER TABLE "drive_files" DROP COLUMN "extracted_text"`, + `ALTER TABLE "drive_files" DROP COLUMN IF EXISTS "extracted_text"`, ); } }