diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/ranking/adapter/out/persistence/DefaultCreatorRankingSnapshotRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/ranking/adapter/out/persistence/DefaultCreatorRankingSnapshotRepository.kt index 5acccb76..1c2ec6ed 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/v2/ranking/adapter/out/persistence/DefaultCreatorRankingSnapshotRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/ranking/adapter/out/persistence/DefaultCreatorRankingSnapshotRepository.kt @@ -28,6 +28,10 @@ class DefaultCreatorRankingSnapshotRepository( return repository.findPreviousCompletedSnapshots().map { it.toRecord() } } + override fun isSnapshotTableEmpty(): Boolean { + return repository.count() == 0L + } + @Transactional override fun replaceSnapshots( aggregationStartAtUtc: LocalDateTime, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/ranking/port/out/CreatorRankingSnapshotPort.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/ranking/port/out/CreatorRankingSnapshotPort.kt index dc57ad9b..dd49e25c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/v2/ranking/port/out/CreatorRankingSnapshotPort.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/ranking/port/out/CreatorRankingSnapshotPort.kt @@ -12,6 +12,8 @@ interface CreatorRankingSnapshotPort { fun findPreviousCompletedSnapshots(): List + fun isSnapshotTableEmpty(): Boolean + fun replaceSnapshots( aggregationStartAtUtc: LocalDateTime, aggregationEndAtUtc: LocalDateTime, diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/v2/ranking/adapter/out/persistence/DefaultCreatorRankingSnapshotRepositoryTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/v2/ranking/adapter/out/persistence/DefaultCreatorRankingSnapshotRepositoryTest.kt index 55d7df75..062db614 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/v2/ranking/adapter/out/persistence/DefaultCreatorRankingSnapshotRepositoryTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/v2/ranking/adapter/out/persistence/DefaultCreatorRankingSnapshotRepositoryTest.kt @@ -147,6 +147,22 @@ class DefaultCreatorRankingSnapshotRepositoryTest @Autowired constructor( assertEquals(emptyList(), snapshots) } + @Test + @DisplayName("스냅샷 row가 하나도 없을 때만 테이블 완전 공백으로 판단한다") + fun shouldReturnTrueOnlyWhenSnapshotTableHasNoRows() { + assertEquals(true, adapter.isSnapshotTableEmpty()) + + repository.save( + snapshot( + creatorId = 1L, + aggregationStartAtUtc = LocalDateTime.of(2026, 5, 24, 15, 0), + aggregationEndAtUtc = LocalDateTime.of(2026, 5, 31, 15, 0) + ) + ) + + assertEquals(false, adapter.isSnapshotTableEmpty()) + } + @Test @DisplayName("20위 점수 경계 동점 후보는 저장소에서 누락 없이 저장하고 조회할 수 있다") fun shouldPersistAllCandidatesTiedAtTwentiethScoreBoundary() { diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/v2/ranking/application/CreatorRankingSnapshotRefreshServiceTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/v2/ranking/application/CreatorRankingSnapshotRefreshServiceTest.kt index a6de4469..f43fa67e 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/v2/ranking/application/CreatorRankingSnapshotRefreshServiceTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/v2/ranking/application/CreatorRankingSnapshotRefreshServiceTest.kt @@ -256,6 +256,8 @@ private class FakeCreatorRankingSnapshotPort : CreatorRankingSnapshotPort { override fun findPreviousCompletedSnapshots(): List = snapshots + override fun isSnapshotTableEmpty(): Boolean = snapshots.isEmpty() + override fun replaceSnapshots( aggregationStartAtUtc: LocalDateTime, aggregationEndAtUtc: LocalDateTime,