import { PrismaClient } from "@prisma/client"; import { logger } from "../utils/logger"; const prisma = new PrismaClient(); // 타입 정의 interface CreateDataflowDiagramData { diagram_name: string; relationships: any; // JSON 데이터 node_positions?: any; // JSON 데이터 (노드 위치 정보) // 조건부 연결 관련 필드 control?: any; // JSON 데이터 (조건 설정) category?: any; // JSON 데이터 (연결 종류) plan?: any; // JSON 데이터 (실행 계획) company_code: string; created_by: string; updated_by: string; } interface UpdateDataflowDiagramData { diagram_name?: string; relationships?: any; // JSON 데이터 node_positions?: any; // JSON 데이터 (노드 위치 정보) // 조건부 연결 관련 필드 control?: any; // JSON 데이터 (조건 설정) category?: any; // JSON 데이터 (연결 종류) plan?: any; // JSON 데이터 (실행 계획) updated_by: string; } /** * 관계도 목록 조회 (페이지네이션) */ export const getDataflowDiagrams = async ( companyCode: string, page: number = 1, size: number = 20, searchTerm?: string ) => { try { const offset = (page - 1) * size; // 검색 조건 구성 const whereClause: any = {}; // company_code가 '*'가 아닌 경우에만 필터링 if (companyCode !== "*") { whereClause.company_code = companyCode; } if (searchTerm) { whereClause.diagram_name = { contains: searchTerm, mode: "insensitive", }; } // 총 개수 조회 const total = await prisma.dataflow_diagrams.count({ where: whereClause, }); // 데이터 조회 const diagrams = await prisma.dataflow_diagrams.findMany({ where: whereClause, orderBy: { updated_at: "desc", }, skip: offset, take: size, }); const totalPages = Math.ceil(total / size); return { diagrams, pagination: { page, size, total, totalPages, }, }; } catch (error) { logger.error("관계도 목록 조회 서비스 오류:", error); throw error; } }; /** * 특정 관계도 조회 */ export const getDataflowDiagramById = async ( diagramId: number, companyCode: string ) => { try { const whereClause: any = { diagram_id: diagramId, }; // company_code가 '*'가 아닌 경우에만 필터링 if (companyCode !== "*") { whereClause.company_code = companyCode; } const diagram = await prisma.dataflow_diagrams.findFirst({ where: whereClause, }); return diagram; } catch (error) { logger.error("관계도 조회 서비스 오류:", error); throw error; } }; /** * 새로운 관계도 생성 */ export const createDataflowDiagram = async ( data: CreateDataflowDiagramData ) => { try { const newDiagram = await prisma.dataflow_diagrams.create({ data: { diagram_name: data.diagram_name, relationships: data.relationships, node_positions: data.node_positions || null, company_code: data.company_code, created_by: data.created_by, updated_by: data.updated_by, }, }); return newDiagram; } catch (error) { logger.error("관계도 생성 서비스 오류:", error); throw error; } }; /** * 관계도 수정 */ export const updateDataflowDiagram = async ( diagramId: number, data: UpdateDataflowDiagramData, companyCode: string ) => { try { // 먼저 해당 관계도가 존재하는지 확인 const whereClause: any = { diagram_id: diagramId, }; // company_code가 '*'가 아닌 경우에만 필터링 if (companyCode !== "*") { whereClause.company_code = companyCode; } const existingDiagram = await prisma.dataflow_diagrams.findFirst({ where: whereClause, }); if (!existingDiagram) { return null; } // 업데이트 실행 const updatedDiagram = await prisma.dataflow_diagrams.update({ where: { diagram_id: diagramId, }, data: { ...(data.diagram_name && { diagram_name: data.diagram_name }), ...(data.relationships && { relationships: data.relationships }), ...(data.node_positions !== undefined && { node_positions: data.node_positions, }), updated_by: data.updated_by, updated_at: new Date(), }, }); return updatedDiagram; } catch (error) { logger.error("관계도 수정 서비스 오류:", error); throw error; } }; /** * 관계도 삭제 */ export const deleteDataflowDiagram = async ( diagramId: number, companyCode: string ) => { try { // 먼저 해당 관계도가 존재하는지 확인 const whereClause: any = { diagram_id: diagramId, }; // company_code가 '*'가 아닌 경우에만 필터링 if (companyCode !== "*") { whereClause.company_code = companyCode; } const existingDiagram = await prisma.dataflow_diagrams.findFirst({ where: whereClause, }); if (!existingDiagram) { return false; } // 삭제 실행 await prisma.dataflow_diagrams.delete({ where: { diagram_id: diagramId, }, }); return true; } catch (error) { logger.error("관계도 삭제 서비스 오류:", error); throw error; } }; /** * 관계도 복제 */ export const copyDataflowDiagram = async ( diagramId: number, companyCode: string, newName?: string, userId: string = "SYSTEM" ) => { try { // 원본 관계도 조회 const whereClause: any = { diagram_id: diagramId, }; // company_code가 '*'가 아닌 경우에만 필터링 if (companyCode !== "*") { whereClause.company_code = companyCode; } const originalDiagram = await prisma.dataflow_diagrams.findFirst({ where: whereClause, }); if (!originalDiagram) { return null; } // 새로운 이름 생성 (제공되지 않은 경우) let copyName = newName; if (!copyName) { // 기존 이름에서 (n) 패턴을 찾아서 증가 const baseNameMatch = originalDiagram.diagram_name.match( /^(.+?)(\s*\((\d+)\))?$/ ); const baseName = baseNameMatch ? baseNameMatch[1] : originalDiagram.diagram_name; // 같은 패턴의 이름들을 찾아서 가장 큰 번호 찾기 const copyWhereClause: any = { diagram_name: { startsWith: baseName, }, }; // company_code가 '*'가 아닌 경우에만 필터링 if (companyCode !== "*") { copyWhereClause.company_code = companyCode; } const existingCopies = await prisma.dataflow_diagrams.findMany({ where: copyWhereClause, select: { diagram_name: true, }, }); let maxNumber = 0; existingCopies.forEach((copy) => { const match = copy.diagram_name.match(/\((\d+)\)$/); if (match) { const num = parseInt(match[1]); if (num > maxNumber) { maxNumber = num; } } }); copyName = `${baseName} (${maxNumber + 1})`; } // 새로운 관계도 생성 const copiedDiagram = await prisma.dataflow_diagrams.create({ data: { diagram_name: copyName, relationships: originalDiagram.relationships as any, company_code: companyCode, created_by: userId, updated_by: userId, }, }); return copiedDiagram; } catch (error) { logger.error("관계도 복제 서비스 오류:", error); throw error; } };