summaryrefslogtreecommitdiff
path: root/lib/vendor-document-list/import-service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor-document-list/import-service.ts')
-rw-r--r--lib/vendor-document-list/import-service.ts287
1 files changed, 160 insertions, 127 deletions
diff --git a/lib/vendor-document-list/import-service.ts b/lib/vendor-document-list/import-service.ts
index bc384ea2..c7ba041a 100644
--- a/lib/vendor-document-list/import-service.ts
+++ b/lib/vendor-document-list/import-service.ts
@@ -1332,156 +1332,189 @@ class ImportService {
/**
* 가져오기 상태 조회
*/
- async getImportStatus(
- contractId: number,
- sourceSystem: string = 'DOLCE'
- ): Promise<ImportStatus> {
- try {
- // 마지막 가져오기 시간 조회
- const [lastImport] = await db
- .select({
- lastSynced: sql<string>`MAX(${documents.externalSyncedAt})`
- })
- .from(documents)
- .where(and(
- eq(documents.contractId, contractId),
- eq(documents.externalSystemType, sourceSystem)
- ))
+ /**
+ * 가져오기 상태 조회 - 에러 시 안전한 기본값 반환
+ */
+async getImportStatus(
+ contractId: number,
+ sourceSystem: string = 'DOLCE'
+): Promise<ImportStatus> {
+ try {
+ // 마지막 가져오기 시간 조회
+ const [lastImport] = await db
+ .select({
+ lastSynced: sql<string>`MAX(${documents.externalSyncedAt})`
+ })
+ .from(documents)
+ .where(and(
+ eq(documents.contractId, contractId),
+ eq(documents.externalSystemType, sourceSystem)
+ ))
- // 프로젝트 코드와 벤더 코드 조회
- const contractInfo = await this.getContractInfoById(contractId)
+ // 프로젝트 코드와 벤더 코드 조회
+ const contractInfo = await this.getContractInfoById(contractId)
- if (!contractInfo?.projectCode || !contractInfo?.vendorCode) {
- throw new Error(`Project code or vendor code not found for contract ${contractId}`)
+ // 🔥 계약 정보가 없으면 기본 상태 반환 (에러 throw 하지 않음)
+ if (!contractInfo?.projectCode || !contractInfo?.vendorCode) {
+ console.warn(`Project code or vendor code not found for contract ${contractId}`)
+ return {
+ lastImportAt: lastImport?.lastSynced ? new Date(lastImport.lastSynced).toISOString() : undefined,
+ availableDocuments: 0,
+ newDocuments: 0,
+ updatedDocuments: 0,
+ availableRevisions: 0,
+ newRevisions: 0,
+ updatedRevisions: 0,
+ availableAttachments: 0,
+ newAttachments: 0,
+ updatedAttachments: 0,
+ importEnabled: false, // 🔥 계약 정보가 없으면 import 비활성화
+ error: `Contract ${contractId}에 대한 프로젝트 코드 또는 벤더 코드를 찾을 수 없습니다.` // 🔥 에러 메시지 추가
}
+ }
- let availableDocuments = 0
- let newDocuments = 0
- let updatedDocuments = 0
- let availableRevisions = 0
- let newRevisions = 0
- let updatedRevisions = 0
- let availableAttachments = 0
- let newAttachments = 0
- let updatedAttachments = 0
+ let availableDocuments = 0
+ let newDocuments = 0
+ let updatedDocuments = 0
+ let availableRevisions = 0
+ let newRevisions = 0
+ let updatedRevisions = 0
+ let availableAttachments = 0
+ let newAttachments = 0
+ let updatedAttachments = 0
- try {
- // 각 drawingKind별로 확인
- const drawingKinds = ['B3', 'B4', 'B5']
+ try {
+ // 각 drawingKind별로 확인
+ const drawingKinds = ['B3', 'B4', 'B5']
- for (const drawingKind of drawingKinds) {
- try {
- const externalDocs = await this.fetchFromDOLCE(
- contractInfo.projectCode,
- contractInfo.vendorCode,
- drawingKind
- )
- availableDocuments += externalDocs.length
-
- // 신규/업데이트 문서 수 계산
- for (const externalDoc of externalDocs) {
- const existing = await db
- .select({ id: documents.id, updatedAt: documents.updatedAt })
- .from(documents)
- .where(and(
- eq(documents.contractId, contractId),
- eq(documents.docNumber, externalDoc.DrawingNo)
- ))
- .limit(1)
-
- if (existing.length === 0) {
- newDocuments++
- } else {
- // DOLCE의 CreateDt와 로컬 updatedAt 비교
- if (externalDoc.CreateDt && existing[0].updatedAt) {
- const externalModified = new Date(externalDoc.CreateDt)
- const localModified = new Date(existing[0].updatedAt)
- if (externalModified > localModified) {
- updatedDocuments++
- }
+ for (const drawingKind of drawingKinds) {
+ try {
+ const externalDocs = await this.fetchFromDOLCE(
+ contractInfo.projectCode,
+ contractInfo.vendorCode,
+ drawingKind
+ )
+ availableDocuments += externalDocs.length
+
+ // 신규/업데이트 문서 수 계산
+ for (const externalDoc of externalDocs) {
+ const existing = await db
+ .select({ id: documents.id, updatedAt: documents.updatedAt })
+ .from(documents)
+ .where(and(
+ eq(documents.contractId, contractId),
+ eq(documents.docNumber, externalDoc.DrawingNo)
+ ))
+ .limit(1)
+
+ if (existing.length === 0) {
+ newDocuments++
+ } else {
+ // DOLCE의 CreateDt와 로컬 updatedAt 비교
+ if (externalDoc.CreateDt && existing[0].updatedAt) {
+ const externalModified = new Date(externalDoc.CreateDt)
+ const localModified = new Date(existing[0].updatedAt)
+ if (externalModified > localModified) {
+ updatedDocuments++
}
}
+ }
- // revisions 및 attachments 상태도 확인
- try {
- const detailDocs = await this.fetchDetailFromDOLCE(
- externalDoc.ProjectNo,
- externalDoc.DrawingNo,
- externalDoc.Discipline,
- externalDoc.DrawingKind
- )
- availableRevisions += detailDocs.length
-
- for (const detailDoc of detailDocs) {
- const existingRevision = await db
- .select({ id: revisions.id })
- .from(revisions)
- .where(eq(revisions.registerId, detailDoc.RegisterId))
- .limit(1)
-
- if (existingRevision.length === 0) {
- newRevisions++
- } else {
- updatedRevisions++
- }
+ // revisions 및 attachments 상태도 확인
+ try {
+ const detailDocs = await this.fetchDetailFromDOLCE(
+ externalDoc.ProjectNo,
+ externalDoc.DrawingNo,
+ externalDoc.Discipline,
+ externalDoc.DrawingKind
+ )
+ availableRevisions += detailDocs.length
+
+ for (const detailDoc of detailDocs) {
+ const existingRevision = await db
+ .select({ id: revisions.id })
+ .from(revisions)
+ .where(eq(revisions.registerId, detailDoc.RegisterId))
+ .limit(1)
+
+ if (existingRevision.length === 0) {
+ newRevisions++
+ } else {
+ updatedRevisions++
+ }
- // FS Category 문서의 첨부파일 확인
- if (detailDoc.Category === 'FS' && detailDoc.UploadId) {
- try {
- const fileInfos = await this.fetchFileInfoFromDOLCE(detailDoc.UploadId)
- availableAttachments += fileInfos.filter(f => f.UseYn === 'Y').length
-
- for (const fileInfo of fileInfos) {
- if (fileInfo.UseYn !== 'Y') continue
-
- const existingAttachment = await db
- .select({ id: documentAttachments.id })
- .from(documentAttachments)
- .where(eq(documentAttachments.fileId, fileInfo.FileId))
- .limit(1)
-
- if (existingAttachment.length === 0) {
- newAttachments++
- } else {
- updatedAttachments++
- }
+ // FS Category 문서의 첨부파일 확인
+ if (detailDoc.Category === 'FS' && detailDoc.UploadId) {
+ try {
+ const fileInfos = await this.fetchFileInfoFromDOLCE(detailDoc.UploadId)
+ availableAttachments += fileInfos.filter(f => f.UseYn === 'Y').length
+
+ for (const fileInfo of fileInfos) {
+ if (fileInfo.UseYn !== 'Y') continue
+
+ const existingAttachment = await db
+ .select({ id: documentAttachments.id })
+ .from(documentAttachments)
+ .where(eq(documentAttachments.fileId, fileInfo.FileId))
+ .limit(1)
+
+ if (existingAttachment.length === 0) {
+ newAttachments++
+ } else {
+ updatedAttachments++
}
- } catch (error) {
- console.warn(`Failed to check files for ${detailDoc.UploadId}:`, error)
}
+ } catch (error) {
+ console.warn(`Failed to check files for ${detailDoc.UploadId}:`, error)
}
}
- } catch (error) {
- console.warn(`Failed to check revisions for ${externalDoc.DrawingNo}:`, error)
}
+ } catch (error) {
+ console.warn(`Failed to check revisions for ${externalDoc.DrawingNo}:`, error)
}
- } catch (error) {
- console.warn(`Failed to check ${drawingKind} for status:`, error)
}
+ } catch (error) {
+ console.warn(`Failed to check ${drawingKind} for status:`, error)
}
- } catch (error) {
- console.warn(`Failed to fetch external data for status: ${error}`)
}
+ } catch (error) {
+ console.warn(`Failed to fetch external data for status: ${error}`)
+ // 🔥 외부 API 호출 실패 시에도 기본값 반환
+ }
- return {
- lastImportAt: lastImport?.lastSynced ? new Date(lastImport.lastSynced).toISOString() : undefined,
- availableDocuments,
- newDocuments,
- updatedDocuments,
- availableRevisions,
- newRevisions,
- updatedRevisions,
- availableAttachments,
- newAttachments,
- updatedAttachments,
- importEnabled: this.isImportEnabled(sourceSystem)
- }
+ return {
+ lastImportAt: lastImport?.lastSynced ? new Date(lastImport.lastSynced).toISOString() : undefined,
+ availableDocuments,
+ newDocuments,
+ updatedDocuments,
+ availableRevisions,
+ newRevisions,
+ updatedRevisions,
+ availableAttachments,
+ newAttachments,
+ updatedAttachments,
+ importEnabled: this.isImportEnabled(sourceSystem)
+ }
- } catch (error) {
- console.error('Failed to get import status:', error)
- throw error
+ } catch (error) {
+ // 🔥 최종적으로 모든 에러를 catch하여 안전한 기본값 반환
+ console.error('Failed to get import status:', error)
+ return {
+ lastImportAt: undefined,
+ availableDocuments: 0,
+ newDocuments: 0,
+ updatedDocuments: 0,
+ availableRevisions: 0,
+ newRevisions: 0,
+ updatedRevisions: 0,
+ availableAttachments: 0,
+ newAttachments: 0,
+ updatedAttachments: 0,
+ importEnabled: false,
+ error: error instanceof Error ? error.message : 'Unknown error occurred'
}
}
+}
/**
* 가져오기 활성화 여부 확인