-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
870603e
commit 326de14
Showing
14 changed files
with
332 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,5 @@ include::news-api.adoc[] | |
include::crawler-api.adoc[] | ||
|
||
include::auth-api.adoc[] | ||
|
||
include::translation-api.adoc[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[[translation-api]] | ||
== 번역 | ||
|
||
[[translation-translate]] | ||
=== 뉴스 번역 요청 | ||
|
||
*요청* | ||
include::{snippets}/translation/translate/http-request.adoc[] | ||
include::{snippets}/translation/translate/path-parameters.adoc[] | ||
include::{snippets}/translation/translate/request-fields.adoc[] | ||
|
||
*응답* | ||
include::{snippets}/translation/translate/http-response.adoc[] | ||
include::{snippets}/translation/translate/response-fields.adoc[] | ||
|
||
[[translation-find-by-id]] | ||
=== 번역 진행 상황 단건 조회 | ||
|
||
*요청* | ||
include::{snippets}/translation/find-by-id/http-request.adoc[] | ||
include::{snippets}/translation/find-by-id/path-parameters.adoc[] | ||
|
||
*응답* | ||
include::{snippets}/translation/find-by-id/http-response.adoc[] | ||
include::{snippets}/translation/find-by-id/response-fields.adoc[] |
45 changes: 45 additions & 0 deletions
45
src/main/kotlin/kr/galaxyhub/sc/api/v1/translation/TranslationControllerV1.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package kr.galaxyhub.sc.api.v1.translation | ||
|
||
import java.util.UUID | ||
import kr.galaxyhub.sc.api.common.ApiResponse | ||
import kr.galaxyhub.sc.api.v1.translation.dto.TranslationRequest | ||
import kr.galaxyhub.sc.common.support.toUri | ||
import kr.galaxyhub.sc.translation.application.TranslationCommandService | ||
import kr.galaxyhub.sc.translation.application.TranslationQueryService | ||
import kr.galaxyhub.sc.translation.application.dto.TranslationCommand | ||
import kr.galaxyhub.sc.translation.application.dto.TranslationResponse | ||
import org.springframework.http.ResponseEntity | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.PathVariable | ||
import org.springframework.web.bind.annotation.PostMapping | ||
import org.springframework.web.bind.annotation.RequestBody | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
|
||
@RestController | ||
@RequestMapping("/api/v1/translation") | ||
class TranslationControllerV1( | ||
private val translationCommandService: TranslationCommandService, | ||
private val translationQueryService: TranslationQueryService, | ||
) { | ||
|
||
@PostMapping("/{newsId}") | ||
fun translate( | ||
@PathVariable newsId: UUID, | ||
@RequestBody request: TranslationRequest, | ||
): ResponseEntity<ApiResponse<UUID>> { | ||
val command = TranslationCommand(newsId, request.destinationLanguage) | ||
val translateProgressionId = translationCommandService.translate(command) | ||
return ResponseEntity.created("/api/v1/translation/${translateProgressionId}".toUri()) | ||
.body(ApiResponse.success(translateProgressionId)) | ||
} | ||
|
||
@GetMapping("/{translateProgressionId}") | ||
fun findById( | ||
@PathVariable translateProgressionId: UUID, | ||
): ResponseEntity<ApiResponse<TranslationResponse>> { | ||
val response = translationQueryService.findById(translateProgressionId) | ||
return ResponseEntity.ok() | ||
.body(ApiResponse.success(response)) | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/kotlin/kr/galaxyhub/sc/api/v1/translation/dto/TranslationRequest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package kr.galaxyhub.sc.api.v1.translation.dto | ||
|
||
import kr.galaxyhub.sc.news.domain.Language | ||
|
||
data class TranslationRequest( | ||
val destinationLanguage: Language | ||
) |
23 changes: 23 additions & 0 deletions
23
src/main/kotlin/kr/galaxyhub/sc/translation/application/TranslationCommandService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package kr.galaxyhub.sc.translation.application | ||
|
||
import java.util.UUID | ||
import kr.galaxyhub.sc.translation.application.dto.TranslationCommand | ||
import kr.galaxyhub.sc.translation.domain.TranslateProgression | ||
import kr.galaxyhub.sc.translation.domain.TranslationProgressionRepository | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
@Service | ||
@Transactional | ||
class TranslationCommandService( | ||
private val translationProgressionRepository: TranslationProgressionRepository | ||
) { | ||
|
||
fun translate(command: TranslationCommand): UUID { | ||
val newsId = command.newsId | ||
val destinationLanguage = command.destinationLanguage | ||
val translateProgression = TranslateProgression(newsId, destinationLanguage) | ||
translationProgressionRepository.save(translateProgression) | ||
return translateProgression.id | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/kotlin/kr/galaxyhub/sc/translation/application/TranslationQueryService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package kr.galaxyhub.sc.translation.application | ||
|
||
import java.util.UUID | ||
import kr.galaxyhub.sc.translation.application.dto.TranslationResponse | ||
import kr.galaxyhub.sc.translation.domain.TranslationProgressionRepository | ||
import kr.galaxyhub.sc.translation.domain.getOrThrow | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
@Service | ||
@Transactional(readOnly = true) | ||
class TranslationQueryService( | ||
private val translationProgressionRepository: TranslationProgressionRepository, | ||
) { | ||
|
||
fun findById(translateProgressionId: UUID): TranslationResponse { | ||
return translationProgressionRepository.getOrThrow(translateProgressionId) | ||
.let { TranslationResponse.from(it) } | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/kotlin/kr/galaxyhub/sc/translation/application/dto/TranslationCommand.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package kr.galaxyhub.sc.translation.application.dto | ||
|
||
import java.util.UUID | ||
import kr.galaxyhub.sc.news.domain.Language | ||
|
||
data class TranslationCommand( | ||
val newsId: UUID, | ||
val destinationLanguage: Language | ||
) |
25 changes: 25 additions & 0 deletions
25
src/main/kotlin/kr/galaxyhub/sc/translation/application/dto/TranslationResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package kr.galaxyhub.sc.translation.application.dto | ||
|
||
import java.util.UUID | ||
import kr.galaxyhub.sc.translation.domain.TranslateProgression | ||
import kr.galaxyhub.sc.translation.domain.TranslationStatus | ||
|
||
data class TranslationResponse( | ||
val translateProgressionId: UUID, | ||
val targetNewsId: UUID, | ||
val translationStatus: TranslationStatus, | ||
val message: String? = null, | ||
) { | ||
|
||
companion object { | ||
|
||
fun from(translationProgression: TranslateProgression): TranslationResponse { | ||
return TranslationResponse( | ||
translateProgressionId = translationProgression.id, | ||
targetNewsId = translationProgression.newsId, | ||
translationStatus = translationProgression.translationStatus, | ||
message = translationProgression.message | ||
) | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/main/kotlin/kr/galaxyhub/sc/translation/domain/TranslateProgression.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package kr.galaxyhub.sc.translation.domain | ||
|
||
import jakarta.persistence.Column | ||
import jakarta.persistence.Entity | ||
import jakarta.persistence.EnumType | ||
import jakarta.persistence.Enumerated | ||
import jakarta.persistence.Table | ||
import jakarta.persistence.UniqueConstraint | ||
import java.util.UUID | ||
import kr.galaxyhub.sc.common.domain.PrimaryKeyEntity | ||
import kr.galaxyhub.sc.news.domain.Language | ||
|
||
@Entity | ||
@Table( | ||
uniqueConstraints = [ | ||
UniqueConstraint( | ||
name = "UNIQUE_NEWS_ID_AND_DESTINATION_LANGUAGE", | ||
columnNames = [ | ||
"news_id", | ||
"destination_language" | ||
] | ||
) | ||
] | ||
) | ||
class TranslateProgression( | ||
newsId: UUID, | ||
destinationLanguage: Language, | ||
) : PrimaryKeyEntity() { | ||
|
||
@Column(name = "news_id", nullable = false, columnDefinition = "uuid") | ||
val newsId: UUID = newsId | ||
|
||
@Enumerated(EnumType.STRING) | ||
@Column(name = "destination_language", nullable = false, columnDefinition = "varchar") | ||
val destinationLanguage: Language = destinationLanguage | ||
|
||
@Enumerated(EnumType.STRING) | ||
@Column(name = "translation_status", nullable = false, columnDefinition = "varchar") | ||
var translationStatus: TranslationStatus = TranslationStatus.PROGRESS | ||
protected set | ||
|
||
@Column(name = "message") | ||
var message: String? = null | ||
protected set | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/kotlin/kr/galaxyhub/sc/translation/domain/TranslationProgressionRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package kr.galaxyhub.sc.translation.domain | ||
|
||
import java.util.UUID | ||
import kr.galaxyhub.sc.common.exception.NotFoundException | ||
import org.springframework.data.repository.Repository | ||
|
||
fun TranslationProgressionRepository.getOrThrow(translateProgressionId: UUID) = findById(translateProgressionId) | ||
?: throw NotFoundException("식별자에 대한 번역 진행 상황을 찾을 수 없습니다. id=$translateProgressionId") | ||
|
||
interface TranslationProgressionRepository : Repository<TranslateProgression, UUID> { | ||
|
||
fun save(translateProgression: TranslateProgression): TranslateProgression | ||
|
||
fun findById(translateProgressionId: UUID): TranslateProgression? | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/kotlin/kr/galaxyhub/sc/translation/domain/TranslationStatus.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package kr.galaxyhub.sc.translation.domain | ||
|
||
enum class TranslationStatus { | ||
PROGRESS, | ||
COMPLETE, | ||
ERROR, | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/resources/db/migration/V3__add_translate_progression.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CREATE TABLE translate_progression | ||
( | ||
id BINARY(36) NOT NULL, | ||
news_id BINARY(36) NOT NULL, | ||
destination_language VARCHAR(255) NOT NULL, | ||
translation_status VARCHAR(255) NOT NULL, | ||
message VARCHAR(255) NULL, | ||
CONSTRAINT pk_translate_progression PRIMARY KEY (id) | ||
); | ||
|
||
ALTER TABLE translate_progression | ||
ADD CONSTRAINT UNIQUE_NEWS_ID_AND_DESTINATION_LANGUAGE UNIQUE (news_id, destination_language); |
95 changes: 95 additions & 0 deletions
95
src/test/kotlin/kr/galaxyhub/sc/api/v1/translation/TranslationControllerV1Test.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package kr.galaxyhub.sc.api.v1.translation | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import com.ninjasquad.springmockk.MockkBean | ||
import io.kotest.core.spec.style.DescribeSpec | ||
import io.mockk.every | ||
import java.util.UUID | ||
import kr.galaxyhub.sc.api.support.ENUM | ||
import kr.galaxyhub.sc.api.support.STRING | ||
import kr.galaxyhub.sc.api.support.andDocument | ||
import kr.galaxyhub.sc.api.support.docGet | ||
import kr.galaxyhub.sc.api.support.docPost | ||
import kr.galaxyhub.sc.api.support.pathMeans | ||
import kr.galaxyhub.sc.api.support.type | ||
import kr.galaxyhub.sc.api.v1.translation.dto.TranslationRequest | ||
import kr.galaxyhub.sc.news.domain.Language | ||
import kr.galaxyhub.sc.translation.application.TranslationCommandService | ||
import kr.galaxyhub.sc.translation.application.TranslationQueryService | ||
import kr.galaxyhub.sc.translation.application.dto.TranslationResponse | ||
import kr.galaxyhub.sc.translation.domain.TranslationStatus | ||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs | ||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest | ||
import org.springframework.http.MediaType | ||
import org.springframework.test.web.servlet.MockMvc | ||
|
||
@WebMvcTest(TranslationControllerV1::class) | ||
@AutoConfigureRestDocs | ||
class TranslationControllerV1Test( | ||
private val mockMvc: MockMvc, | ||
private val objectMapper: ObjectMapper, | ||
@MockkBean | ||
private val translationCommandService: TranslationCommandService, | ||
@MockkBean | ||
private val translationQueryService: TranslationQueryService, | ||
) : DescribeSpec({ | ||
|
||
describe("POST /api/v1/translation/{newsId}") { | ||
context("유효한 요청이 전달되면") { | ||
val request = TranslationRequest(Language.KOREAN) | ||
val newsId = UUID.randomUUID() | ||
every { translationCommandService.translate(any()) } returns UUID.randomUUID() | ||
|
||
it("201 응답과 번역 진행 상황의 식별자가 반환된다.") { | ||
mockMvc.docPost("/api/v1/translation/{newsId}", newsId) { | ||
contentType = MediaType.APPLICATION_JSON | ||
content = objectMapper.writeValueAsString(request) | ||
}.andExpect { | ||
status { isCreated() } | ||
}.andDocument("translation/translate") { | ||
pathParameters( | ||
"newsId" pathMeans "번역할 뉴스의 식별자" | ||
) | ||
requestBody( | ||
"destinationLanguage" type ENUM(Language::class) means "번역 도착 언어" | ||
) | ||
responseBody( | ||
"data" type STRING means "번역 진행 상황의 식별자" | ||
) | ||
} | ||
} | ||
} | ||
} | ||
|
||
describe("GET /api/v1/translation/{translateProgressionId}") { | ||
context("유효한 요청이 전달되면") { | ||
val translateProgressionId = UUID.randomUUID() | ||
val response = translationResponse(translateProgressionId) | ||
every { translationQueryService.findById(any()) } returns response | ||
|
||
it("200 응답과 번역 진행 상황의 정보가 조회된다.") { | ||
mockMvc.docGet("/api/v1/translation/{translateProgressionId}", translateProgressionId) { | ||
contentType = MediaType.APPLICATION_JSON | ||
}.andExpect { | ||
status { isOk() } | ||
}.andDocument("translation/find-by-id") { | ||
pathParameters( | ||
"translateProgressionId" pathMeans "번역 진행 상황의 식별자" | ||
) | ||
responseBody( | ||
"data.translateProgressionId" type STRING means "번역 진행 상황의 식별자", | ||
"data.targetNewsId" type STRING means "번역할 뉴스의 식별자", | ||
"data.translationStatus" type ENUM(TranslationStatus::class) means "번역 상태", | ||
"data.message" type STRING means "번역 진행 상황의 추가적 메시지" isOptional true | ||
) | ||
} | ||
} | ||
} | ||
} | ||
}) | ||
|
||
private fun translationResponse(translateProgressionId: UUID) = TranslationResponse( | ||
translateProgressionId = translateProgressionId, | ||
targetNewsId = UUID.randomUUID(), | ||
translationStatus = TranslationStatus.PROGRESS, | ||
) |
3 changes: 2 additions & 1 deletion
3
src/test/resources/org/springframework/restdocs/templates/response-fields.snippet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,13 @@ | ||
|
||
==== Response Fields | ||
|=== | ||
|필드명|타입|설명|null여부 | ||
|필드명|타입|설명|null여부|형식 | ||
|
||
{{#fields}} | ||
|{{#tableCellContent}}`+{{path}}+`{{/tableCellContent}} | ||
|{{#tableCellContent}}`+{{type}}+`{{/tableCellContent}} | ||
|{{#tableCellContent}}{{description}}{{/tableCellContent}} | ||
|{{#tableCellContent}}{{#optional}}true{{/optional}}{{^optional}}{{/optional}}{{/tableCellContent}} | ||
|{{#tableCellContent}}{{#format}}{{format}}{{/format}}{{^format}}{{/format}}{{/tableCellContent}} | ||
{{/fields}} | ||
|=== |