// 품목기준관리 API Client // Phase 0: 기본 구조 작성 (API 연동은 백엔드 완성 후) import type { ApiResponse, InitResponse, ItemPageRequest, ItemPageResponse, PageReorderRequest, ItemSectionRequest, ItemSectionResponse, SectionReorderRequest, IndependentSectionRequest, SectionUsageResponse, LinkSectionRequest, ItemFieldRequest, ItemFieldResponse, FieldReorderRequest, IndependentFieldRequest, FieldUsageResponse, LinkFieldRequest, BomItemRequest, BomItemResponse, IndependentBomItemRequest, PageStructureResponse, SectionTemplateRequest, SectionTemplateResponse, MasterFieldRequest, MasterFieldResponse, CustomTabRequest, CustomTabResponse, TabReorderRequest, TabColumnUpdateRequest, UnitOptionRequest, UnitOptionResponse, // 2025-11-27 추가: 엔티티 관계 타입 EntityRelationshipResponse, LinkEntityRequest, LinkBomRequest, ReorderRelationshipsRequest, } from '@/types/item-master-api'; import { getAuthHeaders } from './auth-headers'; import { handleApiError } from './error-handler'; import { apiLogger } from './logger'; // ✅ HttpOnly 쿠키 보안 유지: Next.js API 프록시 사용 // 프록시가 서버에서 쿠키를 읽어 백엔드로 전달 // Frontend: /api/proxy/* → Backend: /api/v1/* const BASE_URL = '/api/proxy'; export const itemMasterApi = { // ============================================ // 초기화 API // ============================================ /** * 초기 데이터 로드 (화면 진입 시 호출) * @returns pages, sectionTemplates, masterFields, customTabs, tabColumns, unitOptions */ init: async (): Promise => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/init`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/init`, { method: 'GET', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/init`, response.status, result, startTime); return result.data; } catch (error) { // 네트워크 오류 (서버 연결 실패, CORS 오류 등) if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/init`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/init`, error as Error, undefined, startTime); throw error; } }, // ============================================ // 페이지 관리 // ============================================ pages: { list: async () => { // TODO: Phase 2에서 구현 throw new Error('API 연동 전'); }, /** * 페이지 생성 * POST /v1/item-master/pages */ create: async (data: ItemPageRequest): Promise => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/pages`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/pages`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/pages`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/pages`, error as Error, undefined, startTime); throw error; } }, /** * 페이지 수정 * PUT /v1/item-master/pages/{id} */ update: async (id: number, data: Partial): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/pages/${id}`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${id}`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/pages/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/pages/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/pages/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 페이지 삭제 * DELETE /v1/item-master/pages/{id} */ delete: async (id: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/pages/${id}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${id}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/pages/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/pages/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/pages/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 페이지 순서 변경 * PUT /v1/item-master/pages/reorder */ reorder: async (data: PageReorderRequest): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/pages/reorder`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/reorder`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/pages/reorder`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/pages/reorder`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/pages/reorder`, error as Error, undefined, startTime); throw error; } }, /** * 페이지에 섹션 연결 * POST /v1/item-master/pages/{id}/link-section * 2025-11-26 신규 API */ linkSection: async (pageId: number, data: LinkSectionRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/pages/${pageId}/link-section`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${pageId}/link-section`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/pages/${pageId}/link-section`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/pages/${pageId}/link-section`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/pages/${pageId}/link-section`, error as Error, undefined, startTime); throw error; } }, /** * 페이지에서 섹션 연결 해제 * DELETE /v1/item-master/pages/{id}/unlink-section/{sectionId} * 2025-11-26 신규 API */ unlinkSection: async (pageId: number, sectionId: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/pages/${pageId}/unlink-section/${sectionId}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${pageId}/unlink-section/${sectionId}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/pages/${pageId}/unlink-section/${sectionId}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/pages/${pageId}/unlink-section/${sectionId}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/pages/${pageId}/unlink-section/${sectionId}`, error as Error, undefined, startTime); throw error; } }, /** * 페이지 전체 구조 조회 * GET /v1/item-master/pages/{id}/structure * 2025-11-26 신규 API */ getStructure: async (pageId: number): Promise => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/pages/${pageId}/structure`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${pageId}/structure`, { method: 'GET', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/pages/${pageId}/structure`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/pages/${pageId}/structure`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/pages/${pageId}/structure`, error as Error, undefined, startTime); throw error; } }, /** * 페이지 관계 조회 * GET /v1/item-master/pages/{id}/relationships * 2025-11-27 신규 API */ getRelationships: async (pageId: number): Promise => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/pages/${pageId}/relationships`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${pageId}/relationships`, { method: 'GET', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/pages/${pageId}/relationships`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/pages/${pageId}/relationships`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/pages/${pageId}/relationships`, error as Error, undefined, startTime); throw error; } }, /** * 페이지에 필드 직접 연결 * POST /v1/item-master/pages/{id}/link-field * 2025-11-27 신규 API */ linkField: async (pageId: number, data: LinkEntityRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/pages/${pageId}/link-field`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${pageId}/link-field`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/pages/${pageId}/link-field`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/pages/${pageId}/link-field`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/pages/${pageId}/link-field`, error as Error, undefined, startTime); throw error; } }, /** * 페이지에서 필드 연결 해제 * DELETE /v1/item-master/pages/{id}/unlink-field/{fieldId} * 2025-11-27 신규 API */ unlinkField: async (pageId: number, fieldId: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/pages/${pageId}/unlink-field/${fieldId}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${pageId}/unlink-field/${fieldId}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/pages/${pageId}/unlink-field/${fieldId}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/pages/${pageId}/unlink-field/${fieldId}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/pages/${pageId}/unlink-field/${fieldId}`, error as Error, undefined, startTime); throw error; } }, }, // ============================================ // 섹션 관리 // ============================================ sections: { /** * 독립 섹션 목록 조회 * GET /v1/item-master/sections * 2025-11-26 신규 API * @param params.is_template - true: 템플릿만, false: 일반 섹션만, undefined: 전체 */ list: async (params?: { is_template?: boolean }): Promise => { const queryParams = new URLSearchParams(); if (params?.is_template !== undefined) { queryParams.set('is_template', String(params.is_template)); } const queryString = queryParams.toString(); const url = `${BASE_URL}/item-master/sections${queryString ? `?${queryString}` : ''}`; const startTime = apiLogger.logRequest('GET', url); try { const headers = getAuthHeaders(); const response = await fetch(url, { method: 'GET', headers }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', url, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', url, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', url, error as Error, undefined, startTime); throw error; } }, /** * 독립 섹션 생성 (페이지에 연결되지 않은 섹션) * POST /v1/item-master/sections * 2025-11-26 신규 API */ createIndependent: async (data: IndependentSectionRequest): Promise => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/sections`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/sections`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/sections`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/sections`, error as Error, undefined, startTime); throw error; } }, /** * 섹션 복제 * POST /v1/item-master/sections/{id}/clone * 2025-11-26 신규 API */ clone: async (id: number): Promise => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/sections/${id}/clone`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${id}/clone`, { method: 'POST', headers }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/sections/${id}/clone`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${id}/clone`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${id}/clone`, error as Error, undefined, startTime); throw error; } }, /** * 섹션 사용처 조회 * GET /v1/item-master/sections/{id}/usage * 2025-11-26 신규 API */ getUsage: async (id: number): Promise => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/sections/${id}/usage`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${id}/usage`, { method: 'GET', headers }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/sections/${id}/usage`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/sections/${id}/usage`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/sections/${id}/usage`, error as Error, undefined, startTime); throw error; } }, /** * 섹션에 필드 연결 * POST /v1/item-master/sections/{id}/link-field * 2025-11-26 신규 API */ linkField: async (sectionId: number, data: LinkFieldRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/sections/${sectionId}/link-field`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${sectionId}/link-field`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/sections/${sectionId}/link-field`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${sectionId}/link-field`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${sectionId}/link-field`, error as Error, undefined, startTime); throw error; } }, /** * 섹션에서 필드 연결 해제 * DELETE /v1/item-master/sections/{id}/unlink-field/{fieldId} * 2025-11-26 신규 API */ unlinkField: async (sectionId: number, fieldId: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/sections/${sectionId}/unlink-field/${fieldId}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${sectionId}/unlink-field/${fieldId}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/sections/${sectionId}/unlink-field/${fieldId}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/sections/${sectionId}/unlink-field/${fieldId}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/sections/${sectionId}/unlink-field/${fieldId}`, error as Error, undefined, startTime); throw error; } }, /** * 섹션에 BOM 연결 * POST /v1/item-master/sections/{id}/link-bom * 2025-11-27 신규 API */ linkBom: async (sectionId: number, data: LinkBomRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/sections/${sectionId}/link-bom`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${sectionId}/link-bom`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/sections/${sectionId}/link-bom`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${sectionId}/link-bom`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${sectionId}/link-bom`, error as Error, undefined, startTime); throw error; } }, /** * 섹션에서 BOM 연결 해제 * DELETE /v1/item-master/sections/{id}/unlink-bom/{bomId} * 2025-11-27 신규 API */ unlinkBom: async (sectionId: number, bomId: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/sections/${sectionId}/unlink-bom/${bomId}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${sectionId}/unlink-bom/${bomId}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/sections/${sectionId}/unlink-bom/${bomId}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/sections/${sectionId}/unlink-bom/${bomId}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/sections/${sectionId}/unlink-bom/${bomId}`, error as Error, undefined, startTime); throw error; } }, /** * 섹션 관계 조회 * GET /v1/item-master/sections/{id}/relationships * 2025-11-27 신규 API */ getRelationships: async (sectionId: number): Promise => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/sections/${sectionId}/relationships`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${sectionId}/relationships`, { method: 'GET', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/sections/${sectionId}/relationships`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/sections/${sectionId}/relationships`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/sections/${sectionId}/relationships`, error as Error, undefined, startTime); throw error; } }, /** * 섹션 생성 (페이지 하위) * POST /v1/item-master/pages/{pageId}/sections */ create: async (pageId: number, data: ItemSectionRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/pages/${pageId}/sections`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${pageId}/sections`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/pages/${pageId}/sections`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/pages/${pageId}/sections`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/pages/${pageId}/sections`, error as Error, undefined, startTime); throw error; } }, /** * 섹션 수정 * PUT /v1/item-master/sections/{id} */ update: async (id: number, data: Partial): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/sections/${id}`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${id}`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/sections/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/sections/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/sections/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 섹션 삭제 * DELETE /v1/item-master/sections/{id} */ delete: async (id: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/sections/${id}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${id}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/sections/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/sections/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/sections/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 섹션 순서 변경 * PUT /v1/item-master/pages/{pageId}/sections/reorder */ reorder: async (pageId: number, data: SectionReorderRequest): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/pages/${pageId}/sections/reorder`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/pages/${pageId}/sections/reorder`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/pages/${pageId}/sections/reorder`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/pages/${pageId}/sections/reorder`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/pages/${pageId}/sections/reorder`, error as Error, undefined, startTime); throw error; } }, }, // ============================================ // 필드 관리 // ============================================ fields: { /** * 독립 필드 목록 조회 * GET /v1/item-master/fields * 2025-11-26 신규 API */ list: async (): Promise => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/fields`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/fields`, { method: 'GET', headers }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/fields`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/fields`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/fields`, error as Error, undefined, startTime); throw error; } }, /** * 독립 필드 생성 * POST /v1/item-master/fields * 2025-11-26 신규 API */ createIndependent: async (data: IndependentFieldRequest): Promise => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/fields`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/fields`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/fields`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/fields`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/fields`, error as Error, undefined, startTime); throw error; } }, /** * 필드 복제 * POST /v1/item-master/fields/{id}/clone * 2025-11-26 신규 API */ clone: async (id: number): Promise => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/fields/${id}/clone`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/fields/${id}/clone`, { method: 'POST', headers }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/fields/${id}/clone`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/fields/${id}/clone`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/fields/${id}/clone`, error as Error, undefined, startTime); throw error; } }, /** * 필드 사용처 조회 * GET /v1/item-master/fields/{id}/usage * 2025-11-26 신규 API */ getUsage: async (id: number): Promise => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/fields/${id}/usage`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/fields/${id}/usage`, { method: 'GET', headers }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/fields/${id}/usage`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/fields/${id}/usage`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/fields/${id}/usage`, error as Error, undefined, startTime); throw error; } }, /** * 필드 생성 (섹션 하위) * POST /v1/item-master/sections/{sectionId}/fields */ create: async (sectionId: number, data: ItemFieldRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/sections/${sectionId}/fields`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${sectionId}/fields`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/sections/${sectionId}/fields`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${sectionId}/fields`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${sectionId}/fields`, error as Error, undefined, startTime); throw error; } }, /** * 필드 수정 * PUT /v1/item-master/fields/{id} */ update: async (id: number, data: Partial): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/fields/${id}`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/fields/${id}`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/fields/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/fields/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/fields/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 필드 삭제 * DELETE /v1/item-master/fields/{id} */ delete: async (id: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/fields/${id}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/fields/${id}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/fields/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/fields/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/fields/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 필드 순서 변경 * PUT /v1/item-master/sections/{sectionId}/fields/reorder */ reorder: async (sectionId: number, data: FieldReorderRequest): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/sections/${sectionId}/fields/reorder`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${sectionId}/fields/reorder`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/sections/${sectionId}/fields/reorder`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/sections/${sectionId}/fields/reorder`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/sections/${sectionId}/fields/reorder`, error as Error, undefined, startTime); throw error; } }, }, // ============================================ // BOM 관리 // ============================================ bomItems: { /** * 독립 BOM 목록 조회 * GET /v1/item-master/bom-items * 2025-11-26 신규 API */ list: async (): Promise => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/bom-items`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/bom-items`, { method: 'GET', headers }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/bom-items`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/bom-items`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/bom-items`, error as Error, undefined, startTime); throw error; } }, /** * 독립 BOM 항목 생성 * POST /v1/item-master/bom-items * 2025-11-26 신규 API */ createIndependent: async (data: IndependentBomItemRequest): Promise => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/bom-items`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/bom-items`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/bom-items`, response.status, result, startTime); return result.data; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/bom-items`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/bom-items`, error as Error, undefined, startTime); throw error; } }, /** * BOM 항목 생성 (섹션 하위) * POST /v1/item-master/sections/{sectionId}/bom-items */ create: async (sectionId: number, data: BomItemRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/sections/${sectionId}/bom-items`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/sections/${sectionId}/bom-items`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/sections/${sectionId}/bom-items`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${sectionId}/bom-items`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/sections/${sectionId}/bom-items`, error as Error, undefined, startTime); throw error; } }, /** * BOM 항목 수정 * PUT /v1/item-master/bom-items/{id} */ update: async (id: number, data: Partial): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/bom-items/${id}`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/bom-items/${id}`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/bom-items/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/bom-items/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/bom-items/${id}`, error as Error, undefined, startTime); throw error; } }, /** * BOM 항목 삭제 * DELETE /v1/item-master/bom-items/{id} */ delete: async (id: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/bom-items/${id}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/bom-items/${id}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/bom-items/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/bom-items/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/bom-items/${id}`, error as Error, undefined, startTime); throw error; } }, }, // ============================================ // 섹션 템플릿 // ============================================ templates: { /** * 템플릿 목록 조회 * GET /v1/item-master/section-templates * Note: init API에 포함되므로 일반적으로 직접 호출 불필요 */ list: async (): Promise> => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/section-templates`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/section-templates`, { method: 'GET', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/section-templates`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/section-templates`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/section-templates`, error as Error, undefined, startTime); throw error; } }, /** * 템플릿 생성 * POST /v1/item-master/section-templates */ create: async (data: SectionTemplateRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/section-templates`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/section-templates`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/section-templates`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/section-templates`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/section-templates`, error as Error, undefined, startTime); throw error; } }, /** * 템플릿 수정 * PUT /v1/item-master/section-templates/{id} */ update: async (id: number, data: Partial): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/section-templates/${id}`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/section-templates/${id}`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/section-templates/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/section-templates/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/section-templates/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 템플릿 삭제 * DELETE /v1/item-master/section-templates/{id} */ delete: async (id: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/section-templates/${id}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/section-templates/${id}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/section-templates/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/section-templates/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/section-templates/${id}`, error as Error, undefined, startTime); throw error; } }, }, // ============================================ // 엔티티 관계 (Entity Relationships) // 2025-11-27 신규: 링크 테이블 기반 순서 변경 // ============================================ relationships: { /** * 관계 순서 변경 * POST /v1/item-master/relationships/reorder * 2025-11-27 신규 API */ reorder: async (data: ReorderRelationshipsRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/relationships/reorder`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/relationships/reorder`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/relationships/reorder`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/relationships/reorder`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/relationships/reorder`, error as Error, undefined, startTime); throw error; } }, }, // ============================================ // 마스터 필드 (DEPRECATED) // 2025-11-27: item_master_fields가 item_fields로 통합됨 // 독립 필드 = item_fields WHERE section_id IS NULL // fields API 사용 권장 (fields.list, fields.createIndependent 등) // ============================================ masterFields: { /** * 마스터 필드 목록 조회 * @deprecated 2025-11-27: fields.list() 사용 권장 * GET /v1/item-master/master-fields * Note: init API에 포함되므로 일반적으로 직접 호출 불필요 */ list: async (): Promise> => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/master-fields`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/master-fields`, { method: 'GET', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/master-fields`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/master-fields`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/master-fields`, error as Error, undefined, startTime); throw error; } }, /** * 마스터 필드 생성 * @deprecated 2025-11-27: fields.createIndependent() 사용 권장 * POST /v1/item-master/master-fields */ create: async (data: MasterFieldRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/master-fields`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/master-fields`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/master-fields`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/master-fields`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/master-fields`, error as Error, undefined, startTime); throw error; } }, /** * 마스터 필드 수정 * @deprecated 2025-11-27: fields.update() 사용 권장 * PUT /v1/item-master/master-fields/{id} */ update: async (id: number, data: Partial): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/master-fields/${id}`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/master-fields/${id}`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/master-fields/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/master-fields/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/master-fields/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 마스터 필드 삭제 * @deprecated 2025-11-27: fields.delete() 사용 권장 * DELETE /v1/item-master/master-fields/{id} */ delete: async (id: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/master-fields/${id}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/master-fields/${id}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/master-fields/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/master-fields/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/master-fields/${id}`, error as Error, undefined, startTime); throw error; } }, }, // ============================================ // 커스텀 탭 // ============================================ customTabs: { /** * 커스텀 탭 목록 조회 * GET /v1/item-master/custom-tabs * Note: init API에 포함되므로 일반적으로 직접 호출 불필요 */ list: async (): Promise> => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/custom-tabs`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/custom-tabs`, { method: 'GET', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/custom-tabs`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/custom-tabs`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/custom-tabs`, error as Error, undefined, startTime); throw error; } }, /** * 커스텀 탭 생성 * POST /v1/item-master/custom-tabs */ create: async (data: CustomTabRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/custom-tabs`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/custom-tabs`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/custom-tabs`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/custom-tabs`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/custom-tabs`, error as Error, undefined, startTime); throw error; } }, /** * 커스텀 탭 수정 * PUT /v1/item-master/custom-tabs/{id} */ update: async (id: number, data: Partial): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/custom-tabs/${id}`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/custom-tabs/${id}`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/custom-tabs/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/custom-tabs/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/custom-tabs/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 커스텀 탭 삭제 * DELETE /v1/item-master/custom-tabs/{id} */ delete: async (id: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/custom-tabs/${id}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/custom-tabs/${id}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/custom-tabs/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/custom-tabs/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/custom-tabs/${id}`, error as Error, undefined, startTime); throw error; } }, /** * 탭 순서 변경 * PUT /v1/item-master/custom-tabs/reorder */ reorder: async (data: TabReorderRequest): Promise> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/custom-tabs/reorder`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/custom-tabs/reorder`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/custom-tabs/reorder`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/custom-tabs/reorder`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/custom-tabs/reorder`, error as Error, undefined, startTime); throw error; } }, /** * 탭별 컬럼 설정 * PUT /v1/item-master/custom-tabs/{id}/columns */ updateColumns: async (id: number, data: TabColumnUpdateRequest): Promise>> => { const startTime = apiLogger.logRequest('PUT', `${BASE_URL}/item-master/custom-tabs/${id}/columns`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/custom-tabs/${id}/columns`, { method: 'PUT', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse> = await response.json(); apiLogger.logResponse('PUT', `${BASE_URL}/item-master/custom-tabs/${id}/columns`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('PUT', `${BASE_URL}/item-master/custom-tabs/${id}/columns`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('PUT', `${BASE_URL}/item-master/custom-tabs/${id}/columns`, error as Error, undefined, startTime); throw error; } }, }, // ============================================ // 단위 옵션 // ============================================ units: { list: async (): Promise> => { const startTime = apiLogger.logRequest('GET', `${BASE_URL}/item-master/unit-options`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/unit-options`, { method: 'GET', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('GET', `${BASE_URL}/item-master/unit-options`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('GET', `${BASE_URL}/item-master/unit-options`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('GET', `${BASE_URL}/item-master/unit-options`, error as Error, undefined, startTime); throw error; } }, create: async (data: UnitOptionRequest): Promise> => { const startTime = apiLogger.logRequest('POST', `${BASE_URL}/item-master/unit-options`, data); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/unit-options`, { method: 'POST', headers, body: JSON.stringify(data), }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('POST', `${BASE_URL}/item-master/unit-options`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('POST', `${BASE_URL}/item-master/unit-options`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('POST', `${BASE_URL}/item-master/unit-options`, error as Error, undefined, startTime); throw error; } }, delete: async (id: number): Promise> => { const startTime = apiLogger.logRequest('DELETE', `${BASE_URL}/item-master/unit-options/${id}`); try { const headers = getAuthHeaders(); const response = await fetch(`${BASE_URL}/item-master/unit-options/${id}`, { method: 'DELETE', headers, }); if (!response.ok) { await handleApiError(response); } const result: ApiResponse = await response.json(); apiLogger.logResponse('DELETE', `${BASE_URL}/item-master/unit-options/${id}`, response.status, result, startTime); return result; } catch (error) { if (error instanceof TypeError) { apiLogger.logError('DELETE', `${BASE_URL}/item-master/unit-options/${id}`, error, undefined, startTime); throw new Error('네트워크 연결을 확인해주세요. 서버에 연결할 수 없습니다.'); } apiLogger.logError('DELETE', `${BASE_URL}/item-master/unit-options/${id}`, error as Error, undefined, startTime); throw error; } }, }, };