feat(recommend): 추천 스냅샷 갱신 서비스를 추가한다
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package kr.co.vividnext.sodalive.v2.recommend.adapter.out.scheduler
|
||||
|
||||
import kr.co.vividnext.sodalive.v2.recommend.application.RecommendationSnapshotRefreshService
|
||||
import org.springframework.scheduling.annotation.Scheduled
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class RecommendationSnapshotScheduler(
|
||||
private val refreshService: RecommendationSnapshotRefreshService
|
||||
) {
|
||||
@Scheduled(cron = "0 0 6 * * *", zone = "Asia/Seoul")
|
||||
fun refreshDailySnapshots() {
|
||||
refreshService.refreshDailySnapshots()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package kr.co.vividnext.sodalive.v2.recommend.application
|
||||
|
||||
import kr.co.vividnext.sodalive.v2.recommend.domain.RecommendedSectionType
|
||||
import kr.co.vividnext.sodalive.v2.recommend.port.out.HomeRecommendationQueryPort
|
||||
import kr.co.vividnext.sodalive.v2.recommend.port.out.RecommendationSnapshotPort
|
||||
import kr.co.vividnext.sodalive.v2.recommend.port.out.RecommendationSnapshotRecord
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
@Service
|
||||
class RecommendationSnapshotRefreshService(
|
||||
private val snapshotPort: RecommendationSnapshotPort,
|
||||
private val queryPort: HomeRecommendationQueryPort
|
||||
) {
|
||||
@Transactional(readOnly = true)
|
||||
fun getLatestSnapshots(sectionType: RecommendedSectionType): List<RecommendationSnapshotRecord> {
|
||||
return snapshotPort.findLatestSnapshots(sectionType)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun refreshDailySnapshots() {
|
||||
refreshDailySnapshots(LocalDateTime.now())
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun refreshDailySnapshots(now: LocalDateTime) {
|
||||
val snapshotAt = now
|
||||
.atZone(UTC_ZONE)
|
||||
.withZoneSameInstant(KST_ZONE)
|
||||
.toLocalDate()
|
||||
.minusDays(1)
|
||||
.atTime(23, 59, 59)
|
||||
val windowStart = snapshotAt.toLocalDate().minusDays(6).atStartOfDay()
|
||||
|
||||
replaceAiCharacterSnapshots(windowStart, snapshotAt)
|
||||
replaceCheerCreatorSnapshots(windowStart, snapshotAt)
|
||||
replacePopularCommunitySnapshots(windowStart, snapshotAt)
|
||||
}
|
||||
|
||||
private fun replaceAiCharacterSnapshots(windowStart: LocalDateTime, snapshotAt: LocalDateTime) {
|
||||
val snapshots = queryPort.findAiCharacterSnapshots(windowStart, snapshotAt, AI_CHARACTER_SNAPSHOT_LIMIT)
|
||||
snapshotPort.replaceSnapshots(RecommendedSectionType.AI_CHARACTER, snapshotAt, snapshots)
|
||||
}
|
||||
|
||||
private fun replaceCheerCreatorSnapshots(windowStart: LocalDateTime, snapshotAt: LocalDateTime) {
|
||||
val snapshots = queryPort.findCheerCreatorSnapshots(windowStart, snapshotAt, CHEER_CREATOR_SNAPSHOT_LIMIT)
|
||||
snapshotPort.replaceSnapshots(RecommendedSectionType.CHEER_CREATOR, snapshotAt, snapshots)
|
||||
}
|
||||
|
||||
private fun replacePopularCommunitySnapshots(windowStart: LocalDateTime, snapshotAt: LocalDateTime) {
|
||||
val snapshots = queryPort.findPopularCommunitySnapshots(windowStart, snapshotAt, POPULAR_COMMUNITY_SNAPSHOT_LIMIT)
|
||||
snapshotPort.replaceSnapshots(RecommendedSectionType.POPULAR_COMMUNITY, snapshotAt, snapshots)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val AI_CHARACTER_SNAPSHOT_LIMIT = 20
|
||||
private const val CHEER_CREATOR_SNAPSHOT_LIMIT = 16
|
||||
private const val POPULAR_COMMUNITY_SNAPSHOT_LIMIT = 20
|
||||
private val UTC_ZONE: ZoneId = ZoneId.of("UTC")
|
||||
private val KST_ZONE: ZoneId = ZoneId.of("Asia/Seoul")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user