ERP-node/src/services/dataflowDiagramService.ts

237 lines
5.5 KiB
TypeScript

import { query, queryOne } from "../database/db";
export interface DataflowDiagram {
diagram_id: number;
diagram_name: string;
relationships: any; // JSON 타입
company_code: string;
created_at?: Date;
updated_at?: Date;
created_by?: string;
updated_by?: string;
}
export interface CreateDataflowDiagramData {
diagram_name: string;
relationships: any;
company_code: string;
created_by?: string;
}
export interface UpdateDataflowDiagramData {
diagram_name?: string;
relationships?: any;
updated_by?: string;
}
export class DataflowDiagramService {
/**
* 관계도 목록 조회 (페이지네이션)
*/
async getDataflowDiagrams(
companyCode: string,
page: number = 1,
size: number = 20,
searchTerm: string = ""
) {
const skip = (page - 1) * size;
const whereClause: any = {
company_code: companyCode,
};
if (searchTerm) {
whereClause.diagram_name = {
contains: searchTerm,
mode: "insensitive",
};
}
// WHERE 절 구성
const whereParts: string[] = ["company_code = $1"];
const params: any[] = [companyCode];
if (searchTerm) {
whereParts.push("diagram_name ILIKE $2");
params.push(`%${searchTerm}%`);
}
const whereSQL = whereParts.join(" AND ");
const [diagrams, totalResult] = await Promise.all([
query<DataflowDiagram>(
`SELECT * FROM dataflow_diagrams
WHERE ${whereSQL}
ORDER BY created_at DESC
LIMIT $${params.length + 1} OFFSET $${params.length + 2}`,
[...params, size, skip]
),
queryOne<{ count: string }>(
`SELECT COUNT(*) as count FROM dataflow_diagrams WHERE ${whereSQL}`,
params
),
]);
const total = parseInt(totalResult?.count || "0", 10);
return {
diagrams,
pagination: {
page,
size,
total,
totalPages: Math.ceil(total / size),
},
};
}
/**
* 특정 관계도 조회
*/
async getDataflowDiagramById(
diagramId: number,
companyCode: string
): Promise<DataflowDiagram | null> {
return await queryOne<DataflowDiagram>(
`SELECT * FROM dataflow_diagrams
WHERE diagram_id = $1 AND company_code = $2`,
[diagramId, companyCode]
);
}
/**
* 관계도 생성
*/
async createDataflowDiagram(
data: CreateDataflowDiagramData
): Promise<DataflowDiagram> {
const result = await queryOne<DataflowDiagram>(
`INSERT INTO dataflow_diagrams
(diagram_name, relationships, company_code, created_by, created_at, updated_at)
VALUES ($1, $2, $3, $4, NOW(), NOW())
RETURNING *`,
[
data.diagram_name,
JSON.stringify(data.relationships),
data.company_code,
data.created_by || null,
]
);
return result!;
}
/**
* 관계도 수정
*/
async updateDataflowDiagram(
diagramId: number,
companyCode: string,
data: UpdateDataflowDiagramData
): Promise<DataflowDiagram | null> {
// 먼저 해당 관계도가 존재하는지 확인
const existingDiagram = await this.getDataflowDiagramById(
diagramId,
companyCode
);
if (!existingDiagram) {
return null;
}
// 동적 UPDATE 쿼리 생성
const updateFields: string[] = ["updated_at = NOW()"];
const params: any[] = [];
let paramIndex = 1;
if (data.diagram_name !== undefined) {
updateFields.push(`diagram_name = $${paramIndex++}`);
params.push(data.diagram_name);
}
if (data.relationships !== undefined) {
updateFields.push(`relationships = $${paramIndex++}`);
params.push(JSON.stringify(data.relationships));
}
if (data.updated_by !== undefined) {
updateFields.push(`updated_by = $${paramIndex++}`);
params.push(data.updated_by);
}
params.push(diagramId);
return await queryOne<DataflowDiagram>(
`UPDATE dataflow_diagrams
SET ${updateFields.join(", ")}
WHERE diagram_id = $${paramIndex}
RETURNING *`,
params
);
}
/**
* 관계도 삭제
*/
async deleteDataflowDiagram(
diagramId: number,
companyCode: string
): Promise<boolean> {
// 먼저 해당 관계도가 존재하는지 확인
const existingDiagram = await this.getDataflowDiagramById(
diagramId,
companyCode
);
if (!existingDiagram) {
return false;
}
await query(`DELETE FROM dataflow_diagrams WHERE diagram_id = $1`, [
diagramId,
]);
return true;
}
/**
* 관계도 복제
*/
async copyDataflowDiagram(
diagramId: number,
companyCode: string,
newName?: string,
createdBy?: string
): Promise<DataflowDiagram | null> {
const originalDiagram = await this.getDataflowDiagramById(
diagramId,
companyCode
);
if (!originalDiagram) {
return null;
}
// 복제본 이름 생성
let copyName = newName;
if (!copyName) {
// "(1)", "(2)" 형식으로 이름 생성
const baseName = originalDiagram.diagram_name;
let counter = 1;
while (true) {
copyName = `${baseName} (${counter})`;
const existing = await queryOne<DataflowDiagram>(
`SELECT * FROM dataflow_diagrams
WHERE company_code = $1 AND diagram_name = $2`,
[companyCode, copyName]
);
if (!existing) break;
counter++;
}
}
return await this.createDataflowDiagram({
diagram_name: copyName,
relationships: originalDiagram.relationships,
company_code: companyCode,
created_by: createdBy,
});
}
}