test #432
@@ -2,15 +2,22 @@ package kr.co.vividnext.sodalive.v2.creator.channel.community.application
|
||||
|
||||
import kr.co.vividnext.sodalive.aws.cloudfront.AudioContentCloudFront
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.extensions.removeDeletedNicknamePrefix
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRole
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||
import kr.co.vividnext.sodalive.v2.common.domain.toCdnUrl
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityComment
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityComments
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityPost
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityPostDetail
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityQueryPolicy
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityReplies
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityReply
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityTab
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCommentRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCreatorRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityPostRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityQueryPort
|
||||
@@ -93,6 +100,115 @@ class CreatorChannelCommunityQueryService(
|
||||
.map { it.toDomain(viewerId) }
|
||||
}
|
||||
|
||||
fun getCommunityPostDetail(
|
||||
postId: Long,
|
||||
viewer: Member,
|
||||
now: LocalDateTime = LocalDateTime.now()
|
||||
): CreatorChannelCommunityPostDetail {
|
||||
val queryPort = queryPortProvider.getObject()
|
||||
val viewerId = viewer.id!!
|
||||
val canViewAdultContent = memberContentPreferenceService.canViewAdultContent(viewer)
|
||||
val postRecord = queryPort.findCommunityPost(postId, viewerId, canViewAdultContent)
|
||||
?: throw SodaException(messageKey = INVALID_COMMUNITY_REQUEST_MESSAGE_KEY)
|
||||
|
||||
validateNotBlocked(queryPort, viewerId, postRecord.creatorId)
|
||||
|
||||
return CreatorChannelCommunityPostDetail(
|
||||
post = postRecord.toDomain(viewerId),
|
||||
comments = getCommunityComments(postId, viewer, page = 0, size = 20, now = now)
|
||||
)
|
||||
}
|
||||
|
||||
fun getCommunityComments(
|
||||
postId: Long,
|
||||
viewer: Member,
|
||||
page: Int?,
|
||||
size: Int?,
|
||||
now: LocalDateTime = LocalDateTime.now()
|
||||
): CreatorChannelCommunityComments {
|
||||
val communityPage = queryPolicy.createPage(page, size)
|
||||
val queryPort = queryPortProvider.getObject()
|
||||
val viewerId = viewer.id!!
|
||||
val canViewAdultContent = memberContentPreferenceService.canViewAdultContent(viewer)
|
||||
val postRecord = queryPort.findCommunityPost(postId, viewerId, canViewAdultContent)
|
||||
?: throw SodaException(messageKey = INVALID_COMMUNITY_REQUEST_MESSAGE_KEY)
|
||||
|
||||
validateNotBlocked(queryPort, viewerId, postRecord.creatorId)
|
||||
|
||||
if (!postRecord.isCommentAvailable) {
|
||||
return CreatorChannelCommunityComments(
|
||||
commentCount = 0,
|
||||
comments = emptyList(),
|
||||
page = communityPage,
|
||||
hasNext = false
|
||||
)
|
||||
}
|
||||
|
||||
val fetchedComments = queryPort.findCommunityComments(
|
||||
postId = postId,
|
||||
viewerId = viewerId,
|
||||
creatorId = postRecord.creatorId,
|
||||
offset = communityPage.offset,
|
||||
limit = communityPage.fetchLimit
|
||||
)
|
||||
val limitedComments = queryPolicy.limitItems(fetchedComments, communityPage)
|
||||
val latestReplies = queryPort.findLatestRepliesByCommentIds(
|
||||
commentIds = limitedComments.map { it.commentId },
|
||||
viewerId = viewerId
|
||||
).associateBy { it.parentCommentId }
|
||||
|
||||
return CreatorChannelCommunityComments(
|
||||
commentCount = queryPort.countCommunityComments(
|
||||
postId = postId,
|
||||
viewerId = viewerId,
|
||||
creatorId = postRecord.creatorId
|
||||
),
|
||||
comments = limitedComments.map { it.toCommentDomain(latestReplies[it.commentId]?.toReplyDomain()) },
|
||||
page = communityPage,
|
||||
hasNext = queryPolicy.hasNext(fetchedComments, communityPage)
|
||||
)
|
||||
}
|
||||
|
||||
fun getCommunityReplies(
|
||||
commentId: Long,
|
||||
viewer: Member,
|
||||
page: Int?,
|
||||
size: Int?,
|
||||
now: LocalDateTime = LocalDateTime.now()
|
||||
): CreatorChannelCommunityReplies {
|
||||
val communityPage = queryPolicy.createPage(page, size)
|
||||
val queryPort = queryPortProvider.getObject()
|
||||
val viewerId = viewer.id!!
|
||||
val canViewAdultContent = memberContentPreferenceService.canViewAdultContent(viewer)
|
||||
val context = queryPort.findRootCommentContext(commentId, viewerId, canViewAdultContent)
|
||||
?: throw SodaException(messageKey = INVALID_COMMUNITY_REQUEST_MESSAGE_KEY)
|
||||
|
||||
validateNotBlocked(queryPort, viewerId, context.creatorId)
|
||||
|
||||
if (!context.isCommentAvailable) {
|
||||
return CreatorChannelCommunityReplies(
|
||||
replyCount = 0,
|
||||
replies = emptyList(),
|
||||
page = communityPage,
|
||||
hasNext = false
|
||||
)
|
||||
}
|
||||
|
||||
val fetchedReplies = queryPort.findCommunityReplies(
|
||||
commentId = commentId,
|
||||
viewerId = viewerId,
|
||||
offset = communityPage.offset,
|
||||
limit = communityPage.fetchLimit
|
||||
)
|
||||
|
||||
return CreatorChannelCommunityReplies(
|
||||
replyCount = queryPort.countCommunityReplies(commentId, viewerId),
|
||||
replies = queryPolicy.limitItems(fetchedReplies, communityPage).map { it.toReplyDomain() },
|
||||
page = communityPage,
|
||||
hasNext = queryPolicy.hasNext(fetchedReplies, communityPage)
|
||||
)
|
||||
}
|
||||
|
||||
private fun validateCreatorRole(creator: CreatorChannelCommunityCreatorRecord) {
|
||||
when (creator.role) {
|
||||
MemberRole.CREATOR -> return
|
||||
@@ -100,6 +216,12 @@ class CreatorChannelCommunityQueryService(
|
||||
}
|
||||
}
|
||||
|
||||
private fun validateNotBlocked(queryPort: CreatorChannelCommunityQueryPort, viewerId: Long, creatorId: Long) {
|
||||
if (queryPort.existsBlockedBetween(viewerId, creatorId)) {
|
||||
throw SodaException(messageKey = INVALID_COMMUNITY_REQUEST_MESSAGE_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CreatorChannelCommunityPostRecord.toDomain(viewerId: Long): CreatorChannelCommunityPost {
|
||||
val canAccessPaidContent = price <= 0 || viewerId == creatorId || existOrdered
|
||||
return CreatorChannelCommunityPost(
|
||||
@@ -126,6 +248,29 @@ class CreatorChannelCommunityQueryService(
|
||||
)
|
||||
}
|
||||
|
||||
private fun CreatorChannelCommunityCommentRecord.toCommentDomain(
|
||||
latestReply: CreatorChannelCommunityReply?
|
||||
): CreatorChannelCommunityComment {
|
||||
return CreatorChannelCommunityComment(
|
||||
commentId = commentId,
|
||||
writerProfileImageUrl = writerProfilePath.toCdnUrl(cloudFrontHost) ?: defaultProfileImageUrl(),
|
||||
writerNickname = writerNickname.removeDeletedNicknamePrefix(),
|
||||
content = content,
|
||||
createdAt = createdAt,
|
||||
latestReply = latestReply
|
||||
)
|
||||
}
|
||||
|
||||
private fun CreatorChannelCommunityCommentRecord.toReplyDomain(): CreatorChannelCommunityReply {
|
||||
return CreatorChannelCommunityReply(
|
||||
commentId = commentId,
|
||||
writerProfileImageUrl = writerProfilePath.toCdnUrl(cloudFrontHost) ?: defaultProfileImageUrl(),
|
||||
writerNickname = writerNickname.removeDeletedNicknamePrefix(),
|
||||
content = content,
|
||||
createdAt = createdAt
|
||||
)
|
||||
}
|
||||
|
||||
private fun String?.toSignedAudioUrl(): String? {
|
||||
if (isNullOrBlank()) return null
|
||||
return audioContentCloudFront.generateSignedURL(this, AUDIO_SIGNED_URL_EXPIRATION_MILLIS)
|
||||
@@ -135,5 +280,6 @@ class CreatorChannelCommunityQueryService(
|
||||
|
||||
companion object {
|
||||
private const val AUDIO_SIGNED_URL_EXPIRATION_MILLIS = 1000L * 60 * 30
|
||||
private const val INVALID_COMMUNITY_REQUEST_MESSAGE_KEY = "creator.community.invalid_request_retry"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import kr.co.vividnext.sodalive.member.MemberProvider
|
||||
import kr.co.vividnext.sodalive.member.MemberRole
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.domain.CreatorChannelCommunityQueryPolicy
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCommentContextRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCommentRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCreatorRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityPostRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityQueryPort
|
||||
@@ -173,6 +175,119 @@ class CreatorChannelCommunityQueryServiceTest {
|
||||
assertEquals(true, posts.single().isLiked)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 상세는 게시글과 초기 댓글 및 최신 답글을 조립한다")
|
||||
fun shouldAssembleCommunityPostDetailWithInitialComments() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort().apply {
|
||||
communityPost = communityPostRecord(1L, price = 0, isLiked = true)
|
||||
communityCommentCount = 21
|
||||
communityComments = (1L..21L).map { communityCommentRecord(it) }
|
||||
latestReplies = listOf(communityCommentRecord(100L, parentCommentId = 1L, writerNickname = "deleted_reply-writer"))
|
||||
}
|
||||
val service = createService(port)
|
||||
val viewer = createMember(id = 10L)
|
||||
|
||||
val detail = service.getCommunityPostDetail(1L, viewer, LocalDateTime.of(2026, 7, 6, 10, 0))
|
||||
|
||||
assertEquals(1L, detail.post.postId)
|
||||
assertEquals(true, detail.post.isLiked)
|
||||
assertEquals(21, detail.comments.commentCount)
|
||||
assertEquals(20, detail.comments.comments.size)
|
||||
assertEquals(true, detail.comments.hasNext)
|
||||
assertEquals("reply-writer", detail.comments.comments.first().latestReply?.writerNickname)
|
||||
assertEquals("https://cdn.test/profile/default-profile.png", detail.comments.comments.first().writerProfileImageUrl)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("댓글 불가 게시글은 댓글 port를 호출하지 않고 빈 댓글 응답을 반환한다")
|
||||
fun shouldReturnEmptyCommentsWhenCommentUnavailable() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort().apply {
|
||||
communityPost = communityPostRecord(1L, price = 0, isCommentAvailable = false)
|
||||
}
|
||||
val service = createService(port)
|
||||
|
||||
val comments = service.getCommunityComments(1L, createMember(id = 10L), -1, 100, LocalDateTime.of(2026, 7, 6, 10, 0))
|
||||
|
||||
assertEquals(0, comments.commentCount)
|
||||
assertEquals(0, comments.comments.size)
|
||||
assertEquals(0, comments.page.page)
|
||||
assertEquals(50, comments.page.size)
|
||||
assertEquals(false, comments.hasNext)
|
||||
assertEquals(false, port.commentListCalled)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 댓글은 page fallback과 최신 답글을 적용한다")
|
||||
fun shouldApplyCommentPageFallbackAndLatestReply() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort().apply {
|
||||
communityPost = communityPostRecord(1L, price = 0)
|
||||
communityCommentCount = 60
|
||||
communityComments = (1L..51L).map { communityCommentRecord(it, writerProfilePath = "profile/$it.png") }
|
||||
latestReplies = listOf(communityCommentRecord(100L, parentCommentId = 2L))
|
||||
}
|
||||
val service = createService(port)
|
||||
|
||||
val comments = service.getCommunityComments(1L, createMember(id = 10L), -1, 100, LocalDateTime.of(2026, 7, 6, 10, 0))
|
||||
|
||||
assertEquals(0L, port.commentListOffset)
|
||||
assertEquals(51, port.commentListLimit)
|
||||
assertEquals((1L..50L).toList(), port.latestReplyCommentIds)
|
||||
assertEquals(50, comments.comments.size)
|
||||
assertEquals(true, comments.hasNext)
|
||||
assertEquals("https://cdn.test/profile/1.png", comments.comments.first().writerProfileImageUrl)
|
||||
assertEquals(100L, comments.comments[1].latestReply?.commentId)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 답글은 부모 댓글 context를 확인하고 page fallback으로 조립한다")
|
||||
fun shouldAssembleCommunityReplies() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort().apply {
|
||||
rootCommentContext = CreatorChannelCommunityCommentContextRecord(1L, 10L, 1L, true)
|
||||
communityReplyCount = 51
|
||||
communityReplies = (1L..51L).map { communityCommentRecord(it, parentCommentId = 1L) }
|
||||
}
|
||||
val service = createService(port)
|
||||
|
||||
val replies = service.getCommunityReplies(1L, createMember(id = 10L), -1, 100, LocalDateTime.of(2026, 7, 6, 10, 0))
|
||||
|
||||
assertEquals(51, replies.replyCount)
|
||||
assertEquals(50, replies.replies.size)
|
||||
assertEquals(0L, port.replyListOffset)
|
||||
assertEquals(51, port.replyListLimit)
|
||||
assertEquals(true, replies.hasNext)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("부모 댓글 context가 보이지 않으면 커뮤니티 답글 조회는 예외를 던진다")
|
||||
fun shouldThrowWhenRootCommentContextNotVisible() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort().apply { rootCommentContext = null }
|
||||
val service = createService(port)
|
||||
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
service.getCommunityReplies(1L, createMember(id = 10L), null, null, LocalDateTime.of(2026, 7, 6, 10, 0))
|
||||
}
|
||||
|
||||
assertEquals("creator.community.invalid_request_retry", exception.messageKey)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("댓글 불가 게시글의 답글 직접 조회는 빈 응답을 반환한다")
|
||||
fun shouldReturnEmptyRepliesWhenCommentUnavailable() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort().apply {
|
||||
rootCommentContext = CreatorChannelCommunityCommentContextRecord(1L, 10L, 1L, false)
|
||||
communityReplyCount = 1
|
||||
communityReplies = listOf(communityCommentRecord(2L, parentCommentId = 1L))
|
||||
}
|
||||
val service = createService(port)
|
||||
|
||||
val replies = service.getCommunityReplies(1L, createMember(id = 10L), null, null, LocalDateTime.of(2026, 7, 6, 10, 0))
|
||||
|
||||
assertEquals(0, replies.replyCount)
|
||||
assertEquals(0, replies.replies.size)
|
||||
assertEquals(false, replies.hasNext)
|
||||
assertEquals(null, port.replyListOffset)
|
||||
}
|
||||
|
||||
private fun createService(
|
||||
port: FakeCreatorChannelCommunityQueryPort,
|
||||
audioContentCloudFront: AudioContentCloudFront = Mockito.mock(AudioContentCloudFront::class.java),
|
||||
@@ -226,11 +341,29 @@ private class FakeCreatorChannelCommunityQueryPort : CreatorChannelCommunityQuer
|
||||
var blocked = false
|
||||
var communityPostCount = 1
|
||||
var communityPosts = listOf(communityPostRecord(1L, price = 0))
|
||||
var communityPost: CreatorChannelCommunityPostRecord? = communityPostRecord(1L, price = 0)
|
||||
var homeCommunityPosts = listOf(communityPostRecord(1L, price = 0))
|
||||
var communityCommentCount = 0
|
||||
var communityComments = emptyList<CreatorChannelCommunityCommentRecord>()
|
||||
var latestReplies = emptyList<CreatorChannelCommunityCommentRecord>()
|
||||
var rootCommentContext: CreatorChannelCommunityCommentContextRecord? = CreatorChannelCommunityCommentContextRecord(
|
||||
commentId = 1L,
|
||||
postId = 1L,
|
||||
creatorId = 1L,
|
||||
isCommentAvailable = true
|
||||
)
|
||||
var communityReplyCount = 0
|
||||
var communityReplies = emptyList<CreatorChannelCommunityCommentRecord>()
|
||||
var countCanViewAdultContent: Boolean? = null
|
||||
var listCanViewAdultContent: Boolean? = null
|
||||
var listOffset: Long? = null
|
||||
var listLimit: Int? = null
|
||||
var commentListCalled = false
|
||||
var commentListOffset: Long? = null
|
||||
var commentListLimit: Int? = null
|
||||
var latestReplyCommentIds = emptyList<Long>()
|
||||
var replyListOffset: Long? = null
|
||||
var replyListLimit: Int? = null
|
||||
var homeCreatorId: Long? = null
|
||||
var homeViewerId: Long? = null
|
||||
var homeIsPinned: Boolean? = null
|
||||
@@ -277,6 +410,54 @@ private class FakeCreatorChannelCommunityQueryPort : CreatorChannelCommunityQuer
|
||||
homeLimit = limit
|
||||
return homeCommunityPosts
|
||||
}
|
||||
|
||||
override fun findCommunityPost(
|
||||
postId: Long,
|
||||
viewerId: Long,
|
||||
canViewAdultContent: Boolean
|
||||
): CreatorChannelCommunityPostRecord? = communityPost
|
||||
|
||||
override fun countCommunityComments(postId: Long, viewerId: Long, creatorId: Long): Int = communityCommentCount
|
||||
|
||||
override fun findCommunityComments(
|
||||
postId: Long,
|
||||
viewerId: Long,
|
||||
creatorId: Long,
|
||||
offset: Long,
|
||||
limit: Int
|
||||
): List<CreatorChannelCommunityCommentRecord> {
|
||||
commentListCalled = true
|
||||
commentListOffset = offset
|
||||
commentListLimit = limit
|
||||
return communityComments
|
||||
}
|
||||
|
||||
override fun findLatestRepliesByCommentIds(
|
||||
commentIds: List<Long>,
|
||||
viewerId: Long
|
||||
): List<CreatorChannelCommunityCommentRecord> {
|
||||
latestReplyCommentIds = commentIds
|
||||
return latestReplies
|
||||
}
|
||||
|
||||
override fun findRootCommentContext(
|
||||
commentId: Long,
|
||||
viewerId: Long,
|
||||
canViewAdultContent: Boolean
|
||||
): CreatorChannelCommunityCommentContextRecord? = rootCommentContext
|
||||
|
||||
override fun countCommunityReplies(commentId: Long, viewerId: Long): Int = communityReplyCount
|
||||
|
||||
override fun findCommunityReplies(
|
||||
commentId: Long,
|
||||
viewerId: Long,
|
||||
offset: Long,
|
||||
limit: Int
|
||||
): List<CreatorChannelCommunityCommentRecord> {
|
||||
replyListOffset = offset
|
||||
replyListLimit = limit
|
||||
return communityReplies
|
||||
}
|
||||
}
|
||||
|
||||
private fun communityPostRecord(
|
||||
@@ -287,7 +468,8 @@ private fun communityPostRecord(
|
||||
creatorProfilePath: String? = "profile/$postId.png",
|
||||
imagePath: String? = "image/$postId.png",
|
||||
audioPath: String? = "audio/$postId.mp3",
|
||||
isLiked: Boolean = false
|
||||
isLiked: Boolean = false,
|
||||
isCommentAvailable: Boolean = true
|
||||
): CreatorChannelCommunityPostRecord {
|
||||
return CreatorChannelCommunityPostRecord(
|
||||
postId = postId,
|
||||
@@ -300,10 +482,28 @@ private fun communityPostRecord(
|
||||
price = price,
|
||||
createdAt = LocalDateTime.of(2026, 6, 21, 10, 0).plusMinutes(postId),
|
||||
existOrdered = existOrdered,
|
||||
isCommentAvailable = true,
|
||||
isCommentAvailable = isCommentAvailable,
|
||||
likeCount = postId.toInt(),
|
||||
commentCount = postId.toInt() + 1,
|
||||
isPinned = postId == 1L,
|
||||
isLiked = isLiked
|
||||
)
|
||||
}
|
||||
|
||||
private fun communityCommentRecord(
|
||||
commentId: Long,
|
||||
parentCommentId: Long? = null,
|
||||
writerProfilePath: String? = null,
|
||||
writerNickname: String = "writer-$commentId"
|
||||
): CreatorChannelCommunityCommentRecord {
|
||||
return CreatorChannelCommunityCommentRecord(
|
||||
commentId = commentId,
|
||||
parentCommentId = parentCommentId,
|
||||
postId = 1L,
|
||||
writerId = commentId + 100L,
|
||||
writerProfilePath = writerProfilePath,
|
||||
writerNickname = writerNickname,
|
||||
content = "comment-$commentId",
|
||||
createdAt = LocalDateTime.of(2026, 7, 6, 10, 0).plusMinutes(commentId)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -742,4 +742,40 @@ private class FakeCreatorChannelCommunityQueryPort : CreatorChannelCommunityQuer
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun findCommunityPost(
|
||||
postId: Long,
|
||||
viewerId: Long,
|
||||
canViewAdultContent: Boolean
|
||||
): CreatorChannelCommunityPostRecord? = null
|
||||
|
||||
override fun countCommunityComments(postId: Long, viewerId: Long, creatorId: Long): Int = 0
|
||||
|
||||
override fun findCommunityComments(
|
||||
postId: Long,
|
||||
viewerId: Long,
|
||||
creatorId: Long,
|
||||
offset: Long,
|
||||
limit: Int
|
||||
) = emptyList<kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCommentRecord>()
|
||||
|
||||
override fun findLatestRepliesByCommentIds(
|
||||
commentIds: List<Long>,
|
||||
viewerId: Long
|
||||
) = emptyList<kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCommentRecord>()
|
||||
|
||||
override fun findRootCommentContext(
|
||||
commentId: Long,
|
||||
viewerId: Long,
|
||||
canViewAdultContent: Boolean
|
||||
): kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCommentContextRecord? = null
|
||||
|
||||
override fun countCommunityReplies(commentId: Long, viewerId: Long): Int = 0
|
||||
|
||||
override fun findCommunityReplies(
|
||||
commentId: Long,
|
||||
viewerId: Long,
|
||||
offset: Long,
|
||||
limit: Int
|
||||
) = emptyList<kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCommentRecord>()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user