summaryrefslogtreecommitdiff
path: root/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts')
-rw-r--r--app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts235
1 files changed, 235 insertions, 0 deletions
diff --git a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts
new file mode 100644
index 00000000..5d407e1f
--- /dev/null
+++ b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_DEPARTMENT_CODE/route.ts
@@ -0,0 +1,235 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { NextRequest } from "next/server";
+import db from "@/db/db";
+import {
+ DEPARTMENT_CODE_CMCTB_DEPT_MDG,
+ DEPARTMENT_CODE_CMCTB_DEPT_MDG_COMPNM,
+ DEPARTMENT_CODE_CMCTB_DEPT_MDG_CORPNM,
+ DEPARTMENT_CODE_CMCTB_DEPT_MDG_DEPTNM
+} from "@/db/schema/MDG/mdg";
+import {
+ ToXMLFields,
+ serveWsdl,
+ createXMLParser,
+ extractRequestData,
+ convertXMLToDBData,
+ processNestedArray,
+ createErrorResponse,
+ createSuccessResponse,
+ replaceSubTableData,
+ withSoapLogging
+} from "../utils";
+
+// 스키마에서 직접 타입 추론
+type DeptData = typeof DEPARTMENT_CODE_CMCTB_DEPT_MDG.$inferInsert;
+type CompnmData = typeof DEPARTMENT_CODE_CMCTB_DEPT_MDG_COMPNM.$inferInsert;
+type CorpnmData = typeof DEPARTMENT_CODE_CMCTB_DEPT_MDG_CORPNM.$inferInsert;
+type DeptnmData = typeof DEPARTMENT_CODE_CMCTB_DEPT_MDG_DEPTNM.$inferInsert;
+
+// XML에서 받는 데이터 구조
+type DeptXML = ToXMLFields<Omit<DeptData, 'id' | 'createdAt' | 'updatedAt'>> & {
+ DEPTNM?: DeptnmXML[];
+ COMPNM?: CompnmXML[];
+ CORPNM?: CorpnmXML[];
+};
+
+type DeptnmXML = ToXMLFields<Omit<DeptnmData, 'id' | 'createdAt' | 'updatedAt'>>;
+type CompnmXML = ToXMLFields<Omit<CompnmData, 'id' | 'createdAt' | 'updatedAt'>>;
+type CorpnmXML = ToXMLFields<Omit<CorpnmData, 'id' | 'createdAt' | 'updatedAt'>>;
+
+// 처리된 데이터 구조
+interface ProcessedDepartmentData {
+ dept: DeptData;
+ deptnms: DeptnmData[];
+ compnms: CompnmData[];
+ corpnms: CorpnmData[];
+}
+
+export async function GET(request: NextRequest) {
+ const url = new URL(request.url);
+ if (url.searchParams.has('wsdl')) {
+ return serveWsdl('IF_MDZ_EVCP_DEPARTMENT_CODE.wsdl');
+ }
+
+ return new Response('Method Not Allowed', { status: 405 });
+}
+
+export async function POST(request: NextRequest) {
+ const url = new URL(request.url);
+ if (url.searchParams.has('wsdl')) {
+ return serveWsdl('IF_MDZ_EVCP_DEPARTMENT_CODE.wsdl');
+ }
+
+ const body = await request.text();
+
+ return withSoapLogging(
+ 'INBOUND',
+ 'S-ERP',
+ 'IF_MDZ_EVCP_DEPARTMENT_CODE',
+ body,
+ async () => {
+ console.log('Request Body 일부:', body.substring(0, 200) + (body.length > 200 ? '...' : ''));
+
+ const parser = createXMLParser(['CMCTB_DEPT_MDG', 'DEPTNM', 'COMPNM', 'CORPNM']);
+ const parsedData = parser.parse(body);
+ console.log('XML root keys:', Object.keys(parsedData));
+
+ const requestData = extractRequestData(parsedData, 'IF_MDZ_EVCP_DEPARTMENT_CODEReq');
+
+ if (!requestData) {
+ console.error('Could not find valid request data in the received payload');
+ console.error('Received XML structure:', JSON.stringify(parsedData, null, 2));
+ throw new Error('Missing request data - could not find IF_MDZ_EVCP_DEPARTMENT_CODEReq or CMCTB_DEPT_MDG data');
+ }
+
+ console.log('Validating request data structure:',
+ `CMCTB_DEPT_MDG: ${requestData.CMCTB_DEPT_MDG ? 'found' : 'not found'}`
+ );
+
+ if (requestData.CMCTB_DEPT_MDG && Array.isArray(requestData.CMCTB_DEPT_MDG) && requestData.CMCTB_DEPT_MDG.length > 0) {
+ console.log('First CMCTB_DEPT_MDG sample:', JSON.stringify(requestData.CMCTB_DEPT_MDG[0], null, 2));
+ }
+
+ // XML 데이터를 DB 삽입 가능한 형태로 변환
+ const processedDepts = transformDepartmentData(requestData.CMCTB_DEPT_MDG as DeptXML[] || []);
+
+ // 필수 필드 검증
+ for (const deptData of processedDepts) {
+ if (!deptData.dept.DEPTCD) {
+ throw new Error('Missing required field: DEPTCD in department');
+ }
+ if (!deptData.dept.CORPCD) {
+ throw new Error('Missing required field: CORPCD in department');
+ }
+ }
+
+ // 데이터베이스 저장
+ await saveToDatabase(processedDepts);
+
+ console.log(`Processed ${processedDepts.length} departments`);
+
+ return createSuccessResponse('http://60.101.108.100/api/IF_MDZ_EVCP_DEPARTMENT_CODE/');
+ }
+ ).catch(error => {
+ return createErrorResponse(error);
+ });
+}
+
+// XML 데이터를 DB 삽입 가능한 형태로 변환
+function transformDepartmentData(deptData: DeptXML[]): ProcessedDepartmentData[] {
+ if (!deptData || !Array.isArray(deptData)) {
+ return [];
+ }
+
+ return deptData.map(dept => {
+ // 메인 Department 데이터 변환
+ const deptRecord = convertXMLToDBData<DeptData>(
+ dept as Record<string, string | undefined>,
+ ['DEPTCD', 'CORPCD']
+ );
+
+ // 필수 필드 보정
+ if (!deptRecord.DEPTCD) {
+ deptRecord.DEPTCD = '';
+ }
+ if (!deptRecord.CORPCD) {
+ deptRecord.CORPCD = '';
+ }
+
+ // FK 데이터 준비
+ const fkData = { DEPTCD: dept.DEPTCD || '' };
+
+ // DEPTNM 데이터 변환
+ const deptnms = processNestedArray(
+ dept.DEPTNM,
+ (deptnm) => convertXMLToDBData<DeptnmData>(deptnm, ['SPRAS'], fkData),
+ fkData
+ );
+
+ // COMPNM 데이터 변환
+ const compnms = processNestedArray(
+ dept.COMPNM,
+ (compnm) => convertXMLToDBData<CompnmData>(compnm, ['SPRAS'], fkData),
+ fkData
+ );
+
+ // CORPNM 데이터 변환
+ const corpnms = processNestedArray(
+ dept.CORPNM,
+ (corpnm) => convertXMLToDBData<CorpnmData>(corpnm, ['SPRAS'], fkData),
+ fkData
+ );
+
+ return {
+ dept: deptRecord,
+ deptnms,
+ compnms,
+ corpnms
+ };
+ });
+}
+
+// 데이터베이스 저장 함수
+async function saveToDatabase(processedDepts: ProcessedDepartmentData[]) {
+ console.log(`데이터베이스 저장 함수가 호출됨. ${processedDepts.length}개의 부서 데이터 수신.`);
+
+ try {
+ await db.transaction(async (tx) => {
+ for (const deptData of processedDepts) {
+ const { dept, deptnms, compnms, corpnms } = deptData;
+
+ if (!dept.DEPTCD) {
+ console.warn('부서코드(DEPTCD)가 없는 항목 발견, 건너뜁니다.');
+ continue;
+ }
+
+ // 1. Department 테이블 Upsert (최상위 테이블)
+ await tx.insert(DEPARTMENT_CODE_CMCTB_DEPT_MDG)
+ .values(dept)
+ .onConflictDoUpdate({
+ target: DEPARTMENT_CODE_CMCTB_DEPT_MDG.DEPTCD,
+ set: {
+ ...dept,
+ updatedAt: new Date(),
+ }
+ });
+
+ // 2. 하위 테이블 데이터 처리 - FK 기준으로 전체 삭제 후 재삽입
+ await Promise.all([
+ // DEPTNM 테이블 처리
+ replaceSubTableData(
+ tx,
+ DEPARTMENT_CODE_CMCTB_DEPT_MDG_DEPTNM,
+ deptnms,
+ 'DEPTCD',
+ dept.DEPTCD
+ ),
+
+ // COMPNM 테이블 처리
+ replaceSubTableData(
+ tx,
+ DEPARTMENT_CODE_CMCTB_DEPT_MDG_COMPNM,
+ compnms,
+ 'DEPTCD',
+ dept.DEPTCD
+ ),
+
+ // CORPNM 테이블 처리
+ replaceSubTableData(
+ tx,
+ DEPARTMENT_CODE_CMCTB_DEPT_MDG_CORPNM,
+ corpnms,
+ 'DEPTCD',
+ dept.DEPTCD
+ )
+ ]);
+ }
+ });
+
+ console.log(`${processedDepts.length}개의 부서 데이터 처리 완료.`);
+ return true;
+ } catch (error) {
+ console.error('데이터베이스 저장 중 오류 발생:', error);
+ throw error;
+ }
+}