diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/useraction/UserActionService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/useraction/UserActionService.kt index 210b47d..240c8a7 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/useraction/UserActionService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/useraction/UserActionService.kt @@ -10,7 +10,9 @@ import kr.co.vividnext.sodalive.point.MemberPointRepository import kr.co.vividnext.sodalive.point.PointGrantLog import kr.co.vividnext.sodalive.point.PointGrantLogRepository import kr.co.vividnext.sodalive.point.PointRewardPolicyRepository +import org.slf4j.LoggerFactory import org.springframework.stereotype.Service +import org.springframework.transaction.support.TransactionTemplate import java.time.LocalDateTime @Service @@ -20,6 +22,7 @@ class UserActionService( private val policyRepository: PointRewardPolicyRepository, private val grantLogRepository: PointGrantLogRepository, private val memberPointRepository: MemberPointRepository, + private val transactionTemplate: TransactionTemplate, private val fcmService: FcmService ) { @@ -34,82 +37,107 @@ class UserActionService( ) { coroutineScope.launch { val now = LocalDateTime.now() - repository.save(UserActionLog(memberId, actionType)) + transactionTemplate.execute { + repository.save(UserActionLog(memberId, actionType)) + repository.flush() + } - val policy = policyRepository.findByActionTypeAndIsActiveTrue(actionType, now) - if (policy != null) { - val policyType = policy.policyType - val todayAt15 = now.toLocalDate().atTime(15, 0) - val policyTypeDailyStartDate = if (now.toLocalTime().isBefore(todayAt15.toLocalTime())) { - now.toLocalDate().minusDays(1).atTime(15, 0) - } else { - todayAt15 - } - - val order = if (contentId != null) { - orderRepository.findByMemberIdAndContentId( - memberId = memberId, - contentId = contentId, - createdAt = if (policyType == PolicyType.DAILY) policyTypeDailyStartDate else policy.startDate - ) - } else { - null - } - if (actionType == ActionType.ORDER_CONTENT_COMMENT && order == null) return@launch - - val actionCount = repository.countByMemberIdAndActionTypeAndCreatedAtBetween( - memberId = memberId, - actionType = actionType, - startDate = if (policyType == PolicyType.DAILY) policyTypeDailyStartDate else policy.startDate, - endDate = policy.endDate ?: now - ) - if (actionCount < policy.threshold) return@launch - - val grantedCount = grantLogRepository.countByMemberIdAndPolicyIdAndStartDate( - memberId, - policy.id!!, - startDate = if (policyType == PolicyType.DAILY) policyTypeDailyStartDate else policy.startDate - ) - if (grantedCount >= policy.availableCount) return@launch - - grantLogRepository.save( - PointGrantLog( - memberId = memberId, - point = if (actionType == ActionType.ORDER_CONTENT_COMMENT && order != null) { - order.can + try { + transactionTemplate.execute { + val policy = policyRepository.findByActionTypeAndIsActiveTrue(actionType, now) + if (policy != null) { + val policyType = policy.policyType + val todayAt15 = now.toLocalDate().atTime(15, 0) + val policyTypeDailyStartDate = if (now.toLocalTime().isBefore(todayAt15.toLocalTime())) { + now.toLocalDate().minusDays(1).atTime(15, 0) } else { - policy.pointAmount - }, - actionType = actionType, - policyId = policy.id!!, - orderId = order?.id - ) - ) - - memberPointRepository.save( - MemberPoint( - memberId = memberId, - point = if (actionType == ActionType.ORDER_CONTENT_COMMENT && order != null) { - order.can - } else { - policy.pointAmount - }, - actionType = actionType, - expiresAt = now.plusDays(3) - ) - ) - - if (pushTokenList.isNotEmpty()) { - fcmService.sendPointGranted( - pushTokenList, - if (actionType == ActionType.ORDER_CONTENT_COMMENT && order != null) { - order.can - } else { - policy.pointAmount + todayAt15 } - ) + + val order = if (contentId != null) { + orderRepository.findByMemberIdAndContentId( + memberId = memberId, + contentId = contentId, + createdAt = if (policyType == PolicyType.DAILY) { + policyTypeDailyStartDate + } else { + policy.startDate + } + ) + } else { + null + } + if (actionType == ActionType.ORDER_CONTENT_COMMENT && order == null) return@execute + + val actionCount = repository.countByMemberIdAndActionTypeAndCreatedAtBetween( + memberId = memberId, + actionType = actionType, + startDate = if (policyType == PolicyType.DAILY) { + policyTypeDailyStartDate + } else { + policy.startDate + }, + endDate = policy.endDate ?: now + ) + if (actionCount < policy.threshold) return@execute + + val grantedCount = grantLogRepository.countByMemberIdAndPolicyIdAndStartDate( + memberId, + policy.id!!, + startDate = if (policyType == PolicyType.DAILY) { + policyTypeDailyStartDate + } else { + policy.startDate + } + ) + if (grantedCount >= policy.availableCount) return@execute + + grantLogRepository.save( + PointGrantLog( + memberId = memberId, + point = if (actionType == ActionType.ORDER_CONTENT_COMMENT && order != null) { + order.can + } else { + policy.pointAmount + }, + actionType = actionType, + policyId = policy.id!!, + orderId = order?.id + ) + ) + + memberPointRepository.save( + MemberPoint( + memberId = memberId, + point = if (actionType == ActionType.ORDER_CONTENT_COMMENT && order != null) { + order.can + } else { + policy.pointAmount + }, + actionType = actionType, + expiresAt = now.plusDays(3) + ) + ) + + if (pushTokenList.isNotEmpty()) { + fcmService.sendPointGranted( + pushTokenList, + if (actionType == ActionType.ORDER_CONTENT_COMMENT && order != null) { + order.can + } else { + policy.pointAmount + } + ) + } + } } + } catch (e: Exception) { + logger.warn("포인트 지급 또는 알림 실패: ${e.message}") } } } + + companion object { + private val logger = LoggerFactory.getLogger(UserActionService::class.java) + } }