Skip to content

Commit f02adab

Browse files
authored
refactor: 검색 리팩토링 (#370)
* feat(center): id로 센터명 조회하는 메서드 추가 * test(center): id로 센터명 조회하는 메서드 테스트 추가 * refactor(search): volunteer/center -> newVolunteer/newCenter * refactor(search): 특정 기관이 작성한 모집글 elastic search index에서 조회하는 메서드 추가 * refactor(search): 특정 기관 모집글 조회, 기관이 작성한 모집글 조회 search 도메인 이동 * test(search): 특정 기관 모집글 조회, 기관이 작성한 모집글 조회 test 추가 및 volunteer, center 변경 * refactor(search): sonarqube 반영 - 불필요한 import 제거 * refactor(center): center 아이디로 센터명 조회하는 메서드 Optional로 변경 - BadRequestException -> NoSuchElementException * test(center): center 아이디로 센터명 조회하는 메서드 변경으로 인한 Test 수정 * test(center): 불필요한 import 제거
1 parent 90190fd commit f02adab

17 files changed

+445
-108
lines changed

src/main/java/com/somemore/center/repository/NEWCenterRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,7 @@ default boolean doesNotExistById(UUID id) {
2424
}
2525

2626
List<CenterOverviewInfo> findOverviewInfosByIds(List<UUID> ids);
27+
28+
Optional<String> findNameById(UUID id);
29+
2730
}

src/main/java/com/somemore/center/repository/NEWCenterRepositoryImpl.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.somemore.center.repository;
22

3+
import com.querydsl.core.types.Path;
34
import com.querydsl.core.types.Projections;
45
import com.querydsl.core.types.dsl.BooleanExpression;
56
import com.querydsl.jpa.impl.JPAQueryFactory;
@@ -101,6 +102,11 @@ public List<CenterOverviewInfo> findOverviewInfosByIds(List<UUID> ids) {
101102
.fetch();
102103
}
103104

105+
@Override
106+
public Optional<String> findNameById(UUID id) {
107+
return findDynamicFieldByCenterId(id, userCommonAttribute.name);
108+
}
109+
104110
private static BooleanExpression idIn(List<UUID> ids) {
105111
return center.id.in(ids);
106112
}
@@ -113,4 +119,18 @@ private BooleanExpression isNotDeleted() {
113119
return center.deleted.isFalse();
114120
}
115121

122+
private <T> Optional<T> findDynamicFieldByCenterId(UUID id, Path<T> field) {
123+
return Optional.ofNullable(
124+
queryFactory
125+
.select(field)
126+
.from(center)
127+
.join(userCommonAttribute)
128+
.on(userCommonAttribute.userId.eq(center.userId))
129+
.where(
130+
center.id.eq(id),
131+
isNotDeleted()
132+
)
133+
.fetchOne()
134+
);
135+
}
116136
}

src/main/java/com/somemore/center/service/NEWCenterQueryService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.somemore.center.repository.record.CenterProfileDto;
1111
import com.somemore.center.usecase.NEWCenterQueryUseCase;
1212
import com.somemore.center.usecase.PreferItemQueryUseCase;
13+
import com.somemore.global.exception.BadRequestException;
1314
import com.somemore.global.exception.ExceptionMessage;
1415
import com.somemore.global.exception.NoSuchElementException;
1516
import com.somemore.user.repository.usercommonattribute.record.UserProfileDto;
@@ -74,4 +75,10 @@ public List<CenterOverviewInfo> getCenterOverviewsByIds(List<UUID> ids) {
7475
return centerRepository.findOverviewInfosByIds(ids);
7576
}
7677

78+
@Override
79+
public String getNameById(UUID id) {
80+
return centerRepository.findNameById(id)
81+
.orElseThrow(
82+
() -> new NoSuchElementException(ExceptionMessage.NOT_EXISTS_CENTER));
83+
}
7784
}

