Skip to content
This repository was archived by the owner on Jul 7, 2025. It is now read-only.

Commit 7f895d3

Browse files
authored
Merge pull request #130 from ASAP-Lettering/ASAP-451
ASAP-451 익명 편지 전송 api 추가
2 parents cf5837f + 5864874 commit 7f895d3

File tree

18 files changed

+227
-66
lines changed

18 files changed

+227
-66
lines changed

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,18 @@ package com.asap.application.letter.port.`in`
33
import java.time.LocalDate
44

55
interface GetVerifiedLetterUsecase {
6-
7-
fun get(
8-
query: Query
9-
): Response
6+
fun get(query: Query): Response
107

118
data class Query(
129
val letterId: String,
13-
val userId: String
10+
val userId: String,
1411
)
1512

1613
data class Response(
17-
val senderName: String,
14+
val senderName: String?,
1815
val content: String,
1916
val sendDate: LocalDate,
2017
val templateType: Int,
21-
val images: List<String>
18+
val images: List<String>,
2219
)
23-
24-
25-
}
20+
}
Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
package com.asap.application.letter.port.`in`
22

33
interface SendLetterUsecase {
4+
fun send(command: Command): Response
45

5-
fun send(
6-
command: Command
7-
): Response
6+
fun sendAnonymous(command: AnonymousCommand): Response
87

98
data class Command(
109
val receiverName: String,
1110
val content: String,
1211
val images: List<String>,
1312
val templateType: Int,
1413
val draftId: String?,
15-
val userId: String
14+
val userId: String,
15+
)
16+
17+
data class AnonymousCommand(
18+
val receiverName: String,
19+
val content: String,
20+
val images: List<String>,
21+
val templateType: Int,
1622
)
1723

1824
data class Response(
19-
val letterCode: String
25+
val letterCode: String,
2026
)
21-
}
27+
}

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

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,27 @@ class LetterCommandService(
5656
return SendLetterUsecase.Response(letterCode = sendLetter.letterCode!!)
5757
}
5858

