diff --git a/.github/workflows/CD-dev.yml b/.github/workflows/CD-dev.yml index 57aa6078..b08394fd 100644 --- a/.github/workflows/CD-dev.yml +++ b/.github/workflows/CD-dev.yml @@ -85,4 +85,4 @@ jobs: docker compose stop ${{secrets.DOCKER_REPOSITORY}} docker compose rm -f ${{secrets.DOCKER_REPOSITORY}} docker compose -f docker-compose-dev.yml up -d - docker image prune -f \ No newline at end of file + docker image prune -f diff --git a/Api-Module/src/docs/asciidoc/Experience.adoc b/Api-Module/src/docs/asciidoc/Experience.adoc index c8301b4f..5d777c67 100644 --- a/Api-Module/src/docs/asciidoc/Experience.adoc +++ b/Api-Module/src/docs/asciidoc/Experience.adoc @@ -15,3 +15,8 @@ operation::ExperienceControllerTest/createOverTitleLengthTest/[snippets='http-re === 역량 키워드 제한(5개) 초과 예외 operation::ExperienceControllerTest/createOverStrongPointCountTest/[snippets='http-request,request-headers,request-body,http-response,response-body,response-fields'] + +[[DeleteExperienceTest]] +=== 경험 삭제 API + +operation::ExperienceControllerTest/deleteExperienceTest/[snippets='http-request,path-parameters,request-headers,request-body,http-response,response-body'] 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 index 223398a9..d4cb8468 100644 --- 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 @@ -10,27 +10,23 @@ import org.springframework.transaction.annotation.Transactional @Service class ExperienceCreateService( val experienceAppender: ExperienceAppender, - val experienceContentAppender: ExperienceContentAppender + 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) - } + val newExperience = experienceAppender.appendExperience( + title = request.title, + userId = currentUserId, + startedAt = request.startedAt, + endedAt = request.endedAt + ) + + request.contents.forEach { + experienceContentAppender.appendExperienceContent(it.question, it.answer, newExperience.id) + } + + return CreateExperience.Response(newExperience.id) } } diff --git a/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/service/ExperienceDeleteService.kt b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/service/ExperienceDeleteService.kt new file mode 100644 index 00000000..505ec498 --- /dev/null +++ b/Api-Module/src/main/kotlin/com/bamyanggang/apimodule/domain/experience/application/service/ExperienceDeleteService.kt @@ -0,0 +1,16 @@ +package com.bamyanggang.apimodule.domain.experience.application.service + +import com.bamyanggang.domainmodule.domain.experience.service.ExperienceRemover +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import java.util.* + +@Service +class ExperienceDeleteService( + val experienceRemover: ExperienceRemover +) { + @Transactional + fun deleteExperienceById(experienceId: UUID) { + experienceRemover.remove(experienceId) + } +} 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 index 503900d0..af97b408 100644 --- 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 @@ -2,4 +2,5 @@ package com.bamyanggang.apimodule.domain.experience.presentation object ExperienceApi { const val BASE_URL = "/api/experiences" + const val EXPERIENCE_PATH_VARIABLE_URL = "$BASE_URL/{experienceId}" } 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 index 2410073a..0f2e6235 100644 --- 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 @@ -2,16 +2,22 @@ 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 +import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceDeleteService +import org.springframework.web.bind.annotation.* +import java.util.* @RestController class ExperienceController( - private val experienceCreateService: ExperienceCreateService + private val experienceCreateService: ExperienceCreateService, + private val experienceDeleteService: ExperienceDeleteService ) { @PostMapping(ExperienceApi.BASE_URL) fun createExperience(@RequestBody request: CreateExperience.Request): CreateExperience.Response { return experienceCreateService.createExperience(request) } + + @DeleteMapping(ExperienceApi.EXPERIENCE_PATH_VARIABLE_URL) + fun deleteExperience(@PathVariable("experienceId") experienceId: UUID) { + experienceDeleteService.deleteExperienceById(experienceId) + } } diff --git a/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/application/ExperienceCreateServiceTest.kt b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/application/ExperienceCreateServiceTest.kt new file mode 100644 index 00000000..307050f0 --- /dev/null +++ b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/application/ExperienceCreateServiceTest.kt @@ -0,0 +1,49 @@ +//package com.bamyanggang.apimodule.domain.experience.application +// +//import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience +//import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceCreateService +//import com.bamyanggang.commonmodule.fixture.generateFixture +//import com.bamyanggang.domainmodule.domain.experience.service.ExperienceAppender +//import com.bamyanggang.domainmodule.domain.experience.service.ExperienceContentAppender +//import io.kotest.core.spec.style.BehaviorSpec +//import io.mockk.every +//import io.mockk.mockk +//import io.mockk.verify +//import java.util.* +// +//class ExperienceCreateServiceTest : BehaviorSpec({ +// +// val experienceAppender: ExperienceAppender = mockk() +// val experienceContentAppender: ExperienceContentAppender = mockk() +// val createExperienceService = ExperienceCreateService(experienceAppender, experienceContentAppender) +// +// Given("등록할 경험 Request과 응답이 주어지면") { +// val request : CreateExperience.Request = generateFixture() +// val response : CreateExperience.Response = generateFixture() +// +// When("ExperienceCreateService.createExperience가 호출 되었을 때" ) { +// every { createExperienceService.createExperience(request) } returns response +// +// Then("experienceAppender.appendExperience가 호출된다.") { +// verify { +// experienceAppender.appendExperience( +// request.title, +// generateFixture(), +// request.startedAt, +// request.endedAt +// ) +// } +// } +// +// Then("experienceContentAppender.appendExperienceContent가 호출된다.") { +// verify { +// experienceContentAppender.appendExperienceContent( +// generateFixture(), +// generateFixture(), +// generateFixture(), +// ) +// } +// } +// } +// } +//}) diff --git a/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/application/ExperienceDeleteServiceTest.kt b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/application/ExperienceDeleteServiceTest.kt new file mode 100644 index 00000000..67e1922e --- /dev/null +++ b/Api-Module/src/test/kotlin/com/bamyanggang/apimodule/domain/experience/application/ExperienceDeleteServiceTest.kt @@ -0,0 +1,27 @@ +package com.bamyanggang.apimodule.domain.experience.application + +import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceDeleteService +import com.bamyanggang.domainmodule.domain.experience.service.ExperienceRemover +import io.kotest.core.spec.style.BehaviorSpec +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import java.util.* + +class ExperienceDeleteServiceTest : BehaviorSpec({ + val experienceRemover = mockk() + val experienceDeleteService = ExperienceDeleteService(experienceRemover) + + Given("ExperienceDeleteService 테스트") { + When("삭제할 UUID가 주어지면") { + val deleteId = UUID.randomUUID() + every { experienceDeleteService.deleteExperienceById(deleteId) } returns Unit + + experienceDeleteService.deleteExperienceById(deleteId) + + Then("ExperienceRemover.remove가 호출된다.") { + verify { experienceRemover.remove(deleteId) } + } + } + } +}) 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 index 7c54deeb..41280de3 100644 --- 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 @@ -3,6 +3,7 @@ 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.apimodule.domain.experience.application.service.ExperienceDeleteService import com.bamyanggang.commonmodule.exception.ExceptionHandler import com.bamyanggang.commonmodule.fixture.generateFixture import org.junit.jupiter.api.DisplayName @@ -17,6 +18,8 @@ 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.restdocs.request.RequestDocumentation.parameterWithName +import org.springframework.restdocs.request.RequestDocumentation.pathParameters import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import java.time.LocalDateTime import java.util.* @@ -28,6 +31,9 @@ class ExperienceControllerTest : BaseRestDocsTest() { @MockBean private lateinit var experienceCreateService: ExperienceCreateService + @MockBean + private lateinit var experienceDeleteService: ExperienceDeleteService + @Test @DisplayName("경험을 등록한다.") fun createExperienceTest() { @@ -190,5 +196,29 @@ class ExperienceControllerTest : BaseRestDocsTest() { ) ) } + + @Test + @DisplayName("경험을 삭제한다.") + fun deleteExperienceTest() { + //given + val request = RestDocumentationRequestBuilders.delete(ExperienceApi.EXPERIENCE_PATH_VARIABLE_URL, generateFixture()) + .header("Authorization", "Bearer Access Token") + .contentType(MediaType.APPLICATION_JSON_VALUE) + + //when + val result = mockMvc.perform(request) + + //then + result.andExpect(status().isOk).andDo( + resultHandler.document( + requestHeaders( + headerWithName("Authorization").description("엑세스 토큰") + ), + pathParameters( + parameterWithName("experienceId").description("경험 id") + ) + ) + ) + } } diff --git a/Domain-Module/.jqwik-database b/Domain-Module/.jqwik-database new file mode 100644 index 00000000..711006c3 Binary files /dev/null and b/Domain-Module/.jqwik-database differ 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 566cadd5..90d462f3 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 @@ -8,11 +8,7 @@ import java.util.* data class Experience( override val id: UUID = UuidCreator.create(), val userId : UUID, - val parentTagId : UUID, - val childTagId : UUID, - val strongPointIds : List = emptyList(), val title : String, - val contentIds : List = emptyList(), val startedAt : LocalDateTime, val endedAt : LocalDateTime, val createdAt : LocalDateTime, @@ -20,26 +16,17 @@ data class Experience( ) : 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, - contentIds: List = emptyList(), startedAt: LocalDateTime, endedAt: LocalDateTime, ): Experience { return Experience( userId = userId, - parentTagId = parentTagId, - childTagId = childTagId, - strongPointIds = strongPointIds, title = title, - contentIds = contentIds, startedAt = startedAt, endedAt = endedAt, createdAt = LocalDateTime.now(), @@ -50,11 +37,7 @@ data class Experience( fun toDomain( id: UUID, userId: UUID, - parentTagId: UUID, - childTagId: UUID, - strongPointIds: List, title: String, - contentIds: List = emptyList(), startedAt: LocalDateTime, endedAt: LocalDateTime, createdAt: LocalDateTime, @@ -63,11 +46,7 @@ data class Experience( return Experience( id = id, userId = userId, - parentTagId = parentTagId, - childTagId = childTagId, - strongPointIds = strongPointIds, title = title, - contentIds = contentIds, startedAt = startedAt, endedAt = endedAt, createdAt = createdAt, 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 ea87e745..f1e49ab7 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,15 +8,16 @@ 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): ExperienceContent { - return ExperienceContent(question = question, answer = answer) + fun create(question: String, answer: String, experienceId: UUID): ExperienceContent { + return ExperienceContent(question = question, answer = answer, experienceId = experienceId) } - fun toDomain(id: UUID, question: String, answer: String): ExperienceContent { - return ExperienceContent(id, question, answer) + fun toDomain(id: UUID, question: String, answer: String, experienceId: UUID): ExperienceContent { + return ExperienceContent(id, question, answer, experienceId) } } } 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 index a01d4acf..810521d9 100644 --- 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 @@ -5,4 +5,6 @@ import java.util.* interface ExperienceContentRepository { fun save(experienceContent: ExperienceContent) + fun findByExperienceId(experienceId: UUID) : List + fun deleteAllByIds(experienceContents: List) } 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 20608311..954ab671 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 @@ -5,4 +5,6 @@ import java.util.* interface ExperienceRepository { fun save(experience: Experience) + fun deleteByExperienceId(experienceId: UUID) + fun findByExperienceId(id: UUID): 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 index e40cec7d..333b16ab 100644 --- 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 @@ -12,20 +12,12 @@ class ExperienceAppender( ) { 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 { 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 index e4c49cb9..13dec3ba 100644 --- 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 @@ -3,13 +3,14 @@ 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 +import java.util.* @Service class ExperienceContentAppender( private val experienceContentRepository: ExperienceContentRepository ) { - fun appendExperienceContent(question: String, answer: String): ExperienceContent { - return ExperienceContent.create(question, answer).also { + fun appendExperienceContent(question: String, answer: String, experienceId: UUID): ExperienceContent { + return ExperienceContent.create(question, answer, experienceId).also { experienceContentRepository.save(it) } } diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentReader.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentReader.kt new file mode 100644 index 00000000..f36c8110 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentReader.kt @@ -0,0 +1,15 @@ +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 +import java.util.* + +@Service +class ExperienceContentReader( + private val experienceRepository: ExperienceContentRepository +) { + fun readByExperienceId(experienceId: UUID): List { + return experienceRepository.findByExperienceId(experienceId) + } +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentRemover.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentRemover.kt new file mode 100644 index 00000000..94d653f4 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceContentRemover.kt @@ -0,0 +1,14 @@ +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 ExperienceContentRemover( + private val experienceContentRepository: ExperienceContentRepository +) { + fun removeAllByIds(experienceContents: List) { + experienceContentRepository.deleteAllByIds(experienceContents) + } +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceReader.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceReader.kt new file mode 100644 index 00000000..02b9afa1 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceReader.kt @@ -0,0 +1,15 @@ +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.util.* + +@Service +class ExperienceReader( + private val experienceRepository: ExperienceRepository +) { + fun readExperience(experienceId: UUID): Experience { + return experienceRepository.findByExperienceId(experienceId) + } +} diff --git a/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceRemover.kt b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceRemover.kt new file mode 100644 index 00000000..eed11a05 --- /dev/null +++ b/Domain-Module/src/main/kotlin/com/bamyanggang/domainmodule/domain/experience/service/ExperienceRemover.kt @@ -0,0 +1,19 @@ +package com.bamyanggang.domainmodule.domain.experience.service + +import com.bamyanggang.domainmodule.domain.experience.repository.ExperienceRepository +import org.springframework.stereotype.Service +import java.util.* + +@Service +class ExperienceRemover( + private val experienceRepository: ExperienceRepository, + private val experienceContentReader: ExperienceContentReader, + private val experienceContentRemover: ExperienceContentRemover +) { + fun remove(experienceId: UUID) { + val experienceContents = experienceContentReader.readByExperienceId(experienceId) + experienceContentRemover.removeAllByIds(experienceContents) + + experienceRepository.deleteByExperienceId(experienceId) + } +} 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 index af96d36e..940db76c 100644 --- 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 @@ -11,31 +11,19 @@ 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 } @@ -47,27 +35,6 @@ class ExperienceTest : FunSpec({ 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/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 deleted file mode 100644 index 9555dd0d..00000000 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceContentImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -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/ExperienceContentRepositoryImpl.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceContentRepositoryImpl.java new file mode 100644 index 00000000..ad4b0a94 --- /dev/null +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/ExperienceContentRepositoryImpl.java @@ -0,0 +1,39 @@ +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.ExperienceMapper; +import java.util.List; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class ExperienceContentRepositoryImpl implements ExperienceContentRepository { + private final ExperienceContentJpaRepository experienceContentJpaRepository; + private final ExperienceMapper experienceMapper; + @Override + public void save(ExperienceContent experienceContent) { + ExperienceContentJpaEntity experienceContentJpaEntity = experienceMapper.toExperienceContentJpaEntity( + experienceContent); + + experienceContentJpaRepository.save(experienceContentJpaEntity); + } + + @Override + public List findByExperienceId(UUID experienceId) { + return experienceContentJpaRepository.findByExperienceId(experienceId).stream() + .map(experienceMapper::toExperienceContentDomainEntity).toList(); + } + + @Override + public void deleteAllByIds(List experienceContents) { + List experienceContentJpaEntities = experienceContents.stream() + .map(experienceMapper::toExperienceContentJpaEntity).toList(); + + experienceContentJpaRepository.deleteAllByQuery(experienceContentJpaEntities); + } +} 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 5f37e912..4b4e933f 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 @@ -2,9 +2,11 @@ import com.bamyanggang.domainmodule.domain.experience.aggregate.Experience; import com.bamyanggang.domainmodule.domain.experience.repository.ExperienceRepository; +import com.bamyanggang.persistence.common.exception.PersistenceException.NotFound; import com.bamyanggang.persistence.experience.jpa.entity.ExperienceJpaEntity; import com.bamyanggang.persistence.experience.jpa.repository.ExperienceJpaRepository; import com.bamyanggang.persistence.experience.mapper.ExperienceMapper; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -16,7 +18,20 @@ public class ExperienceRepositoryImpl implements ExperienceRepository { @Override public void save(Experience experience) { - ExperienceJpaEntity experienceJpaEntity = experienceMapper.toJpaEntity(experience); + ExperienceJpaEntity experienceJpaEntity = experienceMapper.toExperienceJpaEntity(experience); experienceJpaRepository.save(experienceJpaEntity); } + + @Override + public void deleteByExperienceId(UUID experienceId) { + experienceJpaRepository.deleteById(experienceId); + } + + @Override + public Experience findByExperienceId(UUID experienceId) { + ExperienceJpaEntity experienceJpaEntity = experienceJpaRepository.findById(experienceId) + .orElseThrow(NotFound::new); + + return experienceMapper.toExperienceDomainEntity(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 72260f91..a71bfee8 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 @@ -12,24 +12,29 @@ import lombok.NoArgsConstructor; @Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "experience_content") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter public class ExperienceContentJpaEntity { @Id @Column(name = "experience_content_id", columnDefinition = "BINARY(16)") @Convert(converter = UUIDBinaryConverter.class) private UUID experienceContentId; - @Column(columnDefinition = "TEXT") + @Column(columnDefinition = "VARCHAR(255)") private String question; - @Column(columnDefinition = "TEXT") + @Column(columnDefinition = "VARCHAR(6000)") private String answer; - public ExperienceContentJpaEntity(UUID id, String question, String answer) { + @Column(name = "experience_id", columnDefinition = "BINARY(16)") + @Convert(converter = UUIDBinaryConverter.class) + private UUID experienceId; + + public ExperienceContentJpaEntity(UUID id, String question, String answer, UUID experienceId) { this.experienceContentId = id; this.question = question; this.answer = answer; + this.experienceId = experienceId; } } 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 8b490cb2..4b031dab 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 @@ -28,12 +28,14 @@ public class ExperienceJpaEntity{ private LocalDateTime endedAt; - private UUID userId; - private LocalDateTime createdAt; private LocalDateTime updatedAt; + @Column(name = "user_id", columnDefinition = "BINARY(16)") + @Convert(converter = UUIDBinaryConverter.class) + private UUID userId; + public ExperienceJpaEntity( UUID id, String title, diff --git a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/repository/ExperienceContentJpaRepository.java b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/repository/ExperienceContentJpaRepository.java index 2b418bd3..3e72dd98 100644 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/repository/ExperienceContentJpaRepository.java +++ b/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/jpa/repository/ExperienceContentJpaRepository.java @@ -1,8 +1,17 @@ package com.bamyanggang.persistence.experience.jpa.repository; import com.bamyanggang.persistence.experience.jpa.entity.ExperienceContentJpaEntity; +import java.util.List; import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface ExperienceContentJpaRepository extends JpaRepository { + List findByExperienceId(UUID experienceId); + + @Modifying + @Query("delete from ExperienceContentJpaEntity ec where ec in :experienceContents") + void deleteAllByQuery(@Param("experienceContents") List experienceContents); } 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 deleted file mode 100644 index aa109e40..00000000 --- a/Infrastructure-Module/persistence/src/main/java/com/bamyanggang/persistence/experience/mapper/ExperienceContentMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.bamyanggang.persistence.experience.mapper; - -import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceContent; -import com.bamyanggang.persistence.experience.jpa.entity.ExperienceContentJpaEntity; -import org.springframework.stereotype.Component; - -@Component -public class ExperienceContentMapper { - public ExperienceContentJpaEntity toJpaEntity(ExperienceContent experienceContent) { - return new ExperienceContentJpaEntity( - experienceContent.getId(), - experienceContent.getQuestion(), - experienceContent.getAnswer() - ); - } - - public ExperienceContent toDomainEntity(ExperienceContentJpaEntity experienceContentJpaEntity) { - return ExperienceContent.Companion.toDomain( - experienceContentJpaEntity.getExperienceContentId(), - experienceContentJpaEntity.getQuestion(), - experienceContentJpaEntity.getAnswer() - ); - } -} 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 ad941711..7495c525 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 @@ -1,14 +1,14 @@ package com.bamyanggang.persistence.experience.mapper; import com.bamyanggang.domainmodule.domain.experience.aggregate.Experience; +import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceContent; +import com.bamyanggang.persistence.experience.jpa.entity.ExperienceContentJpaEntity; import com.bamyanggang.persistence.experience.jpa.entity.ExperienceJpaEntity; -import java.util.List; -import java.util.UUID; import org.springframework.stereotype.Component; @Component public class ExperienceMapper { - public ExperienceJpaEntity toJpaEntity(Experience experience) { + public ExperienceJpaEntity toExperienceJpaEntity(Experience experience) { return new ExperienceJpaEntity( experience.getId(), experience.getTitle(), @@ -20,20 +20,33 @@ public ExperienceJpaEntity toJpaEntity(Experience experience) { ); } - public Experience toDomainEntity(ExperienceJpaEntity experienceJpaEntity, UUID parentTagId, UUID childTagId, - List strongPointIds, List experienceContentIds) { + public Experience toExperienceDomainEntity(ExperienceJpaEntity experienceJpaEntity) { return Experience.Companion.toDomain( experienceJpaEntity.getExperienceId(), experienceJpaEntity.getUserId(), - parentTagId, - childTagId, - strongPointIds, experienceJpaEntity.getTitle(), - experienceContentIds, experienceJpaEntity.getStartedAt(), experienceJpaEntity.getEndedAt(), experienceJpaEntity.getCreatedAt(), experienceJpaEntity.getUpdatedAt() ); } + + public ExperienceContentJpaEntity toExperienceContentJpaEntity(ExperienceContent experienceContent) { + return new ExperienceContentJpaEntity( + experienceContent.getId(), + experienceContent.getQuestion(), + experienceContent.getAnswer(), + experienceContent.getExperienceId() + ); + } + + public ExperienceContent toExperienceContentDomainEntity(ExperienceContentJpaEntity experienceContentJpaEntity) { + return ExperienceContent.Companion.toDomain( + experienceContentJpaEntity.getExperienceContentId(), + experienceContentJpaEntity.getQuestion(), + experienceContentJpaEntity.getAnswer(), + experienceContentJpaEntity.getExperienceId() + ); + } }