From 66ae7d7beb948c6d1a7225b3df41613b8571c1d9 Mon Sep 17 00:00:00 2001 From: pricelees Date: Thu, 11 Sep 2025 17:04:08 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=A0=A5=EC=9D=84=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=B3=84=EB=8F=84=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/business/LoginHistoryService.kt | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/main/kotlin/roomescape/auth/business/LoginHistoryService.kt diff --git a/src/main/kotlin/roomescape/auth/business/LoginHistoryService.kt b/src/main/kotlin/roomescape/auth/business/LoginHistoryService.kt new file mode 100644 index 00000000..bffedb50 --- /dev/null +++ b/src/main/kotlin/roomescape/auth/business/LoginHistoryService.kt @@ -0,0 +1,60 @@ +package roomescape.auth.business + +import com.github.f4b6a3.tsid.TsidFactory +import io.github.oshai.kotlinlogging.KLogger +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Propagation +import org.springframework.transaction.annotation.Transactional +import roomescape.auth.infrastructure.persistence.LoginHistoryEntity +import roomescape.auth.infrastructure.persistence.LoginHistoryRepository +import roomescape.auth.web.LoginContext +import roomescape.common.config.next +import roomescape.common.dto.PrincipalType + +private val log: KLogger = KotlinLogging.logger {} + +@Service +class LoginHistoryService( + private val loginHistoryRepository: LoginHistoryRepository, + private val tsidFactory: TsidFactory, +) { + @Transactional(propagation = Propagation.REQUIRES_NEW) + fun createSuccessHistory( + principalId: Long, + principalType: PrincipalType, + context: LoginContext + ) { + createHistory(principalId, principalType, success = true, context = context) + } + + @Transactional(propagation = Propagation.REQUIRES_NEW) + fun createFailureHistory( + principalId: Long, + principalType: PrincipalType, + context: LoginContext + ) { + createHistory(principalId, principalType, success = false, context = context) + } + + private fun createHistory( + principalId: Long, + principalType: PrincipalType, + success: Boolean, + context: LoginContext + ) { + log.info { "[LoginHistoryService.createHistory] 로그인 이력 저장 시작: id=${principalId}, type=${principalType}, success=${success}" } + + LoginHistoryEntity( + id = tsidFactory.next(), + principalId = principalId, + principalType = principalType, + success = success, + ipAddress = context.ipAddress, + userAgent = context.userAgent, + ).also { + loginHistoryRepository.save(it) + log.info { "[LoginHistoryService.createHistory] 로그인 이력 저장 완료: principalId=${principalId}, historyId=${it.id}" } + } + } +}