Skip to content

Commit

Permalink
refactor: 봉사 지원 조회 관련 리팩토링 (#337)
Browse files Browse the repository at this point in the history
* refactor(volunteer): 봉사자 정보 조회 기능

* test(volunteer): 봉사자 정보 조회 기능 테스트

* refactor(volunteer-apply): 봉사자 조회 기능 변경에 따른 봉사 지원 조회 기능 리팩토링

* test(volunteer-apply): 봉사자 조회 기능 변경에 따른 봉사 지원 조회 기능 리팩토링 테스트

* test(volunteer-apply): 봉사자 조회 기능 변경에 따른 봉사 지원 조회 기능 리팩토링 테스트

* refactor(volunteer): 불필요한 기능 제거

* refactor(volunteer-apply): CurrentUser -> RoleId

* chore: sonarqube 이슈 해결

* refactor(volunteer-apply): Map 변수명 변경
  • Loading branch information
leebs0521 authored Jan 31, 2025
1 parent 61aac31 commit 5b50d7d
Show file tree
Hide file tree
Showing 30 changed files with 390 additions and 314 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.somemore.domains.volunteer.domain.Volunteer;
import com.somemore.domains.volunteer.repository.mapper.VolunteerOverviewForRankingByHours;
import com.somemore.domains.volunteer.repository.mapper.VolunteerSimpleInfo;

import java.util.List;
import java.util.Optional;
Expand All @@ -24,8 +23,6 @@ public interface VolunteerRepository {

List<Volunteer> findAllByIds(List<UUID> volunteerIds);

List<VolunteerSimpleInfo> findSimpleInfoByIds(List<UUID> ids);

boolean existsByVolunteerId(UUID volunteerId);

default boolean doesNotExistsByVolunteerId(UUID volunteerId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.somemore.domains.volunteer.domain.QVolunteer;
import com.somemore.domains.volunteer.domain.QVolunteerDetail;
import com.somemore.domains.volunteer.domain.Volunteer;
import com.somemore.domains.volunteer.repository.mapper.VolunteerOverviewForRankingByHours;
import com.somemore.domains.volunteer.repository.mapper.VolunteerSimpleInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

Expand All @@ -24,7 +22,6 @@ public class VolunteerRepositoryImpl implements VolunteerRepository {
private final JPAQueryFactory queryFactory;

private static final QVolunteer volunteer = QVolunteer.volunteer;
private static final QVolunteerDetail volunteerDetail = QVolunteerDetail.volunteerDetail;

@Override
public Volunteer save(Volunteer volunteer) {
Expand Down Expand Up @@ -75,25 +72,6 @@ public List<Volunteer> findAllByIds(List<UUID> volunteerIds) {
return volunteerJpaRepository.findAllByIdInAndDeletedFalse(volunteerIds);
}

@Override
public List<VolunteerSimpleInfo> findSimpleInfoByIds(List<UUID> ids) {
BooleanExpression exp = volunteer.id.in(ids)
.and(isNotDeleted());

return queryFactory
.select(Projections.constructor(VolunteerSimpleInfo.class,
volunteer.id,
volunteerDetail.name,
volunteer.nickname,
volunteerDetail.email,
volunteer.imgUrl,
volunteer.tier))
.from(volunteer)
.join(volunteerDetail).on(volunteer.id.eq(volunteerDetail.volunteerId))
.where(exp)
.fetch();
}

private Optional<Volunteer> findOne(BooleanExpression condition) {

return Optional.ofNullable(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@

import com.somemore.domains.volunteer.domain.Volunteer;
import com.somemore.domains.volunteer.dto.response.VolunteerRankingResponseDto;
import com.somemore.domains.volunteer.repository.VolunteerDetailRepository;
import com.somemore.domains.volunteer.repository.VolunteerRepository;
import com.somemore.domains.volunteer.repository.mapper.VolunteerOverviewForRankingByHours;
import com.somemore.domains.volunteer.repository.mapper.VolunteerSimpleInfo;
import com.somemore.domains.volunteer.usecase.VolunteerQueryUseCase;
import com.somemore.domains.volunteer.validator.VolunteerDetailAccessValidator;
import com.somemore.global.exception.BadRequestException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -26,8 +23,6 @@
public class VolunteerQueryService implements VolunteerQueryUseCase {

private final VolunteerRepository volunteerRepository;
private final VolunteerDetailRepository volunteerDetailRepository;
private final VolunteerDetailAccessValidator volunteerDetailAccessValidator;

@Override
public UUID getVolunteerIdByOAuthId(String oAuthId) {
Expand Down Expand Up @@ -58,11 +53,6 @@ public List<Volunteer> getAllByIds(List<UUID> volunteerIds) {
return volunteerRepository.findAllByIds(volunteerIds);
}

@Override
public List<VolunteerSimpleInfo> getVolunteerSimpleInfosByIds(List<UUID> ids) {
return volunteerRepository.findSimpleInfoByIds(ids);
}

@Override
public void validateVolunteerExists(UUID volunteerId) {
if (volunteerRepository.doesNotExistsByVolunteerId(volunteerId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.somemore.domains.volunteer.domain.Volunteer;
import com.somemore.domains.volunteer.dto.response.VolunteerRankingResponseDto;
import com.somemore.domains.volunteer.repository.mapper.VolunteerSimpleInfo;

import java.util.List;
import java.util.UUID;
Expand All @@ -17,7 +16,5 @@ public interface VolunteerQueryUseCase {

List<Volunteer> getAllByIds(List<UUID> volunteerIds);

List<VolunteerSimpleInfo> getVolunteerSimpleInfosByIds(List<UUID> ids);

void validateVolunteerExists(UUID volunteerId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.somemore.domains.volunteerapply.dto.response.VolunteerApplyWithReviewStatusResponseDto;
import com.somemore.domains.volunteerapply.usecase.VolunteerApplyQueryFacadeUseCase;
import com.somemore.domains.volunteerapply.usecase.VolunteerApplyQueryUseCase;
import com.somemore.global.auth.annotation.CurrentUser;
import com.somemore.global.auth.annotation.RoleId;
import com.somemore.global.common.response.ApiResponse;
import com.somemore.global.exception.NoSuchElementException;
Expand Down Expand Up @@ -90,7 +89,7 @@ public ApiResponse<Page<VolunteerApplyRecruitInfoResponseDto>> getVolunteerAppli
@Operation(summary = "지원자 리스트 조회", description = "특정 모집글에 대한 지원자 리스트를 조회합니다.")
@GetMapping("/volunteer-applies/recruit-board/{recruitBoardId}")
public ApiResponse<Page<VolunteerApplyVolunteerInfoResponseDto>> getVolunteerApplies(
@CurrentUser UUID centerId,
@RoleId UUID centerId,
@PathVariable Long recruitBoardId,
@PageableDefault(sort = "created_at", direction = DESC) Pageable pageable,
@RequestParam(required = false) Boolean attended,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.somemore.domains.volunteer.dto.response.VolunteerSimpleInfoResponseDto;
import com.somemore.domains.volunteer.repository.mapper.VolunteerSimpleInfo;
import com.somemore.domains.volunteerapply.domain.ApplyStatus;
import com.somemore.domains.volunteerapply.domain.VolunteerApply;
import com.somemore.volunteer.dto.VolunteerInfoResponseDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;

Expand All @@ -19,25 +18,23 @@ public record VolunteerApplyVolunteerInfoResponseDto(
Long id,
@Schema(description = "모집글 ID", example = "2")
Long recruitBoardId,
@Schema(description = "지원 상태", example = "WAITING", allowableValues = {"WAITING",
"APPROVED", "REJECTED"})
@Schema(description = "지원 상태", example = "WAITING", allowableValues = {"WAITING", "APPROVED", "REJECTED"})
ApplyStatus status,
@Schema(description = "참석 여부", example = "true")
Boolean attend,
@Schema(description = "지원 생성일", example = "2024-11-01T12:00:00")
LocalDateTime createdAt,
@Schema(description = "지원 수정일", example = "2024-11-05T12:00:00")
LocalDateTime updatedAt,
@Schema(description = "봉사자 정보", implementation = VolunteerSimpleInfoResponseDto.class)
VolunteerSimpleInfoResponseDto volunteer
@Schema(description = "봉사자 정보", implementation = VolunteerInfoResponseDto.class)
VolunteerInfoResponseDto volunteer
) {

public static VolunteerApplyVolunteerInfoResponseDto of(
VolunteerApply volunteerApply,
VolunteerSimpleInfo volunteerSimpleInfo
VolunteerInfoResponseDto volunteer
) {
VolunteerSimpleInfoResponseDto volunteer = VolunteerSimpleInfoResponseDto.from(
volunteerSimpleInfo);

return VolunteerApplyVolunteerInfoResponseDto.builder()
.id(volunteerApply.getId())
.recruitBoardId(volunteerApply.getRecruitBoardId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@ public interface VolunteerApplyRepository {

List<VolunteerApply> findAllByRecruitId(Long recruitId);

Page<VolunteerApply> findAllByRecruitId(Long recruitId,
VolunteerApplySearchCondition condition);
Page<VolunteerApply> findAllByRecruitId(Long recruitId, VolunteerApplySearchCondition condition);

Page<VolunteerApply> findAllByVolunteerId(UUID volunteerId,
VolunteerApplySearchCondition condition);
Page<VolunteerApply> findAllByVolunteerId(UUID volunteerId, VolunteerApplySearchCondition condition);

List<VolunteerApply> findAllByIds(List<Long> ids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
import com.somemore.domains.recruitboard.service.validator.RecruitBoardValidator;
import com.somemore.domains.recruitboard.usecase.RecruitBoardQueryUseCase;
import com.somemore.domains.review.usecase.ReviewQueryUseCase;
import com.somemore.domains.volunteer.repository.mapper.VolunteerSimpleInfo;
import com.somemore.domains.volunteer.usecase.VolunteerQueryUseCase;
import com.somemore.domains.volunteerapply.domain.VolunteerApply;
import com.somemore.domains.volunteerapply.dto.condition.VolunteerApplySearchCondition;
import com.somemore.domains.volunteerapply.dto.response.VolunteerApplyRecruitInfoResponseDto;
import com.somemore.domains.volunteerapply.dto.response.VolunteerApplyVolunteerInfoResponseDto;
import com.somemore.domains.volunteerapply.dto.response.VolunteerApplyWithReviewStatusResponseDto;
import com.somemore.domains.volunteerapply.usecase.VolunteerApplyQueryFacadeUseCase;
import com.somemore.domains.volunteerapply.usecase.VolunteerApplyQueryUseCase;
import com.somemore.user.domain.UserCommonAttribute;
import com.somemore.user.usecase.UserQueryUseCase;
import com.somemore.volunteer.dto.VolunteerInfoResponseDto;
import com.somemore.volunteer.repository.record.VolunteerNicknameAndId;
import com.somemore.volunteer.usecase.NEWVolunteerQueryUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
Expand All @@ -21,6 +24,7 @@
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

@RequiredArgsConstructor
Expand All @@ -30,40 +34,52 @@ public class VolunteerApplyQueryFacadeService implements VolunteerApplyQueryFaca

private final VolunteerApplyQueryUseCase volunteerApplyQueryUseCase;
private final RecruitBoardQueryUseCase recruitBoardQueryUseCase;
private final VolunteerQueryUseCase volunteerQueryUseCase;
private final NEWVolunteerQueryUseCase volunteerQueryUseCase;
private final UserQueryUseCase userQueryUseCase;
private final ReviewQueryUseCase reviewQueryUseCase;
private final RecruitBoardValidator recruitBoardValidator;

@Override
public VolunteerApplyWithReviewStatusResponseDto getVolunteerApplyByRecruitIdAndVolunteerId(Long recruitId, UUID volunteerId) {
VolunteerApply apply = volunteerApplyQueryUseCase.getByRecruitIdAndVolunteerId(recruitId, volunteerId);
public VolunteerApplyWithReviewStatusResponseDto getVolunteerApplyByRecruitIdAndVolunteerId(
Long recruitBoardId,
UUID volunteerId
) {
VolunteerApply apply = volunteerApplyQueryUseCase.getByRecruitIdAndVolunteerId(recruitBoardId, volunteerId);
boolean isReviewed = checkIfReviewed(apply);

return VolunteerApplyWithReviewStatusResponseDto.of(apply, isReviewed);
}

@Override
public Page<VolunteerApplyVolunteerInfoResponseDto> getVolunteerAppliesByRecruitIdAndCenterId(
Long recruitId, UUID centerId, VolunteerApplySearchCondition condition) {
RecruitBoard recruitBoard = recruitBoardQueryUseCase.getById(recruitId);
Long recruitBoardId,
UUID centerId,
VolunteerApplySearchCondition condition
) {
RecruitBoard recruitBoard = recruitBoardQueryUseCase.getById(recruitBoardId);
recruitBoardValidator.validateWriter(recruitBoard, centerId);

Page<VolunteerApply> applies = volunteerApplyQueryUseCase.getAllByRecruitId(recruitId, condition);
Map<UUID, VolunteerSimpleInfo> volunteerMap = getVolunteerInfoMap(applies);
Page<VolunteerApply> applies = volunteerApplyQueryUseCase.getAllByRecruitId(recruitBoardId, condition);
Map<UUID, VolunteerInfoResponseDto> volunteerMapToVolunteerId = getVolunteerInfoMap(applies);

return applies.map(
apply -> VolunteerApplyVolunteerInfoResponseDto.of(apply, volunteerMap.getOrDefault(apply.getVolunteerId(), null)));
return applies.map(apply -> VolunteerApplyVolunteerInfoResponseDto.of(
apply,
volunteerMapToVolunteerId.get(apply.getVolunteerId())
));
}

@Override
public Page<VolunteerApplyRecruitInfoResponseDto> getVolunteerAppliesByVolunteerId(
UUID volunteerId, VolunteerApplySearchCondition condition) {

UUID volunteerId,
VolunteerApplySearchCondition condition
) {
Page<VolunteerApply> applies = volunteerApplyQueryUseCase.getAllByVolunteerId(volunteerId, condition);
Map<Long, RecruitBoard> boardMap = getRecruitBoardMap(applies);
Map<Long, RecruitBoard> boardMapToId = getRecruitBoardMap(applies);

return applies.map(
apply -> VolunteerApplyRecruitInfoResponseDto.of(apply, boardMap.getOrDefault(apply.getRecruitBoardId(), null)));
return applies.map(apply -> VolunteerApplyRecruitInfoResponseDto.of(
apply,
boardMapToId.get(apply.getRecruitBoardId()))
);
}

private boolean checkIfReviewed(VolunteerApply apply) {
Expand All @@ -72,25 +88,49 @@ private boolean checkIfReviewed(VolunteerApply apply) {
}

private Map<Long, RecruitBoard> getRecruitBoardMap(Page<VolunteerApply> applies) {
// 1. 모집글 ID 추출
List<Long> boardIds = applies.getContent().stream()
.map(VolunteerApply::getRecruitBoardId)
.toList();

// 2. 모집글 ID가 비어 있는 경우 빈 맵 반환
if (boardIds.isEmpty()) {
return Map.of();
}

// 3. ID로 모집글 조회
List<RecruitBoard> boards = recruitBoardQueryUseCase.getAllByIds(boardIds);

// 4. 조회된 모집글을 Map 변환
return boards.stream()
.collect(Collectors.toMap(RecruitBoard::getId,
board -> board));
.collect(Collectors.toMap(RecruitBoard::getId, Function.identity()));
}

private Map<UUID, VolunteerSimpleInfo> getVolunteerInfoMap(Page<VolunteerApply> applies) {
private Map<UUID, VolunteerInfoResponseDto> getVolunteerInfoMap(Page<VolunteerApply> applies) {
// 1. Volunteer IDs 추출
List<UUID> volunteerIds = applies.getContent().stream()
.map(VolunteerApply::getVolunteerId)
.toList();

List<VolunteerSimpleInfo> volunteers = volunteerQueryUseCase.getVolunteerSimpleInfosByIds(volunteerIds);

return volunteers.stream()
.collect(Collectors.toMap(VolunteerSimpleInfo::id, volunteer -> volunteer));
// 2. Volunteer 정보 조회
List<VolunteerNicknameAndId> volunteerNicknameAndIds =
volunteerQueryUseCase.getVolunteerNicknameAndIdsByIds(volunteerIds);

// 3. User 정보 조회
Map<UUID, UserCommonAttribute> userAttributesMap =
userQueryUseCase.getAllByUserIds(
volunteerNicknameAndIds.stream()
.map(VolunteerNicknameAndId::userId)
.toList()
).stream()
.collect(Collectors.toMap(UserCommonAttribute::getUserId, user -> user));

// 4. VolunteerInfoResponseDto 생성 및 Map 변환
return volunteerNicknameAndIds.stream()
.map(volunteer -> VolunteerInfoResponseDto.of(
volunteer,
userAttributesMap.get(volunteer.userId())
))
.collect(Collectors.toMap(VolunteerInfoResponseDto::id, Function.identity()));
}

}
Loading

0 comments on commit 5b50d7d

Please sign in to comment.