Skip to content
This repository has been archived by the owner on May 19, 2024. It is now read-only.

Commit

Permalink
[WEAV-331] 미팅 매칭시 채팅방 생성 (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
waterfogSW authored Apr 15, 2024
1 parent c25b3c4 commit 9e159f2
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.studentcenter.weave.application.meeting.port.inbound

import java.util.*

fun interface MeetingAttendanceCreateUseCase {
fun interface CreateMeetingAttendance {

fun invoke(meetingId: UUID, attendance: Boolean)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.studentcenter.weave.application.meeting.port.outbound

import com.studentcenter.weave.domain.meeting.event.MeetingCompletedEvent

interface MeetingEventPublisher {

fun publish(meetingCompletedEvent: MeetingCompletedEvent)

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ package com.studentcenter.weave.application.meeting.service.application

import com.studentcenter.weave.application.common.exception.MeetingExceptionType
import com.studentcenter.weave.application.common.security.context.getCurrentUserAuthentication
import com.studentcenter.weave.application.meeting.port.inbound.MeetingAttendanceCreateUseCase
import com.studentcenter.weave.application.meeting.port.inbound.CreateMeetingAttendance
import com.studentcenter.weave.application.meeting.port.outbound.MeetingEventPort
import com.studentcenter.weave.application.meeting.port.outbound.MeetingEventPublisher
import com.studentcenter.weave.application.meeting.service.domain.MeetingAttendanceDomainService
import com.studentcenter.weave.application.meeting.service.domain.MeetingDomainService
import com.studentcenter.weave.application.meeting.vo.MeetingMatchingEvent
import com.studentcenter.weave.application.meetingTeam.port.inbound.GetMeetingTeam
import com.studentcenter.weave.domain.meeting.entity.Meeting
import com.studentcenter.weave.domain.meeting.entity.MeetingAttendance
import com.studentcenter.weave.domain.meeting.event.MeetingCompletedEvent.Companion.createCompletedEvent
import com.studentcenter.weave.support.common.exception.CustomException
import com.studentcenter.weave.support.lock.distributedLock
import kotlinx.coroutines.CoroutineScope
Expand All @@ -20,12 +22,13 @@ import java.time.LocalDateTime
import java.util.*

@Service
class MeetingAttendanceCreateApplicationService(
class CreateMeetingAttendanceService(
private val meetingDomainService: MeetingDomainService,
private val meetingAttendanceDomainService: MeetingAttendanceDomainService,
private val getMeetingTeam: GetMeetingTeam,
private val meetingEventPort: MeetingEventPort,
) : MeetingAttendanceCreateUseCase {
private val meetingEventPublisher: MeetingEventPublisher,
) : CreateMeetingAttendance {

override fun invoke(
meetingId: UUID,
Expand Down Expand Up @@ -94,7 +97,12 @@ class MeetingAttendanceCreateApplicationService(
meeting: Meeting,
memberCount: Int,
) {
meetingDomainService.save(meeting.complete())
meeting
.complete()
.also {
meetingDomainService.save(it)
meetingEventPublisher.publish(it.createCompletedEvent())
}

val matchedMeetingCount = meetingDomainService.countByStatusIsCompleted()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.studentcenter.weave.application.meeting.service.domain

import com.studentcenter.weave.application.meeting.port.outbound.MeetingEventPublisher
import com.studentcenter.weave.domain.meeting.event.MeetingCompletedEvent
import org.springframework.context.ApplicationEventPublisher
import org.springframework.stereotype.Service

@Service
class MeetingEventService(
private val eventPublisher: ApplicationEventPublisher,
): MeetingEventPublisher {

override fun publish(meetingCompletedEvent: MeetingCompletedEvent) {
eventPublisher.publishEvent(meetingCompletedEvent)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.studentcenter.weave.bootstrap.meeting.controller

import com.studentcenter.weave.application.chat.port.inbound.CreateChatRoom
import com.studentcenter.weave.domain.meeting.event.MeetingCompletedEvent
import org.springframework.context.event.EventListener
import org.springframework.stereotype.Controller

@Controller
class MeetingEventHandler(
private val createChatRoom: CreateChatRoom,
) {

@EventListener
fun handleMeetingEvent(meetingCompletedEvent: MeetingCompletedEvent) {
meetingCompletedEvent
.entity
.also { createChatRoom.invoke(it) }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.studentcenter.weave.bootstrap.meeting.controller
import com.studentcenter.weave.application.meeting.port.inbound.FindMyRequestMeetingByReceivingTeamIdUseCase
import com.studentcenter.weave.application.meeting.port.inbound.GetAllOtherTeamMemberInfoUseCase
import com.studentcenter.weave.application.meeting.port.inbound.GetMeetingAttendancesUseCase
import com.studentcenter.weave.application.meeting.port.inbound.MeetingAttendanceCreateUseCase
import com.studentcenter.weave.application.meeting.port.inbound.CreateMeetingAttendance
import com.studentcenter.weave.application.meeting.port.inbound.MeetingRequestUseCase
import com.studentcenter.weave.application.meeting.port.inbound.ScrollPendingMeetingUseCase
import com.studentcenter.weave.application.meeting.port.inbound.ScrollPreparedMeetingUseCase
Expand All @@ -25,7 +25,7 @@ class MeetingRestController(
private val scrollPendingMeetingUseCase: ScrollPendingMeetingUseCase,
private val scrollPreparedMeetingUseCase: ScrollPreparedMeetingUseCase,
private val getMeetingAttendancesUseCase: GetMeetingAttendancesUseCase,
private val meetingAttendanceCreateUseCase: MeetingAttendanceCreateUseCase,
private val createMeetingAttendance: CreateMeetingAttendance,
private val findMyRequestMeetingByReceivingTeamIdUseCase: FindMyRequestMeetingByReceivingTeamIdUseCase,
private val getAllOtherTeamMemberInfoUseCase: GetAllOtherTeamMemberInfoUseCase,
) : MeetingApi {
Expand Down Expand Up @@ -58,14 +58,14 @@ class MeetingRestController(
}

override fun createAttendanceForAttend(meetingId: UUID) {
meetingAttendanceCreateUseCase.invoke(
createMeetingAttendance.invoke(
meetingId = meetingId,
attendance = true,
)
}

override fun createAttendanceForPass(meetingId: UUID) {
meetingAttendanceCreateUseCase.invoke(
createMeetingAttendance.invoke(
meetingId = meetingId,
attendance = false,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.studentcenter.weave.bootstrap.integration

import com.studentcenter.weave.application.common.security.context.UserSecurityContext
import com.studentcenter.weave.application.meeting.service.application.MeetingAttendanceCreateApplicationService
import com.studentcenter.weave.application.meeting.service.application.CreateMeetingAttendanceService
import com.studentcenter.weave.application.meeting.service.domain.MeetingAttendanceDomainService
import com.studentcenter.weave.application.meeting.service.domain.MeetingDomainService
import com.studentcenter.weave.application.meetingTeam.port.outbound.MeetingTeamRepository
Expand All @@ -22,12 +22,12 @@ import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.annotation.DisplayName
import io.kotest.matchers.shouldBe

@DisplayName("MeetingAttendanceCreateApplicationService Integration Test")
class MeetingAttendanceCreateApplicationServiceIntegrationTest(
@DisplayName("CreateMeetingAttendance Integration Test")
class CreateMeetingAttendanceIntegrationTest(
private val meetingDomainService: MeetingDomainService,
private val meetingAttendanceDomainService: MeetingAttendanceDomainService,
private val meetingTeamRepository: MeetingTeamRepository,
private val sut: MeetingAttendanceCreateApplicationService,
private val sut: CreateMeetingAttendanceService,
) : IntegrationTestDescribeSpec({

val currentUser = UserFixtureFactory.create()
Expand Down Expand Up @@ -185,7 +185,7 @@ class MeetingAttendanceCreateApplicationServiceIntegrationTest(
}

context("미팅 참여하는 경우, 마지막 참여라면") {
it("미팅이 완료 상태로 변경된다.") {
it("미팅이 완료 상태로 변경하고, 미팅 완료 이벤트를 발행한다") {
// arrange
val attendance = true
val memberCount = 2
Expand Down Expand Up @@ -219,6 +219,7 @@ class MeetingAttendanceCreateApplicationServiceIntegrationTest(

// assert
meetingDomainService.getById(meeting.id).status shouldBe MeetingStatus.COMPLETED

}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.studentcenter.weave.bootstrap.meeting.controller

import com.ninjasquad.springmockk.MockkBean
import com.studentcenter.weave.application.chat.port.inbound.CreateChatRoom
import com.studentcenter.weave.bootstrap.integration.IntegrationTestDescribeSpec
import com.studentcenter.weave.domain.meeting.entity.MeetingFixtureFactory
import com.studentcenter.weave.domain.meeting.enums.MeetingStatus
import com.studentcenter.weave.domain.meeting.event.MeetingCompletedEvent.Companion.createCompletedEvent
import io.kotest.core.annotation.DisplayName
import io.mockk.every
import io.mockk.just
import io.mockk.runs
import io.mockk.verify
import org.springframework.context.ApplicationEventPublisher

@DisplayName("MeetingEventHandler 테스트")
class MeetingEventHandlerTest(
private val applicationEventPublisher: ApplicationEventPublisher,
@MockkBean
private val createChatRoom: CreateChatRoom,
) : IntegrationTestDescribeSpec({

describe("미팅 완료 이벤트를 전달 받으면") {
it("새로운 채팅방을 생성한다") {
// arrange
val meetingFixture = MeetingFixtureFactory.create(status = MeetingStatus.COMPLETED)
val meetingCompletedEvent = meetingFixture.createCompletedEvent()

every { createChatRoom.invoke(meetingCompletedEvent.entity) } just runs

// act
applicationEventPublisher.publishEvent(meetingCompletedEvent)

// assert
verify { createChatRoom.invoke(meetingCompletedEvent.entity) }
}
}

})
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.studentcenter.weave.domain.common

interface AggregateRoot : DomainEntity
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.studentcenter.weave.domain.common

import java.util.*

interface DomainEntity {

val id: UUID

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.studentcenter.weave.domain.common

interface DomainEvent<T : AggregateRoot> {

val entity: T

}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package com.studentcenter.weave.domain.meeting.entity

import com.studentcenter.weave.domain.common.AggregateRoot
import com.studentcenter.weave.domain.meeting.enums.MeetingStatus
import com.studentcenter.weave.support.common.uuid.UuidCreator
import java.time.LocalDateTime
import java.util.*

data class Meeting(
val id: UUID = UuidCreator.create(),
override val id: UUID = UuidCreator.create(),
val requestingTeamId: UUID,
val receivingTeamId: UUID,
val status: MeetingStatus = MeetingStatus.PENDING,
val createdAt: LocalDateTime = LocalDateTime.now(),
val finishedAt: LocalDateTime? = null,
) {
) : AggregateRoot {

val pendingEndAt: LocalDateTime = createdAt.plusDays(PENDING_DAYS)

init {
Expand Down Expand Up @@ -56,6 +58,7 @@ data class Meeting(
}

companion object {

const val PENDING_DAYS = 3L

fun create(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.studentcenter.weave.domain.meeting.event

import com.studentcenter.weave.domain.common.DomainEvent
import com.studentcenter.weave.domain.meeting.entity.Meeting

data class MeetingCompletedEvent(
override val entity: Meeting,
) : DomainEvent<Meeting> {

companion object {

fun Meeting.createCompletedEvent(): MeetingCompletedEvent {
require(isCompleted()) { "미팅이 완료되지 않았습니다." }

return MeetingCompletedEvent(this)
}

}

}

0 comments on commit 9e159f2

Please sign in to comment.