diff options
| author | joonhoekim <26rote@gmail.com> | 2025-09-22 19:33:16 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-09-22 19:33:16 +0900 |
| commit | 480ac58010604140d1a52fa2b839aedb6ac15941 (patch) | |
| tree | 4cc45c96ea174991d59c1a058ed9da05a2a3ac8c /lib/pos/get-pos.ts | |
| parent | ba35e67845f935c8ce0151c9ef1fefa0b0510faf (diff) | |
(김준회) POS I/F 로직 및 UI 처리 구현
Diffstat (limited to 'lib/pos/get-pos.ts')
| -rw-r--r-- | lib/pos/get-pos.ts | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/lib/pos/get-pos.ts b/lib/pos/get-pos.ts new file mode 100644 index 00000000..6424b880 --- /dev/null +++ b/lib/pos/get-pos.ts @@ -0,0 +1,174 @@ +'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', + }; + } +} |
