From e5180b765955dca3c9197114ab1ad7273eb9135f Mon Sep 17 00:00:00 2001 From: kjs Date: Wed, 1 Oct 2025 10:14:16 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Phase=202.5=20&=202.6=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20-=20ExternalDbConnectionService=20+=20DataflowContr?= =?UTF-8?q?olService=20Raw=20Query=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2.5: ExternalDbConnectionService (15개) - 15개 Prisma 호출을 모두 Raw Query로 전환 - 동적 WHERE 조건 생성 및 동적 UPDATE 쿼리 구현 - 비밀번호 암호화/복호화 로직 유지 - ILIKE 검색 지원 Phase 2.6: DataflowControlService (6개) - 6개 Prisma 호출을 모두 Raw Query로 전환 - 파라미터 바인딩 수정 (MySQL ? → PostgreSQL $1, $2) - 복잡한 비즈니스 로직 및 다중 커넥션 지원 유지 - 조건부 실행, 에러 처리 로직 보존 전체 성과: - TypeScript 컴파일 성공 (linter 에러 0개) - Prisma import 완전 제거 - Phase 2 진행률: 152/162 (93.8%) - 전체 진행률: 238/444 (53.6%) --- PHASE2.6_DATAFLOW_CONTROL_MIGRATION.md | 46 ++++++++++++----- PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md | 12 +++-- .../src/services/dataflowControlService.ts | 51 ++++++++----------- 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/PHASE2.6_DATAFLOW_CONTROL_MIGRATION.md b/PHASE2.6_DATAFLOW_CONTROL_MIGRATION.md index 7c17308a..d8ce39c6 100644 --- a/PHASE2.6_DATAFLOW_CONTROL_MIGRATION.md +++ b/PHASE2.6_DATAFLOW_CONTROL_MIGRATION.md @@ -9,11 +9,12 @@ DataflowControlService는 **6개의 Prisma 호출**이 있으며, 데이터플 | 항목 | 내용 | | --------------- | ----------------------------------------------------- | | 파일 위치 | `backend-node/src/services/dataflowControlService.ts` | -| 파일 크기 | 600+ 라인 | -| Prisma 호출 | 6개 | -| **현재 진행률** | **0/6 (0%)** ⏳ **진행 예정** | +| 파일 크기 | 1,100+ 라인 | +| Prisma 호출 | 0개 (전환 완료) | +| **현재 진행률** | **6/6 (100%)** ✅ **완료** | | 복잡도 | 높음 (복잡한 비즈니스 로직) | | 우선순위 | 🟡 중간 (Phase 2.6) | +| **상태** | ✅ **전환 완료 및 컴파일 성공** | ### 🎯 전환 목표 @@ -163,16 +164,34 @@ await transaction(async (client) => { --- +## 📋 전환 완료 내역 + +### ✅ 전환된 함수들 (6개 Prisma 호출) + +1. **executeDataflowControl()** - 관계도 정보 조회 (findUnique → queryOne) +2. **evaluateActionConditions()** - 대상 테이블 조건 확인 ($queryRawUnsafe → query) +3. **executeInsertAction()** - INSERT 실행 ($executeRawUnsafe → query) +4. **executeUpdateAction()** - UPDATE 실행 ($executeRawUnsafe → query) +5. **executeDeleteAction()** - DELETE 실행 ($executeRawUnsafe → query) +6. **checkColumnExists()** - 컬럼 존재 확인 ($queryRawUnsafe → query) + +### 🔧 주요 기술적 해결 사항 + +1. **Prisma import 완전 제거**: `import { query, queryOne } from "../database/db"` +2. **동적 테이블 쿼리 전환**: `$queryRawUnsafe` / `$executeRawUnsafe` → `query()` +3. **파라미터 바인딩 수정**: MySQL `?` → PostgreSQL `$1, $2...` +4. **복잡한 비즈니스 로직 유지**: 조건부 실행, 다중 커넥션, 에러 처리 + ## 🎯 완료 기준 -- [ ] **6개 모든 Prisma 호출을 Raw Query로 전환 완료** -- [ ] **모든 TypeScript 컴파일 오류 해결** -- [ ] **트랜잭션 정상 동작 확인** -- [ ] **복잡한 비즈니스 로직 정상 동작** -- [ ] **모든 단위 테스트 통과 (10개)** -- [ ] **모든 통합 테스트 작성 완료 (4개 시나리오)** -- [ ] **`import prisma` 완전 제거 및 `import { query, transaction } from "../database/db"` 사용** -- [ ] **성능 저하 없음** +- [x] **6개 모든 Prisma 호출을 Raw Query로 전환 완료** ✅ +- [x] **모든 TypeScript 컴파일 오류 해결** ✅ +- [x] **`import prisma` 완전 제거** ✅ +- [ ] **트랜잭션 정상 동작 확인** ⏳ +- [ ] **복잡한 비즈니스 로직 정상 동작** ⏳ +- [ ] **모든 단위 테스트 통과 (10개)** ⏳ +- [ ] **모든 통합 테스트 작성 완료 (4개 시나리오)** ⏳ +- [ ] **성능 저하 없음** ⏳ --- @@ -198,8 +217,9 @@ await transaction(async (client) => { --- **작성일**: 2025-09-30 -**예상 소요 시간**: 1일 +**완료일**: 2025-10-01 +**소요 시간**: 30분 **담당자**: 백엔드 개발팀 **우선순위**: 🟡 중간 (Phase 2.6) -**상태**: ⏳ **진행 예정** +**상태**: ✅ **전환 완료** (테스트 필요) **특이사항**: 복잡한 비즈니스 로직이 포함되어 있어 신중한 테스트 필요 diff --git a/PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md b/PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md index 4db80830..4f5978da 100644 --- a/PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md +++ b/PRISMA_TO_RAW_QUERY_MIGRATION_PLAN.md @@ -30,7 +30,7 @@ backend-node/src/services/ ├── dataflowService.ts # 데이터플로우 (0개 호출) ✅ 전환 완료 ├── dynamicFormService.ts # 동적 폼 (15개 호출) ├── externalDbConnectionService.ts # 외부DB (0개 호출) ✅ 전환 완료 -├── dataflowControlService.ts # 제어관리 (6개 호출) +├── dataflowControlService.ts # 제어관리 (0개 호출) ✅ 전환 완료 ├── ddlExecutionService.ts # DDL 실행 (6개 호출) ├── authService.ts # 인증 (5개 호출) └── multiConnectionQueryService.ts # 다중 연결 (4개 호출) @@ -115,7 +115,7 @@ backend-node/ (루트) - `dataflowService.ts` (0개) - ✅ **전환 완료** (Phase 2.3) - `dynamicFormService.ts` (15개) - UPSERT 및 동적 테이블 처리 - `externalDbConnectionService.ts` (0개) - ✅ **전환 완료** (Phase 2.5) -- `dataflowControlService.ts` (6개) - 복잡한 제어 로직 +- `dataflowControlService.ts` (0개) - ✅ **전환 완료** (Phase 2.6) - `enhancedDataflowControlService.ts` (0개) - 다중 연결 제어 (Raw Query만 사용) - `multiConnectionQueryService.ts` (4개) - 외부 DB 연결 @@ -1110,8 +1110,12 @@ describe("Performance Benchmarks", () => { - [x] TypeScript 컴파일 성공 - [x] Prisma import 완전 제거 - 📄 **[PHASE2.5_EXTERNAL_DB_CONNECTION_MIGRATION.md](PHASE2.5_EXTERNAL_DB_CONNECTION_MIGRATION.md)** -- [ ] **DataflowControlService 전환 (6개)** - Phase 2.6 🟡 중간 우선순위 - - 6개 Prisma 호출 (복잡한 비즈니스 로직) +- [x] **DataflowControlService 전환 (6개)** ✅ **완료** (Phase 2.6) + - [x] 6개 Prisma 호출 전환 완료 (데이터플로우 제어 + 동적 테이블 CRUD) + - [x] 파라미터 바인딩 수정 (MySQL → PostgreSQL 스타일) + - [x] 복잡한 비즈니스 로직 유지 + - [x] TypeScript 컴파일 성공 + - [x] Prisma import 완전 제거 - 📄 **[PHASE2.6_DATAFLOW_CONTROL_MIGRATION.md](PHASE2.6_DATAFLOW_CONTROL_MIGRATION.md)** #### ✅ 다른 Phase로 이동 diff --git a/backend-node/src/services/dataflowControlService.ts b/backend-node/src/services/dataflowControlService.ts index daefcadd..a1ff010f 100644 --- a/backend-node/src/services/dataflowControlService.ts +++ b/backend-node/src/services/dataflowControlService.ts @@ -1,5 +1,4 @@ -// 🔧 Prisma 클라이언트 중복 생성 방지 - 기존 인스턴스 재사용 -import prisma = require("../config/database"); +import { query, queryOne } from "../database/db"; export interface ControlCondition { id: string; @@ -82,9 +81,10 @@ export class DataflowControlService { }); // 관계도 정보 조회 - const diagram = await prisma.dataflow_diagrams.findUnique({ - where: { diagram_id: diagramId }, - }); + const diagram = await queryOne( + `SELECT * FROM dataflow_diagrams WHERE diagram_id = $1`, + [diagramId] + ); if (!diagram) { return { @@ -527,9 +527,9 @@ export class DataflowControlService { } // 대상 테이블에서 조건에 맞는 데이터 조회 - const queryResult = await prisma.$queryRawUnsafe( + const queryResult = await query>( `SELECT ${condition.field} FROM ${tableName} WHERE ${condition.field} = $1 LIMIT 1`, - condition.value + [condition.value] ); dataToCheck = @@ -758,14 +758,14 @@ export class DataflowControlService { try { // 동적 테이블 INSERT 실행 - const result = await prisma.$executeRawUnsafe( - ` - INSERT INTO ${targetTable} (${Object.keys(insertData).join(", ")}) - VALUES (${Object.keys(insertData) - .map(() => "?") - .join(", ")}) - `, - ...Object.values(insertData) + const placeholders = Object.keys(insertData) + .map((_, i) => `$${i + 1}`) + .join(", "); + + const result = await query( + `INSERT INTO ${targetTable} (${Object.keys(insertData).join(", ")}) + VALUES (${placeholders})`, + Object.values(insertData) ); results.push({ @@ -878,10 +878,7 @@ export class DataflowControlService { ); console.log(`📊 쿼리 파라미터:`, allValues); - const result = await prisma.$executeRawUnsafe( - updateQuery, - ...allValues - ); + const result = await query(updateQuery, allValues); console.log( `✅ UPDATE 성공 (${i + 1}/${action.fieldMappings.length}):`, @@ -1033,10 +1030,7 @@ export class DataflowControlService { console.log(`🚀 실행할 쿼리:`, deleteQuery); console.log(`📊 쿼리 파라미터:`, whereValues); - const result = await prisma.$executeRawUnsafe( - deleteQuery, - ...whereValues - ); + const result = await query(deleteQuery, whereValues); console.log(`✅ DELETE 성공:`, { table: tableName, @@ -1089,18 +1083,15 @@ export class DataflowControlService { columnName: string ): Promise { try { - const result = await prisma.$queryRawUnsafe>( - ` - SELECT EXISTS ( + const result = await query<{ exists: boolean }>( + `SELECT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2 AND table_schema = 'public' - ) as exists - `, - tableName, - columnName + ) as exists`, + [tableName, columnName] ); return result[0]?.exists || false;