Skip to content

Commit c1ea48c

Browse files
committed
ASAP-395 실물 편지 등록할 때 임시 저장 id를 지정할 수 있도록 추가
1 parent 4243bf1 commit c1ea48c

File tree

12 files changed

+97
-40
lines changed

12 files changed

+97
-40
lines changed

Application-Module/src/main/kotlin/com/asap/application/letter/port/in/AddLetterUsecase.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface AddLetterUsecase {
1717
val images: List<String>,
1818
val templateType: Int,
1919
val userId: String,
20+
val draftId: String?,
2021
) : Command()
2122
}
2223
}

Application-Module/src/main/kotlin/com/asap/application/letter/service/LetterCommandService.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class LetterCommandService(
123123
images = command.images.toMutableList(),
124124
),
125125
receiveDate = LocalDate.now(),
126+
draftId = command.draftId?.let { DomainId(it) },
126127
)
127128
independentLetterManagementPort.save(independentLetter)
128129
}

Application-Module/src/test/kotlin/com/asap/application/letter/service/LetterCommandServiceTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ class LetterCommandServiceTest :
153153
images = emptyList(),
154154
templateType = 1,
155155
userId = "user-id",
156+
draftId = null,
156157
)
157158
`when`("편지를 추가하면") {
158159
letterCommandService.addPhysicalLetter(command)

Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/letter/controller/LetterController.kt

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,7 @@ package com.asap.bootstrap.web.letter.controller
22

33
import com.asap.application.letter.port.`in`.*
44
import com.asap.bootstrap.web.letter.api.LetterApi
5-
import com.asap.bootstrap.web.letter.dto.AddPhysicalLetterRequest
6-
import com.asap.bootstrap.web.letter.dto.AddVerifiedLetterRequest
7-
import com.asap.bootstrap.web.letter.dto.AllLetterCountResponse
8-
import com.asap.bootstrap.web.letter.dto.DeleteSendLettersRequest
9-
import com.asap.bootstrap.web.letter.dto.GetIndependentLetterDetailResponse
10-
import com.asap.bootstrap.web.letter.dto.GetIndependentLetterSimpleInfo
11-
import com.asap.bootstrap.web.letter.dto.LetterVerifyRequest
12-
import com.asap.bootstrap.web.letter.dto.LetterVerifyResponse
13-
import com.asap.bootstrap.web.letter.dto.ModifyLetterRequest
14-
import com.asap.bootstrap.web.letter.dto.SendLetterDetailResponse
15-
import com.asap.bootstrap.web.letter.dto.SendLetterHistoryResponse
16-
import com.asap.bootstrap.web.letter.dto.SendLetterRequest
17-
import com.asap.bootstrap.web.letter.dto.SendLetterResponse
18-
import com.asap.bootstrap.web.letter.dto.VerifiedLetterInfoResponse
5+
import com.asap.bootstrap.web.letter.dto.*
196
import com.asap.common.page.ListResponse
207
import com.asap.common.page.SliceResponse
218
import org.springframework.web.bind.annotation.RestController
@@ -91,6 +78,7 @@ class LetterController(
9178
images = request.images,
9279
templateType = request.templateType,
9380
userId = userId,
81+
draftId = request.draftId,
9482
),
9583
)
9684
}

Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/letter/dto/AddPhysicalLetterRequest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ class AddPhysicalLetterRequest(
44
val senderName: String,
55
val content: String,
66
val images: List<String>,
7-
val templateType: Int
7+
val templateType: Int,
8+
val draftId: String?
89
) {
910
}

Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/letter/handler/DraftLetterEventHandler.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.asap.bootstrap.web.letter.handler
22

33
import com.asap.application.letter.port.`in`.RemoveDraftLetterUsecase
44
import com.asap.application.user.event.UserEvent
5+
import com.asap.domain.letter.event.IndependentLetterEvent
56
import com.asap.domain.letter.event.SendLetterEvent
67
import org.springframework.context.event.EventListener
78
import org.springframework.web.bind.annotation.RestController
@@ -22,6 +23,18 @@ class DraftLetterEventHandler(
2223
}
2324
}
2425

