summaryrefslogtreecommitdiff
path: root/app/api/(S-ERP)/(ECC)/IF_ECC_EVCP_PR_INFORMATION/route.ts
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/(S-ERP)/(ECC)/IF_ECC_EVCP_PR_INFORMATION/route.ts')
-rw-r--r--app/api/(S-ERP)/(ECC)/IF_ECC_EVCP_PR_INFORMATION/route.ts66
1 files changed, 29 insertions, 37 deletions
diff --git a/app/api/(S-ERP)/(ECC)/IF_ECC_EVCP_PR_INFORMATION/route.ts b/app/api/(S-ERP)/(ECC)/IF_ECC_EVCP_PR_INFORMATION/route.ts
index 31b61ffc..fdf0c8d4 100644
--- a/app/api/(S-ERP)/(ECC)/IF_ECC_EVCP_PR_INFORMATION/route.ts
+++ b/app/api/(S-ERP)/(ECC)/IF_ECC_EVCP_PR_INFORMATION/route.ts
@@ -1,6 +1,9 @@
import { NextRequest } from 'next/server';
import db from '@/db/db';
-
+import {
+ PR_INFORMATION_T_BID_HEADER,
+ PR_INFORMATION_T_BID_ITEM,
+} from '@/db/schema/ECC/ecc';
import {
ToXMLFields,
serveWsdl,
@@ -11,14 +14,13 @@ import {
createErrorResponse,
createSuccessResponse,
createSoapResponse,
- replaceSubTableData,
withSoapLogging,
} from '@/lib/soap/utils';
-
import {
- PR_INFORMATION_T_BID_HEADER,
- PR_INFORMATION_T_BID_ITEM,
-} from '@/db/schema/ECC/ecc';
+ bulkUpsert,
+ bulkReplaceSubTableData
+} from "@/lib/soap/batch-utils";
+
// 스키마에서 타입 추론
type BidHeaderData = typeof PR_INFORMATION_T_BID_HEADER.$inferInsert;
@@ -34,6 +36,7 @@ interface ProcessedPRData {
bidItems: BidItemData[];
}
+// GET 요청 처리는 ?wsdl 달고 있으면 WSDL 서비스 제공
export async function GET(request: NextRequest) {
const url = new URL(request.url);
if (url.searchParams.has('wsdl')) {
@@ -43,6 +46,7 @@ export async function GET(request: NextRequest) {
return new Response('Method Not Allowed', { status: 405 });
}
+// POST 요청이 데이터 적재 요구 (SOAP)
export async function POST(request: NextRequest) {
const url = new URL(request.url);
if (url.searchParams.has('wsdl')) {
@@ -54,7 +58,7 @@ export async function POST(request: NextRequest) {
// SOAP 로깅 래퍼 함수 사용
return withSoapLogging(
'INBOUND',
- 'S-ERP',
+ 'ECC',
'IF_ECC_EVCP_PR_INFORMATION',
body,
async () => {
@@ -155,45 +159,33 @@ function transformPRData(requestData: PRRequestXML): ProcessedPRData[] {
// 데이터베이스 저장 함수
async function saveToDatabase(processedPRs: ProcessedPRData[]) {
- console.log(`데이터베이스 저장 시작: ${processedPRs.length}개 PR 데이터`);
+ console.log(`데이터베이스(배치) 저장 시작: ${processedPRs.length}개 PR 데이터`);
try {
await db.transaction(async (tx) => {
- for (const prData of processedPRs) {
- const { bidHeader, bidItems } = prData;
+ // 1) 부모 테이블 데이터 준비 (키 없는 이상데이터 제거)
+ const bidHeaderRows = processedPRs
+ .map((c) => c.bidHeader)
+ .filter((h): h is BidHeaderData => !!h.ANFNR);
- if (!bidHeader.ANFNR) {
- console.warn('ANFNR가 없는 헤더 발견, 건너뜁니다.');
- continue;
- }
+ const bidHeaderKeys = bidHeaderRows.map((h) => h.ANFNR as string);
- // 1. 헤더 테이블 Upsert (ANFNR 기준)
- await tx
- .insert(PR_INFORMATION_T_BID_HEADER)
- .values(bidHeader)
- .onConflictDoUpdate({
- target: PR_INFORMATION_T_BID_HEADER.ANFNR,
- set: {
- ...bidHeader,
- updatedAt: new Date(),
- },
- });
-
- // 2. 아이템 테이블 전체 교체 (ANFNR FK 기준)
- await replaceSubTableData(
- tx,
- PR_INFORMATION_T_BID_ITEM,
- bidItems,
- 'ANFNR',
- bidHeader.ANFNR
- );
- }
+ // 2) 하위 테이블 데이터 평탄화
+ const bidItems = processedPRs.flatMap((c) => c.bidItems);
+
+ // 3) 부모 테이블 UPSERT (배치)
+ await bulkUpsert(tx, PR_INFORMATION_T_BID_HEADER, bidHeaderRows, 'ANFNR');
+
+ // 4) 하위 테이블 교체 (배치)
+ await Promise.all([
+ bulkReplaceSubTableData(tx, PR_INFORMATION_T_BID_ITEM, bidItems, PR_INFORMATION_T_BID_ITEM.ANFNR, bidHeaderKeys),
+ ]);
});
- console.log(`데이터베이스 저장 완료: ${processedPRs.length}개 PR`);
+ console.log(`데이터베이스(배치) 저장 완료: ${processedPRs.length}개 PR`);
return true;
} catch (error) {
- console.error('데이터베이스 저장 중 오류 발생:', error);
+ console.error('데이터베이스(배치) 저장 중 오류 발생:', error);
throw error;
}
} \ No newline at end of file