Skip to content

#139 - 쪽지 방 생성을 구현합니다. #149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 19, 2025
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
@@ -1,4 +1,4 @@
package com.wespot.message
package com.wespot.message.v1

import com.wespot.message.port.`in`.DeleteMessageUseCase
import org.springframework.http.ResponseEntity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.wespot.message
package com.wespot.message.v1

import com.wespot.message.MessageType
import com.wespot.message.dto.response.*
import com.wespot.message.port.`in`.GetMessageUseCase
import org.springframework.http.ResponseEntity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.wespot.message
package com.wespot.message.v1

import com.wespot.message.dto.request.UpdateMessageRequest
import com.wespot.message.dto.response.UpdateMessageResponse
import com.wespot.message.port.`in`.ModifyMessageUseCase
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wespot.message
package com.wespot.message.v1

import com.wespot.message.dto.request.SendMessageRequest
import com.wespot.message.dto.response.SendMessageResponse
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.wespot.message.v2

import com.wespot.message.dto.request.CreatedMessageV2Request
import com.wespot.message.port.`in`.CreatedMessageV2UseCase
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/v2/messages")
class CreateMessageV2Controller(
private val createdMessageV2Usecase: CreatedMessageV2UseCase
) {

@PostMapping
fun createMessageV2(
createdMessageV2Request: CreatedMessageV2Request
): ResponseEntity<Unit> {
createdMessageV2Usecase.createMessage(createdMessageV2Request)

return ResponseEntity
.status(HttpStatus.CREATED)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.wespot.message.dto.request

class CreatedMessageV2Request(
val content: String,
val receiverId: Long,

val isAnonymous: Boolean,
val anonymousImageUrl: String,
val anonymousProfileName: String,
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.wespot.message.port.`in`

import com.wespot.message.MessageV2
import com.wespot.message.dto.request.CreatedMessageV2Request

interface CreatedMessageV2UseCase {

fun createMessage(createdMessageV2Request: CreatedMessageV2Request): MessageV2

}
11 changes: 11 additions & 0 deletions core/src/main/kotlin/com/wespot/message/port/out/MessageV2Port.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.wespot.message.port.out

import com.wespot.message.MessageV2

interface MessageV2Port {

fun save(messageV2: MessageV2): MessageV2

fun countTodaySendMessages(userId: Long): Int

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
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.MessageV2
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.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

@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 {
val sender = SecurityUtils.getLoginUser(userPort)
val receiver =
userPort.findById(userId = createdMessageV2Request.receiverId) ?: throw CustomException(
HttpStatus.NOT_FOUND,
ExceptionView.TOAST,
"유저를 찾을 수 없습니다."
)
val anonymousProfile = createAnonymousProfile(createdMessageV2Request)

val message = MessageV2.createInitial(
content = createdMessageV2Request.content,
sender = sender,
receiver = receiver,
anonymousProfile = anonymousProfile,
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? {
if (createdMessageV2Request.isAnonymous) {
return profileUseCase.createAnonymousProfile(
CreatedAnonymousProfileRequest(
name = createdMessageV2Request.anonymousProfileName,
imageUrl = createdMessageV2Request.anonymousImageUrl,
receiverId = createdMessageV2Request.receiverId
)
)
}

return null
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,39 @@ import com.wespot.message.event.ReadMessageByReceiverEvent
import com.wespot.message.event.ReceivedMessageEvent
import com.wespot.notification.port.`in`.MessageNotificationUseCase
import com.wespot.notification.service.DisabledNotificationService
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 MessageNotificationEventListener(
private val disabledNotificationService: DisabledNotificationService,
private val messageNotificationService: MessageNotificationUseCase,
) {

@EventListener
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
fun disableMessageNotificationByLimit(messageLimitEvent: MessageLimitEvent) {
disabledNotificationService.disableMessageNotification(
messageLimitEvent.senderId,
messageLimitEvent.sendMessageCount
)
}

@EventListener
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
fun receiveMessage(receivedMessageEvent: ReceivedMessageEvent) {
messageNotificationService.receiveMessage(receivedMessageEvent.receiver, receivedMessageEvent.messageId)
}

@EventListener
@Async
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
fun readMessageByReceiver(readMessageByReceiverEvent: ReadMessageByReceiverEvent) {
messageNotificationService.readMessageByReceiver(
readMessageByReceiverEvent.sender,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ package com.wespot.user.port.`in`

import com.wespot.user.dto.request.CreatedAnonymousProfileRequest
import com.wespot.user.dto.request.UpdatedAnonymousProfileRequest
import com.wespot.user.message.AnonymousProfile


interface AnonymousProfileUseCase {

fun createAnonymousProfile(createdAnonymousProfileRequest: CreatedAnonymousProfileRequest)
fun createAnonymousProfile(
createdAnonymousProfileRequest: CreatedAnonymousProfileRequest
): AnonymousProfile

fun updateAnonymousProfile(profileId: Long, updatedAnonymousProfileRequest: UpdatedAnonymousProfileRequest)
fun updateAnonymousProfile(
profileId: Long,
updatedAnonymousProfileRequest: UpdatedAnonymousProfileRequest
): AnonymousProfile

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.wespot.user.port.out

import com.google.api.services.storage.model.Bucket.Owner
import com.wespot.user.message.AnonymousProfile

interface AnonymousProfilePort {
Expand All @@ -8,4 +9,6 @@ interface AnonymousProfilePort {

fun save(anonymousProfile: AnonymousProfile): AnonymousProfile

fun findAllByOwnerIdAndReceiverId(ownerId: Long, receiverId: Long): List<AnonymousProfile>

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,49 +28,66 @@ class AnonymousProfileService(
) : AnonymousProfileUseCase {

@Transactional
override fun createAnonymousProfile(createdAnonymousProfileRequest: CreatedAnonymousProfileRequest) {
override fun createAnonymousProfile(createdAnonymousProfileRequest: CreatedAnonymousProfileRequest): AnonymousProfile {
val loginUser = SecurityUtils.getLoginUser(userPort)
val names = userPort.findAll()
.map { it.name }
.toSet()
val receiver = userPort.findById(createdAnonymousProfileRequest.receiverId) ?: throw CustomException(
HttpStatus.NOT_FOUND,
ExceptionView.TOAST,
"상대방을 찾을 수 없어 익명 프로필을 생성할 수 없습니다."
)
val users = userPort.findAll()
val image = Image.createImage(createdAnonymousProfileRequest.imageUrl, cloudFrontUrl)
val profileName = ProfileName.of(createdAnonymousProfileRequest.name, names)
val alreadyExistsAnonymousProfileWithReceiver = anonymousProfilePort.findAllByOwnerIdAndReceiverId(
loginUser.id,
receiver.id
)
val profileName = ProfileName.of(
createdAnonymousProfileRequest.name,
users,
alreadyExistsAnonymousProfileWithReceiver
)

val anonymousProfile = AnonymousProfile.of(
val anonymousProfile = AnonymousProfile.createInitial(
image = image,
profileName = profileName,
owner = loginUser,
receiverId = createdAnonymousProfileRequest.receiverId
receiver = receiver,
alreadyExistsAnonymousProfileWithReceiver = alreadyExistsAnonymousProfileWithReceiver,
)

anonymousProfilePort.save(anonymousProfile)
val savedAnonymousProfile = anonymousProfilePort.save(anonymousProfile)
EventUtils.publish(SavedImageEvent(image))
return savedAnonymousProfile
}

@Transactional
override fun updateAnonymousProfile(
profileId: Long,
updatedAnonymousProfileRequest: UpdatedAnonymousProfileRequest
) {
): AnonymousProfile {
val loginUser = SecurityUtils.getLoginUser(userPort)
val names = userPort.findAll()
.map { it.name }
.toSet()
val image = Image.createImage(updatedAnonymousProfileRequest.imageUrl, cloudFrontUrl)
val profileName = ProfileName.of(updatedAnonymousProfileRequest.name, names)

val savedAnonymousProfile = anonymousProfilePort.findByProfileId(profileId) ?: throw CustomException(
HttpStatus.BAD_REQUEST,
ExceptionView.TOAST,
"실명 프로필로를 찾을 수 없습니다."
)
val users = userPort.findAll()
val alreadyExistsAnonymousProfileWithReceiver = anonymousProfilePort.findAllByOwnerIdAndReceiverId(
loginUser.id,
savedAnonymousProfile.receiver.id
)
val image = Image.createImage(updatedAnonymousProfileRequest.imageUrl, cloudFrontUrl)
val profileName =
ProfileName.of(updatedAnonymousProfileRequest.name, users, alreadyExistsAnonymousProfileWithReceiver)


val updatedAnonymousProfile = savedAnonymousProfile.update(
image, profileName, loginUser.id
)
anonymousProfilePort.save(updatedAnonymousProfile)
val savedAnonymousProfileAfterUpdate = anonymousProfilePort.save(updatedAnonymousProfile)

EventUtils.publish(SavedImageEvent(image))
EventUtils.publish(DeletedImageEvent(savedAnonymousProfile.imageUrl))
return savedAnonymousProfileAfterUpdate
}
}
Loading
Loading