f73e468f66
- DdlService.dropColumn: ALTER TABLE ... DROP COLUMN (CASCADE 미사용 → FK 참조 시 Postgres 거부, DBeaver 동일)
- 시스템 테이블 / 예약 컬럼(id/created_date/updated_date/company_code/writer) 보호
- 같은 트랜잭션에서 table_type_columns / column_labels 메타 청소 + ddl_execution_log 기록
- DdlController: DELETE /api/ddl/tables/{table}/columns/{column} (SUPER_ADMIN 전용)
- ddlApi.dropColumn 헬퍼
- ColumnGrid: ... 버튼을 DropdownMenu 로 교체, "컬럼 삭제" destructive 메뉴 아이템
- page.tsx: 컬럼 삭제 확인 다이얼로그 + 핸들러, FK 거부 시 토스트로 안내
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
144 lines
3.4 KiB
TypeScript
144 lines
3.4 KiB
TypeScript
/**
|
|
* DDL 실행 API 클라이언트
|
|
*/
|
|
|
|
import { apiClient } from "./client";
|
|
import {
|
|
CreateTableRequest,
|
|
AddColumnRequest,
|
|
DDLExecutionResult,
|
|
ValidationResult,
|
|
DDLExecutionLog,
|
|
DDLStatistics,
|
|
} from "../../types/ddl";
|
|
|
|
export const ddlApi = {
|
|
/**
|
|
* 새 테이블 생성
|
|
*/
|
|
createTable: async (request: CreateTableRequest): Promise<DDLExecutionResult> => {
|
|
const response = await apiClient.post("/ddl/tables", request);
|
|
return response.data;
|
|
},
|
|
|
|
/**
|
|
* 기존 테이블에 컬럼 추가
|
|
*/
|
|
addColumn: async (tableName: string, request: AddColumnRequest): Promise<DDLExecutionResult> => {
|
|
const response = await apiClient.post(`/ddl/tables/${tableName}/columns`, request);
|
|
return response.data;
|
|
},
|
|
|
|
/**
|
|
* 테이블 삭제 (DROP TABLE)
|
|
*/
|
|
dropTable: async (tableName: string): Promise<DDLExecutionResult> => {
|
|
const response = await apiClient.delete(`/ddl/tables/${tableName}`);
|
|
return response.data;
|
|
},
|
|
|
|
/**
|
|
* 컬럼 삭제 (ALTER TABLE ... DROP COLUMN)
|
|
*/
|
|
dropColumn: async (tableName: string, columnName: string): Promise<DDLExecutionResult> => {
|
|
const response = await apiClient.delete(`/ddl/tables/${tableName}/columns/${columnName}`);
|
|
return response.data;
|
|
},
|
|
|
|
/**
|
|
* 테이블 생성 사전 검증 (실제 생성하지 않고 검증만)
|
|
*/
|
|
validateTableCreation: async (request: CreateTableRequest): Promise<ValidationResult> => {
|
|
const response = await apiClient.post("/ddl/validate/table", request);
|
|
return response.data.data;
|
|
},
|
|
|
|
/**
|
|
* DDL 실행 로그 조회
|
|
*/
|
|
getDDLLogs: async (params?: {
|
|
limit?: number;
|
|
userId?: string;
|
|
ddlType?: string;
|
|
}): Promise<{
|
|
logs: DDLExecutionLog[];
|
|
total: number;
|
|
}> => {
|
|
const response = await apiClient.get("/ddl/logs", { params });
|
|
return response.data.data;
|
|
},
|
|
|
|
/**
|
|
* DDL 실행 통계 조회
|
|
*/
|
|
getDDLStatistics: async (params?: { fromDate?: string; toDate?: string }): Promise<DDLStatistics> => {
|
|
const response = await apiClient.get("/ddl/statistics", { params });
|
|
return response.data.data;
|
|
},
|
|
|
|
/**
|
|
* 특정 테이블의 DDL 히스토리 조회
|
|
*/
|
|
getTableDDLHistory: async (
|
|
tableName: string,
|
|
): Promise<{
|
|
tableName: string;
|
|
history: DDLExecutionLog[];
|
|
total: number;
|
|
}> => {
|
|
const response = await apiClient.get(`/ddl/tables/${tableName}/history`);
|
|
return response.data.data;
|
|
},
|
|
|
|
/**
|
|
* 생성된 테이블 정보 조회
|
|
*/
|
|
getTableInfo: async (
|
|
tableName: string,
|
|
): Promise<{
|
|
tableInfo: any;
|
|
columns: any[];
|
|
}> => {
|
|
const response = await apiClient.get(`/ddl/tables/${tableName}/info`);
|
|
return response.data.data;
|
|
},
|
|
|
|
/**
|
|
* 오래된 DDL 로그 정리
|
|
*/
|
|
cleanupOldLogs: async (
|
|
retentionDays?: number,
|
|
): Promise<{
|
|
deletedCount: number;
|
|
retentionDays: number;
|
|
}> => {
|
|
const response = await apiClient.delete("/ddl/logs/cleanup", {
|
|
params: { retentionDays },
|
|
});
|
|
return response.data.data;
|
|
},
|
|
|
|
/**
|
|
* DDL 서비스 정보 조회
|
|
*/
|
|
getServiceInfo: async (): Promise<any> => {
|
|
const response = await apiClient.get("/ddl/info");
|
|
return response.data.data;
|
|
},
|
|
|
|
/**
|
|
* DDL 서비스 헬스체크
|
|
*/
|
|
healthCheck: async (): Promise<{
|
|
status: string;
|
|
timestamp: string;
|
|
checks: {
|
|
database: string;
|
|
service: string;
|
|
};
|
|
}> => {
|
|
const response = await apiClient.get("/ddl/health");
|
|
return response.data;
|
|
},
|
|
};
|