26+
@EventListener
27+
fun deletePhysicalDraftLetter(event: IndependentLetterEvent.IndependentLetterCreatedEvent) {
28+
event.receiveDraftId?.let {
29+
removeDraftLetterUsecase.deleteBy(
30+
RemoveDraftLetterUsecase.Command.Physical(
31+
userId = event.independentLetter.getOwnerId().value,
32+
draftId = it,
33+
),
34+
)
35+
}
36+
}
37+
2538
@EventListener
2639
fun onUserDelete(event: UserEvent.UserDeletedEvent) {
2740
removeDraftLetterUsecase.deleteBy(

Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/acceptance/letter/controller/LetterControllerTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ class LetterControllerTest : LetterAcceptanceSupporter() {
338338
content = "content",
339339
images = listOf("images"),
340340
templateType = 1,
341+
draftId = null
341342
)
342343
// when
343344
val response =

Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/letter/DraftLetterEventHandlerTest.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@ import com.asap.application.user.event.UserEvent
55
import com.asap.bootstrap.IntegrationSupporter
66
import com.asap.bootstrap.web.letter.handler.DraftLetterEventHandler
77
import org.junit.jupiter.api.Test
8-
import org.springframework.beans.factory.annotation.Autowired
98
import org.springframework.test.web.servlet.get
109

11-
class DraftLetterEventHandlerTest : IntegrationSupporter() {
12-
@Autowired
13-
private lateinit var draftLetterEventHandler: DraftLetterEventHandler
14-
15-
@Autowired
16-
private lateinit var letterMockManager: LetterMockManager
10+
class DraftLetterEventHandlerTest(
11+
val draftLetterEventHandler: DraftLetterEventHandler,
12+
val letterMockManager: LetterMockManager,
13+
) : IntegrationSupporter() {
1714

1815
@Test
1916
fun onUserDelete() {

Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/letter/LetterApiIntegrationTest.kt

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -610,28 +610,64 @@ class LetterApiIntegrationTest : IntegrationSupporter() {
610610
}
611611
}
612612

613-
@Test
614-
fun addPhysicalLetter() {
615-
// given
616-
val request =
617-
AddPhysicalLetterRequest(
618-
senderName = "senderName",
619-
content = "content",
620-
images = listOf("images"),
621-
templateType = 1,
622-
)
623-
val userId = userMockManager.settingUser()
624-
val accessToken = jwtMockManager.generateAccessToken(userId)
625-
// when
626-
val response =
613+
@Nested
614+
@DisplayName("실물 편지 추가")
615+
inner class AddPhysicalLetter {
616+
@Test
617+
fun addPhysicalLetter() {
618+
// given
619+
val request =
620+
AddPhysicalLetterRequest(
621+
senderName = "senderName",
622+
content = "content",
623+
images = listOf("images"),
624+
templateType = 1,
625+
draftId = null,
626+
)
627+
val userId = userMockManager.settingUser()
628+
val accessToken = jwtMockManager.generateAccessToken(userId)
629+
// when
630+
val response =
631+
mockMvc.post("/api/v1/letters/physical/receive") {
632+
contentType = MediaType.APPLICATION_JSON
633+
content = objectMapper.writeValueAsString(request)
634+
header("Authorization", "Bearer $accessToken")
635+
}
636+
// then
637+
response.andExpect {
638+
status { isOk() }
639+
}
640+
}
641+
642+
643+
@Test
644+
fun `addPhysicalLetter with draftId`() {
645+
// given
646+
val userId = userMockManager.settingUser()
647+
val accessToken = jwtMockManager.generateAccessToken(userId)
648+
val receiveDraftId = letterMockManager.generateMockReceiveDraftLetter(userId)
649+
650+
val request =
651+
AddPhysicalLetterRequest(
652+
senderName = "senderName",
653+
content = "content",
654+
images = listOf("images"),
655+
templateType = 1,
656+
draftId = receiveDraftId,
657+
)
658+
// when
627659
mockMvc.post("/api/v1/letters/physical/receive") {
628660
contentType = MediaType.APPLICATION_JSON
629661
content = objectMapper.writeValueAsString(request)
630662
header("Authorization", "Bearer $accessToken")
631663
}
632-
// then
633-
response.andExpect {
634-
status { isOk() }
664+
// then
665+
mockMvc
666+
.get("/api/v1/letters/drafts/physical/$receiveDraftId") {
667+
header("Authorization", "Bearer $accessToken")
668+
}.andExpect {
669+
status { isNotFound() }
670+
}
635671
}
636672
}
637673

Domain-Module/src/main/kotlin/com/asap/domain/letter/entity/IndependentLetter.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.asap.domain.letter.entity
22

33
import com.asap.domain.common.Aggregate
44
import com.asap.domain.common.DomainId
5+
import com.asap.domain.letter.event.IndependentLetterEvent
56
import com.asap.domain.letter.vo.LetterContent
67
import com.asap.domain.letter.vo.ReceiverInfo
78
import com.asap.domain.letter.vo.SenderInfo
@@ -40,6 +41,7 @@ class IndependentLetter(
4041
receiveDate: LocalDate,
4142
movedAt: LocalDateTime = LocalDateTime.now(),
4243
isOpened: Boolean = false,
44+
draftId: DomainId? = null,
4345
): IndependentLetter =
4446
IndependentLetter(
4547
id = id,
@@ -49,7 +51,9 @@ class IndependentLetter(
4951
receiveDate = receiveDate,
5052
movedAt = movedAt,
5153
isOpened = isOpened,
52-
)
54+
).also {
55+
it.registerEvent(IndependentLetterEvent.IndependentLetterCreatedEvent(it, draftId?.value))
56+
}
5357
}
5458

5559
fun isNew(): Boolean = movedAt.isAfter(LocalDateTime.now().minusDays(1)) && isOpened.not()
@@ -75,6 +79,8 @@ class IndependentLetter(
7579
this.sender.delete()
7680
}
7781

82+
fun getOwnerId(): DomainId = receiver.receiverId
83+
7884
override fun toString(): String =
7985
"IndependentLetter(content=$content, sender=$sender, receiver=$receiver, receiveDate=$receiveDate, movedAt=$movedAt, isOpened=$isOpened)"
8086
}

Domain-Module/src/main/kotlin/com/asap/domain/letter/event/LetterEvent.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.asap.domain.letter.event
22

33
import com.asap.domain.common.DomainEvent
4+
import com.asap.domain.letter.entity.IndependentLetter
45
import com.asap.domain.letter.entity.SendLetter
56

67
sealed class SendLetterEvent : DomainEvent<SendLetter> {
@@ -10,3 +11,11 @@ sealed class SendLetterEvent : DomainEvent<SendLetter> {
1011
val draftId: String?,
1112
) : SendLetterEvent()
1213
}
14+
15+
sealed class IndependentLetterEvent : DomainEvent<IndependentLetter> {
16+
17+
data class IndependentLetterCreatedEvent(
18+
val independentLetter: IndependentLetter,
19+
val receiveDraftId: String?,
20+
) : IndependentLetterEvent()
21+
}

Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/letter/adapter/ReceiveLetterManagementJpaAdapter.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.asap.persistence.jpa.letter.adapter
33
import com.asap.application.letter.exception.LetterException
44
import com.asap.application.letter.port.out.IndependentLetterManagementPort
55
import com.asap.application.letter.port.out.SpaceLetterManagementPort
6+
import com.asap.common.event.EventPublisher
67
import com.asap.common.page.Page
78
import com.asap.common.page.PageRequest
89
import com.asap.domain.common.DomainId
@@ -18,6 +19,7 @@ import java.time.LocalDateTime
1819
@Repository
1920
class ReceiveLetterManagementJpaAdapter(
2021
private val receiveLetterJpaRepository: ReceiveLetterJpaRepository,
22+
private val eventPublisher: EventPublisher,
2123
) : IndependentLetterManagementPort,
2224
SpaceLetterManagementPort {
2325
override fun save(letter: IndependentLetter) {
@@ -35,6 +37,7 @@ class ReceiveLetterManagementJpaAdapter(
3537
spaceId = null,
3638
).also {
3739
receiveLetterJpaRepository.save(it)
40+
eventPublisher.publishAll(letter.pullEvents())
3841
}
3942
}
4043

0 commit comments

Comments
 (0)