src/main/java/com/somemore/center/usecase/NEWCenterQueryUseCase.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ public interface NEWCenterQueryUseCase {
1919
void validateCenterExists(UUID id);
2020

2121
List<CenterOverviewInfo> getCenterOverviewsByIds(List<UUID> ids);
22+
23+
String getNameById(UUID id);
24+
2225
}
Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,21 @@
11
package com.somemore.domains.recruitboard.controller;
22

3-
import com.somemore.domains.recruitboard.domain.RecruitStatus;
4-
import com.somemore.domains.recruitboard.domain.VolunteerCategory;
53
import com.somemore.domains.recruitboard.dto.condition.RecruitBoardSearchCondition;
6-
import com.somemore.domains.recruitboard.dto.response.RecruitBoardResponseDto;
74
import com.somemore.domains.recruitboard.dto.response.RecruitBoardWithCenterResponseDto;
85
import com.somemore.domains.recruitboard.dto.response.RecruitBoardWithLocationResponseDto;
96
import com.somemore.domains.recruitboard.usecase.RecruitBoardQueryUseCase;
10-
import com.somemore.global.auth.annotation.RoleId;
117
import com.somemore.global.common.response.ApiResponse;
128
import io.swagger.v3.oas.annotations.Operation;
139
import io.swagger.v3.oas.annotations.tags.Tag;
1410
import lombok.RequiredArgsConstructor;
1511
import org.springframework.data.domain.Page;
1612
import org.springframework.data.domain.Pageable;
1713
import org.springframework.data.web.PageableDefault;
18-
import org.springframework.security.access.annotation.Secured;
1914
import org.springframework.web.bind.annotation.GetMapping;
2015
import org.springframework.web.bind.annotation.PathVariable;
2116
import org.springframework.web.bind.annotation.RequestMapping;
22-
import org.springframework.web.bind.annotation.RequestParam;
2317
import org.springframework.web.bind.annotation.RestController;
2418

25-
import java.util.UUID;
26-
2719
import static org.springframework.data.domain.Sort.Direction.DESC;
2820

2921
@Tag(name = "Recruit Board Query API", description = "봉사 활동 모집 조회 관련 API")
@@ -62,59 +54,4 @@ public ApiResponse<Page<RecruitBoardWithCenterResponseDto>> getAll(
6254
"봉사 활동 모집글 리스트 조회 성공"
6355
);
6456
}
65-
66-
@GetMapping("/recruit-boards/center/{centerId}")
67-
@Operation(summary = "특정 기관 모집글 조회", description = "특정 기관의 봉사 모집글을 조회합니다.")
68-
public ApiResponse<Page<RecruitBoardResponseDto>> getRecruitBoardsByCenterId(
69-
@PathVariable UUID centerId,
70-
@PageableDefault(sort = "created_at", direction = DESC) Pageable pageable,
71-
@RequestParam(required = false) String keyword,
72-
@RequestParam(required = false) VolunteerCategory category,
73-
@RequestParam(required = false) String region,
74-
@RequestParam(required = false) Boolean admitted,
75-
@RequestParam(required = false) RecruitStatus status
76-
) {
77-
RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder()
78-
.keyword(keyword)
79-
.category(category)
80-
.region(region)
81-
.admitted(admitted)
82-
.status(status)
83-
.pageable(pageable)
84-
.build();
85-
86-
return ApiResponse.ok(
87-
200,
88-
recruitBoardQueryUseCase.getRecruitBoardsByCenterId(centerId, condition),
89-
"특정 기관 봉사 활동 모집글 조회 성공"
90-
);
91-
}
92-
93-
@Secured("ROLE_CENTER")
94-
@GetMapping("/recruit-boards/me")
95-
@Operation(summary = "기관이 작성한 모집글 조회", description = "기관의 봉사 모집글을 조회합니다.")
96-
public ApiResponse<Page<RecruitBoardResponseDto>> getMyRecruitBoards(
97-
@RoleId UUID centerId,
98-
@PageableDefault(sort = "created_at", direction = DESC) Pageable pageable,
99-
@RequestParam(required = false) String keyword,
100-
@RequestParam(required = false) VolunteerCategory category,
101-
@RequestParam(required = false) String region,
102-
@RequestParam(required = false) Boolean admitted,
103-
@RequestParam(required = false) RecruitStatus status
104-
) {
105-
RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder()
106-
.keyword(keyword)
107-
.category(category)
108-
.region(region)
109-
.admitted(admitted)
110-
.status(status)
111-
.pageable(pageable)
112-
.build();
113-
114-
return ApiResponse.ok(
115-
200,
116-
recruitBoardQueryUseCase.getRecruitBoardsByCenterId(centerId, condition),
117-
"기관 봉사 활동 모집글 조회 성공"
118-
);
119-
}
12057
}

