Skip to content

Commit d0203f0

Browse files
committed
리뷰 반영: 대시보드 집계 안정성 보강
1 parent e382b33 commit d0203f0

5 files changed

Lines changed: 21 additions & 8 deletions

File tree

src/main/java/com/Rootin/domain/dashboard/service/DashboardService.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public GrassGraphResponse getGrassGraph(Long userId) {
5757
.sorted(Comparator.comparing(GrassCell::date))
5858
.collect(Collectors.toList());
5959

60-
List<LocalDate> publishedDates = tilRepository.findDistinctPublishedDatesByUserId(userId, PostStatus.PUBLISHED.name()).stream()
60+
List<LocalDate> publishedDates = tilRepository.findDistinctPublishedDatesByUserId(userId, PostStatus.PUBLISHED).stream()
6161
.map(java.sql.Date::toLocalDate)
6262
.toList();
6363
int currentStreak = levelCalculator.calculateStreakFromDates(publishedDates);
@@ -115,12 +115,12 @@ public PersonalStatsResponse getPersonalStats(Long userId) {
115115
.toList();
116116
int totalStudyDays = wateredDates.size();
117117

118-
List<LocalDate> publishedDates = tilRepository.findDistinctPublishedDatesByUserId(userId, PostStatus.PUBLISHED.name()).stream()
118+
List<LocalDate> publishedDates = tilRepository.findDistinctPublishedDatesByUserId(userId, PostStatus.PUBLISHED).stream()
119119
.map(java.sql.Date::toLocalDate)
120120
.toList();
121121
int currentStreak = levelCalculator.calculateStreakFromDates(publishedDates);
122122

123-
int longestStreak = calculateMaxStreak(wateredDates);
123+
int longestStreak = calculateMaxStreak(publishedDates);
124124

125125
int currentPoints = Optional.ofNullable(overview.getCurrentPoints()).orElse(0);
126126

@@ -181,18 +181,24 @@ public QuestResponse getQuests(Long userId) {
181181
// 반열린 구간 [todayStart, tomorrowStart) — datetime(6) microsecond 누락 방지
182182
LocalDateTime tomorrowStart = today.plusDays(1).atStartOfDay();
183183

184-
WateringLogAggregateProjection todayStats = wateringLogRepository
184+
Optional<WateringLogAggregateProjection> todayStats = wateringLogRepository
185185
.aggregateByUserIdAndWateredAtGreaterThanEqualAndWateredAtLessThan(userId, todayStart, tomorrowStart);
186+
long todayTilCount = todayStats
187+
.map(WateringLogAggregateProjection::getTilCount)
188+
.orElse(0L);
189+
long todayContentLength = todayStats
190+
.map(WateringLogAggregateProjection::getContentLength)
191+
.orElse(0L);
186192

187193
// Q1: 오늘 TIL >= 1개
188-
boolean q1 = todayStats.getTilCount() >= 1;
194+
boolean q1 = todayTilCount >= 1;
189195

190196
// Q2: 오늘 TIL에 태그 >= 1개
191197
long todayTagCount = tilTagRepository.countByUserTodayTil(userId, PostStatus.PUBLISHED, todayStart, tomorrowStart);
192198
boolean q2 = todayTagCount >= 1;
193199

194200
// Q3: 오늘 총 글자 수 >= 200
195-
boolean q3 = todayStats.getContentLength() >= 200;
201+
boolean q3 = todayContentLength >= 200;
196202

197203
// 달성된 퀘스트에 대해 오늘 첫 달성이면 포인트 지급
198204
awardQuestPoints(userId, q1, q2, q3, today);

src/main/java/com/Rootin/domain/garden/repository/WateringLogRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ SELECT COUNT(w) AS tilCount,
137137
AND w.wateredAt >= :from
138138
AND w.wateredAt < :to
139139
""")
140-
WateringLogAggregateProjection aggregateByUserIdAndWateredAtGreaterThanEqualAndWateredAtLessThan(
140+
Optional<WateringLogAggregateProjection> aggregateByUserIdAndWateredAtGreaterThanEqualAndWateredAtLessThan(
141141
@Param("userId") Long userId,
142142
@Param("from") LocalDateTime from,
143143
@Param("to") LocalDateTime to

src/main/java/com/Rootin/domain/garden/service/GardenDashboardService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public GardenInfoResponse getGardenDashboard(Long potId, Long userId) {
126126

127127
// 11. 유저의 TIL 발행 날짜만 조회해 현재 연속 작성일(스트릭)을 계산합니다.
128128
// 같은 날짜에 여러 글을 작성해도 스트릭에는 날짜 하나만 필요하므로 DISTINCT 날짜 조회로 힙 사용량을 줄입니다.
129-
List<LocalDate> publishedDates = tilRepository.findDistinctPublishedDatesByUserId(userId, PostStatus.PUBLISHED.name())
129+
List<LocalDate> publishedDates = tilRepository.findDistinctPublishedDatesByUserId(userId, PostStatus.PUBLISHED)
130130
.stream()
131131
.map(java.sql.Date::toLocalDate)
132132
.toList();

src/main/java/com/Rootin/domain/til/repository/TilRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ List<java.sql.Date> findDistinctPublishedDatesByUserId(
4040
@Param("status") String status
4141
);
4242

43+
default List<java.sql.Date> findDistinctPublishedDatesByUserId(Long userId, PostStatus status) {
44+
return findDistinctPublishedDatesByUserId(userId, status.name());
45+
}
46+
4347
Optional<Til> findFirstByUserIdAndPotIdAndStatus(Long userId, Long potId, PostStatus status);
4448

4549
@Query("""

src/test/java/com/Rootin/domain/dashboard/service/DashboardServiceQuestTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,16 @@ void grassGraph_maxStreak_usesOnlyGraphRangeDates() {
224224
@DisplayName("현재 스트릭은 물주기 로그 날짜가 아니라 TIL 발행 날짜 기준으로 계산한다")
225225
void currentStreak_usesPublishedTilDates() {
226226
Til todayTil = tilRepository.save(Til.create(user, "오늘 발행 TIL", "내용", pot));
227+
Til anotherTodayTil = tilRepository.save(Til.create(user, "오늘 발행 TIL 2", "내용", pot));
227228
saveWateringLogAt(todayTil.getId(), 50, LocalDate.now().minusDays(10));
229+
saveWateringLogAt(anotherTodayTil.getId(), 50, LocalDate.now().minusDays(9));
228230

229231
var grass = dashboardService.getGrassGraph(user.getId());
230232
var personalStats = dashboardService.getPersonalStats(user.getId());
231233

232234
assertThat(grass.currentStreak()).isEqualTo(1);
233235
assertThat(personalStats.currentStreak()).isEqualTo(1);
236+
// 물주기 로그 날짜 기준이면 2가 되지만, 개인 통계의 연속 기록은 TIL 발행 날짜 기준으로 통일한다.
234237
assertThat(personalStats.longestStreak()).isEqualTo(1);
235238
}
236239

0 commit comments

Comments
 (0)