feat: Phase 3.16 데이터 관리 서비스 Raw Query 전환 완료

4개 서비스 18개 Prisma 호출 전환 완료:

1. **EnhancedDynamicFormService** (6개)
   - validateTableExists - information_schema 조회
   - getTableColumns - 테이블 컬럼 정보 조회 with 캐싱
   - getColumnWebTypes - 웹타입 정보 조회
   - getPrimaryKeys - Primary Key 조회
   - performInsert - 동적 INSERT with RETURNING
   - performUpdate - 동적 UPDATE with RETURNING

2. **DataMappingService** (5개)
   - getSourceData - 소스 테이블 데이터 조회
   - executeInsert - 동적 INSERT
   - executeUpsert - ON CONFLICT DO UPDATE
   - executeUpdate - 동적 UPDATE
   - disconnect - 제거 (Raw Query 불필요)

3. **DataService** (4개)
   - getTableData - 동적 SELECT with 동적 WHERE/ORDER BY
   - checkTableExists - information_schema 테이블 존재 확인
   - getTableColumnsSimple - 컬럼 정보 조회
   - getColumnLabel - 컬럼 라벨 조회

4. **AdminService** (3개)
   - getAdminMenuList - WITH RECURSIVE 쿼리
   - getUserMenuList - WITH RECURSIVE 쿼리
   - getMenuInfo - LEFT JOIN으로 회사 정보 포함

기술적 성과:
- 변수명 충돌 해결 (query vs sql)
- WITH RECURSIVE 쿼리 전환
- Prisma include → LEFT JOIN 전환
- 동적 쿼리 생성 (WHERE, ORDER BY)
- SQL 인젝션 방지 (컬럼명 검증)

진행률: Phase 3 173/186 (93.0%)
문서: PHASE3.16_DATA_MANAGEMENT_SERVICES_MIGRATION.md
This commit is contained in:
kjs
2025-10-01 12:27:32 +09:00
parent 1791cd9f3f
commit 3d8f70e181
6 changed files with 217 additions and 148 deletions

View File

@@ -1,4 +1,4 @@
import { PrismaClient } from "@prisma/client";
import { query } from "../database/db";
import {
DataMappingConfig,
InboundMapping,
@@ -11,10 +11,8 @@ import {
} from "../types/dataMappingTypes";
export class DataMappingService {
private prisma: PrismaClient;
constructor() {
this.prisma = new PrismaClient();
// No prisma instance needed
}
/**
@@ -404,10 +402,10 @@ export class DataMappingService {
}
// Raw SQL을 사용한 동적 쿼리
const query = `SELECT * FROM ${tableName}${mapping.sourceFilter ? ` WHERE ${mapping.sourceFilter}` : ""}`;
console.log(`🔍 [DataMappingService] 쿼리 실행: ${query}`);
const sql = `SELECT * FROM ${tableName}${mapping.sourceFilter ? ` WHERE ${mapping.sourceFilter}` : ""}`;
console.log(`🔍 [DataMappingService] 쿼리 실행: ${sql}`);
const result = await this.prisma.$queryRawUnsafe(query);
const result = await query<any>(sql, []);
return result;
} catch (error) {
console.error(
@@ -429,14 +427,14 @@ export class DataMappingService {
const values = Object.values(data);
const placeholders = values.map((_, i) => `$${i + 1}`).join(", ");
const query = `INSERT INTO ${tableName} (${columns.join(", ")}) VALUES (${placeholders})`;
const sql = `INSERT INTO ${tableName} (${columns.join(", ")}) VALUES (${placeholders})`;
console.log(`📝 [DataMappingService] INSERT 실행:`, {
table: tableName,
columns,
query,
query: sql,
});
await this.prisma.$executeRawUnsafe(query, ...values);
await query(sql, values);
}
/**
@@ -460,7 +458,7 @@ export class DataMappingService {
.map((col) => `${col} = EXCLUDED.${col}`)
.join(", ");
const query = `
const sql = `
INSERT INTO ${tableName} (${columns.join(", ")})
VALUES (${placeholders})
ON CONFLICT (${keyFields.join(", ")})
@@ -470,9 +468,9 @@ export class DataMappingService {
console.log(`🔄 [DataMappingService] UPSERT 실행:`, {
table: tableName,
keyFields,
query,
query: sql,
});
await this.prisma.$executeRawUnsafe(query, ...values);
await query(sql, values);
}
/**
@@ -503,14 +501,14 @@ export class DataMappingService {
...keyFields.map((field) => data[field]),
];
const query = `UPDATE ${tableName} SET ${updateClauses} WHERE ${whereConditions}`;
const sql = `UPDATE ${tableName} SET ${updateClauses} WHERE ${whereConditions}`;
console.log(`✏️ [DataMappingService] UPDATE 실행:`, {
table: tableName,
keyFields,
query,
query: sql,
});
await this.prisma.$executeRawUnsafe(query, ...values);
await query(sql, values);
}
/**
@@ -570,6 +568,6 @@ export class DataMappingService {
* 리소스 정리
*/
async disconnect(): Promise<void> {
await this.prisma.$disconnect();
// No disconnect needed for raw queries
}
}