'use server'; import { XMLBuilder, XMLParser } from 'fast-xml-parser'; import { withSoapLogging } from '@/lib/soap/utils'; import type { GetEncryptDocumentumFileParams } from './types'; import { POS_SOAP_ENDPOINT } from './types'; import { debugLog, debugError, debugSuccess, debugProcess } from '@/lib/debug-utils'; /** * 문서 암호화 파일을 서버에 다운로드하고 경로를 반환하는 POS(Documentum) SOAP 액션 * 반환값은 서버 내 파일 다운로드 경로입니다. (예: "asd_as_2509131735233768_OP02\asd_as_2509131735233768_OP02.tif") * 실제 파일은 \\60.100.99.123\ECM_NAS_PRM\Download\ 경로에 저장됩니다. */ export async function getEncryptDocumentumFile( params: GetEncryptDocumentumFileParams ): Promise<{ success: boolean; result?: string; error?: string; }> { try { const { objectID, sabun = 'EVM0236', // context2.txt에 따라 기본값 설정 appCode = process.env.POS_APP_CODE || 'SO13', // 환경변수 사용 fileCreateMode = 1, // context2.txt에 따라 기본값 변경 securityLevel = 'SedamsClassID', isDesign = true, // context2.txt에 따라 기본값 변경 } = params; debugLog(`🌐 POS SOAP API 호출 시작`, { objectID, sabun, appCode, fileCreateMode, securityLevel, isDesign, endpoint: POS_SOAP_ENDPOINT }); // 1. SOAP Envelope 생성 (SOAP 1.2) debugProcess(`📄 SOAP Envelope 생성 중...`); const envelopeObj = { 'soap12:Envelope': { '@_xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', '@_xmlns:xsd': 'http://www.w3.org/2001/XMLSchema', '@_xmlns:soap12': 'http://www.w3.org/2003/05/soap-envelope', 'soap12:Body': { GetEncryptDocumentumFile: { '@_xmlns': 'Sedams.WebServices.Documentum', objectID, sabun, appCode, fileCreateMode: String(fileCreateMode), securityLevel, isDesign: String(isDesign), }, }, }, }; const builder = new XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '@_', format: false, suppressEmptyNode: true, }); const xmlBody = builder.build(envelopeObj); debugLog(`📄 생성된 SOAP XML`, { objectID, xmlLength: xmlBody.length, envelope: envelopeObj['soap12:Envelope']['soap12:Body'] }); // 2. SOAP 호출 (로그 포함) debugProcess(`🌐 SOAP 요청 전송 중... (${POS_SOAP_ENDPOINT})`); const responseText = await withSoapLogging( 'OUTBOUND', 'SEDAMS Documentum', 'GetEncryptDocumentumFile', xmlBody, async () => { const res = await fetch(POS_SOAP_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'text/xml; charset=utf-8', SOAPAction: '"Sedams.WebServices.Documentum/GetEncryptDocumentumFile"', }, body: xmlBody, }); const text = await res.text(); debugLog(`🌐 HTTP 응답 수신`, { objectID, status: res.status, statusText: res.statusText, responseLength: text.length, headers: Object.fromEntries(res.headers.entries()) }); if (!res.ok) { debugError(`❌ HTTP 오류 응답`, { objectID, status: res.status, statusText: res.statusText, responseBody: text }); throw new Error(`HTTP ${res.status}: ${res.statusText}`); } return text; } ); debugSuccess(`✅ SOAP 응답 수신 완료 (응답 길이: ${responseText.length})`); // 3. 응답 XML 파싱 debugProcess(`📝 XML 응답 파싱 중...`); const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_', }); const parsed = parser.parse(responseText); debugLog(`📝 파싱된 XML 구조`, { objectID, parsedKeys: Object.keys(parsed), parsed: parsed }); let result: string | undefined; try { // SOAP 1.2 규격 debugProcess(`🔍 SOAP 1.2 구조에서 결과 추출 시도...`); result = parsed['soap:Envelope']['soap:Body'][ 'GetEncryptDocumentumFileResponse' ]['GetEncryptDocumentumFileResult']; debugLog(`🎯 SOAP 1.2에서 결과 추출 성공`, { objectID, result }); } catch (e1) { debugLog(`⚠️ SOAP 1.2 구조 추출 실패, Fallback 시도...`, { objectID, error: e1 }); // Fallback: SOAP 1.1 또는 다른 응답 형태 try { debugProcess(`🔍 SOAP 1.1 구조에서 결과 추출 시도...`); result = parsed['soap:Envelope']['soap:Body'][ 'GetEncryptDocumentumFileResponse' ]['GetEncryptDocumentumFileResult']; debugLog(`🎯 SOAP 1.1에서 결과 추출 성공`, { objectID, result }); } catch (e2) { debugLog(`⚠️ SOAP 1.1 구조 추출 실패, 단순 string 시도...`, { objectID, error: e2 }); // HTTP POST 응답 형태 (단순 string) try { debugProcess(`🔍 단순 string 구조에서 결과 추출 시도...`); result = parsed.string; debugLog(`🎯 단순 string에서 결과 추출 성공`, { objectID, result }); } catch (e3) { debugError(`❌ 모든 파싱 방법 실패`, { objectID, errors: [e1, e2, e3], parsedStructure: parsed }); } } } debugSuccess(`✅ POS API 호출 성공`, { objectID, result }); return { success: true, result }; } catch (error) { debugError('❌ POS SOAP 호출 실패', { objectID: params.objectID, error: error instanceof Error ? error.message : 'Unknown error', stack: error instanceof Error ? error.stack : undefined }); return { success: false, error: error instanceof Error ? error.message : 'Unknown error', }; } }