feat(creator-channel): FanTalk 탭 도메인 계약을 추가한다

This commit is contained in:
2026-06-22 14:26:31 +09:00
parent dc9ee06bb8
commit 41937c7cce
4 changed files with 229 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
package kr.co.vividnext.sodalive.v2.creator.channel.fantalk.domain
import kr.co.vividnext.sodalive.v2.creator.channel.live.domain.CreatorChannelPage
import org.springframework.stereotype.Component
@Component
class CreatorChannelFanTalkQueryPolicy {
fun createPage(page: Int?, size: Int?): CreatorChannelPage {
return CreatorChannelPage(
page = page?.coerceAtLeast(MIN_PAGE) ?: DEFAULT_PAGE,
size = size?.coerceIn(MIN_PAGE_SIZE, MAX_PAGE_SIZE) ?: DEFAULT_PAGE_SIZE
)
}
fun <T> limitItems(fetched: List<T>, page: CreatorChannelPage): List<T> {
return fetched.take(page.size)
}
fun hasNext(fetched: List<*>, page: CreatorChannelPage): Boolean {
return fetched.size > page.size
}
companion object {
private const val DEFAULT_PAGE = 0
private const val DEFAULT_PAGE_SIZE = 20
private const val MIN_PAGE = 0
private const val MIN_PAGE_SIZE = 20
private const val MAX_PAGE_SIZE = 50
}
}

View File

@@ -0,0 +1,30 @@
package kr.co.vividnext.sodalive.v2.creator.channel.fantalk.domain
import kr.co.vividnext.sodalive.v2.creator.channel.live.domain.CreatorChannelPage
import java.time.LocalDateTime
data class CreatorChannelFanTalkTab(
val fanTalkCount: Int,
val fanTalks: List<CreatorChannelFanTalk>,
val page: CreatorChannelPage,
val hasNext: Boolean
)
data class CreatorChannelFanTalk(
val fanTalkId: Long,
val writerId: Long,
val writerNickname: String,
val writerProfileImageUrl: String,
val content: String,
val createdAt: LocalDateTime,
val creatorReplies: List<CreatorChannelFanTalkReply>
)
data class CreatorChannelFanTalkReply(
val fanTalkId: Long,
val writerId: Long,
val writerNickname: String,
val writerProfileImageUrl: String,
val content: String,
val createdAt: LocalDateTime
)

View File

@@ -0,0 +1,49 @@
package kr.co.vividnext.sodalive.v2.creator.channel.fantalk.port.out
import kr.co.vividnext.sodalive.member.MemberRole
import java.time.LocalDateTime
interface CreatorChannelFanTalkQueryPort {
fun findCreator(creatorId: Long, viewerId: Long?): CreatorChannelFanTalkCreatorRecord?
fun existsBlockedBetween(viewerId: Long, creatorId: Long): Boolean
fun countFanTalks(creatorId: Long, viewerId: Long): Int
fun findFanTalks(
creatorId: Long,
viewerId: Long,
offset: Long,
limit: Int
): List<CreatorChannelFanTalkRecord>
fun findCreatorReplies(
creatorId: Long,
parentFanTalkIds: List<Long>
): List<CreatorChannelFanTalkReplyRecord>
}
data class CreatorChannelFanTalkCreatorRecord(
val creatorId: Long,
val role: MemberRole,
val nickname: String
)
data class CreatorChannelFanTalkRecord(
val fanTalkId: Long,
val writerId: Long,
val writerNickname: String,
val writerProfileImagePath: String?,
val content: String,
val createdAt: LocalDateTime
)
data class CreatorChannelFanTalkReplyRecord(
val fanTalkId: Long,
val parentFanTalkId: Long,
val writerId: Long,
val writerNickname: String,
val writerProfileImagePath: String?,
val content: String,
val createdAt: LocalDateTime
)