diff options
Diffstat (limited to 'lib/users')
| -rw-r--r-- | lib/users/department-domain/service.ts | 161 |
1 files changed, 94 insertions, 67 deletions
diff --git a/lib/users/department-domain/service.ts b/lib/users/department-domain/service.ts index 834de83a..6be6704c 100644 --- a/lib/users/department-domain/service.ts +++ b/lib/users/department-domain/service.ts @@ -8,7 +8,7 @@ import { departmentDomainAssignmentHistory } from "@/db/schema/departmentDomainAssignments"; import { users } from "@/db/schema/users"; -import { and, eq, inArray, desc } from "drizzle-orm"; +import { and, eq, inArray, desc, sql, ne } from "drizzle-orm"; import { getServerSession } from "next-auth/next"; import { authOptions } from "@/app/api/auth/[...nextauth]/route"; import { getErrorMessage } from "@/lib/handle-error"; @@ -439,98 +439,125 @@ export async function getDepartmentDomainStats() { )(); } -// pending 도메인 사용자들의 부서별 도메인 자동 할당 -export async function autoAssignPendingUsersDomains() { +// 도메인 사용자들의 부서별 도메인 자동 할당 +export async function autoAssignUsersDomains() { unstable_noStore(); try { - console.log('[DOMAIN-AUTO-ASSIGN] pending 사용자 도메인 자동 할당 시작'); - - // 1. pending 도메인 사용자들의 부서 정보 조회 - const pendingUsers = await db + console.log('[DOMAIN-AUTO-ASSIGN] 사용자 도메인 자동 할당 시작'); + + // 1. 모든 활성 부서별 도메인 할당 정보 조회 + const domainAssignments = await db .select({ - id: users.id, - email: users.email, - name: users.name, - deptCode: users.deptCode, - deptName: users.deptName, + companyCode: departmentDomainAssignments.companyCode, + departmentCode: departmentDomainAssignments.departmentCode, + assignedDomain: departmentDomainAssignments.assignedDomain, }) - .from(users) - .where(eq(users.domain, 'pending')); + .from(departmentDomainAssignments) + .where(eq(departmentDomainAssignments.isActive, true)); - console.log(`[DOMAIN-AUTO-ASSIGN] pending 사용자 ${pendingUsers.length}명 발견`); + console.log(`[DOMAIN-AUTO-ASSIGN] ${domainAssignments.length}개 부서의 도메인 할당 정보 로드됨`); - if (pendingUsers.length === 0) { - console.log('[DOMAIN-AUTO-ASSIGN] pending 도메인 사용자가 없습니다.'); + if (domainAssignments.length === 0) { + console.log('[DOMAIN-AUTO-ASSIGN] 활성 부서별 도메인 할당 정보가 없습니다.'); return { success: true, processedCount: 0, assignedCount: 0, skippedCount: 0, - message: 'pending 도메인 사용자가 없습니다.', + message: '활성 부서별 도메인 할당 정보가 없습니다.', }; } - // 2. 모든 활성 부서별 도메인 할당 정보 조회 - const domainAssignments = await db - .select({ - companyCode: departmentDomainAssignments.companyCode, - departmentCode: departmentDomainAssignments.departmentCode, - assignedDomain: departmentDomainAssignments.assignedDomain, - }) - .from(departmentDomainAssignments) - .where(eq(departmentDomainAssignments.isActive, true)); + let totalAssignedCount = 0; + let totalSkippedCount = 0; - // 3. 부서별 도메인 매핑을 위한 Map 생성 - const domainMap = new Map<string, string>(); - domainAssignments.forEach(assignment => { - const key = `${assignment.companyCode}-${assignment.departmentCode}`; - domainMap.set(key, assignment.assignedDomain); - }); - - console.log(`[DOMAIN-AUTO-ASSIGN] ${domainAssignments.length}개 부서의 도메인 할당 정보 로드됨`); + // 2. 각 부서별로 partners가 아닌 도메인 사용자들을 업데이트 + for (const assignment of domainAssignments) { + try { + // 해당 부서의 partners가 아닌 도메인 사용자들 중 도메인이 다른 사용자만 업데이트 + const updateResult = await db + .update(users) + .set({ + domain: assignment.assignedDomain as UserDomain, + updatedAt: new Date(), + }) + .where(and( + ne(users.domain, 'partners'), // partners가 아닌 모든 도메인 사용자 + ne(users.domain, assignment.assignedDomain), // 이미 할당된 도메인과 다른 경우만 + eq(users.deptCode, assignment.departmentCode) // 해당 부서의 사용자 + )); - let assignedCount = 0; - let skippedCount = 0; + const affectedRows = updateResult.rowCount || 0; - // 4. 각 pending 사용자에 대해 도메인 할당 처리 - for (const user of pendingUsers) { - try { - // 사용자의 부서에 대한 도메인 할당 정보 확인 - // 현재 회사 코드 사용 (환경변수 또는 기본값) - const companyCode = process.env.CURRENT_COMPANY_CODE || 'D60'; - const domainKey = `${companyCode}-${user.deptCode || ''}`; - const assignedDomain = domainMap.get(domainKey); - - if (assignedDomain && assignedDomain !== 'pending') { - // 도메인 할당 정보가 있으면 업데이트 - await db - .update(users) - .set({ - domain: assignedDomain as UserDomain, - updatedAt: new Date(), - }) - .where(eq(users.id, user.id)); - - assignedCount++; - console.log(`[DOMAIN-AUTO-ASSIGN] 사용자 ${user.name}(${user.email}) -> ${assignedDomain} 도메인 할당`); + if (affectedRows > 0) { + totalAssignedCount += affectedRows; + console.log(`[DOMAIN-AUTO-ASSIGN] 부서 ${assignment.companyCode}-${assignment.departmentCode} -> ${assignment.assignedDomain} 도메인으로 ${affectedRows}명 업데이트`); } else { - // 할당 정보가 없으면 pending 유지 - skippedCount++; - console.log(`[DOMAIN-AUTO-ASSIGN] 사용자 ${user.name}(${user.email}) -> 부서(${user.deptCode})에 대한 도메인 할당 정보 없음, pending 유지`); + totalSkippedCount++; + console.log(`[DOMAIN-AUTO-ASSIGN] 부서 ${assignment.companyCode}-${assignment.departmentCode} -> 업데이트할 사용자가 없음`); } + } catch (error) { - console.error(`[DOMAIN-AUTO-ASSIGN] 사용자 ${user.email} 처리 실패:`, error); - skippedCount++; + console.error(`[DOMAIN-AUTO-ASSIGN] 부서 ${assignment.companyCode}-${assignment.departmentCode} 처리 실패:`, error); + totalSkippedCount++; } } + // 3. partners가 아닌 도메인을 가진 총 사용자 수 확인 + const totalNonPartnersUsers = await db + .select({ count: sql<number>`count(*)` }) + .from(users) + .where(ne(users.domain, 'partners')); + + const totalNonPartnersCount = totalNonPartnersUsers[0]?.count || 0; + + // 4. 부서 코드가 없어서 pending으로 남아있는 사용자 조회 및 로깅 + const pendingUsersWithoutDept = await db + .select({ + id: users.id, + name: users.name, + email: users.email, + employeeNumber: users.employeeNumber, + deptCode: users.deptCode, + deptName: users.deptName, + }) + .from(users) + .where(and( + eq(users.domain, 'pending'), + ne(users.domain, 'partners') + )); + + // 부서 코드가 없는 pending 사용자 필터링 및 로깅 + const usersWithoutDeptCode = pendingUsersWithoutDept.filter(u => !u.deptCode); + + if (usersWithoutDeptCode.length > 0) { + console.warn(`[DOMAIN-AUTO-ASSIGN] ⚠️ 부서 코드가 없어 pending 상태로 남은 사용자: ${usersWithoutDeptCode.length}명`); + console.warn(`[DOMAIN-AUTO-ASSIGN] 부서 코드 없는 사용자 목록:`); + usersWithoutDeptCode.forEach(user => { + console.warn(` - ID: ${user.id}, 이름: ${user.name}, 이메일: ${user.email}, 사번: ${user.employeeNumber || 'N/A'}, 부서코드: ${user.deptCode || 'NULL'}, 부서명: ${user.deptName || 'N/A'}`); + }); + } + + // 부서가 있지만 할당 규칙이 없어서 pending인 사용자도 로깅 + const usersWithDeptButNoAssignment = pendingUsersWithoutDept.filter(u => !!u.deptCode); + + if (usersWithDeptButNoAssignment.length > 0) { + console.info(`[DOMAIN-AUTO-ASSIGN] ℹ️ 부서는 있지만 도메인 할당 규칙이 없어 pending 상태인 사용자: ${usersWithDeptButNoAssignment.length}명`); + console.info(`[DOMAIN-AUTO-ASSIGN] 할당 규칙 없는 부서의 사용자 목록:`); + usersWithDeptButNoAssignment.forEach(user => { + console.info(` - ID: ${user.id}, 이름: ${user.name}, 이메일: ${user.email}, 부서코드: ${user.deptCode}, 부서명: ${user.deptName || 'N/A'}`); + }); + } + const result = { success: true, - processedCount: pendingUsers.length, - assignedCount, - skippedCount, - message: `${assignedCount}명의 사용자에게 도메인이 자동 할당되었습니다. (스킵: ${skippedCount}명)`, + processedCount: totalNonPartnersCount, + assignedCount: totalAssignedCount, + skippedCount: totalSkippedCount, + pendingWithoutDeptCount: usersWithoutDeptCode.length, + pendingWithDeptButNoAssignmentCount: usersWithDeptButNoAssignment.length, + message: `${totalAssignedCount}명의 사용자에게 도메인이 자동 할당되었습니다.`, }; console.log(`[DOMAIN-AUTO-ASSIGN] 완료: ${JSON.stringify(result)}`); |
