"use server"; import { logIntegrationExecution } from "./service"; /** * DB 연동 로깅 래퍼 함수 * * @description * 데이터베이스 작업을 자동으로 로깅하는 래퍼 함수입니다. * 동기화, 삽입, 수정, 삭제 등 다양한 DB 작업의 실행 시간과 결과를 기록합니다. * * @param integrationId 인터페이스 ID (추후 매핑 필요) * @param tableName 테이블명 * @param operation 작업 유형 (sync, upsert, delete 등) * @param processor 실제 DB 작업 함수 * @returns 처리 결과 * * @example * // 기본 DB 동기화 로깅 * const syncResult = await withDbLogging( * 1, // 인터페이스 ID * 'users', * 'sync', * async () => { * // 외부 시스템에서 사용자 데이터 가져오기 * const externalUsers = await fetchExternalUsers(); * * // 로컬 DB에 동기화 * const result = await syncUsersToLocalDb(externalUsers); * * return { * totalProcessed: result.length, * updated: result.filter(u => u.action === 'updated').length, * created: result.filter(u => u.action === 'created').length * }; * } * ); * * @example * // 데이터 삽입/수정 로깅 * const upsertResult = await withDbLogging( * 2, * 'products', * 'upsert', * async () => { * const productData = await getProductDataFromSap(); * * // 기존 데이터 확인 후 삽입/수정 * const existingProduct = await db.products.findFirst({ * where: { sapId: productData.sapId } * }); * * if (existingProduct) { * return await db.products.update({ * where: { id: existingProduct.id }, * data: productData * }); * } else { * return await db.products.create({ * data: productData * }); * } * } * ); * * @example * // 에러 처리와 함께 * try { * const deleteResult = await withDbLogging( * 3, * 'temp_data', * 'cleanup', * async () => { * // 7일 이전 임시 데이터 삭제 * const cutoffDate = new Date(); * cutoffDate.setDate(cutoffDate.getDate() - 7); * * const result = await db.tempData.deleteMany({ * where: { * createdAt: { lt: cutoffDate } * } * }); * * return { deletedCount: result.count }; * } * ); * * console.log(`${deleteResult.deletedCount}개의 임시 데이터가 삭제됨`); * } catch (error) { * console.error('DB 정리 작업 실패:', error); * } * * @example * // 트랜잭션 내에서 사용 * const transactionResult = await withDbLogging( * 4, * 'orders', * 'bulk_update', * async () => { * return await db.$transaction(async (tx) => { * // 여러 테이블 업데이트 * const orders = await tx.orders.updateMany({ * where: { status: 'pending' }, * data: { status: 'processing' } * }); * * const orderItems = await tx.orderItems.updateMany({ * where: { order: { status: 'processing' } }, * data: { processedAt: new Date() } * }); * * return { ordersUpdated: orders.count, itemsUpdated: orderItems.count }; * }); * } * ); */ export async function withDbLogging( integrationId: number, tableName: string, operation: string, processor: () => Promise ): Promise { const start = Date.now(); try { // 실제 DB 작업 실행 const result = await processor(); const duration = Date.now() - start; // 성공 로그 기록 await logIntegrationExecution({ integrationId, status: 'success', responseTime: duration, requestMethod: 'DB', requestUrl: `${operation}:${tableName}`, correlationId: `db_${tableName}_${Date.now()}`, }); return result; } catch (error) { const duration = Date.now() - start; // 실패 로그 기록 await logIntegrationExecution({ integrationId, status: 'failed', responseTime: duration, errorMessage: error instanceof Error ? error.message : 'Unknown error', requestMethod: 'DB', requestUrl: `${operation}:${tableName}`, correlationId: `db_${tableName}_${Date.now()}`, }); throw error; } } /** * nonsap 동기화 로깅 헬퍼 함수 * * @description * Non-SAP 시스템과의 데이터 동기화를 로깅하는 전용 헬퍼 함수입니다. * 전체 동기화(full)와 증분 동기화(delta) 모두 지원합니다. * * @param tableName 테이블명 * @param syncType 동기화 유형 (full, delta) * @param processor 동기화 작업 함수 * @returns 처리 결과 * * @example * // 전체 동기화 로깅 * const fullSyncResult = await withNonsapSyncLogging( * 'vendors', * 'full', * async () => { * // 외부 시스템에서 전체 벤더 데이터 가져오기 * const allVendors = await fetchAllVendorsFromExternalSystem(); * * // 기존 데이터 모두 삭제 후 재생성 * await db.vendors.deleteMany({}); * * // 새 데이터 삽입 * const created = await db.vendors.createMany({ * data: allVendors * }); * * return { * syncType: 'full', * totalProcessed: allVendors.length, * created: created.count, * updated: 0, * deleted: 0 * }; * } * ); * * @example * // 증분 동기화 로깅 * const deltaSyncResult = await withNonsapSyncLogging( * 'purchase_orders', * 'delta', * async () => { * // 마지막 동기화 이후 변경된 데이터만 가져오기 * const lastSync = await getLastSyncTimestamp('purchase_orders'); * const changedOrders = await fetchChangedOrdersSince(lastSync); * * let created = 0, updated = 0, deleted = 0; * * for (const order of changedOrders) { * if (order.isDeleted) { * // 삭제된 데이터 처리 * await db.purchaseOrders.delete({ where: { externalId: order.id } }); * deleted++; * } else { * // 삽입/수정 데이터 처리 * const result = await db.purchaseOrders.upsert({ * where: { externalId: order.id }, * create: order, * update: order * }); * * if (result.createdAt === result.updatedAt) { * created++; * } else { * updated++; * } * } * } * * // 동기화 타임스탬프 업데이트 * await updateLastSyncTimestamp('purchase_orders', new Date()); * * return { * syncType: 'delta', * totalProcessed: changedOrders.length, * created, * updated, * deleted * }; * } * ); * * @example * // 에러 복구가 포함된 동기화 * const resilientSyncResult = await withNonsapSyncLogging( * 'inventory', * 'delta', * async () => { * let processedCount = 0; * let errorCount = 0; * const errors: string[] = []; * * const inventoryUpdates = await fetchInventoryUpdates(); * * for (const update of inventoryUpdates) { * try { * await db.inventory.upsert({ * where: { productId: update.productId }, * create: update, * update: { quantity: update.quantity, updatedAt: new Date() } * }); * processedCount++; * } catch (error) { * errorCount++; * errors.push(`Product ${update.productId}: ${error.message}`); * * // 개별 에러는 로그에 남기지만 전체 작업은 계속 진행 * console.warn(`재고 업데이트 실패 - ${update.productId}:`, error); * } * } * * return { * totalItems: inventoryUpdates.length, * processedCount, * errorCount, * errors: errors.slice(0, 10) // 최대 10개 에러만 반환 * }; * } * ); */ export async function withNonsapSyncLogging( tableName: string, syncType: 'full' | 'delta', processor: () => Promise ): Promise { return withDbLogging( 2, // nonsap 동기화 인터페이스 ID (추후 매핑 필요) tableName, `nonsap_${syncType}_sync`, processor ); }