/** * 플로우 정의 서비스 */ import db from "../database/db"; import { FlowDefinition, CreateFlowDefinitionRequest, UpdateFlowDefinitionRequest, } from "../types/flow"; export class FlowDefinitionService { /** * 플로우 정의 생성 */ async create( request: CreateFlowDefinitionRequest, userId: string ): Promise { const query = ` INSERT INTO flow_definition (name, description, table_name, created_by) VALUES ($1, $2, $3, $4) RETURNING * `; const result = await db.query(query, [ request.name, request.description || null, request.tableName, userId, ]); return this.mapToFlowDefinition(result[0]); } /** * 플로우 정의 목록 조회 */ async findAll( tableName?: string, isActive?: boolean ): Promise { let query = "SELECT * FROM flow_definition WHERE 1=1"; const params: any[] = []; let paramIndex = 1; if (tableName) { query += ` AND table_name = $${paramIndex}`; params.push(tableName); paramIndex++; } if (isActive !== undefined) { query += ` AND is_active = $${paramIndex}`; params.push(isActive); paramIndex++; } query += " ORDER BY created_at DESC"; const result = await db.query(query, params); return result.map(this.mapToFlowDefinition); } /** * 플로우 정의 단일 조회 */ async findById(id: number): Promise { const query = "SELECT * FROM flow_definition WHERE id = $1"; const result = await db.query(query, [id]); if (result.length === 0) { return null; } return this.mapToFlowDefinition(result[0]); } /** * 플로우 정의 수정 */ async update( id: number, request: UpdateFlowDefinitionRequest ): Promise { const fields: string[] = []; const params: any[] = []; let paramIndex = 1; if (request.name !== undefined) { fields.push(`name = $${paramIndex}`); params.push(request.name); paramIndex++; } if (request.description !== undefined) { fields.push(`description = $${paramIndex}`); params.push(request.description); paramIndex++; } if (request.isActive !== undefined) { fields.push(`is_active = $${paramIndex}`); params.push(request.isActive); paramIndex++; } if (fields.length === 0) { return this.findById(id); } fields.push(`updated_at = NOW()`); const query = ` UPDATE flow_definition SET ${fields.join(", ")} WHERE id = $${paramIndex} RETURNING * `; params.push(id); const result = await db.query(query, params); if (result.length === 0) { return null; } return this.mapToFlowDefinition(result[0]); } /** * 플로우 정의 삭제 */ async delete(id: number): Promise { const query = "DELETE FROM flow_definition WHERE id = $1 RETURNING id"; const result = await db.query(query, [id]); return result.length > 0; } /** * 테이블 존재 여부 확인 */ async checkTableExists(tableName: string): Promise { const query = ` SELECT EXISTS ( SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1 ) as exists `; const result = await db.query(query, [tableName]); return result[0].exists; } /** * DB 행을 FlowDefinition 객체로 변환 */ private mapToFlowDefinition(row: any): FlowDefinition { return { id: row.id, name: row.name, description: row.description, tableName: row.table_name, isActive: row.is_active, createdBy: row.created_by, createdAt: row.created_at, updatedAt: row.updated_at, }; } }