팀 미배정 사용자를 조회하는 API를 구현하는 과정에서 여러 가지 문제가 발생했습니다. 주요 문제는 다음과 같습니다:
팀 미배정 사용자 조회 시, 모든 트랙의 사용자가 조회됨:
GET 요청을 통해 특정 트랙에 속한 사용자를 조회해야 했지만, 모든 트랙의 사용자가 조회되는 문제가 발생했습니다.
예상 원인: 쿼리나 서비스 로직에서 트랙 조건이 제대로 반영되지 않음
로그인 시 LazyInitializationException 발생:
API 접근 권한 문제:
문제 분석:
해결 방안:
// UserRepository.java
@Query("SELECT u FROM User u WHERE u.userId IN " +
"(SELECT tp.user.userId FROM TrackParticipants tp WHERE tp.track.trackId = :trackId) " +
"AND u.userId NOT IN " +
"(SELECT tm.user.userId FROM TeamMembers tm JOIN tm.team t WHERE t.trackWeek.trackWeekId = :weekId)")
List<User> findUsersWithoutTeam(@Param("trackId") Long trackId, @Param("weekId") Long weekId);
// UserService.java
@Transactional(readOnly = true)
public List<UnassignedUserResponseDTO> getUsersWithoutTeam(Long trackId, Long weekId) {
Track track = trackRepository.findById(trackId)
.orElseThrow(() -> new CustomException(ErrorCode.TRACK_NOT_FOUND));
TrackWeek trackWeek = trackWeekRepository.findById(weekId)
.orElseThrow(() -> new CustomException(ErrorCode.TRACK_WEEK_NOT_FOUND));
List<User> users = userRepository.findUsersWithoutTeam(trackId, weekId);
return users.stream()
.map(user -> new UnassignedUserResponseDTO(user.getUserId(), user.getUsername(), user.getEmail()))
.collect(Collectors.toList());
}
결과:
문제 분석:
해결 방안:
// TrackParticipantsRepository.java
@Query("SELECT tp FROM TrackParticipants tp JOIN FETCH tp.track t WHERE tp.user.userId = :userId")
List<TrackParticipants> findByUserUserId(Long userId);
결과:
문제 분석:
해결 방안:
// WebSecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {
// 기존 설정 유지
}
// UserService.java
@Transactional(readOnly = true)
public List<UnassignedUserResponseDTO> getUsersWithoutTeam(Long trackId, Long weekId) {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetailsImpl) {
UserDetailsImpl userDetails = (UserDetailsImpl) principal;
boolean isAdmin = userDetails.getAuthorities().stream()
.anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals("ROLE_ADMIN"));
if (!isAdmin) {
throw new CustomException(ErrorCode.FORBIDDEN);
}
} else {
throw new CustomException(ErrorCode.FORBIDDEN);
}
// 나머지 로직
}
결과:
@EnableMethodSecurity
를 사용하고, 메서드 레벨에서 권한 검증을 명시적으로 수행하도록 수정했습니다.