59+
override fun sendAnonymous(command: SendLetterUsecase.AnonymousCommand): SendLetterUsecase.Response {
60+
val sendLetter =
61+
SendLetter.createAnonymous(
62+
receiverName = command.receiverName,
63+
content =
64+
LetterContent(
65+
content = command.content,
66+
templateType = command.templateType,
67+
images = command.images.toMutableList(),
68+
),
69+
letterCode =
70+
letterCodeGenerator.generateCode(
71+
content = command.content,
72+
),
73+
)
74+
75+
sendLetterManagementPort.save(sendLetter)
76+
77+
return SendLetterUsecase.Response(letterCode = sendLetter.letterCode!!)
78+
}
79+
5980
override fun verify(command: VerifyLetterAccessibleUsecase.Command): VerifyLetterAccessibleUsecase.Response {
6081
if (sendLetterManagementPort.verifiedLetter(DomainId(command.userId), command.letterCode)) {
6182
val sendLetter =
@@ -67,15 +88,15 @@ class LetterCommandService(
6788
}
6889

6990
val sendLetter = sendLetterManagementPort.getLetterByCodeNotNull(command.letterCode)
70-
sendLetter
71-
.isSameReceiver {
72-
userManagementPort.getUserNotNull(DomainId(command.userId))
73-
}.takeIf { it }
74-
?.let {
75-
sendLetter.readLetter(DomainId(command.userId))
76-
sendLetterManagementPort.save(sendLetter)
77-
return VerifyLetterAccessibleUsecase.Response(letterId = sendLetter.id.value)
78-
} ?: throw LetterException.InvalidLetterAccessException()
91+
val receiver = userManagementPort.getUserNotNull(DomainId(command.userId))
92+
93+
if (sendLetter.isSameReceiver(receiver)) {
94+
sendLetter.readLetter(DomainId(command.userId))
95+
sendLetterManagementPort.save(sendLetter)
96+
return VerifyLetterAccessibleUsecase.Response(letterId = sendLetter.id.value)
97+
}
98+
99+
throw LetterException.InvalidLetterAccessException()
79100
}
80101

81102
override fun addVerifiedLetter(command: AddLetterUsecase.Command.VerifyLetter) {
@@ -89,7 +110,10 @@ class LetterCommandService(
89110
sender =
90111
SenderInfo(
91112
senderId = sendLetter.senderId,
92-
senderName = userManagementPort.getUserNotNull(sendLetter.senderId).username,
113+
senderName =
114+
sendLetter.senderId
115+
?.let { userManagementPort.getUserNotNull(it).username }
116+
.orEmpty(),
93117
),
94118
receiver =
95119
ReceiverInfo(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ class LetterQueryService(
3232
receiverId = DomainId(query.userId),
3333
letterId = DomainId(query.letterId),
3434
).also {
35-
val sender = userManagementPort.getUserNotNull(it.senderId)
35+
val sender = it.senderId?.let { userManagementPort.getUserNotNull(it) }
3636
return GetVerifiedLetterUsecase.Response(
37-
senderName = sender.username,
37+
senderName = sender?.username,
3838
content = it.content.content,
3939
sendDate = it.createdDate,
4040
templateType = it.content.templateType,

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,26 @@ class LetterCommandServiceTest :
5757
}
5858
}
5959

60+
given("익명 편지 전송 요청이 들어올 때") {
61+
val command =
62+
SendLetterUsecase.AnonymousCommand(
63+
receiverName = "receiver-name",
64+
content = "content",
65+
images = emptyList(),
66+
templateType = 1,
67+
)
68+
`when`("익명 편지 전송 요청을 처리하면") {
69+
val response = letterCommandService.sendAnonymous(command)
70+
then("편지 코드가 생성되고, 편지가 저장되어야 한다") {
71+
response.letterCode shouldNotBeNull {
72+
this.isNotBlank()
73+
this.isNotEmpty()
74+
}
75+
verify { mockSendLetterManagementPort.save(any()) }
76+
}
77+
}
78+
}
79+
6080
given("편지 검증 시에") {
6181
val letterCode = "letter-code"
6282
val mockUser = UserFixture.createUser(username = "receiver-name")

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class LetterQueryServiceTest :
4242
userId = user.id.value,
4343
)
4444
val mockSendLetter = LetterFixture.generateSendLetter(user.id)
45-
val mockSender = UserFixture.createUser(mockSendLetter.senderId, "sender-name")
45+
val mockSender = UserFixture.createUser(mockSendLetter.senderId!!, "sender-name")
4646
every {
4747
mockSendLetterManagementPort.getReadLetterNotNull(
4848
receiverId = DomainId(query.userId),
@@ -96,9 +96,10 @@ class LetterQueryServiceTest :
9696
letterId = "letter-id",
9797
userId = "user-id",
9898
)
99-
val space = SpaceFixture.createSpace(
100-
userId = DomainId(query.userId),
101-
)
99+
val space =
100+
SpaceFixture.createSpace(
101+
userId = DomainId(query.userId),
102+
)
102103
val spaceLetter = LetterFixture.generateSpaceLetter(receiverId = DomainId(query.userId), spaceId = space.id)
103104
val prevSpaceLetter =
104105
LetterFixture.generateSpaceLetter(receiverId = DomainId(query.userId), spaceId = space.id)

Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/letter/api/LetterApi.kt

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

33
import com.asap.bootstrap.common.exception.ExceptionResponse
44
import com.asap.bootstrap.common.security.annotation.AccessUser
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 io.swagger.v3.oas.annotations.Operation
@@ -317,4 +304,28 @@ interface LetterApi {
317304
@RequestBody request: DeleteSendLettersRequest,
318305
@AccessUser userId: String,
319306
)
307+
308+
@Operation(summary = "비회원 편지 쓰기")
309+
@PostMapping("/anonymous/send")
310+
@ApiResponses(
311+
value = [
312+
ApiResponse(
313+
responseCode = "200",
314+
description = "비회원 편지 전송 성공",
315+
content = [
316+
Content(
317+
mediaType = "application/json",
318+
schema = Schema(implementation = SendLetterResponse::class),
319+
),
320+
],
321+
),
322+
ApiResponse(
323+
responseCode = "4XX",
324+
description = "비회원 편지 전송 실패",
325+
),
326+
],
327+
)
328+
fun sendAnonymousLetter(
329+
@RequestBody request: AnonymousSendLetterRequest,
330+
): SendLetterResponse
320331
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,4 +265,19 @@ class LetterController(
265265
),
266266
)
267267
}
268+
269+
override fun sendAnonymousLetter(request: AnonymousSendLetterRequest): SendLetterResponse {
270+
val response =
271+
sendLetterUsecase.sendAnonymous(
272+
SendLetterUsecase.AnonymousCommand(
273+
receiverName = request.receiverName,
274+
content = request.content,
275+
images = request.images,
276+
templateType = request.templateType,
277+
),
278+
)
279+
return SendLetterResponse(
280+
letterCode = response.letterCode,
281+
)
282+
}
268283
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.asap.bootstrap.web.letter.dto
2+
3+
data class AnonymousSendLetterRequest(
4+
val receiverName: String,
5+
val content: String,
6+
val images: List<String>,
7+
val templateType: Int,
8+
)

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ package com.asap.bootstrap.web.letter.dto
33
import java.time.LocalDate
44

55
data class VerifiedLetterInfoResponse(
6-
val senderName: String,
6+
val senderName: String?,
77
val content: String,
88
val date: LocalDate,
99
val templateType: Int,
10-
val images: List<String>
11-
) {
12-
}
10+
val images: List<String>,
11+
)

0 commit comments

Comments
 (0)