import { oracleKnex } from '@/lib/oracle-db/db'; import db from '@/db/db'; import { users } from '@/db/schema/users'; import { eq } from 'drizzle-orm'; /** * 오라클 NonSAP 데이터베이스에서 구매그룹 정보 조회 * CMCTB_CD 테이블에서 CD_CLF='MMA070' 조건으로 구매그룹 데이터를 가져옴 */ async function fetchPurchasingGroupsFromOracle(): Promise> { try { console.log('🔍 오라클에서 구매그룹 데이터 조회 시작...'); const result = await oracleKnex .select('CD as code', 'USR_DF_CHAR_9 as employeeNumber') .from('CMCTB_CD') .where('CD_CLF', 'MMA070') .whereNotNull('USR_DF_CHAR_9') console.log(`✅ 구매그룹 데이터 ${result.length}건 조회 완료`); return result; } catch (error) { console.error('❌ 오라클에서 구매그룹 데이터 조회 중 오류:', error); throw error; } } /** * employeeNumber 기준으로 users 테이블에 사용자 코드 upsert */ async function updateUsersCode(purchasingGroups: Array<{ code: string; employeeNumber: string }>) { try { console.log('🔄 사용자 테이블 사용자 코드 업데이트 시작...'); let updateCount = 0; let notFoundCount = 0; const errors: Array<{ employeeNumber: string; error: string }> = []; // 개별 트랜잭션으로 안전하게 처리 for (const group of purchasingGroups) { try { await db.transaction(async (tx) => { const result = await tx .update(users) .set({ userCode: group.code, updatedAt: new Date() }) .where(eq(users.employeeNumber, group.employeeNumber)) .returning({ id: users.id }); if (result.length > 0) { updateCount++; } else { notFoundCount++; console.warn(`⚠️ 사번 ${group.employeeNumber}에 해당하는 사용자를 찾을 수 없음 (사용자 코드: ${group.code})`); } }); } catch (error) { errors.push({ employeeNumber: group.employeeNumber, error: error instanceof Error ? error.message : '알 수 없는 오류' }); console.error(`❌ 사번 ${group.employeeNumber} 업데이트 중 오류:`, error); } } // 에러가 있었다면 로그 출력 if (errors.length > 0) { console.error(`❌ ${errors.length}건의 업데이트 오류 발생:`); errors.forEach(({ employeeNumber, error }) => { console.error(` - 사번 ${employeeNumber}: ${error}`); }); } console.log(`✅ 사용자 코드 업데이트 완료: 성공 ${updateCount}건, 미발견 ${notFoundCount}건`); return { updateCount, notFoundCount }; } catch (error) { console.error('❌ 사용자 테이블 업데이트 중 오류:', error); throw error; } } /** * 사용자 코드 동기화 메인 함수 * 오라클에서 구매그룹 데이터를 조회하여 users 테이블을 업데이트 */ export async function syncUserCodes(): Promise<{ success: boolean; updateCount: number; notFoundCount: number; error?: string }> { try { console.log('🚀 사용자 코드 동기화 작업 시작...'); const startTime = Date.now(); // 1. 오라클에서 구매그룹 데이터 조회 const purchasingGroups = await fetchPurchasingGroupsFromOracle(); if (purchasingGroups.length === 0) { console.log('⚠️ 조회된 구매그룹 데이터가 없습니다.'); return { success: true, updateCount: 0, notFoundCount: 0 }; } // 2. users 테이블 업데이트 const { updateCount, notFoundCount } = await updateUsersCode(purchasingGroups); const endTime = Date.now(); const duration = endTime - startTime; console.log(`🎉 사용자 코드 동기화 완료! 소요시간: ${duration}ms`); console.log(`📊 처리 결과: 총 ${purchasingGroups.length}건 중 업데이트 ${updateCount}건, 미발견 ${notFoundCount}건`); return { success: true, updateCount, notFoundCount }; } catch (error) { console.error('💥 사용자 코드 동기화 작업 중 오류:', error); return { success: false, updateCount: 0, notFoundCount: 0, error: error instanceof Error ? error.message : '알 수 없는 오류' }; } } /** * 특정 사번의 사용자 코드를 조회하는 함수 (개별 조회용) */ export async function getUserCodeByEmployeeNumber(employeeNumber: string): Promise { try { const result = await oracleKnex .select('CD') .from('CMCTB_CD') .where('CD_CLF', 'MMA070') .andWhere('USR_DF_CHAR_9', employeeNumber) .limit(1); return result.length > 0 ? result[0].CD : null; } catch (error) { console.error(`사용자 코드 조회 중 오류 (사번: ${employeeNumber}):`, error); return null; } }