import { NextRequest } from 'next/server'; import db from '@/db/db'; import { ZMM_PCR } from '@/db/schema/ECC/ecc'; import { ToXMLFields, serveWsdl, createXMLParser, extractRequestData, convertXMLToDBData, createSoapResponse, withSoapLogging, } from '@/lib/soap/utils'; import { bulkUpsert } from "@/lib/soap/batch-utils"; import { mapAndSaveECCPcrData, } from '@/lib/soap/ecc/mapper/pcr-mapper'; type PCRData = typeof ZMM_PCR.$inferInsert; // GET 요청 처리는 ?wsdl 달고 있으면 WSDL 서비스 제공 export async function GET(request: NextRequest) { const url = new URL(request.url); if (url.searchParams.has('wsdl')) { return serveWsdl('IF_ECC_EVCP_PCR.wsdl'); } return new Response('Method Not Allowed', { status: 405 }); } // POST 요청이 데이터 적재 요구 (SOAP) export async function POST(request: NextRequest) { const url = new URL(request.url); if (url.searchParams.has('wsdl')) { return serveWsdl('IF_ECC_EVCP_PCR.wsdl'); } const body = await request.text(); // SOAP 로깅 래퍼 함수 사용 return withSoapLogging( 'INBOUND', 'ECC', 'IF_ECC_EVCP_PCR', body, async () => { console.log('🚀 PCR 수신 시작, 데이터 길이:', body.length); // 1) XML 파싱 const parser = createXMLParser(['ZMM_PCR']); const parsedData = parser.parse(body); // 2) SOAP Body 또는 루트에서 요청 데이터 추출 const requestData = extractRequestData(parsedData, 'IF_ECC_EVCP_PCRReq'); if (!requestData) { console.error('유효한 요청 데이터를 찾을 수 없습니다'); throw new Error('Missing request data - IF_ECC_EVCP_PCRReq not found'); } // 3) XML 데이터를 DB 삽입 가능한 형태로 변환 const processedData = transformPCRData(requestData as PCRRequestXML); // 4) 필수 필드 검증 for (const pcrData of processedData) { if (!pcrData.PCR_REQ || !pcrData.PCR_REQ_SEQ || !pcrData.EBELN || !pcrData.EBELP) { throw new Error('Missing required fields: PCR_REQ, PCR_REQ_SEQ, EBELN, EBELP'); } } // 5) 데이터베이스 저장 (ZMM_PCR 수신 테이블) await saveToDatabase(processedData); console.log(`🎉 ZMM_PCR 저장 완료: ${processedData.length}개 PCR 데이터`); // 6) 비즈니스 테이블로 매핑 및 저장 (pcrPo, pcrPr) console.log('📋 비즈니스 테이블 매핑 시작...'); const mappingResult = await mapAndSaveECCPcrData(processedData); if (mappingResult.success) { console.log(`✅ 비즈니스 테이블 매핑 완료: ${mappingResult.processedCount}개 PCR`); } else { console.error(`❌ 비즈니스 테이블 매핑 실패: ${mappingResult.message}`); // 매핑 실패해도 수신 테이블에는 저장되었으므로 경고만 출력 } // 7) 성공 응답 반환 - 각 PCR 데이터에 대해 ZMM_RT 객체 생성 const responseZmmRtList = processedData.map((pcrData) => ({ PCR_REQ: pcrData.PCR_REQ || '', PCR_REQ_SEQ: pcrData.PCR_REQ_SEQ || '', EBELN: pcrData.EBELN || '', EBELP: pcrData.EBELP || '', MSGTY: 'S', MSGTXT: '', })); return createSoapResponse('http://60.101.108.100/', { 'tns:IF_ECC_EVCP_PCRRes': { ZMM_RT: responseZmmRtList, }, }); } ).catch((error) => { // withSoapLogging에서 이미 에러 로그를 처리하므로, 여기서는 응답만 생성 return createSoapResponse('http://60.101.108.100/', { 'tns:IF_ECC_EVCP_PCRRes': { ZMM_RT: { PCR_REQ: '', // 에러 시에는 빈 값으로 설정 PCR_REQ_SEQ: '', EBELN: '', EBELP: '', MSGTY: 'E', MSGTXT: error instanceof Error ? error.message.slice(0, 100) : 'Unknown error', }, }, }); }); } // ----------------------------------------------------------------------------- // 데이터 변환 및 저장 관련 유틸리티 // ----------------------------------------------------------------------------- // XML 구조 타입 정의 type PCRDataXML = ToXMLFields>; // Root XML Request 타입 type PCRRequestXML = { CHG_GB?: string; ZMM_PCR?: PCRDataXML[]; }; // XML -> DB 데이터 변환 함수 function transformPCRData(requestData: PCRRequestXML): PCRData[] { const pcrItems = requestData.ZMM_PCR || []; return pcrItems.map((item) => { // PCR 데이터 변환 (단일 테이블이므로 간단함) const pcrDataConverted = convertXMLToDBData( item as Record, undefined // PCR은 단일 테이블이므로 FK 데이터 불필요 ); return pcrDataConverted; }); } // 데이터베이스 저장 함수 async function saveToDatabase(processedPCRs: PCRData[]) { console.log(`데이터베이스(배치) 저장 시작: ${processedPCRs.length}개 PCR 데이터`); try { await db.transaction(async (tx) => { // 필수 키 필드가 있는 데이터만 필터링 (PCR_REQ가 unique key) const validPCRRows = processedPCRs.filter((pcr): pcr is PCRData => !!pcr.PCR_REQ); // PCR 테이블에 UPSERT (배치) // PCR_REQ가 unique 키이므로 이를 기준으로 upsert await bulkUpsert(tx, ZMM_PCR, validPCRRows, 'PCR_REQ'); }); console.log(`데이터베이스(배치) 저장 완료: ${processedPCRs.length}개 PCR`); return true; } catch (error) { console.error('데이터베이스(배치) 저장 중 오류 발생:', error); throw error; } }