import { apiClient } from "./client"; import type { CodeInfo, CodeDetail, ApiResponse, GetCodeInfoListQuery, GetCodeDetailListQuery, DuplicateCheckResult, } from "@/types/commonCode"; /** * 공통코드 API 클라이언트 (마스터-디테일 구조) * * code_info — 그룹 마스터 * code_detail — 트리 노드 (depth 2 시작, 무한 depth) * * 백엔드 계약 (BE Agent 가 만드는 것): * /api/common-codes/info/... * /api/common-codes/detail/... * * 응답 포맷: * 목록: { success, data: [...], total: N, message } * 단건/CRUD: { success, data: {...}, message } */ /* ───────────────────────── code_info (그룹 마스터) ───────────────────────── */ /** 그룹 목록 (페이징/검색) */ export async function getCodeInfoList( params?: GetCodeInfoListQuery, ): Promise> { const search = new URLSearchParams(); if (params?.search) search.append("search", params.search); if (params?.is_active !== undefined) search.append("is_active", params.is_active.toString()); if (params?.page !== undefined) search.append("page", params.page.toString()); if (params?.size !== undefined) search.append("size", params.size.toString()); const qs = search.toString(); const url = `/common-codes/info${qs ? `?${qs}` : ""}`; const response = await apiClient.get(url); return response.data; } /** 그룹 단건 */ export async function getCodeInfoInfo(codeInfo: string): Promise> { const response = await apiClient.get(`/common-codes/info/${encodeURIComponent(codeInfo)}`); return response.data; } /** 그룹 생성 */ export async function createCodeInfo(data: Record): Promise> { const response = await apiClient.post("/common-codes/info", data); return response.data; } /** 그룹 수정 */ export async function updateCodeInfo( codeInfo: string, data: Record, ): Promise> { const response = await apiClient.put( `/common-codes/info/${encodeURIComponent(codeInfo)}`, data, ); return response.data; } /** 그룹 삭제 (CASCADE) */ export async function deleteCodeInfo(codeInfo: string): Promise { const response = await apiClient.delete(`/common-codes/info/${encodeURIComponent(codeInfo)}`); return response.data; } /** 그룹 중복 체크 */ export async function checkCodeInfoDuplicate( field: "code_info" | "code_name" | "code_name_eng", value: string, excludeCode?: string, ): Promise> { const search = new URLSearchParams(); search.append("field", field); search.append("value", value); if (excludeCode) search.append("excludeCode", excludeCode); const response = await apiClient.get(`/common-codes/info/check-duplicate?${search}`); return response.data; } /* ───────────────────────── code_detail (디테일 트리) ───────────────────────── */ /** 그룹의 전체 디테일 트리 (depth+sort_order 평탄화 리스트) */ export async function getCodeDetailTree( params: GetCodeDetailListQuery, ): Promise> { const search = new URLSearchParams(); search.append("code_info", params.code_info); if (params.search) search.append("search", params.search); if (params.is_active !== undefined) search.append("is_active", params.is_active.toString()); const response = await apiClient.get(`/common-codes/detail?${search}`); return response.data; } /** 디테일 단건 */ export async function getCodeDetailInfo( codeDetailId: number | string, ): Promise> { const response = await apiClient.get(`/common-codes/detail/${codeDetailId}`); return response.data; } /** 디테일 생성 */ export async function createCodeDetail( data: Record, ): Promise> { const response = await apiClient.post("/common-codes/detail", data); return response.data; } /** 디테일 수정 */ export async function updateCodeDetail( codeDetailId: number | string, data: Record, ): Promise> { const response = await apiClient.put(`/common-codes/detail/${codeDetailId}`, data); return response.data; } /** 디테일 삭제 (CASCADE) */ export async function deleteCodeDetail(codeDetailId: number | string): Promise { const response = await apiClient.delete(`/common-codes/detail/${codeDetailId}`); return response.data; } /** 디테일 중복 체크 (그룹 + 필드 단위) */ export async function checkCodeDetailDuplicate( codeInfo: string, field: "code_value" | "code_name" | "code_name_eng", value: string, excludeId?: number | string, ): Promise> { const search = new URLSearchParams(); search.append("code_info", codeInfo); search.append("field", field); search.append("value", value); if (excludeId !== undefined && excludeId !== null && excludeId !== "") { search.append("excludeId", String(excludeId)); } const response = await apiClient.get(`/common-codes/detail/check-duplicate?${search}`); return response.data; } /* ───────────────────────── compat: 화면관리/캐시에서 사용 ───────────────────────── */ /** * 그룹의 활성 디테일 옵션 (label/value) * 기존 `commonCodeApi.options.getOptions(categoryCode)` 의 대체. */ export async function getCodeOptions( codeInfo: string, ): Promise>> { const tree = await getCodeDetailTree({ code_info: codeInfo, is_active: true }); const options = (tree.data || []).map((row) => ({ value: row.code_value, label: row.code_name || row.code_value, depth: row.depth, parent_detail_id: row.parent_detail_id ?? null, })); return { success: tree.success, data: options, message: tree.message, total: options.length, }; } /** * 호환 객체. 기존 코드가 `commonCodeApi.codes.getList(category, ...)` 등으로 부르고 있어 * 깨끗한 1안 마이그레이션 동안 임시로 노출. 새 코드는 위 함수들을 직접 import. * * NOTE: 사용처가 점진적으로 제거되면 이 객체도 삭제. */ export const commonCodeApi = { info: { getList: getCodeInfoList, get: getCodeInfoInfo, create: createCodeInfo, update: updateCodeInfo, delete: deleteCodeInfo, checkDuplicate: checkCodeInfoDuplicate, }, detail: { getTree: getCodeDetailTree, get: getCodeDetailInfo, create: createCodeDetail, update: updateCodeDetail, delete: deleteCodeDetail, checkDuplicate: checkCodeDetailDuplicate, }, options: { getOptions: getCodeOptions, }, };