Skip to content

Commit 3886a8d

Browse files
committed
fix(DashboardService): getQuests todayEnd 23:59:59를 tomorrowStart 반열린 구간으로 교체, awardQuestPoints 시그니처를 LocalDate today로 단순화, PointLog.forQuest() 팩토리 사용 및 QUEST_REASONS 상수 추출
1 parent fce3a28 commit 3886a8d

1 file changed

Lines changed: 16 additions & 17 deletions

File tree

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

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -169,25 +169,27 @@ public InterestsResponse getInterests(Long userId, int months) {
169169

170170
@Transactional
171171
public QuestResponse getQuests(Long userId) {
172-
LocalDate today = LocalDate.now();
173-
LocalDateTime todayStart = today.atStartOfDay();
174-
LocalDateTime todayEnd = today.atTime(23, 59, 59);
172+
LocalDate today = LocalDate.now();
173+
LocalDateTime todayStart = today.atStartOfDay();
174+
// 반열린 구간 [todayStart, tomorrowStart) — datetime(6) microsecond 누락 방지
175+
LocalDateTime tomorrowStart = today.plusDays(1).atStartOfDay();
175176

176-
List<WateringLog> todayLogs = wateringLogRepository.findByUserIdAndWateredAtBetween(userId, todayStart, todayEnd);
177+
List<WateringLog> todayLogs = wateringLogRepository
178+
.findByUserIdAndWateredAtGreaterThanEqualAndWateredAtLessThan(userId, todayStart, tomorrowStart);
177179

178180
// Q1: 오늘 TIL >= 1개
179181
boolean q1 = !todayLogs.isEmpty();
180182

181183
// Q2: 오늘 TIL에 태그 >= 1개
182-
long todayTagCount = tilTagRepository.countByUserTodayTil(userId, PostStatus.PUBLISHED, todayStart, todayEnd);
184+
long todayTagCount = tilTagRepository.countByUserTodayTil(userId, PostStatus.PUBLISHED, todayStart, tomorrowStart);
183185
boolean q2 = todayTagCount >= 1;
184186

185187
// Q3: 오늘 총 글자 수 >= 200
186188
int todayCharCount = todayLogs.stream().mapToInt(WateringLog::getContentLength).sum();
187189
boolean q3 = todayCharCount >= 200;
188190

189191
// 달성된 퀘스트에 대해 오늘 첫 달성이면 포인트 지급
190-
awardQuestPoints(userId, q1, q2, q3, todayStart, todayEnd);
192+
awardQuestPoints(userId, q1, q2, q3, today);
191193

192194
List<QuestDto> quests = List.of(
193195
new QuestDto("Q1", "TIL 1개 작성하기", q1, 50),
@@ -201,17 +203,19 @@ public QuestResponse getQuests(Long userId) {
201203
return new QuestResponse(quests, earnedToday, totalToday);
202204
}
203205

204-
private void awardQuestPoints(Long userId, boolean q1, boolean q2, boolean q3,
205-
LocalDateTime from, LocalDateTime to) {
206+
private static final Set<PointLogReason> QUEST_REASONS =
207+
Set.of(PointLogReason.QUEST_Q1, PointLogReason.QUEST_Q2, PointLogReason.QUEST_Q3);
208+
209+
private void awardQuestPoints(Long userId, boolean q1, boolean q2, boolean q3, LocalDate today) {
206210
// 달성된 퀘스트가 없으면 DB 조회 없이 early return
207211
if (!q1 && !q2 && !q3) return;
208212

209-
// 오늘 이미 지급된 퀘스트 reason을 1번 쿼리로 조회 후 메모리에서 중복 체크
210-
Set<PointLogReason> awardedToday = pointLogRepository.findReasonsByUserIdAndCreatedAtBetween(userId, from, to);
213+
// awardedDate 기준으로 오늘 이미 지급된 퀘스트 reason 조회 (createdAt BETWEEN 대신)
214+
Set<PointLogReason> awardedToday =
215+
pointLogRepository.findQuestReasonsByUserIdAndAwardedDate(userId, today, QUEST_REASONS);
211216

212217
// User 풀 로딩 없이 프록시 참조만 사용 (PointLog FK 저장용)
213218
User userRef = userRepository.getReferenceById(userId);
214-
LocalDate today = from.toLocalDate();
215219

216220
awardIfNew(userId, userRef, q1, PointLogReason.QUEST_Q1, 50, awardedToday, today);
217221
awardIfNew(userId, userRef, q2, PointLogReason.QUEST_Q2, 30, awardedToday, today);
@@ -225,12 +229,7 @@ private void awardIfNew(Long userId, User userRef, boolean done, PointLogReason
225229

226230
// 원자적 UPDATE — 동시 요청 시 lost update 방지
227231
userRepository.incrementPoint(userId, point);
228-
pointLogRepository.save(PointLog.builder()
229-
.user(userRef)
230-
.reason(reason)
231-
.amount(point)
232-
.awardedDate(awardedDate)
233-
.build());
232+
pointLogRepository.save(PointLog.forQuest(userRef, reason, point, awardedDate));
234233
}
235234

236235
private int calculateMaxStreak(Set<LocalDate> dateSet) {

0 commit comments

Comments
 (0)