Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ import com.didit.application.achievement.required.RetrospectAchievementReader
import com.didit.application.retrospect.required.RetrospectiveRepository
import com.didit.domain.retrospect.RetroStatus
import com.didit.domain.shared.ServiceTime
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.UUID

@Component
class RetrospectAchievementReaderImpl(
private val retrospectiveRepository: RetrospectiveRepository,
@Value("\${achievement.feature-launched-at:2026-06-30T00:00:00}") private val featureLaunchedAt: LocalDateTime,
) : RetrospectAchievementReader {
companion object {
private const val MAX_CONSECUTIVE_WEEKS_SCAN = 60
}

override fun countCompletedRetros(userId: UUID): Int =
retrospectiveRepository.countByUserIdAndStatusAndDeletedAtIsNull(userId, RetroStatus.COMPLETED)
override fun countCompletedRetros(userId: UUID): Int = completedAtsSinceLaunch(userId).size

override fun countRetrosInWeek(
userId: UUID,
Expand All @@ -42,9 +44,13 @@ class RetrospectAchievementReaderImpl(
}

private fun weekCountsByMondayKst(userId: UUID): Map<LocalDate, Int> =
retrospectiveRepository
.findCompletedAtByUserIdAndStatusAndDeletedAtIsNull(userId, RetroStatus.COMPLETED)
completedAtsSinceLaunch(userId)
.map { ServiceTime.toServiceDate(it) }
.groupingBy { it.with(DayOfWeek.MONDAY) }
.eachCount()

private fun completedAtsSinceLaunch(userId: UUID): List<LocalDateTime> =
retrospectiveRepository
.findCompletedAtByUserIdAndStatusAndDeletedAtIsNull(userId, RetroStatus.COMPLETED)
.filter { !it.isBefore(featureLaunchedAt) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip legacy completed rows without completedAt

When a user has completed retros from before completed_at was added/backfilled, that column can be NULL (V13__add_completed_at.sql adds it as nullable), and the JPQL projection can return a null element for those COMPLETED rows. This filter dereferences every value with it.isBefore(...), so the first badge check for such a user throws and BadgeEventListener logs/abandons badge awarding instead of just ignoring pre-launch rows. Please filter nulls or add r.completedAt IS NOT NULL/a cutoff predicate in the repository query before comparing.

Useful? React with 👍 / 👎.

}
3 changes: 3 additions & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ jwt:
access-token-expiry-ms: 3600000
refresh-token-expiry-days: 14

achievement:
feature-launched-at: ${ACHIEVEMENT_FEATURE_LAUNCHED_AT:2026-06-30T00:00:00}

clova:
api:
url: https://clovastudio.stream.ntruss.com/v3/chat-completions/HCX-005
Expand Down
Loading