diff options
Diffstat (limited to 'lib/techsales-rfq/approval-handlers.ts')
| -rw-r--r-- | lib/techsales-rfq/approval-handlers.ts | 150 |
1 files changed, 68 insertions, 82 deletions
diff --git a/lib/techsales-rfq/approval-handlers.ts b/lib/techsales-rfq/approval-handlers.ts index 979096b7..9b7b61ff 100644 --- a/lib/techsales-rfq/approval-handlers.ts +++ b/lib/techsales-rfq/approval-handlers.ts @@ -8,7 +8,7 @@ import db from '@/db/db'; import { eq, and } from 'drizzle-orm'; -import { techSalesAttachments, techSalesRfqs, TECH_SALES_RFQ_STATUSES } from '@/db/schema/techSales'; +import { techSalesAttachments } from '@/db/schema/techSales'; import { sendTechSalesRfqToVendors } from './service'; import { decryptWithServerAction } from '@/components/drm/drmUtils'; import { saveFile, deleteFile } from '@/lib/file-stroage'; @@ -127,18 +127,14 @@ export async function sendTechSalesRfqWithApprovalInternal(payload: { } /** - * 기술영업 RFQ 재발송 핸들러 (결재 승인 후 자동 실행) - * - * 이미 발송된 RFQ에 DRM 파일이 추가된 경우 재발송 처리 + * 기술영업 RFQ DRM 해제 핸들러 (결재 승인 후 자동 실행) + * + * 이미 발송된 RFQ에 추가된 DRM 첨부파일을 복호화하여 저장한다. */ export async function resendTechSalesRfqWithDrmInternal(payload: { rfqId: number; rfqCode?: string; - drmFiles: Array<{ - file: File; - attachmentType: string; - description?: string; - }>; + drmAttachmentIds?: number[]; currentUser: { id: string | number; name?: string | null; @@ -146,104 +142,94 @@ export async function resendTechSalesRfqWithDrmInternal(payload: { epId?: string | null; }; }) { - console.log('[TechSales RFQ Resend Handler] Starting DRM resend after approval'); - console.log('[TechSales RFQ Resend Handler] RFQ ID:', payload.rfqId); - console.log('[TechSales RFQ Resend Handler] DRM Files:', payload.drmFiles.length); + console.log('[TechSales RFQ DRM Unlock Handler] Starting DRM unlock after approval'); + console.log('[TechSales RFQ DRM Unlock Handler] RFQ ID:', payload.rfqId); + console.log('[TechSales RFQ DRM Unlock Handler] DRM Attachment Ids:', payload.drmAttachmentIds?.length || 0); try { - // 1. 새로 추가된 DRM 파일들 복호화 및 저장 - for (const drmFile of payload.drmFiles) { + // 1) DRM 첨부 조회 (지정된 ID가 있으면 필터링) + const drmAttachments = await db.query.techSalesAttachments.findMany({ + where: and( + eq(techSalesAttachments.techSalesRfqId, payload.rfqId), + eq(techSalesAttachments.drmEncrypted, true), + ) + }); + + const filteredAttachments = payload.drmAttachmentIds && payload.drmAttachmentIds.length > 0 + ? drmAttachments.filter(att => payload.drmAttachmentIds?.includes(att.id)) + : drmAttachments; + + if (filteredAttachments.length === 0) { + console.log('[TechSales RFQ DRM Unlock Handler] No DRM attachments to process'); + return { success: true, message: '처리할 DRM 첨부파일이 없습니다.' }; + } + + const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || process.env.NEXT_PUBLIC_URL; + + for (const attachment of filteredAttachments) { try { + // DRM 파일 다운로드 + let fileUrl = attachment.filePath; + const absoluteUrl = `${baseUrl}${fileUrl}`; + console.log(`[TechSales RFQ DRM Unlock Handler] Fetching file from: ${absoluteUrl}`); + + const fileResponse = await fetch(absoluteUrl); + if (!fileResponse.ok) { + console.error(`[TechSales RFQ DRM Unlock Handler] Failed to fetch file: ${absoluteUrl} (status: ${fileResponse.status})`); + continue; + } + + const fileBlob = await fileResponse.blob(); + const file = new File([fileBlob], attachment.originalFileName); + // DRM 복호화 - console.log(`[TechSales RFQ Resend Handler] Decrypting: ${drmFile.file.name}`); - const decryptedBuffer = await decryptWithServerAction(drmFile.file); - - // 복호화된 파일 저장 + console.log(`[TechSales RFQ DRM Unlock Handler] Decrypting: ${attachment.originalFileName}`); + const decryptedBuffer = await decryptWithServerAction(file); + + // 복호화된 파일로 재저장 (기존 파일은 보존) const saveResult = await saveFile({ - file: new File([decryptedBuffer], drmFile.file.name), + file: new File([decryptedBuffer], attachment.originalFileName), directory: `techsales-rfq/${payload.rfqId}`, userId: String(payload.currentUser.id), }); - + if (!saveResult.success) { throw new Error(saveResult.error || '파일 저장 실패'); } - - // 기존 DRM 파일 레코드 찾기 및 업데이트 - const existingAttachment = await db.query.techSalesAttachments.findFirst({ - where: and( - eq(techSalesAttachments.techSalesRfqId, payload.rfqId), - eq(techSalesAttachments.originalFileName, drmFile.file.name), - eq(techSalesAttachments.drmEncrypted, true) - ) - }); - - if (existingAttachment) { - // 기존 파일 삭제 - await deleteFile(existingAttachment.filePath); - - // DB 업데이트: drmEncrypted = false, filePath 업데이트 - await db.update(techSalesAttachments) - .set({ - drmEncrypted: false, - filePath: saveResult.publicPath!, - fileName: saveResult.fileName!, - }) - .where(eq(techSalesAttachments.id, existingAttachment.id)); - } else { - // 새 레코드 생성 - await db.insert(techSalesAttachments).values({ - techSalesRfqId: payload.rfqId, - attachmentType: drmFile.attachmentType as "RFQ_COMMON" | "TBE_RESULT" | "CBE_RESULT", - fileName: saveResult.fileName!, - originalFileName: drmFile.file.name, + + // DB 업데이트: drmEncrypted = false, filePath/fileName 갱신 + await db.update(techSalesAttachments) + .set({ + drmEncrypted: false, filePath: saveResult.publicPath!, + fileName: saveResult.fileName!, fileSize: decryptedBuffer.byteLength, - fileType: drmFile.file.type || undefined, - description: drmFile.description, - drmEncrypted: false, // DRM 해제됨 - createdBy: Number(payload.currentUser.id), - }); - } - - console.log(`[TechSales RFQ Resend Handler] ✅ Decrypted and saved: ${drmFile.file.name}`); + }) + .where(eq(techSalesAttachments.id, attachment.id)); + + console.log(`[TechSales RFQ DRM Unlock Handler] ✅ Decrypted and saved: ${attachment.originalFileName}`); } catch (error) { - console.error(`[TechSales RFQ Resend Handler] ❌ Failed to decrypt ${drmFile.file.name}:`, error); + console.error(`[TechSales RFQ DRM Unlock Handler] ❌ Failed to decrypt ${attachment.originalFileName}:`, error); throw error; } } - // 2. RFQ 상태를 "RFQ Sent"로 변경 - await db.update(techSalesRfqs) - .set({ - status: TECH_SALES_RFQ_STATUSES.RFQ_SENT, - updatedAt: new Date(), - }) - .where(eq(techSalesRfqs.id, payload.rfqId)); - - // 3. RFQ 재발송 실행 (기존에 할당된 모든 벤더에게) - const { getTechSalesRfqVendors } = await import('./service'); - const vendorsResult = await getTechSalesRfqVendors(payload.rfqId); - const vendorIds = vendorsResult.data?.map(v => v.vendorId) || []; - - const sendResult = await sendTechSalesRfqToVendors({ - rfqId: payload.rfqId, - vendorIds: vendorIds, - currentUser: payload.currentUser, - }); - - console.log('[TechSales RFQ Resend Handler] ✅ RFQ resent successfully after DRM decryption'); + // 캐시 무효화 + const { revalidateTag, revalidatePath } = await import('next/cache'); + revalidateTag("techSalesRfqs"); + revalidateTag(`techSalesRfq-${payload.rfqId}`); + revalidatePath("/partners/techsales"); return { success: true, - ...sendResult, + message: 'DRM 첨부파일이 해제되었습니다.', }; } catch (error) { - console.error('[TechSales RFQ Resend Handler] ❌ Failed to resend RFQ:', error); + console.error('[TechSales RFQ DRM Unlock Handler] ❌ Failed to unlock DRM:', error); throw new Error( error instanceof Error - ? `RFQ 재발송 실패: ${error.message}` - : 'RFQ 재발송 중 오류가 발생했습니다.' + ? `DRM 해제 실패: ${error.message}` + : 'DRM 해제 중 오류가 발생했습니다.' ); } } |
