diff --git a/src/main/java/com/example/paycheck/domain/auth/service/AuthService.java b/src/main/java/com/example/paycheck/domain/auth/service/AuthService.java index b90baa9..2a9466d 100644 --- a/src/main/java/com/example/paycheck/domain/auth/service/AuthService.java +++ b/src/main/java/com/example/paycheck/domain/auth/service/AuthService.java @@ -139,8 +139,9 @@ private void assertWithinRecoveryPeriod(User user) { /** * 탈퇴한 카카오 계정 복구 (탈퇴 취소) * - User.deletedAt = null로 되돌림 + * - 고용주의 경우 탈퇴 시 비활성화된 사업장을 함께 복원 (사업자번호 재등록 가능) * - UserSettings는 탈퇴 시 보존되었으므로 그대로 사용 (이전 알림 설정 유지) - * - 사업장/계약/근무기록은 자동 복구하지 않음 (다른 사용자 데이터 일관성 보호) + * - 계약/근무기록은 자동 복구하지 않음 (다른 사용자 데이터 일관성 보호) * * @param kakaoAccessToken 카카오 액세스 토큰 * @return 로그인 응답 (refreshToken 포함) @@ -164,6 +165,7 @@ public AuthDto.LoginResponse restoreWithKakao(String kakaoAccessToken) { assertWithinRecoveryPeriod(user); user.restore(); + userWithdrawService.restoreEmployerWorkplaces(user); return buildLoginResponse(user); } diff --git a/src/main/java/com/example/paycheck/domain/user/service/UserWithdrawService.java b/src/main/java/com/example/paycheck/domain/user/service/UserWithdrawService.java index 89e9916..4fb710c 100644 --- a/src/main/java/com/example/paycheck/domain/user/service/UserWithdrawService.java +++ b/src/main/java/com/example/paycheck/domain/user/service/UserWithdrawService.java @@ -139,6 +139,23 @@ private void recalculateTerminationWeekAllowanceAndSalary(WorkerContract contrac }); } + /** + * 고용주 계정 복구 시 탈퇴 과정에서 비활성화된 사업장 재활성화 + * Worker 타입이거나 Employer 프로필이 없으면 아무것도 하지 않는다. + */ + public void restoreEmployerWorkplaces(User user) { + if (user.getUserType() != UserType.EMPLOYER) { + return; + } + Employer employer = employerRepository.findByUserId(user.getId()).orElse(null); + if (employer == null) { + return; + } + List deactivatedWorkplaces = + workplaceRepository.findByEmployerIdAndIsActive(employer.getId(), false); + deactivatedWorkplaces.forEach(Workplace::activate); + } + /** * 공통 데이터 정리 * UserSettings는 30일 이내 복구 시 사용자가 이전에 설정한 알림 옵션을 그대로 살리기 위해 diff --git a/src/test/java/com/example/paycheck/domain/auth/service/AuthServiceTest.java b/src/test/java/com/example/paycheck/domain/auth/service/AuthServiceTest.java index 499569a..77976b6 100644 --- a/src/test/java/com/example/paycheck/domain/auth/service/AuthServiceTest.java +++ b/src/test/java/com/example/paycheck/domain/auth/service/AuthServiceTest.java @@ -572,6 +572,30 @@ void restoreWithKakao_Success() { assertThat(response.getUserType()).isEqualTo("WORKER"); } + @Test + @DisplayName("탈퇴 계정 복구 성공 - EMPLOYER 타입은 사업장 재활성화 호출") + void restoreWithKakao_Employer_ActivatesWorkplaces() { + // given + String kakaoAccessToken = "kakao_access_token"; + User deletedEmployer = User.builder() + .id(3L) + .kakaoId("test_kakao_id") + .name("탈퇴한 고용주") + .userType(UserType.EMPLOYER) + .build(); + deletedEmployer.withdraw(); + + when(oAuthService.getKakaoUserInfo(kakaoAccessToken)).thenReturn(kakaoUserInfo); + when(userRepository.findByKakaoId(kakaoUserInfo.kakaoId())).thenReturn(Optional.of(deletedEmployer)); + when(tokenService.generateTokenPair(deletedEmployer.getId())).thenReturn(tokenPair); + + // when + authService.restoreWithKakao(kakaoAccessToken); + + // then + verify(userWithdrawService).restoreEmployerWorkplaces(deletedEmployer); + } + @Test @DisplayName("탈퇴 계정 복구 실패 - 정상 계정에 호출 시 USER_NOT_WITHDRAWN 예외") void restoreWithKakao_NotWithdrawn_ThrowsException() { diff --git a/src/test/java/com/example/paycheck/domain/user/service/UserWithdrawServiceTest.java b/src/test/java/com/example/paycheck/domain/user/service/UserWithdrawServiceTest.java index 1ec1243..c8ef533 100644 --- a/src/test/java/com/example/paycheck/domain/user/service/UserWithdrawServiceTest.java +++ b/src/test/java/com/example/paycheck/domain/user/service/UserWithdrawServiceTest.java @@ -260,6 +260,46 @@ void withdraw_onlyScheduledWorkRecordsDeleted() { any(), eq(WorkRecordStatus.COMPLETED), any()); } + @Test + @DisplayName("고용주 복구 시 비활성화된 사업장 재활성화") + void restoreEmployerWorkplaces_success() { + // given + Employer employerEntity = Employer.builder() + .id(10L) + .user(employer) + .phone("010-1234-5678") + .build(); + + Workplace deactivatedWorkplace = Workplace.builder() + .id(100L) + .employer(employerEntity) + .name("테스트 사업장") + .businessNumber("166-12-01262") + .isActive(false) + .build(); + + when(employerRepository.findByUserId(employer.getId())).thenReturn(Optional.of(employerEntity)); + when(workplaceRepository.findByEmployerIdAndIsActive(employerEntity.getId(), false)) + .thenReturn(List.of(deactivatedWorkplace)); + + // when + userWithdrawService.restoreEmployerWorkplaces(employer); + + // then + assertThat(deactivatedWorkplace.getIsActive()).isTrue(); + } + + @Test + @DisplayName("WORKER 타입 사용자 복구 시 repository 접근 없이 즉시 return") + void restoreEmployerWorkplaces_workerUser_doesNothing() { + // when + userWithdrawService.restoreEmployerWorkplaces(worker); + + // then + verify(employerRepository, never()).findByUserId(any()); + verify(workplaceRepository, never()).findByEmployerIdAndIsActive(any(), any()); + } + @Test @DisplayName("findById 결과가 비어있을 때 NotFoundException 발생") void withdraw_userNotFound_throwsNotFoundException() {