Skip to content

Commit 29c96ec

Browse files
authored
Merge pull request #285 from Clokey-dev/feat/#269-search-sync-api
[feat/#259] 검색 탭 추천 API 개발
2 parents d82ced9 + 3878fa8 commit 29c96ec

14 files changed

Lines changed: 395 additions & 15 deletions

clokey-api/src/main/java/org/clokey/domain/history/repository/HistoryRepository.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.List;
44
import java.util.Optional;
5+
import java.util.Set;
56
import org.clokey.history.entity.History;
67
import org.springframework.data.jpa.repository.JpaRepository;
78
import org.springframework.data.jpa.repository.Query;
@@ -29,6 +30,7 @@ and FUNCTION('MONTH', h.historyDate) = :month
2930
@Query("SELECT h.id FROM History h")
3031
List<Long> findAllIds();
3132

33+
@Deprecated
3234
@Query(
3335
"""
3436
select new org.clokey.domain.history.repository.HistoryRepository$HistorySituationInfo(
@@ -41,4 +43,13 @@ and FUNCTION('MONTH', h.historyDate) = :month
4143
List<HistorySituationInfo> findSituationInfoByHistoryIds(List<Long> historyIds);
4244

4345
record HistorySituationInfo(Long historyId, Long situationId, String situationName) {}
46+
47+
@Query(
48+
"""
49+
SELECT h.id FROM History h
50+
JOIN h.member m
51+
WHERE h.id IN :historyIds
52+
AND (h.banned = true OR m.memberStatus = 'BANNED')
53+
""")
54+
Set<Long> findBannedHistoryIdsAmong(List<Long> historyIds);
4455
}

clokey-api/src/main/java/org/clokey/domain/search/controller/SearchController.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.clokey.domain.cloth.dto.response.ClothListResponse;
1111
import org.clokey.domain.search.dto.response.SearchedHistoryResponse;
1212
import org.clokey.domain.search.dto.response.SearchedMemberResponse;
13+
import org.clokey.domain.search.dto.response.SearchingRecommendResponse;
1314
import org.clokey.domain.search.enums.HistorySearchSortType;
1415
import org.clokey.domain.search.service.SearchService;
1516
import org.clokey.global.annotation.PageSize;
@@ -126,16 +127,13 @@ public BaseResponse<Void> unSyncAllMembers() {
126127
return BaseResponse.onSuccess(GlobalBaseSuccessCode.OK, null);
127128
}
128129

129-
/* :TODO: 검색 탭 추천 API 추후 구현
130130
@GetMapping("/recommendations")
131131
@Operation(
132132
operationId = "Search_recommendInSearching",
133133
summary = "검색 탭 기록 추천",
134134
description = "검색탭에서 사용자가 시도하지 않은 스타일별/자주 착용한 카테고리/최근 태그한 해시태그별 1개씩의 기록울 추천하는 API입니다.")
135135
public BaseResponse<List<SearchingRecommendResponse>> recommendInSearching() {
136-
List<SearchingRecommendResponse> response =
137-
searchService.recommendInSearching();
136+
List<SearchingRecommendResponse> response = searchService.recommendInSearching();
138137
return BaseResponse.onSuccess(GlobalBaseSuccessCode.OK, response);
139138
}
140-
*/
141139
}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
package org.clokey.domain.search.dto.response;
22

33
public record SearchingRecommendResponse(
4-
Long historyId, String recommendType, String title, String subTitle, String imageUrl) {}
4+
Long historyId,
5+
Long memberId,
6+
String recommendType,
7+
String title,
8+
String subTitle,
9+
String imageUrl) {}
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
package org.clokey.domain.search.enums;
22

3+
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
6+
@Getter
7+
@RequiredArgsConstructor
38
public enum RecommendType {
4-
STYLE,
5-
SEASON,
6-
RECENT_FREQUENT_CATEGORY
9+
UNTRIED_STYLE("분위기 전환이 필요할 때"),
10+
FREQUENTLY_WORN_CATEGORY("언제 입어도 찰떡인"),
11+
RECENTLY_USED_HASHTAG("최근 자주 입으시는");
12+
13+
private final String title;
714
}

clokey-api/src/main/java/org/clokey/domain/search/event/ClothDeleteEventListener.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
import org.clokey.domain.search.document.HistoryDocument;
88
import org.clokey.domain.search.repository.SearchRepository;
99
import org.clokey.domain.search.service.SearchDocumentServiceImpl;
10+
import org.springframework.context.annotation.Profile;
1011
import org.springframework.stereotype.Component;
1112
import org.springframework.transaction.event.TransactionPhase;
1213
import org.springframework.transaction.event.TransactionalEventListener;
1314

1415
@Slf4j
1516
@Component
1617
@RequiredArgsConstructor
18+
@Profile("prod")
1719
public class ClothDeleteEventListener {
1820

1921
private final SearchRepository searchRepository;

clokey-api/src/main/java/org/clokey/domain/search/event/HistoryDeleteEventListener.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import lombok.RequiredArgsConstructor;
44
import lombok.extern.slf4j.Slf4j;
55
import org.clokey.domain.search.repository.SearchRepository;
6+
import org.springframework.context.annotation.Profile;
67
import org.springframework.stereotype.Component;
78
import org.springframework.transaction.event.TransactionPhase;
89
import org.springframework.transaction.event.TransactionalEventListener;
910

1011
@Slf4j
1112
@Component
1213
@RequiredArgsConstructor
14+
@Profile("prod")
1315
public class HistoryDeleteEventListener {
1416

1517
private final SearchRepository searchRepository;

clokey-api/src/main/java/org/clokey/domain/search/event/MeiliSearchSyncEventListener.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.clokey.domain.search.document.MemberDocument;
88
import org.clokey.domain.search.repository.SearchRepository;
99
import org.clokey.domain.search.service.SearchDocumentServiceImpl;
10+
import org.springframework.context.annotation.Profile;
1011
import org.springframework.scheduling.annotation.Async;
1112
import org.springframework.stereotype.Component;
1213
import org.springframework.transaction.event.TransactionPhase;
@@ -15,6 +16,7 @@
1516
@Slf4j
1617
@Component
1718
@RequiredArgsConstructor
19+
@Profile("prod")
1820
public class MeiliSearchSyncEventListener {
1921

2022
private final SearchRepository searchRepository;

clokey-api/src/main/java/org/clokey/domain/search/event/MemberDeleteEventListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
import java.util.List;
44
import lombok.RequiredArgsConstructor;
55
import lombok.extern.slf4j.Slf4j;
6-
import org.clokey.domain.history.repository.HistoryRepository;
76
import org.clokey.domain.search.repository.SearchRepository;
7+
import org.springframework.context.annotation.Profile;
88
import org.springframework.stereotype.Component;
99
import org.springframework.transaction.event.TransactionPhase;
1010
import org.springframework.transaction.event.TransactionalEventListener;
1111

1212
@Slf4j
1313
@Component
1414
@RequiredArgsConstructor
15+
@Profile("prod")
1516
public class MemberDeleteEventListener {
1617

1718
private final SearchRepository searchRepository;
18-
private final HistoryRepository historyRepository;
1919

2020
@TransactionalEventListener(
2121
classes = MemberDeleteEvent.class,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package org.clokey.domain.search.repository;
2+
3+
public record RecommendHistoryRow(Long historyId, String subTitle, Long memberId) {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.clokey.domain.search.repository;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
import java.util.Set;
6+
7+
public interface SearchRecommendRepositoryCustom {
8+
9+
Optional<RecommendHistoryRow> findBestHistoryForUntriedStyle(
10+
List<Long> excludedMemberIds, Set<Long> userUsedStyleIds);
11+
12+
Optional<RecommendHistoryRow> findBestHistoryForCategory(
13+
List<Long> excludedMemberIds, String categoryName);
14+
15+
Optional<RecommendHistoryRow> findBestHistoryForHashtag(
16+
List<Long> excludedMemberIds, String hashtagName);
17+
18+
Optional<String> findTopCategoryNameByHistoryIds(List<Long> memberHistoryIds);
19+
20+
Optional<String> findMostRecentHashtagNameByMemberId(Long memberId);
21+
}

0 commit comments

Comments
 (0)