From fc7143d0bb2acb33a9cb06972d62c3187fd1503a Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 30 Jun 2026 01:09:56 +0900 Subject: [PATCH] =?UTF-8?q?feat(community):=20=EC=B1=84=EB=84=90=20?= =?UTF-8?q?=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tCreatorChannelCommunityQueryRepository.kt | 20 ++++++++++++++++++- ...atorChannelCommunityQueryRepositoryTest.kt | 19 +++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepository.kt index bb8fe23e..3a8f41cb 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepository.kt @@ -186,6 +186,7 @@ class DefaultCreatorChannelCommunityQueryRepository( val postIds = map { it.postId } val orderedPostIds = orderedCommunityPostIds(creatorId, viewerId, postIds) val likeCounts = communityLikeCounts(postIds) + val likedPostIds = likedCommunityPostIds(viewerId, postIds) val commentAvailablePostIds = filter { it.isCommentAvailable }.map { it.postId } val commentCounts = communityCommentCounts(commentAvailablePostIds, creatorId, viewerId) @@ -206,7 +207,8 @@ class DefaultCreatorChannelCommunityQueryRepository( isCommentAvailable = row.isCommentAvailable, likeCount = likeCounts[postId] ?: 0, commentCount = commentCounts[postId] ?: 0, - isPinned = isPinned + isPinned = isPinned, + isLiked = postId in likedPostIds ) } } @@ -233,6 +235,22 @@ class DefaultCreatorChannelCommunityQueryRepository( .toSet() } + private fun likedCommunityPostIds(viewerId: Long, postIds: List): Set { + if (postIds.isEmpty()) return emptySet() + + return queryFactory + .select(creatorCommunityLike.creatorCommunity.id) + .distinct() + .from(creatorCommunityLike) + .where( + creatorCommunityLike.member.id.eq(viewerId), + creatorCommunityLike.creatorCommunity.id.`in`(postIds), + creatorCommunityLike.isActive.isTrue + ) + .fetch() + .toSet() + } + private fun communityLikeCounts(postIds: List): Map { if (postIds.isEmpty()) return emptyMap() diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepositoryTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepositoryTest.kt index 8c53345d..bd307d8b 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepositoryTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/v2/creator/channel/community/adapter/out/persistence/DefaultCreatorChannelCommunityQueryRepositoryTest.kt @@ -153,22 +153,33 @@ class DefaultCreatorChannelCommunityQueryRepositoryTest @Autowired constructor( val inactiveLiker = saveMember("inactive-liker", MemberRole.USER) val commenter = saveMember("unavailable-commenter", MemberRole.USER) val post = saveCommunity(creator, isFixed = false, price = 0, isCommentAvailable = false) + val otherMemberOnlyLikedPost = saveCommunity(creator, isFixed = false, price = 0, isCommentAvailable = false) + val inactiveViewerLikedPost = saveCommunity(creator, isFixed = false, price = 0, isCommentAvailable = false) saveCommunityLike(activeLiker, post, isActive = true) + saveCommunityLike(viewer, post, isActive = true) + saveCommunityLike(activeLiker, otherMemberOnlyLikedPost, isActive = true) saveCommunityLike(inactiveLiker, post, isActive = false) + saveCommunityLike(viewer, inactiveViewerLikedPost, isActive = false) saveCommunityComment(commenter, post, isActive = true) flushAndClear() - val record = repository.findCommunityPosts( + val records = repository.findCommunityPosts( creatorId = creator.id!!, viewerId = viewer.id!!, canViewAdultContent = true, offset = 0, limit = 10 - ).single() + ) + val record = records.single { it.postId == post.id } + val otherMemberOnlyLikedRecord = records.single { it.postId == otherMemberOnlyLikedPost.id } + val inactiveViewerLikedRecord = records.single { it.postId == inactiveViewerLikedPost.id } - assertEquals(1, record.likeCount) + assertEquals(2, record.likeCount) assertEquals(0, record.commentCount) assertFalse(record.isCommentAvailable) + assertTrue(record.isLiked) + assertFalse(otherMemberOnlyLikedRecord.isLiked) + assertFalse(inactiveViewerLikedRecord.isLiked) } @Test @@ -276,6 +287,7 @@ class DefaultCreatorChannelCommunityQueryRepositoryTest @Autowired constructor( val pinned = saveCommunity(creator, isFixed = true, fixedAt = now.minusHours(1), price = 0) val normal = saveCommunity(creator, isFixed = false, price = 0) val adultPinned = saveCommunity(creator, isFixed = true, fixedAt = now, price = 0, isAdult = true) + saveCommunityLike(viewer, normal, isActive = true) flushAndClear() updateCreatedAt("CreatorCommunity", normal.id!!, now.minusDays(1)) flushAndClear() @@ -300,6 +312,7 @@ class DefaultCreatorChannelCommunityQueryRepositoryTest @Autowired constructor( assertFalse(adultPinned.id in pinnedPosts.map { it.postId }) assertTrue(pinnedPosts.single().isPinned) assertFalse(normalPosts.single().isPinned) + assertTrue(normalPosts.single().isLiked) } @Test