diff options
Diffstat (limited to 'app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts')
| -rw-r--r-- | app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts new file mode 100644 index 00000000..5d407e1f --- /dev/null +++ b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts @@ -0,0 +1,235 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { NextRequest } from "next/server"; +import db from "@/db/db"; +import { + DEPARTMENT_CODE_CMCTB_DEPT_MDG, + DEPARTMENT_CODE_CMCTB_DEPT_MDG_COMPNM, + DEPARTMENT_CODE_CMCTB_DEPT_MDG_CORPNM, + DEPARTMENT_CODE_CMCTB_DEPT_MDG_DEPTNM +} from "@/db/schema/MDG/mdg"; +import { + ToXMLFields, + serveWsdl, + createXMLParser, + extractRequestData, + convertXMLToDBData, + processNestedArray, + createErrorResponse, + createSuccessResponse, + replaceSubTableData, + withSoapLogging +} from "../utils"; + +// 스키마에서 직접 타입 추론 +type DeptData = typeof DEPARTMENT_CODE_CMCTB_DEPT_MDG.$inferInsert; +type CompnmData = typeof DEPARTMENT_CODE_CMCTB_DEPT_MDG_COMPNM.$inferInsert; +type CorpnmData = typeof DEPARTMENT_CODE_CMCTB_DEPT_MDG_CORPNM.$inferInsert; +type DeptnmData = typeof DEPARTMENT_CODE_CMCTB_DEPT_MDG_DEPTNM.$inferInsert; + +// XML에서 받는 데이터 구조 +type DeptXML = ToXMLFields<Omit<DeptData, 'id' | 'createdAt' | 'updatedAt'>> & { + DEPTNM?: DeptnmXML[]; + COMPNM?: CompnmXML[]; + CORPNM?: CorpnmXML[]; +}; + +type DeptnmXML = ToXMLFields<Omit<DeptnmData, 'id' | 'createdAt' | 'updatedAt'>>; +type CompnmXML = ToXMLFields<Omit<CompnmData, 'id' | 'createdAt' | 'updatedAt'>>; +type CorpnmXML = ToXMLFields<Omit<CorpnmData, 'id' | 'createdAt' | 'updatedAt'>>; + +// 처리된 데이터 구조 +interface ProcessedDepartmentData { + dept: DeptData; + deptnms: DeptnmData[]; + compnms: CompnmData[]; + corpnms: CorpnmData[]; +} + +export async function GET(request: NextRequest) { + const url = new URL(request.url); + if (url.searchParams.has('wsdl')) { + return serveWsdl('IF_MDZ_EVCP_DEPARTMENT_CODE.wsdl'); + } + + return new Response('Method Not Allowed', { status: 405 }); +} + +export async function POST(request: NextRequest) { + const url = new URL(request.url); + if (url.searchParams.has('wsdl')) { + return serveWsdl('IF_MDZ_EVCP_DEPARTMENT_CODE.wsdl'); + } + + const body = await request.text(); + + return withSoapLogging( + 'INBOUND', + 'S-ERP', + 'IF_MDZ_EVCP_DEPARTMENT_CODE', + body, + async () => { + console.log('Request Body 일부:', body.substring(0, 200) + (body.length > 200 ? '...' : '')); + + const parser = createXMLParser(['CMCTB_DEPT_MDG', 'DEPTNM', 'COMPNM', 'CORPNM']); + const parsedData = parser.parse(body); + console.log('XML root keys:', Object.keys(parsedData)); + + const requestData = extractRequestData(parsedData, 'IF_MDZ_EVCP_DEPARTMENT_CODEReq'); + + if (!requestData) { + console.error('Could not find valid request data in the received payload'); + console.error('Received XML structure:', JSON.stringify(parsedData, null, 2)); + throw new Error('Missing request data - could not find IF_MDZ_EVCP_DEPARTMENT_CODEReq or CMCTB_DEPT_MDG data'); + } + + console.log('Validating request data structure:', + `CMCTB_DEPT_MDG: ${requestData.CMCTB_DEPT_MDG ? 'found' : 'not found'}` + ); + + if (requestData.CMCTB_DEPT_MDG && Array.isArray(requestData.CMCTB_DEPT_MDG) && requestData.CMCTB_DEPT_MDG.length > 0) { + console.log('First CMCTB_DEPT_MDG sample:', JSON.stringify(requestData.CMCTB_DEPT_MDG[0], null, 2)); + } + + // XML 데이터를 DB 삽입 가능한 형태로 변환 + const processedDepts = transformDepartmentData(requestData.CMCTB_DEPT_MDG as DeptXML[] || []); + + // 필수 필드 검증 + for (const deptData of processedDepts) { + if (!deptData.dept.DEPTCD) { + throw new Error('Missing required field: DEPTCD in department'); + } + if (!deptData.dept.CORPCD) { + throw new Error('Missing required field: CORPCD in department'); + } + } + + // 데이터베이스 저장 + await saveToDatabase(processedDepts); + + console.log(`Processed ${processedDepts.length} departments`); + + return createSuccessResponse('http://60.101.108.100/api/IF_MDZ_EVCP_DEPARTMENT_CODE/'); + } + ).catch(error => { + return createErrorResponse(error); + }); +} + +// XML 데이터를 DB 삽입 가능한 형태로 변환 +function transformDepartmentData(deptData: DeptXML[]): ProcessedDepartmentData[] { + if (!deptData || !Array.isArray(deptData)) { + return []; + } + + return deptData.map(dept => { + // 메인 Department 데이터 변환 + const deptRecord = convertXMLToDBData<DeptData>( + dept as Record<string, string | undefined>, + ['DEPTCD', 'CORPCD'] + ); + + // 필수 필드 보정 + if (!deptRecord.DEPTCD) { + deptRecord.DEPTCD = ''; + } + if (!deptRecord.CORPCD) { + deptRecord.CORPCD = ''; + } + + // FK 데이터 준비 + const fkData = { DEPTCD: dept.DEPTCD || '' }; + + // DEPTNM 데이터 변환 + const deptnms = processNestedArray( + dept.DEPTNM, + (deptnm) => convertXMLToDBData<DeptnmData>(deptnm, ['SPRAS'], fkData), + fkData + ); + + // COMPNM 데이터 변환 + const compnms = processNestedArray( + dept.COMPNM, + (compnm) => convertXMLToDBData<CompnmData>(compnm, ['SPRAS'], fkData), + fkData + ); + + // CORPNM 데이터 변환 + const corpnms = processNestedArray( + dept.CORPNM, + (corpnm) => convertXMLToDBData<CorpnmData>(corpnm, ['SPRAS'], fkData), + fkData + ); + + return { + dept: deptRecord, + deptnms, + compnms, + corpnms + }; + }); +} + +// 데이터베이스 저장 함수 +async function saveToDatabase(processedDepts: ProcessedDepartmentData[]) { + console.log(`데이터베이스 저장 함수가 호출됨. ${processedDepts.length}개의 부서 데이터 수신.`); + + try { + await db.transaction(async (tx) => { + for (const deptData of processedDepts) { + const { dept, deptnms, compnms, corpnms } = deptData; + + if (!dept.DEPTCD) { + console.warn('부서코드(DEPTCD)가 없는 항목 발견, 건너뜁니다.'); + continue; + } + + // 1. Department 테이블 Upsert (최상위 테이블) + await tx.insert(DEPARTMENT_CODE_CMCTB_DEPT_MDG) + .values(dept) + .onConflictDoUpdate({ + target: DEPARTMENT_CODE_CMCTB_DEPT_MDG.DEPTCD, + set: { + ...dept, + updatedAt: new Date(), + } + }); + + // 2. 하위 테이블 데이터 처리 - FK 기준으로 전체 삭제 후 재삽입 + await Promise.all([ + // DEPTNM 테이블 처리 + replaceSubTableData( + tx, + DEPARTMENT_CODE_CMCTB_DEPT_MDG_DEPTNM, + deptnms, + 'DEPTCD', + dept.DEPTCD + ), + + // COMPNM 테이블 처리 + replaceSubTableData( + tx, + DEPARTMENT_CODE_CMCTB_DEPT_MDG_COMPNM, + compnms, + 'DEPTCD', + dept.DEPTCD + ), + + // CORPNM 테이블 처리 + replaceSubTableData( + tx, + DEPARTMENT_CODE_CMCTB_DEPT_MDG_CORPNM, + corpnms, + 'DEPTCD', + dept.DEPTCD + ) + ]); + } + }); + + console.log(`${processedDepts.length}개의 부서 데이터 처리 완료.`); + return true; + } catch (error) { + console.error('데이터베이스 저장 중 오류 발생:', error); + throw error; + } +} |
