diff options
Diffstat (limited to 'lib/soap/mdg/mapper/project-mapper.ts')
| -rw-r--r-- | lib/soap/mdg/mapper/project-mapper.ts | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/lib/soap/mdg/mapper/project-mapper.ts b/lib/soap/mdg/mapper/project-mapper.ts new file mode 100644 index 00000000..112dd4f5 --- /dev/null +++ b/lib/soap/mdg/mapper/project-mapper.ts @@ -0,0 +1,169 @@ +import { debugLog, debugSuccess, debugError } from '@/lib/debug-utils'; +import db from '@/db/db'; +import { projects } from '@/db/schema/projects'; +import { PROJECT_MASTER_CMCTB_PROJ_MAST } from '@/db/schema/MDG/mdg'; +import { eq } from 'drizzle-orm'; + +// MDG 데이터 타입 정의 +export type MDGProjectData = typeof PROJECT_MASTER_CMCTB_PROJ_MAST.$inferInsert; + +// 비즈니스 테이블 데이터 타입 정의 +export type ProjectData = typeof projects.$inferInsert; + +/** + * MDG 프로젝트 마스터 데이터를 비즈니스 테이블 projects에 매핑하여 저장 + */ +export async function mapAndSaveMDGProjectData( + mdgProjects: MDGProjectData[] +): Promise<{ success: boolean; message: string; processedCount: number }> { + try { + debugLog('MDG 프로젝트 마스터 데이터 매핑 시작', { count: mdgProjects.length }); + + if (mdgProjects.length === 0) { + return { success: true, message: '처리할 데이터가 없습니다', processedCount: 0 }; + } + + const mappedProjects: ProjectData[] = []; + let processedCount = 0; + + for (const mdgProject of mdgProjects) { + try { + // MDG 데이터를 projects 테이블 구조에 매핑 + const mappedProject = mapMDGToProject(mdgProject); + + if (mappedProject) { + mappedProjects.push(mappedProject); + processedCount++; + } + } catch (error) { + debugError('개별 프로젝트 매핑 중 오류', { + project: mdgProject.PROJ_NO, + error: error instanceof Error ? error.message : 'Unknown error' + }); + // 개별 오류는 로그만 남기고 계속 진행 + continue; + } + } + + if (mappedProjects.length === 0) { + return { success: false, message: '매핑된 프로젝트가 없습니다', processedCount: 0 }; + } + + // 데이터베이스에 저장 + await saveProjectsToDatabase(mappedProjects); + + debugSuccess('MDG 프로젝트 마스터 데이터 매핑 완료', { + total: mdgProjects.length, + processed: processedCount + }); + + return { + success: true, + message: `${processedCount}개 프로젝트 매핑 및 저장 완료`, + processedCount + }; + + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + debugError('MDG 프로젝트 마스터 데이터 매핑 중 오류 발생', { error: errorMessage }); + return { + success: false, + message: `매핑 실패: ${errorMessage}`, + processedCount: 0 + }; + } +} + +/** + * MDG 프로젝트 데이터를 비즈니스 테이블 projects 구조로 변환 + * TODO: 실제 매핑 로직은 사용자가 추가할 예정 + * + id: serial("id").primaryKey(), << 자동 + code: varchar("code", { length: 50 }).notNull(), << + name: text("name").notNull(), + type: varchar("type", { length: 20 }).default("ship").notNull(), + pspid: char('pspid', { length: 24 }).unique(), // 프로젝트ID (ECC), TODO: 매핑 필요 + createdAt: timestamp("created_at").defaultNow().notNull(), + updatedAt: timestamp("updated_at").defaultNow().notNull(), + */ +function mapMDGToProject(mdgProject: MDGProjectData): ProjectData | null { + try { + // 필수 필드 검증 + if (!mdgProject.PROJ_NO) { + debugError('PROJ_NO가 없는 프로젝트 데이터', { project: mdgProject }); + return null; + } + + // TODO: 사용자가 실제 매핑 로직을 추가할 예정 + // 현재는 기본 구조만 제공 + const mappedProject: ProjectData = { + code: mdgProject.PROJ_NO || '', + name: mdgProject.PROJ_NM || mdgProject.PROJ_NO || '', + type: 'ship', // 기본값, 필요시 매핑 로직 추가 + pspid: mdgProject.PROJ_NO || null, // ECC 프로젝트 ID와 연결 + // id, createdAt, updatedAt는 자동 생성 + }; + + debugLog('프로젝트 매핑 완료', { + original: mdgProject.PROJ_NO, + mapped: mappedProject.code + }); + + return mappedProject; + + } catch (error) { + debugError('프로젝트 매핑 중 오류', { + project: mdgProject.PROJ_NO, + error: error instanceof Error ? error.message : 'Unknown error' + }); + return null; + } +} + +/** + * 매핑된 프로젝트 데이터를 데이터베이스에 저장 + */ +async function saveProjectsToDatabase(mappedProjects: ProjectData[]): Promise<void> { + try { + debugLog('프로젝트 데이터베이스 저장 시작', { count: mappedProjects.length }); + + await db.transaction(async (tx) => { + // 기존 데이터와 중복 체크 및 UPSERT + for (const project of mappedProjects) { + if (project.pspid) { + // pspid가 있는 경우 기존 데이터 확인 + const existingProject = await tx + .select({ id: projects.id }) + .from(projects) + .where(eq(projects.pspid, project.pspid)) + .limit(1); + + if (existingProject.length > 0) { + // 기존 데이터 업데이트 + await tx + .update(projects) + .set({ + code: project.code, + name: project.name, + type: project.type, + updatedAt: new Date(), + }) + .where(eq(projects.pspid, project.pspid)); + } else { + // 새 데이터 삽입 + await tx.insert(projects).values(project); + } + } else { + // pspid가 없는 경우 새 데이터 삽입 + await tx.insert(projects).values(project); + } + } + }); + + debugSuccess('프로젝트 데이터베이스 저장 완료', { count: mappedProjects.length }); + + } catch (error) { + debugError('프로젝트 데이터베이스 저장 중 오류', { error }); + throw error; + } +} |
