summaryrefslogtreecommitdiff
path: root/lib/vendor-document-list/sync-service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor-document-list/sync-service.ts')
-rw-r--r--lib/vendor-document-list/sync-service.ts265
1 files changed, 60 insertions, 205 deletions
diff --git a/lib/vendor-document-list/sync-service.ts b/lib/vendor-document-list/sync-service.ts
index 1f2872c4..4c1f5786 100644
--- a/lib/vendor-document-list/sync-service.ts
+++ b/lib/vendor-document-list/sync-service.ts
@@ -1,4 +1,4 @@
-// lib/sync-service.ts (시스템별 분리 버전)
+// lib/sync-service.ts (시스템별 분리 버전 - DOLCE 업로드 통합)
import db from "@/db/db"
import {
changeLogs,
@@ -29,8 +29,6 @@ export interface SyncResult {
class SyncService {
private readonly CHUNK_SIZE = 50
-
-
/**
* 동기화 활성화 여부 확인
*/
@@ -294,7 +292,7 @@ class SyncService {
}
/**
- * DOLCE 시스템 전용 동기화 수행
+ * DOLCE 시스템 전용 동기화 수행 - 실제 업로드 서비스 사용
*/
private async performSyncDOLCE(
changes: ChangeLog[],
@@ -302,143 +300,72 @@ class SyncService {
): Promise<{ success: boolean; successCount: number; failureCount: number; errors?: string[]; endpointResults?: Record<string, any> }> {
const errors: string[] = []
const endpointResults: Record<string, any> = {}
- let overallSuccess = true
-
- // 변경사항을 DOLCE 시스템 형태로 변환
- const syncData = await this.transformChangesForDOLCE(changes)
-
- // DOLCE 엔드포인트 호출들을 직접 정의
- const endpointPromises = []
-
- // 1. DOLCE 메인 엔드포인트
- const mainUrl = process.env.SYNC_DOLCE_URL
- if (mainUrl) {
- endpointPromises.push(
- (async () => {
- try {
- console.log(`Sending to DOLCE main: ${mainUrl}`)
-
- const transformedData = {
- contractId,
- systemType: 'DOLCE',
- changes: syncData,
- batchSize: changes.length,
- timestamp: new Date().toISOString(),
- source: 'EVCP',
- version: '1.0'
- }
-
- // 헤더 구성 (토큰이 있을 때만 Authorization 포함)
- const headers: Record<string, string> = {
- 'Content-Type': 'application/json',
- 'X-API-Version': process.env.SYNC_DOLCE_VERSION || 'v1',
- 'X-System': 'DOLCE'
- }
-
- if (process.env.SYNC_DOLCE_TOKEN) {
- headers['Authorization'] = `Bearer ${process.env.SYNC_DOLCE_TOKEN}`
- }
-
- const response = await fetch(mainUrl, {
- method: 'POST',
- headers,
- body: JSON.stringify(transformedData)
- })
-
- if (!response.ok) {
- const errorText = await response.text()
- throw new Error(`DOLCE main: HTTP ${response.status} - ${errorText}`)
- }
-
- const result = await response.json()
- endpointResults['dolce_main'] = result
-
- console.log(`✅ DOLCE main sync successful`)
- return { success: true, endpoint: 'dolce_main', result }
- } catch (error) {
- const errorMessage = `DOLCE main: ${error instanceof Error ? error.message : 'Unknown error'}`
- errors.push(errorMessage)
- overallSuccess = false
-
- console.error(`❌ DOLCE main sync failed:`, error)
- return { success: false, endpoint: 'dolce_main', error: errorMessage }
- }
- })()
- )
- }
-
- // 2. DOLCE 문서 전용 엔드포인트 (선택사항)
- const docUrl = process.env.SYNC_DOLCE_DOCUMENT_URL
- if (docUrl) {
- endpointPromises.push(
- (async () => {
- try {
- console.log(`Sending to DOLCE documents: ${docUrl}`)
-
- const documentData = {
- documents: syncData.filter(item => item.entityType === 'document'),
- source: 'EVCP_DOLCE',
- timestamp: new Date().toISOString()
- }
-
- // 헤더 구성 (토큰이 있을 때만 Authorization 포함)
- const headers: Record<string, string> = {
- 'Content-Type': 'application/json'
- }
-
- if (process.env.SYNC_DOLCE_TOKEN) {
- headers['Authorization'] = `Bearer ${process.env.SYNC_DOLCE_TOKEN}`
- }
-
- const response = await fetch(docUrl, {
- method: 'PUT',
- headers,
- body: JSON.stringify(documentData)
- })
-
- if (!response.ok) {
- const errorText = await response.text()
- throw new Error(`DOLCE documents: HTTP ${response.status} - ${errorText}`)
- }
+ try {
+ // DOLCE 업로드 서비스 동적 임포트
+ const { dolceUploadService } = await import('./dolce-upload-service')
+
+ if (!dolceUploadService.isUploadEnabled()) {
+ throw new Error('DOLCE upload is not enabled')
+ }
- const result = await response.json()
- endpointResults['dolce_documents'] = result
+ // 변경사항에서 리비전 ID들 추출
+ const revisionIds = changes
+ .filter(change => change.entityType === 'revision')
+ .map(change => change.entityId)
- console.log(`✅ DOLCE documents sync successful`)
- return { success: true, endpoint: 'dolce_documents', result }
+ if (revisionIds.length === 0) {
+ return {
+ success: true,
+ successCount: 0,
+ failureCount: 0,
+ endpointResults: { message: 'No revisions to upload' }
+ }
+ }
- } catch (error) {
- const errorMessage = `DOLCE documents: ${error instanceof Error ? error.message : 'Unknown error'}`
- errors.push(errorMessage)
- overallSuccess = false
-
- console.error(`❌ DOLCE documents sync failed:`, error)
- return { success: false, endpoint: 'dolce_documents', error: errorMessage }
- }
- })()
+ // DOLCE 업로드 실행
+ const uploadResult = await dolceUploadService.uploadToDoLCE(
+ contractId,
+ revisionIds,
+ 'system_user', // 시스템 사용자 ID
+ 'System Upload'
)
- }
- if (endpointPromises.length === 0) {
- throw new Error('No DOLCE sync endpoints configured')
- }
+ endpointResults['dolce_upload'] = uploadResult
- // 모든 엔드포인트 요청 완료 대기
- const results = await Promise.allSettled(endpointPromises)
-
- // 결과 집계
- const successfulEndpoints = results.filter(r => r.status === 'fulfilled' && r.value.success).length
- const totalEndpoints = endpointPromises.length
+ if (uploadResult.success) {
+ console.log(`✅ DOLCE upload successful: ${uploadResult.uploadedDocuments} documents, ${uploadResult.uploadedFiles} files`)
+
+ return {
+ success: true,
+ successCount: changes.length,
+ failureCount: 0,
+ endpointResults
+ }
+ } else {
+ console.error(`❌ DOLCE upload failed:`, uploadResult.errors)
+
+ return {
+ success: false,
+ successCount: 0,
+ failureCount: changes.length,
+ errors: uploadResult.errors,
+ endpointResults
+ }
+ }
- console.log(`DOLCE endpoint results: ${successfulEndpoints}/${totalEndpoints} successful`)
+ } catch (error) {
+ const errorMessage = `DOLCE upload failed: ${error instanceof Error ? error.message : 'Unknown error'}`
+ errors.push(errorMessage)
+ console.error(`❌ DOLCE upload error:`, error)
- return {
- success: overallSuccess && errors.length === 0,
- successCount: overallSuccess ? changes.length : 0,
- failureCount: overallSuccess ? 0 : changes.length,
- errors: errors.length > 0 ? errors : undefined,
- endpointResults
+ return {
+ success: false,
+ successCount: 0,
+ failureCount: changes.length,
+ errors,
+ endpointResults
+ }
}
}
@@ -560,78 +487,6 @@ class SyncService {
}
/**
- * DOLCE 시스템용 데이터 변환
- */
- private async transformChangesForDOLCE(changes: ChangeLog[]): Promise<SyncableEntity[]> {
- const syncData: SyncableEntity[] = []
-
- for (const change of changes) {
- try {
- let entityData = null
-
- // 엔티티 타입별로 현재 데이터 조회
- switch (change.entityType) {
- case 'document':
- if (change.action !== 'DELETE') {
- const [document] = await db
- .select()
- .from(documents)
- .where(eq(documents.id, change.entityId))
- .limit(1)
- entityData = document
- }
- break
-
- case 'revision':
- if (change.action !== 'DELETE') {
- const [revision] = await db
- .select()
- .from(revisions)
- .where(eq(revisions.id, change.entityId))
- .limit(1)
- entityData = revision
- }
- break
-
- case 'attachment':
- if (change.action !== 'DELETE') {
- const [attachment] = await db
- .select()
- .from(documentAttachments)
- .where(eq(documentAttachments.id, change.entityId))
- .limit(1)
- entityData = attachment
- }
- break
- }
-
- // DOLCE 특화 데이터 구조
- syncData.push({
- entityType: change.entityType as any,
- entityId: change.entityId,
- action: change.action as any,
- data: entityData || change.oldValues,
- metadata: {
- changeId: change.id,
- changedAt: change.createdAt,
- changedBy: change.userName,
- changedFields: change.changedFields,
- // DOLCE 전용 메타데이터
- dolceVersion: '2.0',
- processingPriority: change.entityType === 'revision' ? 'HIGH' : 'NORMAL',
- requiresApproval: change.action === 'DELETE'
- }
- })
-
- } catch (error) {
- console.error(`Failed to transform change ${change.id} for DOLCE:`, error)
- }
- }
-
- return syncData
- }
-
- /**
* SWP 시스템용 데이터 변환
*/
private async transformChangesForSWP(changes: ChangeLog[]): Promise<SyncableEntity[]> {
@@ -759,7 +614,7 @@ class SyncService {
await db.update(revisions)
.set({
revisionStatus: "SUBMITTED",
- externalSentAt: new Date().toISOString().slice(0, 10)
+ submittedDate: new Date().toISOString().slice(0, 10)
})
.where(inArray(revisions.id, revisionIds))
}