diff --git a/Api-Module/.jqwik-database b/Api-Module/.jqwik-database new file mode 100644 index 00000000..711006c3 Binary files /dev/null and b/Api-Module/.jqwik-database differ diff --git a/Api-Module/src/docs/asciidoc/Experience.adoc b/Api-Module/src/docs/asciidoc/Experience.adoc new file mode 100644 index 00000000..c8301b4f --- /dev/null +++ b/Api-Module/src/docs/asciidoc/Experience.adoc @@ -0,0 +1,17 @@ +[[Experience-API]] +== Experience-API + +[[CreateExperienceTest]] +=== 경험 등록 API + +operation::ExperienceControllerTest/createExperienceTest/[snippets='http-request,request-headers,request-body,request-fields,http-response,response-body,response-fields'] + +[[CreateOverTitleLengthTest]] +=== 제목 글자 수 제한(50자) 예외 + +operation::ExperienceControllerTest/createOverTitleLengthTest/[snippets='http-request,request-headers,request-body,request-fields,http-response,response-body,response-fields'] + +[[CreateOverStrongPointCountTest]] +=== 역량 키워드 제한(5개) 초과 예외 + +operation::ExperienceControllerTest/createOverStrongPointCountTest/[snippets='http-request,request-headers,request-body,http-response,response-body,response-fields'] diff --git a/Api-Module/src/docs/asciidoc/index.adoc b/Api-Module/src/docs/asciidoc/index.adoc index 7932aa62..2baf3b1d 100644 --- a/Api-Module/src/docs/asciidoc/index.adoc +++ b/Api-Module/src/docs/asciidoc/index.adoc @@ -11,5 +11,4 @@ include::User.adoc[] include::StrongPoint.adoc[] include::Tag.adoc[] include::JobDescription.adoc[] - - +include::Experience.adoc[] diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/.gitkeep b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/dto/CreateExperience.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/dto/CreateExperience.kt new file mode 100644 index 00000000..1d30009d --- /dev/null +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/dto/CreateExperience.kt @@ -0,0 +1,23 @@ +package com.bamyanggang.apimodule.domain.experience.application.dto + +import java.time.LocalDateTime +import java.util.* + +class CreateExperience { + data class Request( + val title: String, + val parentTagId: UUID, + val childTagId: UUID, + val strongPointIds: List, + val contents: List, + val startedAt: LocalDateTime, + val endedAt: LocalDateTime, + ) + + data class Response(val id: UUID) + + data class ExperienceContentRequest( + val question: String, + val answer: String, + ) +} diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/service/ExperienceCreateService.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/service/ExperienceCreateService.kt new file mode 100644 index 00000000..223398a9 --- /dev/null +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/service/ExperienceCreateService.kt @@ -0,0 +1,36 @@ +package com.bamyanggang.apimodule.domain.experience.application.service + +import com.bamyanggang.apimodule.common.getAuthenticationPrincipal +import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience +import com.bamyanggang.domainmodule.domain.experience.service.ExperienceAppender +import com.bamyanggang.domainmodule.domain.experience.service.ExperienceContentAppender +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class ExperienceCreateService( + val experienceAppender: ExperienceAppender, + val experienceContentAppender: ExperienceContentAppender +) { + @Transactional + fun createExperience(request: CreateExperience.Request):CreateExperience.Response { + val currentUserId = getAuthenticationPrincipal() + + return request.contents.map { + experienceContentAppender.appendExperienceContent(it.question, it.answer).id + }.let { + experienceAppender.appendExperience( + title = request.title, + userId = currentUserId, + parentTagId = request.parentTagId, + childTagId = request.childTagId, + strongPointIds = request.strongPointIds, + contentIds = it, + startedAt = request.startedAt, + endedAt = request.endedAt + ) + }.let { + CreateExperience.Response(it.id) + } + } +} diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/.gitkeep b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceApi.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceApi.kt new file mode 100644 index 00000000..503900d0 --- /dev/null +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceApi.kt @@ -0,0 +1,5 @@ +package com.bamyanggang.apimodule.domain.experience.presentation + +object ExperienceApi { + const val BASE_URL = "/api/experiences" +} diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceController.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceController.kt new file mode 100644 index 00000000..2410073a --- /dev/null +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceController.kt @@ -0,0 +1,17 @@ +package com.bamyanggang.apimodule.domain.experience.presentation + +import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience +import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceCreateService +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RestController + +@RestController +class ExperienceController( + private val experienceCreateService: ExperienceCreateService +) { + @PostMapping(ExperienceApi.BASE_URL) + fun createExperience(@RequestBody request: CreateExperience.Request): CreateExperience.Response { + return experienceCreateService.createExperience(request) + } +} diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/service/JobDescriptionCreateService.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/service/JobDescriptionCreateService.kt index ba52ee0f..a156fb98 100644 --- a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/service/JobDescriptionCreateService.kt +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/jobDescription/application/service/JobDescriptionCreateService.kt @@ -25,5 +25,4 @@ class JobDescriptionCreateService( ) }.also { return CreateJobDescription.Response(jobDescriptionId = it.id) } } - } diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/strongpoint/application/service/StrongPointCreateService.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/strongpoint/application/service/StrongPointCreateService.kt index cd877947..f78e9ead 100644 --- a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/strongpoint/application/service/StrongPointCreateService.kt +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/strongpoint/application/service/StrongPointCreateService.kt @@ -7,20 +7,22 @@ import com.bamyanggang.domainmodule.domain.strongpoint.exception.StrongPointExce import com.bamyanggang.domainmodule.domain.strongpoint.service.StrongPointAppender import com.bamyanggang.domainmodule.domain.strongpoint.service.StrongPointReader import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class StrongPointCreateService( val strongPointAppender: StrongPointAppender, val strongPointReader: StrongPointReader, ) { + @Transactional fun createStrongPoint(request: CreateStrongPoint.Request): CreateStrongPoint.Response { return getAuthenticationPrincipal() .also { val userStrongPoints = strongPointReader.readAllByUserId(it) validateDuplicatedStrongPointName(userStrongPoints, request.name) }.let { - val newStrongPointId = strongPointAppender.appendStrongPoint(request.name, it) - CreateStrongPoint.Response(newStrongPointId) + val newStrongPoint = strongPointAppender.appendStrongPoint(request.name, it) + CreateStrongPoint.Response(newStrongPoint.id) } } diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/strongpoint/presentation/StrongPointController.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/strongpoint/presentation/StrongPointController.kt index 43235979..3fec6e3a 100644 --- a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/strongpoint/presentation/StrongPointController.kt +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/strongpoint/presentation/StrongPointController.kt @@ -11,7 +11,7 @@ class StrongPointController( private val strongPointCreateService: StrongPointCreateService, ) { @PostMapping(StrongPointApi.BASE_URL) - fun createStrongPoint(@RequestBody request: CreateStrongPoint.Request): CreateStrongPoint.Response { + fun createStrongPoint(@RequestBody request: CreateStrongPoint.Request): CreateStrongPoint.Response{ return strongPointCreateService.createStrongPoint(request) } -} \ No newline at end of file +} diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/application/service/TagCreateService.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/application/service/TagCreateService.kt index 2d52f369..1a112aac 100644 --- a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/application/service/TagCreateService.kt +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/application/service/TagCreateService.kt @@ -7,6 +7,7 @@ import com.bamyanggang.domainmodule.domain.tag.exception.TagException import com.bamyanggang.domainmodule.domain.tag.service.TagAppender import com.bamyanggang.domainmodule.domain.tag.service.TagReader import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional import java.util.* @Service @@ -14,6 +15,7 @@ class TagCreateService( private val tagAppender: TagAppender, private val tagReader: TagReader, ) { + @Transactional fun createChildTag(request: CreateTag.Request, parentTagId: UUID): CreateTag.Response { return getAuthenticationPrincipal() .also { @@ -21,20 +23,21 @@ class TagCreateService( validateTagCountLimit(userChildTags.size) validateDuplicatedName(userChildTags, request.name) }.let { - val newChildTagId = tagAppender.appendChildTag(request.name, parentTagId, it) - CreateTag.Response(newChildTagId) - } + val newTag = tagAppender.appendChildTag(request.name, parentTagId, it) + CreateTag.Response(newTag.id) + } } - fun createParentTag(request: CreateTag.Request): CreateTag.Response { + @Transactional + fun createParentTag(request: CreateTag.Request) : CreateTag.Response { return getAuthenticationPrincipal() .also { val userParentTags = tagReader.readAllParentTagsByUserId(it) validateTagCountLimit(userParentTags.size) validateDuplicatedName(userParentTags, request.name) }.let { - val newParentTagId = tagAppender.appendParentTag(request.name, it) - CreateTag.Response(newParentTagId) + val newTag = tagAppender.appendParentTag(request.name, it) + CreateTag.Response(newTag.id) } } diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/application/service/TagDeleteService.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/application/service/TagDeleteService.kt index 1e7c7ab2..aa7839c8 100644 --- a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/application/service/TagDeleteService.kt +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/application/service/TagDeleteService.kt @@ -2,12 +2,14 @@ package com.bamyanggang.apimodule.domain.tag.application.service import com.bamyanggang.domainmodule.domain.tag.service.TagRemover import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional import java.util.* @Service class TagDeleteService( private val tagRemover: TagRemover ) { + @Transactional fun deleteTag(tagId: UUID) { tagRemover.removeTag(tagId) } diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/presentation/TagController.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/presentation/TagController.kt index 05ff175a..ebfda540 100644 --- a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/presentation/TagController.kt +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/tag/presentation/TagController.kt @@ -11,15 +11,17 @@ class TagController( private val tagCreateService: TagCreateService, private val tagDeleteService: TagDeleteService ) { - @PostMapping(TagApi.BASE_URL, TagApi.TAG_PATH_VARIABLE_URL) - fun createTag( - @PathVariable("tagId", required = false) parentTagId: UUID?, + @PostMapping(TagApi.BASE_URL) + fun createParentTag(@RequestBody request: CreateTag.Request): CreateTag.Response { + return tagCreateService.createParentTag(request) + } + + @PostMapping(TagApi.TAG_PATH_VARIABLE_URL) + fun createChildTag( @RequestBody request: CreateTag.Request, + @PathVariable("tagId") parentTagId : UUID ): CreateTag.Response { - return when { - parentTagId == null -> tagCreateService.createParentTag(request) - else -> tagCreateService.createChildTag(request, parentTagId) - } + return tagCreateService.createChildTag(request, parentTagId) } @DeleteMapping(TagApi.TAG_PATH_VARIABLE_URL) diff --git a/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceControllerTest.kt b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceControllerTest.kt new file mode 100644 index 00000000..7c54deeb --- /dev/null +++ b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/presentation/ExperienceControllerTest.kt @@ -0,0 +1,194 @@ +package com.bamyanggang.apimodule.domain.experience.presentation + +import com.bamyanggang.apimodule.BaseRestDocsTest +import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience +import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceCreateService +import com.bamyanggang.commonmodule.exception.ExceptionHandler +import com.bamyanggang.commonmodule.fixture.generateFixture +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.mockito.BDDMockito.given +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.context.annotation.Import +import org.springframework.http.HttpStatus +import org.springframework.http.MediaType +import org.springframework.restdocs.headers.HeaderDocumentation.headerWithName +import org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders +import org.springframework.restdocs.payload.PayloadDocumentation.* +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status +import java.time.LocalDateTime +import java.util.* + +@WebMvcTest(ExperienceController::class) +@Import(ExceptionHandler::class) +class ExperienceControllerTest : BaseRestDocsTest() { + + @MockBean + private lateinit var experienceCreateService: ExperienceCreateService + + @Test + @DisplayName("경험을 등록한다.") + fun createExperienceTest() { + //given + val content1 = CreateExperience.ExperienceContentRequest("질문1", "답변1") + val content2 = CreateExperience.ExperienceContentRequest("질문2", "답변2") + + val contentRequest = arrayListOf(content1, content2) + + val createExperienceRequest : CreateExperience.Request = generateFixture { + it.set("title", "제목") + it.set("contents", contentRequest) + it.set("strongPointIds", generateFixture>()) + it.set("parentTagId", generateFixture()) + it.set("childTagId", generateFixture()) + it.set("startedAt", generateFixture()) + it.set("endedAt", generateFixture()) + } + + val createExperienceResponse : CreateExperience.Response = generateFixture() + + given(experienceCreateService.createExperience(createExperienceRequest)).willReturn(createExperienceResponse) + + val request = RestDocumentationRequestBuilders.post(ExperienceApi.BASE_URL) + .header("Authorization", "Bearer Access Token") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content(objectMapper.writeValueAsString(createExperienceRequest)) + + //when + val result = mockMvc.perform(request) + + //then + result.andExpect(status().isOk).andDo( + resultHandler.document( + requestHeaders( + headerWithName("Authorization").description("엑세스 토큰") + ), + requestFields( + fieldWithPath("title").description("경험 제목"), + fieldWithPath("contents").description("경험 내용"), + fieldWithPath("contents[].question").description("경험 내용 질문"), + fieldWithPath("contents[].answer").description("경험 내용 답변"), + fieldWithPath("strongPointIds").description("관련된 역량 키워드"), + fieldWithPath("parentTagId").description("속한 상위 태그"), + fieldWithPath("childTagId").description("속한 하위 태그"), + fieldWithPath("startedAt").description("경험 시작 날짜"), + fieldWithPath("endedAt").description("경험 종료 날짜"), + ), + responseFields( + fieldWithPath("id").description("경험 id") + ) + ) + ) + } + + @Test + @DisplayName("제목 길이가 50이 넘으면 예외가 발생한다.") + fun createOverTitleLengthTest() { + //given + val content1 = CreateExperience.ExperienceContentRequest("질문1", "답변1") + val content2 = CreateExperience.ExperienceContentRequest("질문2", "답변2") + + val contentRequest = arrayListOf(content1, content2) + + val createExperienceRequest : CreateExperience.Request = generateFixture { + it.set("title", "제목") + it.set("contents", contentRequest) + it.set("strongPointIds", generateFixture>()) + it.set("parentTagId", generateFixture()) + it.set("childTagId", generateFixture()) + it.set("startedAt", generateFixture()) + it.set("endedAt", generateFixture()) + } + + given(experienceCreateService.createExperience(createExperienceRequest)).willThrow(IllegalArgumentException("제목의 글자 수는 50자 제한입니다.")) + + val request = RestDocumentationRequestBuilders.post(ExperienceApi.BASE_URL) + .header("Authorization", "Bearer Access Token") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content(objectMapper.writeValueAsString(createExperienceRequest)) + + //when + val result = mockMvc.perform(request) + + //then + result.andExpect(status().isBadRequest).andDo( + resultHandler.document( + requestHeaders( + headerWithName("Authorization").description("엑세스 토큰") + ), + requestFields( + fieldWithPath("title").description("경험 제목"), + fieldWithPath("contents").description("경험 내용"), + fieldWithPath("contents[].question").description("경험 내용 질문"), + fieldWithPath("contents[].answer").description("경험 내용 답변"), + fieldWithPath("strongPointIds").description("관련된 역량 키워드"), + fieldWithPath("parentTagId").description("속한 상위 태그"), + fieldWithPath("childTagId").description("속한 하위 태그"), + fieldWithPath("startedAt").description("경험 시작 날짜"), + fieldWithPath("endedAt").description("경험 종료 날짜"), + ), + responseFields( + fieldWithPath("code").description(HttpStatus.BAD_REQUEST), + fieldWithPath("message").description("제목의 글자 수는 50자 제한입니다.") + ) + ) + ) + } + + @Test + @DisplayName("역량 키워드를 5개 초과하여 등록할 경우 예외를 반환한다.") + fun createOverStrongPointCountTest() { + //given + val content1 = CreateExperience.ExperienceContentRequest("질문1", "답변1") + val content2 = CreateExperience.ExperienceContentRequest("질문2", "답변2") + + val contentRequest = arrayListOf(content1, content2) + + val createExperienceRequest : CreateExperience.Request = generateFixture { + it.set("title", "제목") + it.set("contents", contentRequest) + it.set("strongPointIds", generateFixture>()) + it.set("parentTagId", generateFixture()) + it.set("childTagId", generateFixture()) + it.set("startedAt", generateFixture()) + it.set("endedAt", generateFixture()) + } + + given(experienceCreateService.createExperience(createExperienceRequest)).willThrow(IllegalArgumentException("역량 키워드는 최대 5개까지 붙일 수 있습니다.")) + + val request = RestDocumentationRequestBuilders.post(ExperienceApi.BASE_URL) + .header("Authorization", "Bearer Access Token") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content(objectMapper.writeValueAsString(createExperienceRequest)) + + //when + val result = mockMvc.perform(request) + + //then + result.andExpect(status().isBadRequest).andDo( + resultHandler.document( + requestHeaders( + headerWithName("Authorization").description("엑세스 토큰") + ), + requestFields( + fieldWithPath("title").description("경험 제목"), + fieldWithPath("contents").description("경험 내용"), + fieldWithPath("contents[].question").description("경험 내용 질문"), + fieldWithPath("contents[].answer").description("경험 내용 답변"), + fieldWithPath("strongPointIds").description("관련된 역량 키워드"), + fieldWithPath("parentTagId").description("속한 상위 태그"), + fieldWithPath("childTagId").description("속한 하위 태그"), + fieldWithPath("startedAt").description("경험 시작 날짜"), + fieldWithPath("endedAt").description("경험 종료 날짜"), + ), + responseFields( + fieldWithPath("code").description(HttpStatus.BAD_REQUEST), + fieldWithPath("message").description("역량 키워드는 최대 5개까지 붙일 수 있습니다.") + ) + ) + ) + } +} + diff --git a/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/tag/presentation/TagControllerTest.kt b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/tag/presentation/TagControllerTest.kt index 34c62d41..016b9d57 100644 --- a/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/tag/presentation/TagControllerTest.kt +++ b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/tag/presentation/TagControllerTest.kt @@ -35,7 +35,7 @@ class TagControllerTest : BaseRestDocsTest() { val createTagRequest: CreateTag.Request = generateFixture() val createTagResponse: CreateTag.Response = generateFixture() - given(tagController.createTag(null, createTagRequest)).willReturn(createTagResponse) + given(tagController.createParentTag(createTagRequest)).willReturn(createTagResponse) val request = RestDocumentationRequestBuilders.post(TagApi.BASE_URL) .header("Authorization", "Bearer Access Token") @@ -70,7 +70,7 @@ class TagControllerTest : BaseRestDocsTest() { val parentTagId = generateFixture() - given(tagController.createTag(parentTagId, createChildTagRequest)).willReturn(createChildTagResponse) + given(tagController.createChildTag(createChildTagRequest, parentTagId, )).willReturn(createChildTagResponse) val request = RestDocumentationRequestBuilders.post(TagApi.TAG_PATH_VARIABLE_URL, parentTagId) .header("Authorization", "Bearer Access Token") @@ -106,7 +106,7 @@ class TagControllerTest : BaseRestDocsTest() { val createParentTagRequest: CreateTag.Request = generateFixture() - given(tagController.createTag(null, createParentTagRequest)).willThrow(TagException.DuplicatedTagName()) + given(tagController.createParentTag(createParentTagRequest)).willThrow(TagException.DuplicatedTagName()) val request = RestDocumentationRequestBuilders.post(TagApi.BASE_URL) .header("Authorization", "Bearer Access Token") @@ -140,8 +140,7 @@ class TagControllerTest : BaseRestDocsTest() { val createChildTagRequest: CreateTag.Request = generateFixture() val parentTagId: UUID = generateFixture() - - given(tagController.createTag(parentTagId, createChildTagRequest)).willThrow(TagException.DuplicatedTagName()) + given(tagController.createChildTag(createChildTagRequest, parentTagId)).willThrow(TagException.DuplicatedTagName()) val request = RestDocumentationRequestBuilders.post(TagApi.TAG_PATH_VARIABLE_URL, parentTagId) .header("Authorization", "Bearer Access Token") @@ -178,9 +177,8 @@ class TagControllerTest : BaseRestDocsTest() { val createChildTagRequest: CreateTag.Request = generateFixture() val parentTagId: UUID = generateFixture() - - given(tagController.createTag(parentTagId, createChildTagRequest)).willThrow(TagException.OverTagCountLimit()) - given(tagController.createTag(null, createChildTagRequest)).willThrow(TagException.OverTagCountLimit()) + given(tagController.createChildTag(createChildTagRequest, parentTagId)).willThrow(TagException.OverTagCountLimit()) + given(tagController.createParentTag(createChildTagRequest)).willThrow(TagException.OverTagCountLimit()) val request = RestDocumentationRequestBuilders.post(TagApi.TAG_PATH_VARIABLE_URL, parentTagId) .header("Authorization", "Bearer Access Token") diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/Experience.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/Experience.kt index 9a0a0c52..566cadd5 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/Experience.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/Experience.kt @@ -18,20 +18,22 @@ data class Experience( val createdAt : LocalDateTime, val updatedAt : LocalDateTime, ) : AggregateRoot { - + init { + require(title.length < 50) { "제목의 글자 수는 50자 제한입니다." } + require(strongPointIds.size <= 5) { "역량 키워드는 최대 5개까지 붙일 수 있습니다."} + } companion object { fun create( + title: String, userId: UUID, parentTagId: UUID, childTagId: UUID, strongPointIds: List, - title: String, contentIds: List = emptyList(), startedAt: LocalDateTime, endedAt: LocalDateTime, ): Experience { return Experience( - id = UuidCreator.create(), userId = userId, parentTagId = parentTagId, childTagId = childTagId, @@ -73,4 +75,4 @@ data class Experience( ) } } -} \ No newline at end of file +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/ExperienceContent.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/ExperienceContent.kt index 6cf39357..ea87e745 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/ExperienceContent.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/ExperienceContent.kt @@ -8,16 +8,15 @@ data class ExperienceContent( override val id: UUID = UuidCreator.create(), val question: String, val answer: String, - val experienceId: UUID ) : DomainEntity { companion object { - fun create(question: String, answer: String, experienceId: UUID): ExperienceContent { - return ExperienceContent(UuidCreator.create(), question, answer, experienceId) + fun create(question: String, answer: String): ExperienceContent { + return ExperienceContent(question = question, answer = answer) } - fun toDomain(id: UUID, question: String, answer: String, experienceId: UUID): ExperienceContent { - return ExperienceContent(id, question, answer, experienceId) + fun toDomain(id: UUID, question: String, answer: String): ExperienceContent { + return ExperienceContent(id, question, answer) } } -} \ No newline at end of file +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/repository/ExperienceContentRepository.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/repository/ExperienceContentRepository.kt new file mode 100644 index 00000000..a01d4acf --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/repository/ExperienceContentRepository.kt @@ -0,0 +1,8 @@ +package com.bamyanggang.domainmodule.domain.experience.repository + +import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceContent +import java.util.* + +interface ExperienceContentRepository { + fun save(experienceContent: ExperienceContent) +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/repository/ExperienceRepository.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/repository/ExperienceRepository.kt index 3e63843e..20608311 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/repository/ExperienceRepository.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/repository/ExperienceRepository.kt @@ -1,4 +1,8 @@ package com.bamyanggang.domainmodule.domain.experience.repository +import com.bamyanggang.domainmodule.domain.experience.aggregate.Experience +import java.util.* + interface ExperienceRepository { -} \ No newline at end of file + fun save(experience: Experience) +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceAppender.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceAppender.kt new file mode 100644 index 00000000..e40cec7d --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceAppender.kt @@ -0,0 +1,35 @@ +package com.bamyanggang.domainmodule.domain.experience.service + +import com.bamyanggang.domainmodule.domain.experience.aggregate.Experience +import com.bamyanggang.domainmodule.domain.experience.repository.ExperienceRepository +import org.springframework.stereotype.Service +import java.time.LocalDateTime +import java.util.* + +@Service +class ExperienceAppender( + private val experienceRepository: ExperienceRepository, +) { + fun appendExperience(title: String, + userId: UUID, + parentTagId: UUID, + childTagId: UUID, + strongPointIds: List, + contentIds: List, + startedAt: LocalDateTime, + endedAt: LocalDateTime, + ): Experience { + return Experience.create( + title = title, + userId = userId, + parentTagId = parentTagId, + childTagId = childTagId, + strongPointIds = strongPointIds, + contentIds = contentIds, + startedAt = startedAt, + endedAt = endedAt + ).also { + experienceRepository.save(it) + } + } +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentAppender.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentAppender.kt new file mode 100644 index 00000000..e4c49cb9 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentAppender.kt @@ -0,0 +1,16 @@ +package com.bamyanggang.domainmodule.domain.experience.service + +import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceContent +import com.bamyanggang.domainmodule.domain.experience.repository.ExperienceContentRepository +import org.springframework.stereotype.Service + +@Service +class ExperienceContentAppender( + private val experienceContentRepository: ExperienceContentRepository +) { + fun appendExperienceContent(question: String, answer: String): ExperienceContent { + return ExperienceContent.create(question, answer).also { + experienceContentRepository.save(it) + } + } +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/aggregate/StrongPoint.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/aggregate/StrongPoint.kt index 8e78224b..4d54fdca 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/aggregate/StrongPoint.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/aggregate/StrongPoint.kt @@ -14,11 +14,11 @@ data class StrongPoint( companion object { fun create(name: String, userId: UUID?): StrongPoint { - return StrongPoint(UuidCreator.create(), name, userId) + return StrongPoint(name = name, userId = userId) } fun toDomain(id: UUID, name: String, userId: UUID?): StrongPoint { return StrongPoint(id, name, userId) } } -} \ No newline at end of file +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/repository/StrongPointRepository.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/repository/StrongPointRepository.kt index 7661a35b..d56c6a56 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/repository/StrongPointRepository.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/repository/StrongPointRepository.kt @@ -4,7 +4,7 @@ import com.bamyanggang.domainmodule.domain.strongpoint.aggregate.StrongPoint import java.util.* interface StrongPointRepository { - fun save(newStrongPoint: StrongPoint): UUID + fun save(newStrongPoint: StrongPoint) fun findAllByUserId(userId: UUID): List } diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/service/StrongPointAppender.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/service/StrongPointAppender.kt index a6283383..7a96543c 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/service/StrongPointAppender.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/strongpoint/service/StrongPointAppender.kt @@ -1,7 +1,7 @@ package com.bamyanggang.domainmodule.domain.strongpoint.service -import com.bamyanggang.domainmodule.domain.strongpoint.repository.StrongPointRepository import com.bamyanggang.domainmodule.domain.strongpoint.aggregate.StrongPoint +import com.bamyanggang.domainmodule.domain.strongpoint.repository.StrongPointRepository import org.springframework.stereotype.Service import java.util.* @@ -9,8 +9,8 @@ import java.util.* class StrongPointAppender( private val strongPointRepository: StrongPointRepository ) { - fun appendStrongPoint(name: String, userId: UUID): UUID { - return StrongPoint.create(name, userId).let { + fun appendStrongPoint(name: String, userId: UUID): StrongPoint { + return StrongPoint.create(name, userId).also { strongPointRepository.save(it) } } diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/aggregate/Tag.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/aggregate/Tag.kt index 35a5bacc..f02294fc 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/aggregate/Tag.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/aggregate/Tag.kt @@ -15,7 +15,11 @@ data class Tag( companion object { fun create(name: String, parentTagId: UUID?, userId: UUID): Tag { - return Tag(UuidCreator.create(), name, parentTagId, userId) + return Tag( + name = name, + parentTagId = parentTagId, + userId = userId + ) } fun toDomain(id : UUID, name: String, parentTagId: UUID?, userId: UUID): Tag { diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/repository/TagRepository.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/repository/TagRepository.kt index 20151c31..874c65a6 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/repository/TagRepository.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/repository/TagRepository.kt @@ -4,7 +4,7 @@ import com.bamyanggang.domainmodule.domain.tag.aggregate.Tag import java.util.* interface TagRepository { - fun save(newTag : Tag): UUID + fun save(newTag : Tag) fun findAllParentTagsByUserId(userId: UUID): List fun findAllChildTagsByUserId(userId: UUID, parentId: UUID): List fun deleteByTagId(tagId: UUID) diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/service/TagAppender.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/service/TagAppender.kt index e5d6ebc5..83fe8fbb 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/service/TagAppender.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/service/TagAppender.kt @@ -9,14 +9,14 @@ import java.util.* class TagAppender( private val tagRepository: TagRepository ) { - fun appendParentTag(name: String, userId: UUID): UUID { + fun appendParentTag(name: String, userId: UUID) : Tag { return Tag.create(name, null, userId) - .let { tagRepository.save(it) } + .also { tagRepository.save(it) } } - fun appendChildTag(name: String, parentTagId: UUID, userId: UUID): UUID { + fun appendChildTag(name: String, parentTagId: UUID, userId: UUID): Tag { return Tag.create(name, parentTagId, userId) - .let { tagRepository.save(it) + .also { tagRepository.save(it) } } } diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/service/TagReader.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/service/TagReader.kt index 54b3469a..ca5fbe97 100644 --- a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/service/TagReader.kt +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/tag/service/TagReader.kt @@ -16,6 +16,4 @@ class TagReader( fun readAllChildTagsByUserId(userId: UUID, parentId: UUID): List { return tagRepository.findAllChildTagsByUserId(userId, parentId) } - - } diff --git a/Domain-Module/src/test/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/ExperienceTest.kt b/Domain-Module/src/test/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/ExperienceTest.kt new file mode 100644 index 00000000..af96d36e --- /dev/null +++ b/Domain-Module/src/test/kotlin/com/bamyanggang/domainmodule/domain/experience/aggregate/ExperienceTest.kt @@ -0,0 +1,76 @@ +package com.bamyanggang.domainmodule.domain.experience.aggregate + +import com.bamyanggang.commonmodule.fixture.generateBasicTypeFixture +import com.bamyanggang.commonmodule.fixture.generateFixture +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import java.time.LocalDateTime +import java.util.* + +class ExperienceTest : FunSpec({ + test("Experience 정상 생성 테스트"){ + val title: String = generateBasicTypeFixture(15) + val parentTagId: UUID = generateFixture() + val childTagId: UUID = generateFixture() + val strongPointIds: List = generateFixture() + val startedAt: LocalDateTime = generateFixture() + val endedAt: LocalDateTime = generateFixture() + val contentIds: List = generateFixture() + val userId : UUID = generateFixture() + + val newExperience = Experience.create( + title = title, + userId = userId, + parentTagId = parentTagId, + childTagId = childTagId, + strongPointIds = strongPointIds, + contentIds = contentIds, + startedAt = startedAt, + endedAt = endedAt, + ) + + title shouldBe newExperience.title + userId shouldBe newExperience.userId + parentTagId shouldBe newExperience.parentTagId + childTagId shouldBe newExperience.childTagId + strongPointIds shouldBe strongPointIds + contentIds shouldBe newExperience.contentIds + startedAt shouldBe startedAt + endedAt shouldBe endedAt + } + + test("제목 길이 제한 예외 테스트"){ + val title: String = List(51) { it.toString() }.joinToString("") + + shouldThrow { + Experience.create( + title = title, + userId = generateFixture(), + parentTagId = generateFixture(), + childTagId = generateFixture(), + strongPointIds = generateFixture(), + contentIds = generateFixture(), + startedAt = generateFixture(), + endedAt = generateFixture(), + ) + } + } + + test("역량 키워드 개수 제한 예외 테스트") { + val strongPointIds: List = List(6) { generateFixture() } + + shouldThrow { + Experience.create( + title = generateFixture(), + userId = generateFixture(), + parentTagId = generateFixture(), + childTagId = generateFixture(), + strongPointIds = strongPointIds, + contentIds = generateFixture(), + startedAt = generateFixture(), + endedAt = generateFixture(), + ) + } + } +}) diff --git a/Domain-Module/src/test/kotlin/com/bamyanggang/domainmodule/jobDescription/aggregate/ApplyTest.kt b/Domain-Module/src/test/kotlin/com/bamyanggang/domainmodule/jobDescription/aggregate/ApplyTest.kt index 3d55c309..0dcb7aa6 100644 --- a/Domain-Module/src/test/kotlin/com/bamyanggang/domainmodule/jobDescription/aggregate/ApplyTest.kt +++ b/Domain-Module/src/test/kotlin/com/bamyanggang/domainmodule/jobDescription/aggregate/ApplyTest.kt @@ -9,7 +9,8 @@ import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import java.util.* -class ApplyTest : FunSpec({ +class +ApplyTest : FunSpec({ test("Apply.create 생성") { val jobDescriptionId: UUID = UUID.randomUUID() diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/common/UUIDBinaryConverter.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/common/UUIDBinaryConverter.java index 6212e1f9..11831e1d 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/common/UUIDBinaryConverter.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/common/UUIDBinaryConverter.java @@ -5,7 +5,7 @@ import java.nio.ByteBuffer; import java.util.UUID; -@Converter(autoApply = true) +@Converter public class UUIDBinaryConverter implements AttributeConverter { @Override diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceContentImpl.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceContentImpl.java new file mode 100644 index 00000000..9555dd0d --- /dev/null +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceContentImpl.java @@ -0,0 +1,22 @@ +package com.bamyanggang.persistence.experience; + +import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceContent; +import com.bamyanggang.domainmodule.domain.experience.repository.ExperienceContentRepository; +import com.bamyanggang.persistence.experience.jpa.entity.ExperienceContentJpaEntity; +import com.bamyanggang.persistence.experience.jpa.repository.ExperienceContentJpaRepository; +import com.bamyanggang.persistence.experience.mapper.ExperienceContentMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class ExperienceContentImpl implements ExperienceContentRepository { + private final ExperienceContentJpaRepository experienceContentJpaRepository; + private final ExperienceContentMapper experienceContentMapper; + + @Override + public void save(ExperienceContent experienceContent) { + ExperienceContentJpaEntity experienceContentJpaEntity = experienceContentMapper.toJpaEntity(experienceContent); + experienceContentJpaRepository.save(experienceContentJpaEntity); + } +} diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceRepositoryImpl.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceRepositoryImpl.java index 9100a066..5f37e912 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceRepositoryImpl.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceRepositoryImpl.java @@ -1,5 +1,8 @@ package com.bamyanggang.persistence.experience; +import com.bamyanggang.domainmodule.domain.experience.aggregate.Experience; +import com.bamyanggang.domainmodule.domain.experience.repository.ExperienceRepository; +import com.bamyanggang.persistence.experience.jpa.entity.ExperienceJpaEntity; import com.bamyanggang.persistence.experience.jpa.repository.ExperienceJpaRepository; import com.bamyanggang.persistence.experience.mapper.ExperienceMapper; import lombok.RequiredArgsConstructor; @@ -7,7 +10,13 @@ @Repository @RequiredArgsConstructor -public class ExperienceRepositoryImpl { +public class ExperienceRepositoryImpl implements ExperienceRepository { private final ExperienceJpaRepository experienceJpaRepository; private final ExperienceMapper experienceMapper; + + @Override + public void save(Experience experience) { + ExperienceJpaEntity experienceJpaEntity = experienceMapper.toJpaEntity(experience); + experienceJpaRepository.save(experienceJpaEntity); + } } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceContentJpaEntity.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceContentJpaEntity.java index a8ba9258..72260f91 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceContentJpaEntity.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceContentJpaEntity.java @@ -1,23 +1,24 @@ package com.bamyanggang.persistence.experience.jpa.entity; +import com.bamyanggang.persistence.common.UUIDBinaryConverter; import jakarta.persistence.Column; +import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; import java.util.UUID; import lombok.AccessLevel; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor(access = AccessLevel.PRIVATE) @Table(name = "experience_content") public class ExperienceContentJpaEntity { @Id - @Column(name = "experience_content_id") + @Column(name = "experience_content_id", columnDefinition = "BINARY(16)") + @Convert(converter = UUIDBinaryConverter.class) private UUID experienceContentId; @Column(columnDefinition = "TEXT") @@ -26,9 +27,9 @@ public class ExperienceContentJpaEntity { @Column(columnDefinition = "TEXT") private String answer; - private UUID experienceId; - - public static ExperienceContentJpaEntity of(UUID id, String question, String answer, UUID experienceId) { - return new ExperienceContentJpaEntity(id, question, answer, experienceId); + public ExperienceContentJpaEntity(UUID id, String question, String answer) { + this.experienceContentId = id; + this.question = question; + this.answer = answer; } } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceJpaEntity.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceJpaEntity.java index f0312999..8b490cb2 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceJpaEntity.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceJpaEntity.java @@ -1,24 +1,25 @@ package com.bamyanggang.persistence.experience.jpa.entity; +import com.bamyanggang.persistence.common.UUIDBinaryConverter; import jakarta.persistence.Column; +import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; import java.time.LocalDateTime; import java.util.UUID; import lombok.AccessLevel; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor(access = AccessLevel.PRIVATE) @Table(name = "experience") public class ExperienceJpaEntity{ @Id - @Column(name = "experience_id") + @Column(name = "experience_id", columnDefinition = "BINARY(16)") + @Convert(converter = UUIDBinaryConverter.class) private UUID experienceId; private String title; @@ -33,7 +34,7 @@ public class ExperienceJpaEntity{ private LocalDateTime updatedAt; - public static ExperienceJpaEntity of( + public ExperienceJpaEntity( UUID id, String title, LocalDateTime startedAt, @@ -42,7 +43,13 @@ public static ExperienceJpaEntity of( LocalDateTime createdAt, LocalDateTime updatedAt ) { - return new ExperienceJpaEntity(id, title, startedAt, endedAt, userId, createdAt, updatedAt); + this.experienceId = id; + this.title = title; + this.startedAt = startedAt; + this.endedAt = endedAt; + this.userId = userId; + this.createdAt = createdAt; + this.updatedAt = updatedAt; } } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceStrongPointJpaEntity.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceStrongPointJpaEntity.java index 76081ac6..a74bddb3 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceStrongPointJpaEntity.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceStrongPointJpaEntity.java @@ -1,6 +1,8 @@ package com.bamyanggang.persistence.experience.jpa.entity; +import com.bamyanggang.persistence.common.UUIDBinaryConverter; import jakarta.persistence.Column; +import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; @@ -12,10 +14,13 @@ @Table(name = "experience_strong_point") public class ExperienceStrongPointJpaEntity { @Id - @Column(name = "experience_strong_point_id") + @Column(name = "experience_strong_point_id", columnDefinition = "BINARY(16)") + @Convert(converter = UUIDBinaryConverter.class) private UUID experienceStrongPointId; + @Column(name = "experience_id", columnDefinition = "BINARY(16)") private UUID experienceId; + @Column(name = "strong_point_id", columnDefinition = "BINARY(16)") private UUID strongPointId; } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceTagJpaEntity.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceTagJpaEntity.java index 7bbc4857..d3a554d1 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceTagJpaEntity.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/entity/ExperienceTagJpaEntity.java @@ -1,6 +1,8 @@ package com.bamyanggang.persistence.experience.jpa.entity; +import com.bamyanggang.persistence.common.UUIDBinaryConverter; import jakarta.persistence.Column; +import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; @@ -17,10 +19,13 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ExperienceTagJpaEntity { @Id - @Column(name = "experience_tag_id") + @Column(name = "experience_tag_id", columnDefinition = "BINARY(16)") + @Convert(converter = UUIDBinaryConverter.class) private UUID experienceTagId; + @Column(name = "experience_id", columnDefinition = "BINARY(16)") private UUID experienceId; + @Column(name = "tag_id", columnDefinition = "BINARY(16)") private UUID tagId; } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceContentMapper.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceContentMapper.java index 6b5d6a1b..aa109e40 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceContentMapper.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceContentMapper.java @@ -5,20 +5,20 @@ import org.springframework.stereotype.Component; @Component -class ExperienceContentMapper { +public class ExperienceContentMapper { public ExperienceContentJpaEntity toJpaEntity(ExperienceContent experienceContent) { - return ExperienceContentJpaEntity.of( + return new ExperienceContentJpaEntity( experienceContent.getId(), experienceContent.getQuestion(), - experienceContent.getAnswer(), - experienceContent.getExperienceId()); + experienceContent.getAnswer() + ); } public ExperienceContent toDomainEntity(ExperienceContentJpaEntity experienceContentJpaEntity) { return ExperienceContent.Companion.toDomain( experienceContentJpaEntity.getExperienceContentId(), experienceContentJpaEntity.getQuestion(), - experienceContentJpaEntity.getAnswer(), - experienceContentJpaEntity.getExperienceId()); + experienceContentJpaEntity.getAnswer() + ); } -} \ No newline at end of file +} diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceMapper.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceMapper.java index d87d6ee2..ad941711 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceMapper.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceMapper.java @@ -9,7 +9,7 @@ @Component public class ExperienceMapper { public ExperienceJpaEntity toJpaEntity(Experience experience) { - return ExperienceJpaEntity.of( + return new ExperienceJpaEntity( experience.getId(), experience.getTitle(), experience.getStartedAt(), diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/strongpoint/StrongPointRepositoryImpl.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/strongpoint/StrongPointRepositoryImpl.java index 51883222..0118b0ac 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/strongpoint/StrongPointRepositoryImpl.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/strongpoint/StrongPointRepositoryImpl.java @@ -17,11 +17,9 @@ public class StrongPointRepositoryImpl implements StrongPointRepository { private final StrongPointMapper strongPointMapper; @Override - public UUID save(StrongPoint strongPoint) { + public void save(StrongPoint strongPoint) { StrongPointJpaEntity newStrongPointJpaEntity = strongPointMapper.toJpaEntity(strongPoint); strongPointJpaRepository.save(newStrongPointJpaEntity); - - return newStrongPointJpaEntity.getStrongPointId(); } @Override diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/strongpoint/jpa/entity/StrongPointJpaEntity.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/strongpoint/jpa/entity/StrongPointJpaEntity.java index b2927752..523f68f0 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/strongpoint/jpa/entity/StrongPointJpaEntity.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/strongpoint/jpa/entity/StrongPointJpaEntity.java @@ -1,6 +1,8 @@ package com.bamyanggang.persistence.strongpoint.jpa.entity; +import com.bamyanggang.persistence.common.UUIDBinaryConverter; import jakarta.persistence.Column; +import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; @@ -17,11 +19,14 @@ @Table(name = "strong_point") public class StrongPointJpaEntity { @Id - @Column(name = "strong_point_id") + @Column(name = "strong_point_id", columnDefinition = "BINARY(16)") + @Convert(converter = UUIDBinaryConverter.class) private UUID strongPointId; private String name; + @Column(name = "user_id", columnDefinition = "BINARY(16)") + @Convert(converter = UUIDBinaryConverter.class) private UUID userId; public static StrongPointJpaEntity of(UUID id, String name, UUID userId) { diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/TagRepositoryImpl.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/TagRepositoryImpl.java index 747e53bf..9de7d7ca 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/TagRepositoryImpl.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/TagRepositoryImpl.java @@ -5,7 +5,6 @@ import com.bamyanggang.persistence.tag.jpa.entity.TagJpaEntity; import com.bamyanggang.persistence.tag.jpa.repository.TagJpaRepository; import com.bamyanggang.persistence.tag.mapper.TagMapper; -import jakarta.transaction.Transactional; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -18,23 +17,18 @@ public class TagRepositoryImpl implements TagRepository { private final TagJpaRepository tagJpaRepository; @Override - @Transactional - public UUID save(Tag newTag) { + public void save(Tag newTag) { TagJpaEntity newTagJpaEntity = tagMapper.toJpaEntity(newTag); tagJpaRepository.save(newTagJpaEntity); - - return newTagJpaEntity.getTagId(); } @Override - @Transactional public List findAllParentTagsByUserId(UUID userId) { List parentTagJpaEntities = tagJpaRepository.findAllByUserIdAndParentTagIdIsNull(userId); return parentTagJpaEntities.stream().map(tagMapper::toDomainEntity).toList(); } @Override - @Transactional public List findAllChildTagsByUserId(UUID userId, UUID parentTagId) { List childTagJpaEntities = tagJpaRepository.findAllByUserIdAndParentTagId(userId, parentTagId); return childTagJpaEntities.stream().map(tagMapper::toDomainEntity).toList(); diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/jpa/entity/TagJpaEntity.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/jpa/entity/TagJpaEntity.java index 86c985fb..7adb09b4 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/jpa/entity/TagJpaEntity.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/jpa/entity/TagJpaEntity.java @@ -6,27 +6,30 @@ import jakarta.persistence.Table; import java.util.UUID; import lombok.AccessLevel; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor(access = AccessLevel.PRIVATE) @Table(name = "tag") public class TagJpaEntity { @Id - @Column(name = "tag_id") + @Column(name = "tag_id", columnDefinition = "BINARY(16)") private UUID tagId; private String name; + @Column(name = "parent_tag_id", columnDefinition = "BINARY(16)") private UUID parentTagId; + @Column(name = "user_id", columnDefinition = "BINARY(16)") private UUID userId; - public static TagJpaEntity of(UUID id, String name, UUID parentTagId, UUID userId) { - return new TagJpaEntity(id, name, parentTagId, userId); + public TagJpaEntity (UUID id, String name, UUID parentTagId, UUID userId) { + this.tagId = id; + this.name = name; + this.parentTagId = parentTagId; + this.userId = userId; } } diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/mapper/TagMapper.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/mapper/TagMapper.java index 6ba9e994..39c9bd9e 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/mapper/TagMapper.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/tag/mapper/TagMapper.java @@ -7,7 +7,7 @@ @Component public class TagMapper { public TagJpaEntity toJpaEntity(Tag tag) { - return TagJpaEntity.of(tag.getId(), tag.getName(), tag.getParentTagId(), tag.getUserId()); + return new TagJpaEntity(tag.getId(), tag.getName(), tag.getParentTagId(), tag.getUserId()); } public Tag toDomainEntity(TagJpaEntity tagJpaEntity) { diff --git a/Infrastructure-Module/persistence/src/main/resources/application-db.yml b/Infrastructure-Module/persistence/src/main/resources/application-db.yml index c0792a1f..72d94966 100644 --- a/Infrastructure-Module/persistence/src/main/resources/application-db.yml +++ b/Infrastructure-Module/persistence/src/main/resources/application-db.yml @@ -12,4 +12,4 @@ spring: hibernate: show_sql: true format_sql: true - database-platform: org.hibernate.dialect.MySQLDialect \ No newline at end of file + database-platform: org.hibernate.dialect.MySQLDialect