import { Request, Response } from "express"; import { Client } from "pg"; import { logger } from "../utils/logger"; import { AuthenticatedRequest } from "../types/auth"; import { ApiResponse } from "../types/common"; import { TableManagementService } from "../services/tableManagementService"; import { TableInfo, ColumnTypeInfo, ColumnSettings, TableListResponse, ColumnListResponse, ColumnSettingsResponse, } from "../types/tableManagement"; /** * 테이블 목록 조회 */ export async function getTableList( req: AuthenticatedRequest, res: Response ): Promise { try { logger.info("=== 테이블 목록 조회 시작 ==="); const tableManagementService = new TableManagementService(); const tableList = await tableManagementService.getTableList(); logger.info(`테이블 목록 조회 결과: ${tableList.length}개`); const response: ApiResponse = { success: true, message: "테이블 목록을 성공적으로 조회했습니다.", data: tableList, }; res.status(200).json(response); } catch (error) { logger.error("테이블 목록 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 목록 조회 중 오류가 발생했습니다.", error: { code: "TABLE_LIST_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 컬럼 정보 조회 */ export async function getColumnList( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const { page = 1, size = 50 } = req.query; logger.info( `=== 컬럼 정보 조회 시작: ${tableName} (page: ${page}, size: ${size}) ===` ); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); const result = await tableManagementService.getColumnList( tableName, parseInt(page as string), parseInt(size as string) ); logger.info( `컬럼 정보 조회 결과: ${tableName}, ${result.columns.length}/${result.total}개 (${result.page}/${result.totalPages} 페이지)` ); const response: ApiResponse = { success: true, message: "컬럼 목록을 성공적으로 조회했습니다.", data: result, }; res.status(200).json(response); } catch (error) { logger.error("컬럼 정보 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "컬럼 목록 조회 중 오류가 발생했습니다.", error: { code: "COLUMN_LIST_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 개별 컬럼 설정 업데이트 */ export async function updateColumnSettings( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName, columnName } = req.params; const settings: ColumnSettings = req.body; logger.info(`=== 컬럼 설정 업데이트 시작: ${tableName}.${columnName} ===`); if (!tableName || !columnName) { const response: ApiResponse = { success: false, message: "테이블명과 컬럼명이 필요합니다.", error: { code: "MISSING_PARAMETERS", details: "테이블명 또는 컬럼명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } if (!settings) { const response: ApiResponse = { success: false, message: "컬럼 설정 정보가 필요합니다.", error: { code: "MISSING_SETTINGS", details: "요청 본문에 컬럼 설정 정보가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); await tableManagementService.updateColumnSettings( tableName, columnName, settings ); logger.info(`컬럼 설정 업데이트 완료: ${tableName}.${columnName}`); const response: ApiResponse = { success: true, message: "컬럼 설정을 성공적으로 저장했습니다.", }; res.status(200).json(response); } catch (error) { logger.error("컬럼 설정 업데이트 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "컬럼 설정 저장 중 오류가 발생했습니다.", error: { code: "COLUMN_SETTINGS_UPDATE_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 전체 컬럼 설정 일괄 업데이트 */ export async function updateAllColumnSettings( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const columnSettings: ColumnSettings[] = req.body; logger.info(`=== 전체 컬럼 설정 일괄 업데이트 시작: ${tableName} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } if (!Array.isArray(columnSettings) || columnSettings.length === 0) { const response: ApiResponse = { success: false, message: "컬럼 설정 목록이 필요합니다.", error: { code: "MISSING_COLUMN_SETTINGS", details: "요청 본문에 컬럼 설정 목록이 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); await tableManagementService.updateAllColumnSettings( tableName, columnSettings ); logger.info( `전체 컬럼 설정 일괄 업데이트 완료: ${tableName}, ${columnSettings.length}개` ); const response: ApiResponse = { success: true, message: "모든 컬럼 설정을 성공적으로 저장했습니다.", }; res.status(200).json(response); } catch (error) { logger.error("전체 컬럼 설정 일괄 업데이트 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "컬럼 설정 저장 중 오류가 발생했습니다.", error: { code: "ALL_COLUMN_SETTINGS_UPDATE_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 라벨 정보 조회 */ export async function getTableLabels( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; logger.info(`=== 테이블 라벨 정보 조회 시작: ${tableName} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); const tableLabels = await tableManagementService.getTableLabels(tableName); if (!tableLabels) { // 라벨이 없으면 빈 객체를 성공으로 반환 (404 에러 대신) const response: ApiResponse<{}> = { success: true, message: "테이블 라벨 정보를 조회했습니다.", data: {}, }; res.status(200).json(response); return; } logger.info(`테이블 라벨 정보 조회 완료: ${tableName}`); const response: ApiResponse = { success: true, message: "테이블 라벨 정보를 성공적으로 조회했습니다.", data: tableLabels, }; res.status(200).json(response); } catch (error) { logger.error("테이블 라벨 정보 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 라벨 정보 조회 중 오류가 발생했습니다.", error: { code: "TABLE_LABELS_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 컬럼 라벨 정보 조회 */ export async function getColumnLabels( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName, columnName } = req.params; logger.info(`=== 컬럼 라벨 정보 조회 시작: ${tableName}.${columnName} ===`); if (!tableName || !columnName) { const response: ApiResponse = { success: false, message: "테이블명과 컬럼명이 필요합니다.", error: { code: "MISSING_PARAMETERS", details: "테이블명 또는 컬럼명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); const columnLabels = await tableManagementService.getColumnLabels( tableName, columnName ); if (!columnLabels) { // 라벨이 없으면 빈 객체를 성공으로 반환 (404 에러 대신) const response: ApiResponse<{}> = { success: true, message: "컬럼 라벨 정보를 조회했습니다.", data: {}, }; res.status(200).json(response); return; } logger.info(`컬럼 라벨 정보 조회 완료: ${tableName}.${columnName}`); const response: ApiResponse = { success: true, message: "컬럼 라벨 정보를 성공적으로 조회했습니다.", data: columnLabels, }; res.status(200).json(response); } catch (error) { logger.error("컬럼 라벨 정보 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "컬럼 라벨 정보 조회 중 오류가 발생했습니다.", error: { code: "COLUMN_LABELS_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 라벨 설정 */ export async function updateTableLabel( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const { displayName, description } = req.body; logger.info(`=== 테이블 라벨 설정 시작: ${tableName} ===`); logger.info(`표시명: ${displayName}, 설명: ${description}`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); await tableManagementService.updateTableLabel( tableName, displayName, description ); logger.info(`테이블 라벨 설정 완료: ${tableName}`); const response: ApiResponse = { success: true, message: "테이블 라벨이 성공적으로 설정되었습니다.", data: null, }; res.status(200).json(response); } catch (error) { logger.error("테이블 라벨 설정 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 라벨 설정 중 오류가 발생했습니다.", error: { code: "TABLE_LABEL_UPDATE_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 컬럼 입력 타입 설정 */ export async function updateColumnInputType( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName, columnName } = req.params; const { inputType, detailSettings } = req.body; logger.info( `=== 컬럼 입력 타입 설정 시작: ${tableName}.${columnName} = ${inputType} ===` ); if (!tableName || !columnName || !inputType) { const response: ApiResponse = { success: false, message: "테이블명, 컬럼명, 입력 타입이 모두 필요합니다.", error: { code: "MISSING_PARAMETERS", details: "필수 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); await tableManagementService.updateColumnInputType( tableName, columnName, inputType, detailSettings ); logger.info( `컬럼 입력 타입 설정 완료: ${tableName}.${columnName} = ${inputType}` ); const response: ApiResponse = { success: true, message: "컬럼 입력 타입이 성공적으로 설정되었습니다.", data: null, }; res.status(200).json(response); } catch (error) { logger.error("컬럼 입력 타입 설정 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "컬럼 입력 타입 설정 중 오류가 발생했습니다.", error: { code: "INPUT_TYPE_UPDATE_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 데이터 조회 (페이징 + 검색) */ export async function getTableData( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const { page = 1, size = 10, search = {}, sortBy, sortOrder = "asc", } = req.body; logger.info(`=== 테이블 데이터 조회 시작: ${tableName} ===`); logger.info(`페이징: page=${page}, size=${size}`); logger.info(`검색 조건:`, search); logger.info(`정렬: ${sortBy} ${sortOrder}`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); // 데이터 조회 const result = await tableManagementService.getTableData(tableName, { page: parseInt(page), size: parseInt(size), search, sortBy, sortOrder, }); logger.info( `테이블 데이터 조회 완료: ${tableName}, 총 ${result.total}건, 페이지 ${result.page}/${result.totalPages}` ); const response: ApiResponse = { success: true, message: "테이블 데이터를 성공적으로 조회했습니다.", data: result, }; res.status(200).json(response); } catch (error) { logger.error("테이블 데이터 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 데이터 조회 중 오류가 발생했습니다.", error: { code: "TABLE_DATA_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 데이터 추가 */ export async function addTableData( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const data = req.body; logger.info(`=== 테이블 데이터 추가 시작: ${tableName} ===`); logger.info(`추가할 데이터:`, data); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } if (!data || Object.keys(data).length === 0) { const response: ApiResponse = { success: false, message: "추가할 데이터가 필요합니다.", error: { code: "MISSING_DATA", details: "요청 본문에 데이터가 없습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); // 데이터 추가 await tableManagementService.addTableData(tableName, data); logger.info(`테이블 데이터 추가 완료: ${tableName}`); const response: ApiResponse = { success: true, message: "테이블 데이터를 성공적으로 추가했습니다.", }; res.status(201).json(response); } catch (error) { logger.error("테이블 데이터 추가 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 데이터 추가 중 오류가 발생했습니다.", error: { code: "TABLE_ADD_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 데이터 수정 */ export async function editTableData( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const { originalData, updatedData } = req.body; logger.info(`=== 테이블 데이터 수정 시작: ${tableName} ===`); logger.info(`원본 데이터:`, originalData); logger.info(`수정할 데이터:`, updatedData); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "INVALID_TABLE_NAME", details: "테이블명이 누락되었습니다.", }, }; res.status(400).json(response); return; } if (!originalData || !updatedData) { const response: ApiResponse = { success: false, message: "원본 데이터와 수정할 데이터가 모두 필요합니다.", error: { code: "INVALID_DATA", details: "originalData와 updatedData가 모두 제공되어야 합니다.", }, }; res.status(400).json(response); return; } if (Object.keys(updatedData).length === 0) { const response: ApiResponse = { success: false, message: "수정할 데이터가 없습니다.", error: { code: "INVALID_DATA", details: "수정할 데이터가 비어있습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); // 데이터 수정 await tableManagementService.editTableData( tableName, originalData, updatedData ); logger.info(`테이블 데이터 수정 완료: ${tableName}`); const response: ApiResponse = { success: true, message: "테이블 데이터를 성공적으로 수정했습니다.", }; res.status(200).json(response); } catch (error) { logger.error("테이블 데이터 수정 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 데이터 수정 중 오류가 발생했습니다.", error: { code: "TABLE_EDIT_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 스키마 정보 조회 (컬럼 존재 여부 검증용) */ export async function getTableSchema( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; logger.info(`=== 테이블 스키마 정보 조회 시작: ${tableName} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); const schema = await tableManagementService.getTableSchema(tableName); logger.info( `테이블 스키마 정보 조회 완료: ${tableName}, ${schema.length}개 컬럼` ); const response: ApiResponse = { success: true, message: "테이블 스키마 정보를 성공적으로 조회했습니다.", data: schema, }; res.status(200).json(response); } catch (error) { logger.error("테이블 스키마 정보 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 스키마 정보 조회 중 오류가 발생했습니다.", error: { code: "TABLE_SCHEMA_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 존재 여부 확인 */ export async function checkTableExists( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; logger.info(`=== 테이블 존재 여부 확인 시작: ${tableName} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); const exists = await tableManagementService.checkTableExists(tableName); logger.info(`테이블 존재 여부 확인 완료: ${tableName} = ${exists}`); const response: ApiResponse<{ exists: boolean }> = { success: true, message: "테이블 존재 여부를 확인했습니다.", data: { exists }, }; res.status(200).json(response); } catch (error) { logger.error("테이블 존재 여부 확인 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 존재 여부 확인 중 오류가 발생했습니다.", error: { code: "TABLE_EXISTS_CHECK_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 컬럼 웹타입 정보 조회 (화면관리 연동용) */ export async function getColumnWebTypes( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; logger.info(`=== 컬럼 웹타입 정보 조회 시작: ${tableName} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); const inputTypes = await tableManagementService.getColumnInputTypes(tableName); logger.info( `컬럼 입력타입 정보 조회 완료: ${tableName}, ${inputTypes.length}개 컬럼` ); const response: ApiResponse = { success: true, message: "컬럼 입력타입 정보를 성공적으로 조회했습니다.", data: inputTypes, }; res.status(200).json(response); } catch (error) { logger.error("컬럼 웹타입 정보 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "컬럼 웹타입 정보 조회 중 오류가 발생했습니다.", error: { code: "COLUMN_WEB_TYPES_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 데이터베이스 연결 상태 확인 */ export async function checkDatabaseConnection( req: AuthenticatedRequest, res: Response ): Promise { try { logger.info("=== 데이터베이스 연결 상태 확인 시작 ==="); const tableManagementService = new TableManagementService(); const connectionStatus = await tableManagementService.checkDatabaseConnection(); logger.info( `데이터베이스 연결 상태: ${connectionStatus.connected ? "연결됨" : "연결 안됨"}` ); const response: ApiResponse<{ connected: boolean; message: string }> = { success: true, message: "데이터베이스 연결 상태를 확인했습니다.", data: connectionStatus, }; res.status(200).json(response); } catch (error) { logger.error("데이터베이스 연결 상태 확인 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "데이터베이스 연결 상태 확인 중 오류가 발생했습니다.", error: { code: "DATABASE_CONNECTION_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 테이블 데이터 삭제 */ export async function deleteTableData( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const data = req.body; logger.info(`=== 테이블 데이터 삭제 시작: ${tableName} ===`); logger.info(`삭제할 데이터:`, data); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } if (!data || (Array.isArray(data) && data.length === 0)) { const response: ApiResponse = { success: false, message: "삭제할 데이터가 필요합니다.", error: { code: "MISSING_DATA", details: "요청 본문에 삭제할 데이터가 없습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); // 데이터 삭제 const deletedCount = await tableManagementService.deleteTableData( tableName, data ); logger.info( `테이블 데이터 삭제 완료: ${tableName}, ${deletedCount}건 삭제` ); const response: ApiResponse<{ deletedCount: number }> = { success: true, message: `테이블 데이터를 성공적으로 삭제했습니다. (${deletedCount}건)`, data: { deletedCount }, }; res.status(200).json(response); } catch (error) { logger.error("테이블 데이터 삭제 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "테이블 데이터 삭제 중 오류가 발생했습니다.", error: { code: "TABLE_DELETE_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 컬럼 웹 타입 설정 (레거시 지원) * @deprecated updateColumnInputType 사용 권장 */ export async function updateColumnWebType( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName, columnName } = req.params; const { webType, detailSettings, inputType } = req.body; logger.warn( `레거시 API 사용: updateColumnWebType → updateColumnInputType 사용 권장` ); // webType을 inputType으로 변환 const convertedInputType = inputType || webType || "text"; // 새로운 메서드 호출 req.body = { inputType: convertedInputType, detailSettings }; await updateColumnInputType(req, res); } catch (error) { logger.error("레거시 컬럼 웹 타입 설정 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "컬럼 웹 타입 설정 중 오류가 발생했습니다.", error: { code: "WEB_TYPE_UPDATE_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } // ======================================== // 🎯 테이블 로그 시스템 API // ======================================== /** * 로그 테이블 생성 */ export async function createLogTable( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const { pkColumn } = req.body; const userId = req.user?.userId; logger.info(`=== 로그 테이블 생성 시작: ${tableName} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } if (!pkColumn || !pkColumn.columnName || !pkColumn.dataType) { const response: ApiResponse = { success: false, message: "PK 컬럼 정보가 필요합니다.", error: { code: "MISSING_PK_COLUMN", details: "PK 컬럼명과 데이터 타입이 필요합니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); await tableManagementService.createLogTable(tableName, pkColumn, userId); logger.info(`로그 테이블 생성 완료: ${tableName}_log`); const response: ApiResponse = { success: true, message: "로그 테이블이 성공적으로 생성되었습니다.", }; res.status(200).json(response); } catch (error) { logger.error("로그 테이블 생성 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "로그 테이블 생성 중 오류가 발생했습니다.", error: { code: "LOG_TABLE_CREATE_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 로그 설정 조회 */ export async function getLogConfig( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; logger.info(`=== 로그 설정 조회: ${tableName} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); const logConfig = await tableManagementService.getLogConfig(tableName); const response: ApiResponse = { success: true, message: "로그 설정을 조회했습니다.", data: logConfig, }; res.status(200).json(response); } catch (error) { logger.error("로그 설정 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "로그 설정 조회 중 오류가 발생했습니다.", error: { code: "LOG_CONFIG_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 로그 데이터 조회 */ export async function getLogData( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const { page = 1, size = 20, operationType, startDate, endDate, changedBy, originalId, } = req.query; logger.info(`=== 로그 데이터 조회: ${tableName} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); const result = await tableManagementService.getLogData(tableName, { page: parseInt(page as string), size: parseInt(size as string), operationType: operationType as string, startDate: startDate as string, endDate: endDate as string, changedBy: changedBy as string, originalId: originalId as string, }); logger.info( `로그 데이터 조회 완료: ${tableName}_log, ${result.total}건` ); const response: ApiResponse = { success: true, message: "로그 데이터를 조회했습니다.", data: result, }; res.status(200).json(response); } catch (error) { logger.error("로그 데이터 조회 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "로그 데이터 조회 중 오류가 발생했습니다.", error: { code: "LOG_DATA_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } } /** * 로그 테이블 활성화/비활성화 */ export async function toggleLogTable( req: AuthenticatedRequest, res: Response ): Promise { try { const { tableName } = req.params; const { isActive } = req.body; logger.info(`=== 로그 테이블 토글: ${tableName}, isActive: ${isActive} ===`); if (!tableName) { const response: ApiResponse = { success: false, message: "테이블명이 필요합니다.", error: { code: "MISSING_TABLE_NAME", details: "테이블명 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } if (isActive === undefined || isActive === null) { const response: ApiResponse = { success: false, message: "isActive 값이 필요합니다.", error: { code: "MISSING_IS_ACTIVE", details: "isActive 파라미터가 누락되었습니다.", }, }; res.status(400).json(response); return; } const tableManagementService = new TableManagementService(); await tableManagementService.toggleLogTable( tableName, isActive === "Y" || isActive === true ); logger.info( `로그 테이블 토글 완료: ${tableName}, isActive: ${isActive}` ); const response: ApiResponse = { success: true, message: `로그 기능이 ${isActive ? "활성화" : "비활성화"}되었습니다.`, }; res.status(200).json(response); } catch (error) { logger.error("로그 테이블 토글 중 오류 발생:", error); const response: ApiResponse = { success: false, message: "로그 테이블 토글 중 오류가 발생했습니다.", error: { code: "LOG_TOGGLE_ERROR", details: error instanceof Error ? error.message : "Unknown error", }, }; res.status(500).json(response); } }