feat: Phase 3.10 EventTriggerService Raw Query 전환 완료
6개 Prisma 호출을 모두 Raw Query로 전환 - JSON 필드 검색 (JSONB 연산자 활용) - 동적 INSERT 쿼리 (PostgreSQL 플레이스홀더) - 동적 UPDATE 쿼리 (WHERE 조건 + 플레이스홀더) - 동적 DELETE 쿼리 (WHERE 조건) - UPSERT 쿼리 (ON CONFLICT) - 다이어그램 단건 조회 (findUnique → queryOne) 주요 기술적 해결: - JSON 필드 검색 ($queryRaw → query) - category::text = '"data-save"' - category::jsonb ? 'data-save' - category::jsonb @> '["data-save"]' - MySQL 플레이스홀더(?) → PostgreSQL 플레이스홀더($1, $2, ...) - 동적 테이블 INSERT/UPDATE/DELETE (보안 강화) - ON CONFLICT를 사용한 UPSERT - 조건부 실행 로직 유지 TypeScript 컴파일 성공 Prisma import 완전 제거 Phase 3 진행률: 120/162 (74.1%) 전체 진행률: 371/444 (83.6%)
This commit is contained in:
parent
16d4ba4a51
commit
134d24579c
|
|
@ -131,7 +131,7 @@ backend-node/ (루트)
|
|||
- `layoutService.ts` (0개) - ✅ **전환 완료** (Phase 3.7)
|
||||
- `dbTypeCategoryService.ts` (0개) - ✅ **전환 완료** (Phase 3.8)
|
||||
- `templateStandardService.ts` (0개) - ✅ **전환 완료** (Phase 3.9)
|
||||
- `eventTriggerService.ts` (6개) - JSON 검색 쿼리
|
||||
- `eventTriggerService.ts` (0개) - ✅ **전환 완료** (Phase 3.10)
|
||||
|
||||
#### 🟡 **중간 (단순 CRUD) - 3순위**
|
||||
|
||||
|
|
@ -1214,6 +1214,16 @@ describe("Performance Benchmarks", () => {
|
|||
- [x] DISTINCT 쿼리 (카테고리 목록)
|
||||
- [x] TypeScript 컴파일 성공
|
||||
- [x] Prisma import 완전 제거
|
||||
- [x] **EventTriggerService 전환 (6개)** ✅ **완료** (Phase 3.10)
|
||||
- [x] 6개 Prisma 호출 전환 완료 (이벤트 트리거, JSON 검색)
|
||||
- [x] JSON 필드 검색 ($queryRaw → query, JSONB 연산자)
|
||||
- [x] 동적 INSERT 쿼리 (PostgreSQL 플레이스홀더)
|
||||
- [x] 동적 UPDATE 쿼리 (WHERE 조건 + 플레이스홀더)
|
||||
- [x] 동적 DELETE 쿼리 (WHERE 조건)
|
||||
- [x] UPSERT 쿼리 (ON CONFLICT)
|
||||
- [x] 다이어그램 조회 (findUnique → queryOne)
|
||||
- [x] TypeScript 컴파일 성공
|
||||
- [x] Prisma import 완전 제거
|
||||
- [ ] 배치 관련 서비스 전환 (26개) ⭐ 대규모 신규 발견
|
||||
- [ ] BatchExternalDbService (8개)
|
||||
- [ ] BatchExecutionLogService (7개), BatchManagementService (5개)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
import { PrismaClient } from "@prisma/client";
|
||||
import { query, queryOne } from "../database/db";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
// 조건 노드 타입 정의
|
||||
interface ConditionNode {
|
||||
id: string; // 고유 ID
|
||||
|
|
@ -92,15 +90,16 @@ export class EventTriggerService {
|
|||
|
||||
try {
|
||||
// 🔥 수정: Raw SQL을 사용하여 JSON 배열 검색
|
||||
const diagrams = (await prisma.$queryRaw`
|
||||
SELECT * FROM dataflow_diagrams
|
||||
WHERE company_code = ${companyCode}
|
||||
AND (
|
||||
category::text = '"data-save"' OR
|
||||
category::jsonb ? 'data-save' OR
|
||||
category::jsonb @> '["data-save"]'
|
||||
)
|
||||
`) as any[];
|
||||
const diagrams = await query<any>(
|
||||
`SELECT * FROM dataflow_diagrams
|
||||
WHERE company_code = $1
|
||||
AND (
|
||||
category::text = '"data-save"' OR
|
||||
category::jsonb ? 'data-save' OR
|
||||
category::jsonb @> '["data-save"]'
|
||||
)`,
|
||||
[companyCode]
|
||||
);
|
||||
|
||||
// 각 관계도에서 해당 테이블을 소스로 하는 데이터 저장 관계들 필터링
|
||||
const matchingDiagrams = diagrams.filter((diagram) => {
|
||||
|
|
@ -537,13 +536,14 @@ export class EventTriggerService {
|
|||
data: Record<string, any>
|
||||
): Promise<void> {
|
||||
// 동적 테이블 INSERT 실행
|
||||
const sql = `INSERT INTO ${tableName} (${Object.keys(data).join(", ")}) VALUES (${Object.keys(
|
||||
data
|
||||
)
|
||||
.map(() => "?")
|
||||
.join(", ")})`;
|
||||
// PostgreSQL 파라미터 플레이스홀더로 변경 (? → $1, $2, ...)
|
||||
const values = Object.values(data);
|
||||
const placeholders = values.map((_, i) => `$${i + 1}`).join(", ");
|
||||
const sql = `INSERT INTO ${tableName} (${Object.keys(data).join(
|
||||
", "
|
||||
)}) VALUES (${placeholders})`;
|
||||
|
||||
await prisma.$executeRawUnsafe(sql, ...Object.values(data));
|
||||
await query(sql, values);
|
||||
logger.info(`Inserted data into ${tableName}:`, data);
|
||||
}
|
||||
|
||||
|
|
@ -563,14 +563,15 @@ export class EventTriggerService {
|
|||
}
|
||||
|
||||
// 동적 테이블 UPDATE 실행
|
||||
const values = Object.values(data);
|
||||
const setClause = Object.keys(data)
|
||||
.map((key) => `${key} = ?`)
|
||||
.map((key, i) => `${key} = $${i + 1}`)
|
||||
.join(", ");
|
||||
const whereClause = this.buildWhereClause(conditions);
|
||||
|
||||
const sql = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`;
|
||||
|
||||
await prisma.$executeRawUnsafe(sql, ...Object.values(data));
|
||||
await query(sql, values);
|
||||
logger.info(`Updated data in ${tableName}:`, data);
|
||||
}
|
||||
|
||||
|
|
@ -593,7 +594,7 @@ export class EventTriggerService {
|
|||
const whereClause = this.buildWhereClause(conditions);
|
||||
const sql = `DELETE FROM ${tableName} WHERE ${whereClause}`;
|
||||
|
||||
await prisma.$executeRawUnsafe(sql);
|
||||
await query(sql, []);
|
||||
logger.info(`Deleted data from ${tableName} with conditions`);
|
||||
}
|
||||
|
||||
|
|
@ -608,15 +609,16 @@ export class EventTriggerService {
|
|||
const columns = Object.keys(data);
|
||||
const values = Object.values(data);
|
||||
const conflictColumns = ["id", "company_code"]; // 기본 충돌 컬럼
|
||||
const placeholders = values.map((_, i) => `$${i + 1}`).join(", ");
|
||||
|
||||
const sql = `
|
||||
INSERT INTO ${tableName} (${columns.join(", ")})
|
||||
VALUES (${columns.map(() => "?").join(", ")})
|
||||
VALUES (${placeholders})
|
||||
ON CONFLICT (${conflictColumns.join(", ")})
|
||||
DO UPDATE SET ${columns.map((col) => `${col} = EXCLUDED.${col}`).join(", ")}
|
||||
`;
|
||||
|
||||
await prisma.$executeRawUnsafe(sql, ...values);
|
||||
await query(sql, values);
|
||||
logger.info(`Upserted data into ${tableName}:`, data);
|
||||
}
|
||||
|
||||
|
|
@ -678,9 +680,10 @@ export class EventTriggerService {
|
|||
companyCode: string
|
||||
): Promise<{ conditionMet: boolean; result?: ExecutionResult }> {
|
||||
try {
|
||||
const diagram = await prisma.dataflow_diagrams.findUnique({
|
||||
where: { diagram_id: diagramId },
|
||||
});
|
||||
const diagram = await queryOne<any>(
|
||||
`SELECT * FROM dataflow_diagrams WHERE diagram_id = $1`,
|
||||
[diagramId]
|
||||
);
|
||||
|
||||
if (!diagram) {
|
||||
throw new Error(`Diagram ${diagramId} not found`);
|
||||
|
|
|
|||
Loading…
Reference in New Issue