src/main/java/com/somemore/domains/recruitboard/dto/response/RecruitBoardResponseDto.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.somemore.domains.recruitboard.domain.RecruitStatus;
77
import com.somemore.domains.recruitboard.domain.RecruitmentInfo;
88
import com.somemore.domains.recruitboard.domain.VolunteerCategory;
9+
import com.somemore.domains.search.domain.RecruitBoardDocument;
910
import io.swagger.v3.oas.annotations.media.Schema;
1011
import lombok.Builder;
1112

@@ -69,4 +70,24 @@ public static RecruitBoardResponseDto from(RecruitBoard board) {
6970
.admitted(info.getAdmitted())
7071
.build();
7172
}
73+
74+
public static RecruitBoardResponseDto fromDocument(RecruitBoardDocument document) {
75+
return RecruitBoardResponseDto.builder()
76+
.id(document.getId())
77+
.centerId(document.getCenterId())
78+
.locationId(document.getLocationId())
79+
.createdAt(document.getCreatedAt())
80+
.updatedAt(document.getUpdatedAt())
81+
.title(document.getTitle())
82+
.content(document.getContent())
83+
.region(document.getRegion())
84+
.recruitStatus(document.getRecruitStatus())
85+
.recruitmentCount(document.getRecruitmentCount())
86+
.volunteerStartDateTime(document.getVolunteerStartDateTime())
87+
.volunteerEndDateTime(document.getVolunteerEndDateTime())
88+
.volunteerCategory(document.getVolunteerCategory())
89+
.volunteerHours(document.getVolunteerHours())
90+
.admitted(document.getAdmitted())
91+
.build();
92+
}
7293
}

src/main/java/com/somemore/domains/search/controller/RecruitBoardSearchApiController.java

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,24 @@
55
import com.somemore.domains.recruitboard.dto.condition.RecruitBoardNearByCondition;
66
import com.somemore.domains.recruitboard.dto.condition.RecruitBoardSearchCondition;
77
import com.somemore.domains.recruitboard.dto.response.RecruitBoardDetailResponseDto;
8+
import com.somemore.domains.recruitboard.dto.response.RecruitBoardResponseDto;
89
import com.somemore.domains.recruitboard.dto.response.RecruitBoardWithCenterResponseDto;
910
import com.somemore.domains.recruitboard.usecase.RecruitBoardQueryUseCase;
1011
import com.somemore.domains.search.config.ElasticsearchHealthChecker;
1112
import com.somemore.domains.search.usecase.RecruitBoardDocumentUseCase;
13+
import com.somemore.global.auth.annotation.RoleId;
1214
import com.somemore.global.common.response.ApiResponse;
1315
import io.swagger.v3.oas.annotations.Operation;
1416
import io.swagger.v3.oas.annotations.tags.Tag;
1517
import lombok.RequiredArgsConstructor;
1618
import org.springframework.data.domain.Page;
1719
import org.springframework.data.domain.Pageable;
1820
import org.springframework.data.web.PageableDefault;
21+
import org.springframework.security.access.annotation.Secured;
1922
import org.springframework.web.bind.annotation.*;
2023

2124
import java.util.Optional;
25+
import java.util.UUID;
2226

2327
import static org.springframework.data.domain.Sort.Direction.DESC;
2428

@@ -100,5 +104,76 @@ public ApiResponse<Page<RecruitBoardDetailResponseDto>> getNearbyBySearch(
100104
);
101105
}
102106

