diff options
Diffstat (limited to 'lib/vendor-document-list/import-service.ts')
| -rw-r--r-- | lib/vendor-document-list/import-service.ts | 166 |
1 files changed, 131 insertions, 35 deletions
diff --git a/lib/vendor-document-list/import-service.ts b/lib/vendor-document-list/import-service.ts index f2c62d0b..84e4263c 100644 --- a/lib/vendor-document-list/import-service.ts +++ b/lib/vendor-document-list/import-service.ts @@ -8,6 +8,7 @@ import { join } from "path" import { v4 as uuidv4 } from "uuid" import { extname } from "path" import * as crypto from "crypto" +import { debugError, debugWarn, debugSuccess, debugProcess } from "@/lib/debug-utils" export interface ImportResult { success: boolean @@ -145,14 +146,21 @@ class ImportService { sourceSystem: string = 'DOLCE' ): Promise<ImportResult> { try { - console.log(`Starting import from ${sourceSystem} for contract ${projectId}`) + debugProcess(`DOLCE 가져오기 시작`, { projectId, sourceSystem }) // 1. 계약 정보를 통해 프로젝트 코드와 벤더 코드 조회 const contractInfo = await this.getContractInfoById(projectId) if (!contractInfo?.projectCode || !contractInfo?.vendorCode) { + debugError(`프로젝트 코드 또는 벤더 코드 없음`, { projectId }) throw new Error(`Project code or vendor code not found for contract ${projectId}`) } + debugLog(`계약 정보 조회 완료`, { + projectId, + projectCode: contractInfo.projectCode, + vendorCode: contractInfo.vendorCode + }) + // 2. 각 drawingKind별로 데이터 조회 const allDocuments: DOLCEDocument[] = [] const drawingKinds = ['B3', 'B4', 'B5'] @@ -165,14 +173,18 @@ class ImportService { drawingKind ) allDocuments.push(...documents) - console.log(`Fetched ${documents.length} documents for ${drawingKind}`) + debugSuccess(`${drawingKind} 문서 조회 완료`, { + drawingKind, + documentCount: documents.length + }) } catch (error) { - console.warn(`Failed to fetch ${drawingKind} documents:`, error) + debugWarn(`${drawingKind} 문서 조회 실패`, { drawingKind, error }) // 개별 drawingKind 실패는 전체 실패로 처리하지 않음 } } if (allDocuments.length === 0) { + debugProcess(`가져올 문서 없음`, { projectId }) return { success: true, newCount: 0, @@ -187,6 +199,16 @@ class ImportService { } } + debugProcess(`전체 문서 수`, { + projectId, + totalDocuments: allDocuments.length, + byDrawingKind: { + B3: allDocuments.filter(d => d.DrawingKind === 'B3').length, + B4: allDocuments.filter(d => d.DrawingKind === 'B4').length, + B5: allDocuments.filter(d => d.DrawingKind === 'B5').length + } + }) + let newCount = 0 let updatedCount = 0 let skippedCount = 0 @@ -200,6 +222,11 @@ class ImportService { // 3. 각 문서 동기화 처리 for (const dolceDoc of allDocuments) { try { + debugProcess(`문서 동기화 시작`, { + drawingNo: dolceDoc.DrawingNo, + drawingKind: dolceDoc.DrawingKind + }) + const result = await this.syncSingleDocument(projectId, dolceDoc, sourceSystem) if (result === 'NEW') { @@ -240,19 +267,35 @@ class ImportService { downloadedFilesCount += attachmentResult.downloadedCount } catch (revisionError) { - console.warn(`Failed to sync revisions for ${dolceDoc.DrawingNo}:`, revisionError) + debugWarn(`리비전 동기화 실패`, { + drawingNo: dolceDoc.DrawingNo, + error: revisionError + }) // revisions 동기화 실패는 에러 로그만 남기고 계속 진행 } } catch (error) { + debugError(`문서 동기화 실패`, { + drawingNo: dolceDoc.DrawingNo, + error + }) errors.push(`Document ${dolceDoc.DrawingNo}: ${error instanceof Error ? error.message : 'Unknown error'}`) skippedCount++ } } - console.log(`Import completed: ${newCount} new, ${updatedCount} updated, ${skippedCount} skipped`) - console.log(`Revisions: ${newRevisionsCount} new, ${updatedRevisionsCount} updated`) - console.log(`Attachments: ${newAttachmentsCount} new, ${updatedAttachmentsCount} updated, ${downloadedFilesCount} downloaded`) + debugSuccess(`DOLCE 가져오기 완료`, { + projectId, + newCount, + updatedCount, + skippedCount, + newRevisionsCount, + updatedRevisionsCount, + newAttachmentsCount, + updatedAttachmentsCount, + downloadedFilesCount, + errorCount: errors.length + }) return { success: errors.length === 0, @@ -269,7 +312,7 @@ class ImportService { } } catch (error) { - console.error('Import failed:', error) + debugError(`DOLCE 가져오기 실패`, { projectId, error }) throw error } } @@ -432,7 +475,7 @@ class ImportService { uploadId: uploadId } - console.log(`Fetching file info from DOLCE: ${uploadId}`) + debugProcess(`DOLCE 파일 정보 조회 시작`, { uploadId, endpoint }) try { const response = await fetch(endpoint, { @@ -445,6 +488,7 @@ class ImportService { if (!response.ok) { const errorText = await response.text() + debugError(`DOLCE FileInfo API 실패`, { uploadId, status: response.status, error: errorText }) throw new Error(`DOLCE FileInfo API failed: HTTP ${response.status} - ${errorText}`) } @@ -453,15 +497,20 @@ class ImportService { // DOLCE FileInfo API 응답 구조에 맞게 처리 if (data.FileInfoListResult) { const files = data.FileInfoListResult as DOLCEFileInfo[] - console.log(`Found ${files.length} files for uploadId: ${uploadId}`) + const activeFiles = files.filter(f => f.UseYn === 'Y') + debugSuccess(`DOLCE 파일 정보 조회 완료`, { + uploadId, + totalFiles: files.length, + activeFiles: activeFiles.length + }) return files } else { - console.warn(`Unexpected DOLCE FileInfo response structure:`, data) + debugWarn(`예상치 못한 DOLCE FileInfo 응답 구조`, { uploadId, data }) return [] } } catch (error) { - console.error(`DOLCE FileInfo API call failed for ${uploadId}:`, error) + debugError(`DOLCE FileInfo API 호출 실패`, { uploadId, error }) throw error } } @@ -498,13 +547,13 @@ class ImportService { const downloadUrl = `${process.env.DOLCE_DOWNLOAD_URL}?key=${encryptedKey}` ||`http://60.100.99.217:1111/Download.aspx?key=${encryptedKey}` - console.log(`🔗 DOLCE 다운로드 링크 생성:`) - console.log(` 파일명: ${fileName}`) - console.log(` FileId: ${fileId}`) - console.log(` UserId: ${userId}`) - console.log(` 암호화 키: ${encryptedKey}`) - console.log(` 다운로드 URL: ${downloadUrl}`) - console.log(`📥 DOLCE에서 파일 다운로드 시작: ${fileName}`) + debugProcess(`DOLCE 파일 다운로드 시작`, { + fileName, + fileId, + userId, + encryptedKey, + downloadUrl + }) const response = await fetch(downloadUrl, { method: 'GET', @@ -514,18 +563,25 @@ class ImportService { }) if (!response.ok) { - console.error(`❌ DOLCE 다운로드 실패: HTTP ${response.status}`) - console.error(` URL: ${downloadUrl}`) + debugError(`DOLCE 다운로드 실패`, { + fileName, + status: response.status, + url: downloadUrl + }) throw new Error(`File download failed: HTTP ${response.status}`) } const buffer = Buffer.from(await response.arrayBuffer()) - console.log(`✅ DOLCE에서 파일 다운로드 완료: ${fileName} (${buffer.length} bytes)`) + debugSuccess(`DOLCE 파일 다운로드 완료`, { + fileName, + fileSize: buffer.length, + fileId + }) return buffer } catch (error) { - console.error(`❌ DOLCE 파일 다운로드 실패: ${fileName}`, error) + debugError(`DOLCE 파일 다운로드 실패`, { fileName, fileId, error }) throw error } } @@ -550,7 +606,12 @@ class ImportService { await writeFile(fullPath, buffer) - console.log(`Saved file: ${originalFileName} as ${fileName}`) + debugSuccess(`로컬 파일 저장 완료`, { + originalFileName, + savedFileName: fileName, + filePath: relativePath, + fileSize: buffer.length + }) return { fileName: originalFileName, @@ -559,7 +620,7 @@ class ImportService { } } catch (error) { - console.error(`Failed to save file ${originalFileName}:`, error) + debugError(`로컬 파일 저장 실패`, { originalFileName, error }) throw error } } @@ -745,6 +806,12 @@ class ImportService { sourceSystem: string ): Promise<{ newCount: number; updatedCount: number; downloadedCount: number }> { try { + debugProcess(`문서 첨부파일 동기화 시작`, { + drawingNo: dolceDoc.DrawingNo, + drawingKind: dolceDoc.DrawingKind, + discipline: dolceDoc.Discipline + }) + // 1. 상세 정보 조회 const detailDocs = await this.fetchDetailFromDOLCE( dolceDoc.ProjectNo, @@ -757,10 +824,16 @@ class ImportService { const fsDetailDocs = detailDocs.filter(doc => doc.Category === 'FS') if (fsDetailDocs.length === 0) { - console.log(`No FS category documents found for ${dolceDoc.DrawingNo}`) + debugProcess(`FS 카테고리 문서 없음`, { drawingNo: dolceDoc.DrawingNo }) return { newCount: 0, updatedCount: 0, downloadedCount: 0 } } + debugProcess(`FS 문서 발견`, { + drawingNo: dolceDoc.DrawingNo, + totalDetails: detailDocs.length, + fsDetails: fsDetailDocs.length + }) + let newCount = 0 let updatedCount = 0 let downloadedCount = 0 @@ -769,7 +842,7 @@ class ImportService { for (const detailDoc of fsDetailDocs) { try { if (!detailDoc.UploadId || detailDoc.UploadId.trim() === '') { - console.log(`No UploadId for ${detailDoc.RegisterId}`) + debugProcess(`UploadId 없음`, { registerId: detailDoc.RegisterId }) continue } @@ -781,7 +854,7 @@ class ImportService { .limit(1) if (revisionRecord.length === 0) { - console.warn(`No revision found for RegisterId: ${detailDoc.RegisterId}`) + debugWarn(`Revision 없음`, { registerId: detailDoc.RegisterId }) continue } @@ -792,7 +865,7 @@ class ImportService { for (const fileInfo of fileInfos) { if (fileInfo.UseYn !== 'Y') { - console.log(`Skipping inactive file: ${fileInfo.FileName}`) + debugProcess(`비활성 파일 스킵`, { fileName: fileInfo.FileName }) continue } @@ -812,14 +885,21 @@ class ImportService { } } catch (error) { - console.error(`Failed to sync attachments for ${detailDoc.RegisterId}:`, error) + debugError(`첨부파일 동기화 실패`, { registerId: detailDoc.RegisterId, error }) } } + debugSuccess(`문서 첨부파일 동기화 완료`, { + drawingNo: dolceDoc.DrawingNo, + newCount, + updatedCount, + downloadedCount + }) + return { newCount, updatedCount, downloadedCount } } catch (error) { - console.error(`Failed to sync attachments for ${dolceDoc.DrawingNo}:`, error) + debugError(`문서 첨부파일 동기화 실패`, { drawingNo: dolceDoc.DrawingNo, error }) throw error } } @@ -834,6 +914,13 @@ class ImportService { sourceSystem: string ): Promise<'NEW' | 'UPDATED' | 'SKIPPED'> { try { + debugProcess(`단일 첨부파일 동기화 시작`, { + fileName: fileInfo.FileName, + fileId: fileInfo.FileId, + revisionId, + userId + }) + // 기존 첨부파일 조회 (FileId로) const existingAttachment = await db .select() @@ -846,12 +933,12 @@ class ImportService { if (existingAttachment.length > 0) { // 이미 존재하는 파일인 경우, 필요시 업데이트 로직 추가 - console.log(`File already exists: ${fileInfo.FileName}`) + debugProcess(`파일 이미 존재`, { fileName: fileInfo.FileName, fileId: fileInfo.FileId }) return 'SKIPPED' } // 파일 다운로드 - console.log(`Downloading file: ${fileInfo.FileName}`) + debugProcess(`파일 다운로드 시작`, { fileName: fileInfo.FileName, fileId: fileInfo.FileId }) const fileBuffer = await this.downloadFileFromDOLCE( fileInfo.FileId, userId, @@ -881,11 +968,20 @@ class ImportService { .insert(documentAttachments) .values(attachmentData) - console.log(`Created new attachment: ${fileInfo.FileName}`) + debugSuccess(`새 첨부파일 생성 완료`, { + fileName: fileInfo.FileName, + fileId: fileInfo.FileId, + filePath: savedFile.filePath, + fileSize: savedFile.fileSize + }) return 'NEW' } catch (error) { - console.error(`Failed to sync attachment ${fileInfo.FileName}:`, error) + debugError(`단일 첨부파일 동기화 실패`, { + fileName: fileInfo.FileName, + fileId: fileInfo.FileId, + error + }) throw error } } |
