/** * 테이블 이력 조회 API 클라이언트 */ import { apiClient } from "./client"; export interface TableHistoryRecord { log_id: number; operation_type: "INSERT" | "UPDATE" | "DELETE"; original_id: string; changed_column: string; old_value: string | null; new_value: string | null; changed_by: string; changed_at: string; ip_address: string | null; user_agent: string | null; full_row_before: Record | null; full_row_after: Record | null; } export interface TableHistoryResponse { success: boolean; data?: { records: TableHistoryRecord[]; pagination: { total: number; limit: number; offset: number; hasMore: boolean; }; }; message?: string; error?: string; errorCode?: string; } export interface TableHistoryTimelineEvent { changed_at: string; changed_by: string; operation_type: "INSERT" | "UPDATE" | "DELETE"; ip_address: string | null; changes: Array<{ column: string; oldValue: string | null; newValue: string | null; }>; full_row_before: Record | null; full_row_after: Record | null; } export interface TableHistoryTimelineResponse { success: boolean; data?: TableHistoryTimelineEvent[]; message?: string; error?: string; } export interface TableHistorySummary { operation_type: string; count: number; affected_records: number; unique_users: number; first_change: string; last_change: string; } export interface TableHistorySummaryResponse { success: boolean; data?: TableHistorySummary[]; message?: string; error?: string; } export interface TableHistoryCheckResponse { success: boolean; data?: { tableName: string; logTableName: string; exists: boolean; historyEnabled: boolean; }; message?: string; error?: string; } /** * 레코드 변경 이력 조회 (recordId가 null이면 전체 테이블 이력) */ export async function getRecordHistory( tableName: string, recordId: string | number | null, params?: { limit?: number; offset?: number; operationType?: "INSERT" | "UPDATE" | "DELETE"; changedBy?: string; startDate?: string; endDate?: string; }, ): Promise { try { const queryParams = new URLSearchParams(); if (params?.limit) queryParams.append("limit", params.limit.toString()); if (params?.offset) queryParams.append("offset", params.offset.toString()); if (params?.operationType) queryParams.append("operationType", params.operationType); if (params?.changedBy) queryParams.append("changedBy", params.changedBy); if (params?.startDate) queryParams.append("startDate", params.startDate); if (params?.endDate) queryParams.append("endDate", params.endDate); // recordId가 null이면 전체 테이블 이력 조회 const url = recordId ? `/table-history/${tableName}/${recordId}?${queryParams.toString()}` : `/table-history/${tableName}/all?${queryParams.toString()}`; const response = await apiClient.get(url); return response.data; } catch (error: any) { console.error("❌ 레코드 이력 조회 실패:", error); return { success: false, error: error.response?.data?.message || error.message || "이력 조회 중 오류가 발생했습니다.", errorCode: error.response?.data?.errorCode, }; } } /** * 특정 레코드의 타임라인 조회 (그룹화된 이벤트) */ export async function getRecordTimeline( tableName: string, recordId: string | number, ): Promise { try { const response = await apiClient.get(`/table-history/${tableName}/${recordId}/timeline`); return response.data; } catch (error: any) { console.error("❌ 타임라인 조회 실패:", error); return { success: false, error: error.response?.data?.message || error.message || "타임라인 조회 중 오류가 발생했습니다.", }; } } /** * 테이블 전체 이력 요약 */ export async function getTableHistorySummary(tableName: string): Promise { try { const response = await apiClient.get(`/table-history/${tableName}/summary`); return response.data; } catch (error: any) { console.error("❌ 이력 요약 조회 실패:", error); return { success: false, error: error.response?.data?.message || error.message || "이력 요약 조회 중 오류가 발생했습니다.", }; } } /** * 이력 테이블 존재 여부 확인 */ export async function checkHistoryTableExists(tableName: string): Promise { try { const response = await apiClient.get(`/table-history/${tableName}/check`); return response.data; } catch (error: any) { console.error("❌ 이력 테이블 확인 실패:", error); return { success: false, error: error.response?.data?.message || error.message || "이력 테이블 확인 중 오류가 발생했습니다.", }; } }