103-
//TODO: 특정 기관 모집글 조회, 기관이 작성한 모집글 조회 추가
107+
@GetMapping("/recruit-boards/center/{centerId}")
108+
@Operation(summary = "특정 기관 모집글 조회", description = "특정 기관의 봉사 모집글을 조회합니다.")
109+
public ApiResponse<Page<RecruitBoardResponseDto>> getRecruitBoardsByCenterId(
110+
@PathVariable UUID centerId,
111+
@PageableDefault(sort = "created_at", direction = DESC) Pageable pageable,
112+
@RequestParam(required = false) String keyword,
113+
@RequestParam(required = false) VolunteerCategory category,
114+
@RequestParam(required = false) String region,
115+
@RequestParam(required = false) Boolean admitted,
116+
@RequestParam(required = false) RecruitStatus status
117+
) {
118+
RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder()
119+
.keyword(keyword)
120+
.category(category)
121+
.region(region)
122+
.admitted(admitted)
123+
.status(status)
124+
.pageable(pageable)
125+
.build();
126+
127+
if (elasticsearchHealthChecker.isElasticsearchRunning()) {
128+
return ApiResponse.ok(
129+
200,
130+
recruitBoardDocumentUseCase.get()
131+
.getRecruitBoardsByCenterIdWithKeyword(centerId, condition),
132+
"특정 기관 봉사 활동 모집글 조회 성공"
133+
);
134+
}
135+
136+
return ApiResponse.ok(
137+
200,
138+
recruitBoardQueryUseCase.getRecruitBoardsByCenterId(centerId, condition),
139+
"특정 기관 봉사 활동 모집글 조회 성공"
140+
);
141+
}
142+
143+
@Secured("ROLE_CENTER")
144+
@GetMapping("/recruit-boards/me")
145+
@Operation(summary = "기관이 작성한 모집글 조회", description = "기관의 봉사 모집글을 조회합니다.")
146+
public ApiResponse<Page<RecruitBoardResponseDto>> getMyRecruitBoards(
147+
@RoleId UUID centerId,
148+
@PageableDefault(sort = "created_at", direction = DESC) Pageable pageable,
149+
@RequestParam(required = false) String keyword,
150+
@RequestParam(required = false) VolunteerCategory category,
151+
@RequestParam(required = false) String region,
152+
@RequestParam(required = false) Boolean admitted,
153+
@RequestParam(required = false) RecruitStatus status
154+
) {
155+
RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder()
156+
.keyword(keyword)
157+
.category(category)
158+
.region(region)
159+
.admitted(admitted)
160+
.status(status)
161+
.pageable(pageable)
162+
.build();
163+
164+
if (elasticsearchHealthChecker.isElasticsearchRunning()) {
165+
return ApiResponse.ok(
166+
200,
167+
recruitBoardDocumentUseCase.get()
168+
.getRecruitBoardsByCenterIdWithKeyword(centerId, condition),
169+
"기관 봉사 활동 모집글 조회 성공"
170+
);
171+
}
172+
173+
return ApiResponse.ok(
174+
200,
175+
recruitBoardQueryUseCase.getRecruitBoardsByCenterId(centerId, condition),
176+
"기관 봉사 활동 모집글 조회 성공"
177+
);
178+
}
104179
}

src/main/java/com/somemore/domains/search/repository/SearchBoardRepository.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
import org.springframework.data.domain.Pageable;
1111

1212
import java.util.List;
13+
import java.util.UUID;
1314

1415
public interface SearchBoardRepository {
1516

16-
Page<RecruitBoardDocument> findAllNearbyWithKeyword(RecruitBoardNearByCondition condition);
1717
Page<RecruitBoardDocument> findByRecruitBoardsContaining(RecruitBoardSearchCondition condition);
18+
Page<RecruitBoardDocument> findAllNearbyWithKeyword(RecruitBoardNearByCondition condition);
19+
Page<RecruitBoardDocument> findAllByCenterIdWithKeyword(UUID centerId, RecruitBoardSearchCondition condition);
1820
void saveRecruitBoardDocuments(List<RecruitBoard> recruitBoards);
1921
void deleteRecruitBoardDocument(Long id);
2022

0 commit comments

Comments
 (0)