Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,33 @@ List<Community> findFeedByType(
Pageable pageable
);

/**
* CARDNEWS 탭 피드 조회.
*
* 정책/공모전 중 카드뉴스 이미지가 연결된 커뮤니티만 조회한다.
* 지역 조건은 사용하지 않는다.
*/
@Query("""
select c
from Community c
join fetch c.pin p
join fetch p.user
where c.communityType in :types
and c.cardnewsImages is not empty
and (
cast(:cursorCreatedAt as LocalDateTime) is null
or c.createdAt < :cursorCreatedAt
or (c.createdAt = :cursorCreatedAt and c.communityId < :cursorId)
)
order by c.createdAt desc, c.communityId desc
""")
List<Community> findCardnewsFeedByTypesWithImages(
@Param("types") Collection<CommunityType> types,
@Param("cursorCreatedAt") LocalDateTime cursorCreatedAt,
@Param("cursorId") Long cursorId,
Pageable pageable
);

/**
* ALL 피드 조회.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public class CommunityQueryServiceImpl implements CommunityQueryService {
CommunityType.CARDNEWS
);

private static final List<CommunityType> CARDNEWS_FEED_SOURCE_TYPES = List.of(
CommunityType.POLICY,
CommunityType.CONTEST
);

// HOT 인기 점수 계산용
private static final int HOT_DAYS = 7;
// 홈에서 사용
Expand Down Expand Up @@ -149,6 +154,26 @@ public CommunityCursorPageResDTO getCommunityFeed(
List<Community> pageItems = hasNext ? communities.subList(0, size) : communities;

List<CommunityFeedItemResDTO> content = toFeedItems(pageItems);
if (tab == CommunityTab.CARDNEWS) {
content = content.stream()
.map(item -> new CommunityFeedItemResDTO(
CommunityType.CARDNEWS,
item.communityId(),
item.pinId(),
item.title(),
item.content(),
item.thumbnailUrl(),
item.writerNickname(),
item.writerProfileUrl(),
item.detailAddress(),
item.viewCount(),
item.likeCount(),
item.discount(),
item.eventStartTime(),
item.eventEndTime()
))
.toList();
}
Comment on lines +157 to +176

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

현재 tab == CommunityTab.CARDNEWS일 때, 이미 생성된 CommunityFeedItemResDTO 리스트를 다시 스트림으로 순회하며 모든 필드를 복사하고 kindCARDNEWS로 변경하고 있습니다. 이 방식은 다음과 같은 문제가 있습니다:

  1. 유지보수성 저하: CommunityFeedItemResDTO에 새로운 필드가 추가되거나 기존 필드가 변경될 때, 14개의 인자를 가진 생성자를 호출하는 이 코드도 함께 수정해야 하므로 변경에 취약합니다.
  2. 불필요한 객체 생성: 리스트를 두 번 매핑하면서 불필요한 DTO 객체들이 추가로 생성됩니다.

개선 제안:
toFeedItems 메서드가 CommunityType 오버라이드를 지원하도록 오버로딩하여, 처음부터 원하는 타입으로 DTO를 생성하도록 리팩토링하는 것을 권장합니다.

이를 위해 CommunityQueryServiceImpl 클래스 내부의 toFeedItemstoFeedItem 메서드를 다음과 같이 수정해 주세요:

private List<CommunityFeedItemResDTO> toFeedItems(List<Community> communities) {
    return toFeedItems(communities, null);
}

private List<CommunityFeedItemResDTO> toFeedItems(List<Community> communities, CommunityType typeOverride) {
    FeedItemContext context = buildFeedItemContext(communities);
    return communities.stream()
            .map(community -> toFeedItem(community, context, typeOverride))
            .toList();
}

private CommunityFeedItemResDTO toFeedItem(Community community, FeedItemContext context, CommunityType typeOverride) {
    Pin pin = community.getPin();
    CommunityType type = typeOverride != null ? typeOverride : community.getCommunityType();
    Long pinId = pin.getPinId();
    EventPin eventPin = context.eventPinByPinId().get(pinId);

    return new CommunityFeedItemResDTO(
            type,
            community.getCommunityId(),
            pinId,
            pin.getPinTitle(),
            pin.getPinContent(),
            resolveFeedThumbnailUrl(community, context).orElse(null),
            resolveFeedWriterNickname(community.getCommunityType(), pin, eventPin, context),
            resolveFeedWriterProfileUrl(community.getCommunityType(), pin, eventPin, context),
            context.addressByPinId().get(pinId),
            pin.getViewCount(),
            pin.getLikeCount(),
            eventPin != null ? eventPin.getDiscount() : null,
            eventPin != null ? eventPin.getEventStartTime() : null,
            eventPin != null ? eventPin.getEventEndTime() : null
    );
}
        if (tab == CommunityTab.CARDNEWS) {
            content = toFeedItems(pageItems, CommunityType.CARDNEWS);
        }


String nextCursor = hasNext
? CursorKey.from(pageItems.get(pageItems.size() - 1)).encode()
Expand Down Expand Up @@ -272,8 +297,8 @@ private List<Community> fetchCommunities(CommunityTab tab, Long locationId, Curs
limit
);

case CARDNEWS -> communityRepository.findFeedByType(
CommunityType.CARDNEWS,
case CARDNEWS -> communityRepository.findCardnewsFeedByTypesWithImages(
CARDNEWS_FEED_SOURCE_TYPES,
cursorKey.createdAt(),
cursorKey.communityId(),
limit
Expand Down
Loading