diff options
Diffstat (limited to 'app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts')
| -rw-r--r-- | app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts index 204dffa3..9d76adbb 100644 --- a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts +++ b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts @@ -17,9 +17,12 @@ import { processNestedArray, createErrorResponse, createSuccessResponse, - replaceSubTableData, withSoapLogging -} from "@/lib/soap/mdg/utils"; +} from "@/lib/soap/utils"; +import { + bulkUpsert, + bulkReplaceSubTableData +} from "@/lib/soap/batch-utils"; // 스키마에서 직접 타입 추론 (Insert와 XML을 통합) type MatlData = typeof MODEL_MASTER_MATL.$inferInsert; @@ -211,39 +214,35 @@ function transformMatlData(matlData: MatlXML[]): ProcessedMaterialData[] { * @param processedMaterials 변환된 MODEL 데이터 배열 */ async function saveToDatabase(processedMaterials: ProcessedMaterialData[]) { - console.log(`데이터베이스 저장 시작: ${processedMaterials.length}개 모델 데이터`); + console.log(`데이터베이스(배치) 저장 시작: ${processedMaterials.length}개 모델 데이터`); try { await db.transaction(async (tx) => { - for (const materialData of processedMaterials) { - const { material, descriptions, plants, units, classAssignments, characteristicAssignments } = materialData; - - if (!material.MATNR) { - console.warn('자재번호(MATNR)가 없는 항목 발견, 건너뜁니다.'); - continue; - } + // 1) 부모 테이블 데이터 준비 + const materialRows = processedMaterials + .map((m) => m.material) + .filter((m): m is MatlData => !!m.MATNR); - // 1. MATL 테이블 Upsert (최상위 테이블 - unique 필드: MATNR) - await tx.insert(MODEL_MASTER_MATL) - .values(material) - .onConflictDoUpdate({ - target: MODEL_MASTER_MATL.MATNR, - set: { - ...material, - updatedAt: new Date(), - } - }); + const matnrs = materialRows.map((m) => m.MATNR as string); - // 2. 하위 테이블들 처리 - FK(MATNR) 기준 전체 삭제 후 재삽입 - // 전체 데이터셋 기반 처리로 데이터 일관성 확보 - await Promise.all([ - replaceSubTableData(tx, MODEL_MASTER_MATL_DESC, descriptions, 'MATNR', material.MATNR), - replaceSubTableData(tx, MODEL_MASTER_MATL_PLNT, plants, 'MATNR', material.MATNR), - replaceSubTableData(tx, MODEL_MASTER_MATL_UNIT, units, 'MATNR', material.MATNR), - replaceSubTableData(tx, MODEL_MASTER_MATL_CLASSASGN, classAssignments, 'MATNR', material.MATNR), - replaceSubTableData(tx, MODEL_MASTER_MATL_CHARASGN, characteristicAssignments, 'MATNR', material.MATNR) - ]); - } + // 2) 하위 테이블 데이터 평탄화 + const descriptions = processedMaterials.flatMap((m) => m.descriptions); + const plants = processedMaterials.flatMap((m) => m.plants); + const units = processedMaterials.flatMap((m) => m.units); + const classAssignments = processedMaterials.flatMap((m) => m.classAssignments); + const characteristicAssignments = processedMaterials.flatMap((m) => m.characteristicAssignments); + + // 3) 부모 테이블 UPSERT (배치) + await bulkUpsert(tx, MODEL_MASTER_MATL, materialRows, 'MATNR'); + + // 4) 하위 테이블 교체 (배치) + await Promise.all([ + bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_DESC, descriptions, MODEL_MASTER_MATL_DESC.MATNR, matnrs), + bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_PLNT, plants, MODEL_MASTER_MATL_PLNT.MATNR, matnrs), + bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_UNIT, units, MODEL_MASTER_MATL_UNIT.MATNR, matnrs), + bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_CLASSASGN, classAssignments, MODEL_MASTER_MATL_CLASSASGN.MATNR, matnrs), + bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_CHARASGN, characteristicAssignments, MODEL_MASTER_MATL_CHARASGN.MATNR, matnrs) + ]); }); console.log(`데이터베이스 저장 완료: ${processedMaterials.length}개 모델`); |
