diff --git a/core/src/main/kotlin/com/wespot/message/port/in/CreatedMessageV2UseCase.kt b/core/src/main/kotlin/com/wespot/message/port/in/CreatedMessageV2UseCase.kt index 8d5e7539..518afd0d 100644 --- a/core/src/main/kotlin/com/wespot/message/port/in/CreatedMessageV2UseCase.kt +++ b/core/src/main/kotlin/com/wespot/message/port/in/CreatedMessageV2UseCase.kt @@ -2,9 +2,12 @@ package com.wespot.message.port.`in` import com.wespot.message.v2.MessageV2 import com.wespot.message.dto.request.CreatedMessageV2Request +import com.wespot.user.User interface CreatedMessageV2UseCase { fun createMessage(createdMessageV2Request: CreatedMessageV2Request): MessageV2 + fun welcomeMessage(signUpUser: User) + } diff --git a/core/src/main/kotlin/com/wespot/message/service/listener/MessageEventListener.kt b/core/src/main/kotlin/com/wespot/message/service/listener/MessageEventListener.kt index c04134e3..99ec6e5e 100644 --- a/core/src/main/kotlin/com/wespot/message/service/listener/MessageEventListener.kt +++ b/core/src/main/kotlin/com/wespot/message/service/listener/MessageEventListener.kt @@ -1,15 +1,20 @@ package com.wespot.message.service.listener import com.wespot.message.port.`in`.CreateMessageUseCase -import com.wespot.user.User +import com.wespot.message.port.`in`.CreatedMessageV2UseCase import com.wespot.user.event.WelcomeMessageEvent import org.springframework.context.event.EventListener +import org.springframework.scheduling.annotation.Async import org.springframework.stereotype.Component +import org.springframework.transaction.annotation.Propagation +import org.springframework.transaction.annotation.Transactional +import org.springframework.transaction.event.TransactionPhase import org.springframework.transaction.event.TransactionalEventListener @Component class MessageEventListener( - private val createMessageUseCase: CreateMessageUseCase + private val createMessageUseCase: CreateMessageUseCase, + private val createdMessageV2UseCase: CreatedMessageV2UseCase ) { @EventListener @@ -17,4 +22,12 @@ class MessageEventListener( createMessageUseCase.welcomeMessage(event.signUpUser) } + @Async + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + @Transactional(propagation = Propagation.REQUIRES_NEW) + fun welcomeMessageV2(event: WelcomeMessageEvent){ + createdMessageV2UseCase.welcomeMessage(event.signUpUser) + } + + } diff --git a/core/src/main/kotlin/com/wespot/message/service/v2/CreatedMessageV2Service.kt b/core/src/main/kotlin/com/wespot/message/service/v2/CreatedMessageV2Service.kt index 008101d3..f048b2ed 100644 --- a/core/src/main/kotlin/com/wespot/message/service/v2/CreatedMessageV2Service.kt +++ b/core/src/main/kotlin/com/wespot/message/service/v2/CreatedMessageV2Service.kt @@ -1,28 +1,27 @@ package com.wespot.message.service.v2 -import com.wespot.EventUtils import com.wespot.auth.service.SecurityUtils import com.wespot.exception.CustomException import com.wespot.exception.ExceptionView -import com.wespot.message.v2.MessageV2 +import com.wespot.message.MessageContent import com.wespot.message.dto.request.CreatedMessageV2Request -import com.wespot.message.event.ReceivedMessageEvent import com.wespot.message.port.`in`.CreatedMessageV2UseCase import com.wespot.message.port.out.MessageV2Port +import com.wespot.message.v2.MessageV2 +import com.wespot.user.User import com.wespot.user.dto.request.CreatedAnonymousProfileRequest import com.wespot.user.message.AnonymousProfile import com.wespot.user.port.`in`.AnonymousProfileUseCase -import com.wespot.user.port.out.BlockedUserPort import com.wespot.user.port.out.UserPort import org.springframework.http.HttpStatus import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class CreatedMessageV2Service( private val userPort: UserPort, private val profileUseCase: AnonymousProfileUseCase, private val messageV2Port: MessageV2Port, - private val blockedUserPort: BlockedUserPort ) : CreatedMessageV2UseCase { override fun createMessage(createdMessageV2Request: CreatedMessageV2Request): MessageV2 { @@ -35,21 +34,14 @@ class CreatedMessageV2Service( ) val anonymousProfile = createAnonymousProfile(createdMessageV2Request) - val message = MessageV2.createInitial( + return MessageV2.createInitial( content = createdMessageV2Request.content, sender = sender, receiver = receiver, anonymousProfile = anonymousProfile, + savedMessageFunction = { message -> messageV2Port.save(message) }, alreadyUsedMessageOnToday = messageV2Port.countTodaySendMessages(sender.id), -// isBlockedFromReceiver = blockedUserPort.existsByBlockerIdAndBlockedId( -// blockerId = receiver.id, -// blockedId = sender.id -// ) ) - - EventUtils.publish(ReceivedMessageEvent(receiver = receiver, messageId = message.id)) - - return messageV2Port.save(message) } private fun createAnonymousProfile(createdMessageV2Request: CreatedMessageV2Request): AnonymousProfile? { @@ -66,5 +58,24 @@ class CreatedMessageV2Service( return null } + @Transactional + override fun welcomeMessage(signUpUser: User) { + val ever = userPort.findByName(name = User.EVER_NAME) ?: throw CustomException( + message = "해당 계정이 존재하지 않습니다.", + view = ExceptionView.TOAST, + status = HttpStatus.NOT_FOUND, + ) + + val welcomeMessage = MessageV2.createInitial( + content = MessageContent.createWelcomeMessage(receiverName = signUpUser.name).content, + sender = ever, + receiver = signUpUser, + anonymousProfile = null, + savedMessageFunction = { message -> messageV2Port.save(message) }, + alreadyUsedMessageOnToday = 0, + ) + messageV2Port.save(messageV2 = welcomeMessage) + } + } diff --git a/core/src/main/kotlin/com/wespot/message/service/v2/GetMessageV2Service.kt b/core/src/main/kotlin/com/wespot/message/service/v2/GetMessageV2Service.kt index 087479e7..c48415a5 100644 --- a/core/src/main/kotlin/com/wespot/message/service/v2/GetMessageV2Service.kt +++ b/core/src/main/kotlin/com/wespot/message/service/v2/GetMessageV2Service.kt @@ -72,7 +72,10 @@ class GetMessageV2Service( val messageDetails = messageV2Port.findAllByMessageRoomId(messageRoomId = messageId) val room = MessageRoom.of(viewer = loginUser, roomMessage = roomMessage, messages = messageDetails) - return MessageV2DetailsResponse.from(room = room) + val response = MessageV2DetailsResponse.from(room = room) + room.readUnreadMessages() + .forEach { messageV2Port.save(it) } + return response } } diff --git a/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt b/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt index 104ed650..f79d5785 100644 --- a/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt +++ b/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt @@ -58,4 +58,7 @@ interface UserPort { withdrawalRequestAt: LocalDateTime, withdrawalStatus: WithdrawalStatus ): List + + fun findByName(name: String): User? + } diff --git a/domain/src/main/kotlin/com/wespot/message/v2/MessageDetails.kt b/domain/src/main/kotlin/com/wespot/message/v2/MessageDetails.kt index e2ec051f..41b9063c 100644 --- a/domain/src/main/kotlin/com/wespot/message/v2/MessageDetails.kt +++ b/domain/src/main/kotlin/com/wespot/message/v2/MessageDetails.kt @@ -65,4 +65,11 @@ data class MessageDetails( return messages.filter { it.isNotDeleted(viewer = viewer) } } + fun readUnreadMessage(viewer: User): List { + return messages.filter { it.isUnread(viewer = viewer) } + .onEach { it.message.read(viewer = viewer) } + .map { it.message } + + } + } diff --git a/domain/src/main/kotlin/com/wespot/message/v2/MessageRoom.kt b/domain/src/main/kotlin/com/wespot/message/v2/MessageRoom.kt index cb9cbff2..84e925e7 100644 --- a/domain/src/main/kotlin/com/wespot/message/v2/MessageRoom.kt +++ b/domain/src/main/kotlin/com/wespot/message/v2/MessageRoom.kt @@ -173,4 +173,8 @@ data class MessageRoom( return messages.asList(viewer = viewer) } + fun readUnreadMessages():List{ + return messages.readUnreadMessage(viewer = viewer) + } + } diff --git a/domain/src/main/kotlin/com/wespot/message/v2/MessageV2.kt b/domain/src/main/kotlin/com/wespot/message/v2/MessageV2.kt index 50136843..9050752c 100644 --- a/domain/src/main/kotlin/com/wespot/message/v2/MessageV2.kt +++ b/domain/src/main/kotlin/com/wespot/message/v2/MessageV2.kt @@ -6,10 +6,10 @@ import com.wespot.exception.ExceptionView import com.wespot.message.MessageContent import com.wespot.message.event.MessageAnswerEvent import com.wespot.message.event.ReadMessageByReceiverEvent +import com.wespot.message.event.ReceivedMessageEvent import com.wespot.user.User import com.wespot.user.event.UsedAnswerFeatureEvent import com.wespot.user.message.AnonymousProfile -import org.hibernate.event.internal.EventUtil import org.springframework.http.HttpStatus import java.time.LocalDate import java.time.LocalDateTime @@ -56,7 +56,7 @@ data class MessageV2( receiver: User, anonymousProfile: AnonymousProfile?, alreadyUsedMessageOnToday: Int, -// isBlockedFromReceiver: Boolean // 정책 논의중 + savedMessageFunction: (MessageV2) -> MessageV2 ): MessageV2 { if (COUNT_OF_MAX_ABLE_TO_SEND_MESSAGE_PER_DAY <= alreadyUsedMessageOnToday) { throw CustomException( @@ -64,15 +64,7 @@ data class MessageV2( ) } -// if (isBlockedFromReceiver) { -// throw CustomException( -// HttpStatus.FORBIDDEN, -// ExceptionView.TOAST, -// "차단당한 상대에게는 쪽지를 보낼 수 없습니다." -// ) -// } - - return MessageV2( + val message = MessageV2( id = 0, content = MessageContent.from(content), sender = sender, @@ -102,6 +94,11 @@ data class MessageV2( anonymousProfile = anonymousProfile ) + + val savedMessage = savedMessageFunction.invoke(message) + EventUtils.publish(ReceivedMessageEvent(receiver = receiver, messageId = savedMessage.id)) + + return savedMessage } } diff --git a/domain/src/main/kotlin/com/wespot/user/User.kt b/domain/src/main/kotlin/com/wespot/user/User.kt index d001c268..920da40d 100644 --- a/domain/src/main/kotlin/com/wespot/user/User.kt +++ b/domain/src/main/kotlin/com/wespot/user/User.kt @@ -152,7 +152,7 @@ data class User( companion object { private const val WITHDRAW_USER_NAME = "탈퇴한 유저입니다." - private const val EVER_NAME = "에버" + const val EVER_NAME = "에버" fun create( email: String, diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt index d2e9aecb..760f69e6 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt @@ -172,4 +172,13 @@ class UserPersistenceAdapter( } } + override fun findByName(name: String): User? { + return userJpaRepository.findByName(name = name)?.let { + UserMapper.mapToDomainEntity( + userJpaEntity = it, + schoolJpaEntity = getBySchool(it) + ) + } + } + } diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt index 25e669d5..30e51ad6 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt @@ -79,6 +79,7 @@ interface UserJpaRepository : JpaRepository { @Param("loginUserId") loginUserId: Long, pageable: Pageable ): List + @Query( """ SELECT COUNT(u) @@ -127,4 +128,7 @@ interface UserJpaRepository : JpaRepository { withdrawalRequestAt: LocalDateTime, withdrawalStatus: WithdrawalStatus ): List + + fun findByName(name: String): UserJpaEntity? + }