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

This commit is contained in:
2026-06-22 17:59:01 +09:00
parent b2fae3e081
commit e516a7406f
5 changed files with 265 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
package kr.co.vividnext.sodalive.v2.creator.channel.donation.domain
import kr.co.vividnext.sodalive.v2.creator.channel.live.domain.CreatorChannelPage
import org.springframework.stereotype.Component
import java.time.LocalDateTime
import java.time.ZoneId
@Component
class CreatorChannelDonationQueryPolicy {
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
}
fun currentKstMonthRange(now: LocalDateTime): CreatorChannelDonationMonthRange {
val nowKst = now.atZone(UTC_ZONE_ID).withZoneSameInstant(KST_ZONE_ID)
val start = nowKst.toLocalDate().withDayOfMonth(1).atStartOfDay(KST_ZONE_ID)
.withZoneSameInstant(UTC_ZONE_ID)
.toLocalDateTime()
val end = nowKst.toLocalDate().withDayOfMonth(1).atStartOfDay(KST_ZONE_ID).plusMonths(1)
.withZoneSameInstant(UTC_ZONE_ID)
.toLocalDateTime()
return CreatorChannelDonationMonthRange(
startInclusiveUtc = start,
endExclusiveUtc = end
)
}
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
private val KST_ZONE_ID: ZoneId = ZoneId.of("Asia/Seoul")
private val UTC_ZONE_ID: ZoneId = ZoneId.of("UTC")
}
}
data class CreatorChannelDonationMonthRange(
val startInclusiveUtc: LocalDateTime,
val endExclusiveUtc: LocalDateTime
)

View File

@@ -0,0 +1,27 @@
package kr.co.vividnext.sodalive.v2.creator.channel.donation.domain
import kr.co.vividnext.sodalive.v2.creator.channel.live.domain.CreatorChannelPage
import java.time.LocalDateTime
data class CreatorChannelDonationTab(
val donationCount: Int,
val rankings: List<CreatorChannelDonationRanking>,
val donations: List<CreatorChannelDonation>,
val page: CreatorChannelPage,
val hasNext: Boolean
)
data class CreatorChannelDonationRanking(
val userId: Long,
val nickname: String,
val profileImage: String,
val donationCan: Int
)
data class CreatorChannelDonation(
val nickname: String,
val profileImageUrl: String,
val can: Int,
val message: String,
val createdAt: LocalDateTime
)

View File

@@ -0,0 +1,41 @@
package kr.co.vividnext.sodalive.v2.creator.channel.donation.port.out
import kr.co.vividnext.sodalive.member.DonationRankingPeriod
import kr.co.vividnext.sodalive.member.MemberRole
import java.time.LocalDateTime
interface CreatorChannelDonationQueryPort {
fun findCreator(creatorId: Long, viewerId: Long?): CreatorChannelDonationCreatorRecord?
fun existsBlockedBetween(viewerId: Long, creatorId: Long): Boolean
fun countChannelDonations(
creatorId: Long,
viewerId: Long,
now: LocalDateTime
): Int
fun findChannelDonations(
creatorId: Long,
viewerId: Long,
now: LocalDateTime,
offset: Long,
limit: Int
): List<CreatorChannelDonationRecord>
}
data class CreatorChannelDonationCreatorRecord(
val creatorId: Long,
val role: MemberRole,
val nickname: String,
val isVisibleDonationRank: Boolean,
val donationRankingPeriod: DonationRankingPeriod?
)
data class CreatorChannelDonationRecord(
val nickname: String,
val profileImagePath: String?,
val can: Int,
val message: String?,
val createdAt: LocalDateTime
)

View File

@@ -0,0 +1,18 @@
package kr.co.vividnext.sodalive.v2.creator.channel.donation.port.out
import kr.co.vividnext.sodalive.member.DonationRankingPeriod
interface CreatorChannelDonationRankingPort {
fun findTopRankings(
creatorId: Long,
period: DonationRankingPeriod,
withDonationCan: Boolean
): List<CreatorChannelDonationRankingRecord>
}
data class CreatorChannelDonationRankingRecord(
val userId: Long,
val nickname: String,
val profileImage: String,
val donationCan: Int
)