ERP-node/backend-node/src/services/dataflowDiagramService.ts

387 lines
9.8 KiB
TypeScript
Raw Normal View History

2025-09-15 15:12:02 +09:00
import { PrismaClient, Prisma } from "@prisma/client";
import { logger } from "../utils/logger";
const prisma = new PrismaClient();
// 타입 정의
interface CreateDataflowDiagramData {
diagram_name: string;
2025-09-15 15:12:02 +09:00
relationships: Record<string, unknown>; // JSON 데이터
node_positions?: Record<string, unknown> | null; // JSON 데이터 (노드 위치 정보)
2025-09-12 09:49:53 +09:00
2025-09-15 20:07:28 +09:00
// 🔥 수정: 배열 구조로 변경된 조건부 연결 관련 필드
control?: Array<Record<string, unknown>> | null; // JSON 배열 (각 관계별 조건 설정)
category?: Array<Record<string, unknown>> | null; // JSON 배열 (각 관계별 연결 종류)
plan?: Array<Record<string, unknown>> | null; // JSON 배열 (각 관계별 실행 계획)
2025-09-12 09:49:53 +09:00
company_code: string;
created_by: string;
updated_by: string;
}
interface UpdateDataflowDiagramData {
diagram_name?: string;
2025-09-15 15:12:02 +09:00
relationships?: Record<string, unknown>; // JSON 데이터
node_positions?: Record<string, unknown> | null; // JSON 데이터 (노드 위치 정보)
2025-09-12 09:49:53 +09:00
2025-09-15 20:07:28 +09:00
// 🔥 수정: 배열 구조로 변경된 조건부 연결 관련 필드
control?: Array<Record<string, unknown>> | null; // JSON 배열 (각 관계별 조건 설정)
category?: Array<Record<string, unknown>> | null; // JSON 배열 (각 관계별 연결 종류)
plan?: Array<Record<string, unknown>> | null; // JSON 배열 (각 관계별 실행 계획)
2025-09-12 09:49:53 +09:00
updated_by: string;
}
/**
* ()
*/
export const getDataflowDiagrams = async (
companyCode: string,
page: number = 1,
size: number = 20,
searchTerm?: string
) => {
try {
const offset = (page - 1) * size;
// 검색 조건 구성
2025-09-15 15:12:02 +09:00
const whereClause: {
company_code?: string;
diagram_name?: {
contains: string;
mode: "insensitive";
};
} = {};
// 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 {
2025-09-15 15:12:02 +09:00
const whereClause: {
diagram_id: number;
company_code?: string;
} = {
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,
2025-09-15 15:12:02 +09:00
relationships: data.relationships as Prisma.InputJsonValue,
node_positions: data.node_positions as
| Prisma.InputJsonValue
| undefined,
2025-09-15 20:07:28 +09:00
category: data.category
? (data.category as Prisma.InputJsonValue)
: undefined,
control: data.control as Prisma.InputJsonValue | undefined,
plan: data.plan as Prisma.InputJsonValue | undefined,
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 {
2025-09-15 15:12:02 +09:00
logger.info(
`관계도 수정 서비스 시작 - ID: ${diagramId}, Company: ${companyCode}`
);
// 먼저 해당 관계도가 존재하는지 확인
2025-09-15 15:12:02 +09:00
const whereClause: {
diagram_id: number;
company_code?: string;
} = {
diagram_id: diagramId,
};
// company_code가 '*'가 아닌 경우에만 필터링
if (companyCode !== "*") {
whereClause.company_code = companyCode;
}
const existingDiagram = await prisma.dataflow_diagrams.findFirst({
where: whereClause,
});
2025-09-15 15:12:02 +09:00
logger.info(
`기존 관계도 조회 결과:`,
existingDiagram ? `ID ${existingDiagram.diagram_id} 발견` : "관계도 없음"
);
if (!existingDiagram) {
2025-09-15 15:12:02 +09:00
logger.warn(
`관계도 ID ${diagramId}를 찾을 수 없음 - Company: ${companyCode}`
);
return null;
}
// 업데이트 실행
const updatedDiagram = await prisma.dataflow_diagrams.update({
where: {
diagram_id: diagramId,
},
data: {
...(data.diagram_name && { diagram_name: data.diagram_name }),
2025-09-15 15:12:02 +09:00
...(data.relationships && {
relationships: data.relationships as Prisma.InputJsonValue,
}),
...(data.node_positions !== undefined && {
2025-09-15 15:12:02 +09:00
node_positions: data.node_positions
? (data.node_positions as Prisma.InputJsonValue)
: Prisma.JsonNull,
}),
2025-09-15 20:07:28 +09:00
...(data.category !== undefined && {
category: data.category
? (data.category as Prisma.InputJsonValue)
: undefined,
}),
...(data.control !== undefined && {
control: data.control as Prisma.InputJsonValue | undefined,
}),
...(data.plan !== undefined && {
plan: data.plan as Prisma.InputJsonValue | undefined,
}),
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 {
// 먼저 해당 관계도가 존재하는지 확인
2025-09-15 15:12:02 +09:00
const whereClause: {
diagram_id: number;
company_code?: string;
} = {
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 {
// 원본 관계도 조회
2025-09-15 15:12:02 +09:00
const whereClause: {
diagram_id: number;
company_code?: string;
} = {
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;
// 같은 패턴의 이름들을 찾아서 가장 큰 번호 찾기
2025-09-15 15:12:02 +09:00
const copyWhereClause: {
diagram_name: {
startsWith: string;
};
company_code?: string;
} = {
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,
2025-09-15 15:12:02 +09:00
relationships: originalDiagram.relationships as Prisma.InputJsonValue,
node_positions: originalDiagram.node_positions
? (originalDiagram.node_positions as Prisma.InputJsonValue)
: Prisma.JsonNull,
category: originalDiagram.category || undefined,
company_code: companyCode,
created_by: userId,
updated_by: userId,
},
});
return copiedDiagram;
} catch (error) {
logger.error("관계도 복제 서비스 오류:", error);
throw error;
}
};