데이터 관계도 삭제, 복사 구현
This commit is contained in:
@@ -718,3 +718,111 @@ export async function getDiagramRelationships(
|
||||
res.status(500).json(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 관계도 복사
|
||||
*/
|
||||
export async function copyDiagram(
|
||||
req: AuthenticatedRequest,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
try {
|
||||
const { diagramName } = req.params;
|
||||
const companyCode = (req.user as any)?.company_code || "*";
|
||||
|
||||
if (!diagramName) {
|
||||
const response: ApiResponse<null> = {
|
||||
success: false,
|
||||
message: "관계도 이름이 필요합니다.",
|
||||
error: {
|
||||
code: "MISSING_DIAGRAM_NAME",
|
||||
details: "diagramName 파라미터가 필요합니다.",
|
||||
},
|
||||
};
|
||||
res.status(400).json(response);
|
||||
return;
|
||||
}
|
||||
|
||||
const dataflowService = new DataflowService();
|
||||
const newDiagramName = await dataflowService.copyDiagram(
|
||||
companyCode,
|
||||
decodeURIComponent(diagramName)
|
||||
);
|
||||
|
||||
const response: ApiResponse<{ newDiagramName: string }> = {
|
||||
success: true,
|
||||
message: "관계도가 성공적으로 복사되었습니다.",
|
||||
data: { newDiagramName },
|
||||
};
|
||||
|
||||
res.status(200).json(response);
|
||||
} catch (error) {
|
||||
logger.error("관계도 복사 실패:", error);
|
||||
const response: ApiResponse<null> = {
|
||||
success: false,
|
||||
message: "관계도 복사에 실패했습니다.",
|
||||
error: {
|
||||
code: "DIAGRAM_COPY_FAILED",
|
||||
details:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "알 수 없는 오류가 발생했습니다.",
|
||||
},
|
||||
};
|
||||
res.status(500).json(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 관계도 삭제
|
||||
*/
|
||||
export async function deleteDiagram(
|
||||
req: AuthenticatedRequest,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
try {
|
||||
const { diagramName } = req.params;
|
||||
const companyCode = (req.user as any)?.company_code || "*";
|
||||
|
||||
if (!diagramName) {
|
||||
const response: ApiResponse<null> = {
|
||||
success: false,
|
||||
message: "관계도 이름이 필요합니다.",
|
||||
error: {
|
||||
code: "MISSING_DIAGRAM_NAME",
|
||||
details: "diagramName 파라미터가 필요합니다.",
|
||||
},
|
||||
};
|
||||
res.status(400).json(response);
|
||||
return;
|
||||
}
|
||||
|
||||
const dataflowService = new DataflowService();
|
||||
const deletedCount = await dataflowService.deleteDiagram(
|
||||
companyCode,
|
||||
decodeURIComponent(diagramName)
|
||||
);
|
||||
|
||||
const response: ApiResponse<{ deletedCount: number }> = {
|
||||
success: true,
|
||||
message: "관계도가 성공적으로 삭제되었습니다.",
|
||||
data: { deletedCount },
|
||||
};
|
||||
|
||||
res.status(200).json(response);
|
||||
} catch (error) {
|
||||
logger.error("관계도 삭제 실패:", error);
|
||||
const response: ApiResponse<null> = {
|
||||
success: false,
|
||||
message: "관계도 삭제에 실패했습니다.",
|
||||
error: {
|
||||
code: "DIAGRAM_DELETE_FAILED",
|
||||
details:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "알 수 없는 오류가 발생했습니다.",
|
||||
},
|
||||
};
|
||||
res.status(500).json(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
getTableData,
|
||||
getDataFlowDiagrams,
|
||||
getDiagramRelationships,
|
||||
copyDiagram,
|
||||
deleteDiagram,
|
||||
} from "../controllers/dataflowController";
|
||||
|
||||
const router = express.Router();
|
||||
@@ -94,4 +96,16 @@ router.get("/diagrams", getDataFlowDiagrams);
|
||||
*/
|
||||
router.get("/diagrams/:diagramName/relationships", getDiagramRelationships);
|
||||
|
||||
/**
|
||||
* 관계도 복사
|
||||
* POST /api/dataflow/diagrams/:diagramName/copy
|
||||
*/
|
||||
router.post("/diagrams/:diagramName/copy", copyDiagram);
|
||||
|
||||
/**
|
||||
* 관계도 삭제
|
||||
* DELETE /api/dataflow/diagrams/:diagramName
|
||||
*/
|
||||
router.delete("/diagrams/:diagramName", deleteDiagram);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -889,4 +889,113 @@ export class DataflowService {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 관계도 복사
|
||||
*/
|
||||
async copyDiagram(
|
||||
companyCode: string,
|
||||
originalDiagramName: string
|
||||
): Promise<string> {
|
||||
try {
|
||||
logger.info(`DataflowService: 관계도 복사 시작 - ${originalDiagramName}`);
|
||||
|
||||
// 원본 관계도의 모든 관계 조회
|
||||
const originalRelationships = await prisma.table_relationships.findMany({
|
||||
where: {
|
||||
company_code: companyCode,
|
||||
relationship_name: originalDiagramName,
|
||||
is_active: "Y",
|
||||
},
|
||||
});
|
||||
|
||||
if (originalRelationships.length === 0) {
|
||||
throw new Error("복사할 관계도를 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
// 새로운 관계도 이름 생성 (중복 검사)
|
||||
let newDiagramName = `${originalDiagramName} (1)`;
|
||||
let counter = 1;
|
||||
|
||||
while (true) {
|
||||
const existingDiagram = await prisma.table_relationships.findFirst({
|
||||
where: {
|
||||
company_code: companyCode,
|
||||
relationship_name: newDiagramName,
|
||||
is_active: "Y",
|
||||
},
|
||||
});
|
||||
|
||||
if (!existingDiagram) {
|
||||
break;
|
||||
}
|
||||
|
||||
counter++;
|
||||
newDiagramName = `${originalDiagramName} (${counter})`;
|
||||
}
|
||||
|
||||
// 트랜잭션으로 모든 관계 복사
|
||||
const copiedRelationships = await prisma.$transaction(
|
||||
originalRelationships.map((rel) =>
|
||||
prisma.table_relationships.create({
|
||||
data: {
|
||||
relationship_name: newDiagramName,
|
||||
from_table_name: rel.from_table_name,
|
||||
from_column_name: rel.from_column_name,
|
||||
to_table_name: rel.to_table_name,
|
||||
to_column_name: rel.to_column_name,
|
||||
relationship_type: rel.relationship_type,
|
||||
connection_type: rel.connection_type,
|
||||
settings: rel.settings as any,
|
||||
company_code: rel.company_code,
|
||||
is_active: "Y",
|
||||
created_by: rel.created_by,
|
||||
updated_by: rel.updated_by,
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
logger.info(
|
||||
`DataflowService: 관계도 복사 완료 - ${originalDiagramName} → ${newDiagramName}, ${copiedRelationships.length}개 관계 복사`
|
||||
);
|
||||
|
||||
return newDiagramName;
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
`DataflowService: 관계도 복사 실패 - ${originalDiagramName}`,
|
||||
error
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 관계도 삭제
|
||||
*/
|
||||
async deleteDiagram(
|
||||
companyCode: string,
|
||||
diagramName: string
|
||||
): Promise<number> {
|
||||
try {
|
||||
logger.info(`DataflowService: 관계도 삭제 시작 - ${diagramName}`);
|
||||
|
||||
// 관계도의 모든 관계 삭제 (하드 삭제)
|
||||
const deleteResult = await prisma.table_relationships.deleteMany({
|
||||
where: {
|
||||
company_code: companyCode,
|
||||
relationship_name: diagramName,
|
||||
},
|
||||
});
|
||||
|
||||
logger.info(
|
||||
`DataflowService: 관계도 삭제 완료 - ${diagramName}, ${deleteResult.count}개 관계 삭제`
|
||||
);
|
||||
|
||||
return deleteResult.count;
|
||||
} catch (error) {
|
||||
logger.error(`DataflowService: 관계도 삭제 실패 - ${diagramName}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user