From 7f1d8388fc95dbaf1f038033bd3db932b019a5f5 Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 21:45:38 +0900 Subject: [PATCH 1/9] =?UTF-8?q?ASAP-409=20space=20entity=EC=97=90=20isMain?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/asap/persistence/jpa/space/entity/SpaceEntity.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/entity/SpaceEntity.kt b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/entity/SpaceEntity.kt index 6a616bde..1abc4802 100644 --- a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/entity/SpaceEntity.kt +++ b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/entity/SpaceEntity.kt @@ -39,6 +39,13 @@ class SpaceEntity( ) var spaceStatus: EntityStatus = EntityStatus.ACTIVE + + @Column( + name = "is_main", + nullable = false, + ) + var isMain: Boolean = false + fun update(space: Space) { this.userId = space.userId.value this.name = space.name From b04c1adbb1b69b629aefa20cd8e0b3fce6287e7b Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 22:02:36 +0900 Subject: [PATCH 2/9] =?UTF-8?q?ASAP-409=20IndexedSpace,=20Space=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=EC=97=90=20isMain=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20?= =?UTF-8?q?isMain=20=EC=97=AC=EB=B6=80=20=EC=88=98=EC=A0=95=20api=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../space/port/in/UpdateSpaceIndexUsecase.kt | 15 ---- .../space/port/in/UpdateSpaceUsecase.kt | 25 ++++++ .../space/service/SpaceCommandService.kt | 10 ++- .../space/service/SpaceQueryService.kt | 2 +- .../space/service/SpaceCommandServiceTest.kt | 16 ++-- .../asap/bootstrap/web/space/api/SpaceApi.kt | 15 ++++ .../web/space/controller/SpaceController.kt | 12 ++- .../space/controller/SpaceControllerTest.kt | 18 +++- .../space/SpaceApiIntegrationTest.kt | 84 ++++++++++++++----- .../asap/domain/space/entity/IndexedSpace.kt | 3 +- .../com/asap/domain/space/entity/Space.kt | 1 + 11 files changed, 144 insertions(+), 57 deletions(-) delete mode 100644 Application-Module/src/main/kotlin/com/asap/application/space/port/in/UpdateSpaceIndexUsecase.kt create mode 100644 Application-Module/src/main/kotlin/com/asap/application/space/port/in/UpdateSpaceUsecase.kt diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/port/in/UpdateSpaceIndexUsecase.kt b/Application-Module/src/main/kotlin/com/asap/application/space/port/in/UpdateSpaceIndexUsecase.kt deleted file mode 100644 index 67327fcc..00000000 --- a/Application-Module/src/main/kotlin/com/asap/application/space/port/in/UpdateSpaceIndexUsecase.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.asap.application.space.port.`in` - -interface UpdateSpaceIndexUsecase { - fun update(command: Command) - - data class Command( - val userId: String, - val orders: List, - ) { - data class SpaceOrder( - val spaceId: String, - val index: Int, - ) - } -} diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/port/in/UpdateSpaceUsecase.kt b/Application-Module/src/main/kotlin/com/asap/application/space/port/in/UpdateSpaceUsecase.kt new file mode 100644 index 00000000..622e3c73 --- /dev/null +++ b/Application-Module/src/main/kotlin/com/asap/application/space/port/in/UpdateSpaceUsecase.kt @@ -0,0 +1,25 @@ +package com.asap.application.space.port.`in` + +interface UpdateSpaceUsecase { + fun update(command: Command.Index) + + fun update(command: Command.Main) + + + sealed class Command { + data class Index( + val userId: String, + val orders: List, + ) : Command() + + data class SpaceOrder( + val spaceId: String, + val index: Int, + ) + + data class Main( + val userId: String, + val spaceId: String, + ) : Command() + } +} diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt index ab72e2ff..4d71f7f8 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt @@ -3,8 +3,8 @@ package com.asap.application.space.service import com.asap.application.space.exception.SpaceException import com.asap.application.space.port.`in`.CreateSpaceUsecase import com.asap.application.space.port.`in`.DeleteSpaceUsecase -import com.asap.application.space.port.`in`.UpdateSpaceIndexUsecase import com.asap.application.space.port.`in`.UpdateSpaceNameUsecase +import com.asap.application.space.port.`in`.UpdateSpaceUsecase import com.asap.application.space.port.out.SpaceManagementPort import com.asap.common.exception.DefaultException import com.asap.domain.common.DomainId @@ -20,7 +20,7 @@ class SpaceCommandService( ) : CreateSpaceUsecase, UpdateSpaceNameUsecase, DeleteSpaceUsecase, - UpdateSpaceIndexUsecase { + UpdateSpaceUsecase { private val spaceIndexValidator: SpaceIndexValidator = SpaceIndexValidator() override fun create(command: CreateSpaceUsecase.Command) { @@ -76,7 +76,7 @@ class SpaceCommandService( } } - override fun update(command: UpdateSpaceIndexUsecase.Command) { + override fun update(command: UpdateSpaceUsecase.Command.Index) { val indexedSpaces = spaceManagementPort.getAllIndexedSpace(DomainId(command.userId)) val changeIndexMap = command.orders.associateBy({ DomainId(it.spaceId) }, { it.index }) @@ -107,4 +107,8 @@ class SpaceCommandService( spaceManagementPort.update(indexedSpace) } } + + override fun update(command: UpdateSpaceUsecase.Command.Main) { + TODO("Not yet implemented") + } } diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceQueryService.kt b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceQueryService.kt index f0df5790..4a041cee 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceQueryService.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceQueryService.kt @@ -47,7 +47,7 @@ class SpaceQueryService( GetSpaceUsecase.SpaceDetail( spaceName = it.name, letterCount = spaceLetterManagementPort.countSpaceLetterBy(it.id, DomainId(query.userId)), - isMainSpace = it.isMain(), + isMainSpace = it.isMain, spaceIndex = it.index, spaceId = it.id.value, ) diff --git a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt index c35391e2..1e27d7f1 100644 --- a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt +++ b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt @@ -3,8 +3,8 @@ package com.asap.application.space.service import com.asap.application.space.exception.SpaceException import com.asap.application.space.port.`in`.CreateSpaceUsecase import com.asap.application.space.port.`in`.DeleteSpaceUsecase -import com.asap.application.space.port.`in`.UpdateSpaceIndexUsecase import com.asap.application.space.port.`in`.UpdateSpaceNameUsecase +import com.asap.application.space.port.`in`.UpdateSpaceUsecase import com.asap.application.space.port.out.SpaceManagementPort import com.asap.domain.common.DomainId import com.asap.domain.space.entity.IndexedSpace @@ -114,12 +114,12 @@ class SpaceCommandServiceTest : given("스페이스 인덱스 수정 요청이 들어올 때") { val spaceUpdateIndexCommand = - UpdateSpaceIndexUsecase.Command( + UpdateSpaceUsecase.Command.Index( userId = "userId", orders = listOf( - UpdateSpaceIndexUsecase.Command.SpaceOrder("spaceId1", 1), - UpdateSpaceIndexUsecase.Command.SpaceOrder("spaceId2", 0), + UpdateSpaceUsecase.Command.SpaceOrder("spaceId1", 1), + UpdateSpaceUsecase.Command.SpaceOrder("spaceId2", 0), ), ) val indexedSpaces = @@ -159,13 +159,13 @@ class SpaceCommandServiceTest : } val invalidCommand = - UpdateSpaceIndexUsecase.Command( + UpdateSpaceUsecase.Command.Index( userId = "userId", orders = listOf( - UpdateSpaceIndexUsecase.Command.SpaceOrder("spaceId1", 1), - UpdateSpaceIndexUsecase.Command.SpaceOrder("spaceId2", 2), - UpdateSpaceIndexUsecase.Command.SpaceOrder("spaceId3", 3), + UpdateSpaceUsecase.Command.SpaceOrder("spaceId1", 1), + UpdateSpaceUsecase.Command.SpaceOrder("spaceId2", 2), + UpdateSpaceUsecase.Command.SpaceOrder("spaceId3", 3), ), ) every { diff --git a/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/api/SpaceApi.kt b/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/api/SpaceApi.kt index f84fab5a..db9695a7 100644 --- a/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/api/SpaceApi.kt +++ b/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/api/SpaceApi.kt @@ -114,6 +114,21 @@ interface SpaceApi { @AccessUser userId: String, ) + @Operation(summary = "메인 스페이스 변경") + @PutMapping("/{spaceId}/main") + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", + description = "메인 스페이스 변경 성공", + ), + ], + ) + fun updateSpaceMain( + @PathVariable spaceId: String, + @AccessUser userId: String, + ) + @Operation(summary = "여러 스페이스 삭제") @DeleteMapping @ApiResponses( diff --git a/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/controller/SpaceController.kt b/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/controller/SpaceController.kt index f65d4ff6..cb871887 100644 --- a/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/controller/SpaceController.kt +++ b/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/controller/SpaceController.kt @@ -12,7 +12,7 @@ class SpaceController( private val updateSpaceNameUsecase: UpdateSpaceNameUsecase, private val getSpaceUsecase: GetSpaceUsecase, private val deleteSpaceUsecase: DeleteSpaceUsecase, - private val updateSpaceIndexUsecase: UpdateSpaceIndexUsecase, + private val updateSpaceUsecase: UpdateSpaceUsecase, ) : SpaceApi { override fun getMainSpace(userId: String): MainSpaceInfoResponse { val response = @@ -83,14 +83,18 @@ class SpaceController( request: UpdateSpaceOrderRequest, userId: String, ) { - updateSpaceIndexUsecase.update( - UpdateSpaceIndexUsecase.Command( + updateSpaceUsecase.update( + UpdateSpaceUsecase.Command.Index( userId = userId, - orders = request.orders.map { UpdateSpaceIndexUsecase.Command.SpaceOrder(it.spaceId, it.index) }, + orders = request.orders.map { UpdateSpaceUsecase.Command.SpaceOrder(it.spaceId, it.index) }, ), ) } + override fun updateSpaceMain(spaceId: String, userId: String) { + + } + override fun deleteSpaces( request: DeleteMultipleSpacesRequest, userId: String, diff --git a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/acceptance/space/controller/SpaceControllerTest.kt b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/acceptance/space/controller/SpaceControllerTest.kt index 197c8578..693dbe81 100644 --- a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/acceptance/space/controller/SpaceControllerTest.kt +++ b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/acceptance/space/controller/SpaceControllerTest.kt @@ -33,7 +33,7 @@ class SpaceControllerTest : AcceptanceSupporter() { lateinit var deleteSpaceUsecase: DeleteSpaceUsecase @MockBean - lateinit var updateSpaceIndexUsecase: UpdateSpaceIndexUsecase + lateinit var updateSpaceUsecase: UpdateSpaceUsecase @Test fun getMainSpaceId() { @@ -293,4 +293,20 @@ class SpaceControllerTest : AcceptanceSupporter() { } } } + + @Test + fun updateSpaceMain() { + // given + val accessToken = jwtMockManager.generateAccessToken() + val spaceId = "spaceId" + // when + val response = + mockMvc.put("/api/v1/spaces/$spaceId/main") { + header("Authorization", "Bearer $accessToken") + } + // then + response.andExpect { + status { isOk() } + } + } } diff --git a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt index ea722543..32805e4a 100644 --- a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt +++ b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt @@ -1,18 +1,19 @@ package com.asap.bootstrap.integration.space import com.asap.application.space.SpaceMockManager +import com.asap.application.space.port.out.SpaceManagementPort import com.asap.bootstrap.IntegrationSupporter import com.asap.bootstrap.web.space.dto.CreateSpaceRequest import com.asap.bootstrap.web.space.dto.DeleteMultipleSpacesRequest import com.asap.bootstrap.web.space.dto.UpdateSpaceNameRequest import com.asap.bootstrap.web.space.dto.UpdateSpaceOrderRequest +import com.asap.domain.common.DomainId import io.kotest.matchers.maps.haveValue import io.kotest.matchers.shouldBe import io.kotest.matchers.string.haveLength import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test -import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.MediaType import org.springframework.test.web.servlet.delete import org.springframework.test.web.servlet.get @@ -20,9 +21,10 @@ import org.springframework.test.web.servlet.post import org.springframework.test.web.servlet.put import java.util.* -class SpaceApiIntegrationTest : IntegrationSupporter() { - @Autowired - lateinit var spaceMockManager: SpaceMockManager +class SpaceApiIntegrationTest( + private val spaceMockManager: SpaceMockManager, + private val spaceManagementPort: SpaceManagementPort +) : IntegrationSupporter() { @Nested inner class GetMainSpace { @@ -190,26 +192,31 @@ class SpaceApiIntegrationTest : IntegrationSupporter() { } } - @Test - fun updateSpaceName() { - // given - val userId = userMockManager.settingUser() - val accessToken = jwtMockManager.generateAccessToken(userId) - val spaceId = spaceMockManager.settingSpace(userId).id.value - val request = - UpdateSpaceNameRequest( - spaceName = "change space name", - ) - // when - val response = - mockMvc.put("/api/v1/spaces/$spaceId/name") { - contentType = MediaType.APPLICATION_JSON - content = objectMapper.writeValueAsString(request) - header("Authorization", "Bearer $accessToken") + + @Nested + @DisplayName("updateSpaceName") + inner class UpdateSpaceName{ + @Test + fun updateSpaceName() { + // given + val userId = userMockManager.settingUser() + val accessToken = jwtMockManager.generateAccessToken(userId) + val spaceId = spaceMockManager.settingSpace(userId).id.value + val request = + UpdateSpaceNameRequest( + spaceName = "change space name", + ) + // when + val response = + mockMvc.put("/api/v1/spaces/$spaceId/name") { + contentType = MediaType.APPLICATION_JSON + content = objectMapper.writeValueAsString(request) + header("Authorization", "Bearer $accessToken") + } + // then + response.andExpect { + status { isOk() } } - // then - response.andExpect { - status { isOk() } } } @@ -612,4 +619,35 @@ class SpaceApiIntegrationTest : IntegrationSupporter() { } } } + + @Nested + @DisplayName("updateSpaceMain") + inner class UpdateSpaceMain{ + @Test + fun updateSpaceMain() { + // given + val userId = userMockManager.settingUser() + val accessToken = jwtMockManager.generateAccessToken(userId) + val spaceId = spaceMockManager.settingSpace(userId).id.value + (0..2).forEach { + spaceMockManager.settingSpace(userId) + } + // when + val response = + mockMvc.put("/api/v1/spaces/$spaceId/main") { + header("Authorization", "Bearer $accessToken") + } + // then + response.andExpect { + status { isOk() } + } + spaceManagementPort.getAllSpaceBy(DomainId(userId)).forEach { + if(it.id.value == spaceId) { + it.isMain shouldBe true + }else{ + it.isMain shouldBe false + } + } + } + } } diff --git a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/IndexedSpace.kt b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/IndexedSpace.kt index 7ba52386..9b6482ca 100644 --- a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/IndexedSpace.kt +++ b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/IndexedSpace.kt @@ -9,9 +9,8 @@ class IndexedSpace( val name: String, var index: Int, val templateType: Int, + var isMain: Boolean = false, ) : Aggregate(id) { - fun isMain(): Boolean = index == 0 - fun updateIndex(index: Int) { check(index >= 0) { "Index must be greater than or equal to 0" } this.index = index diff --git a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt index 2c2ac534..588f09a3 100644 --- a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt +++ b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt @@ -9,6 +9,7 @@ class Space( val userId: DomainId, var name: String, val templateType: Int, + var isMain: Boolean = false, ) : Aggregate(id) { companion object { fun create( From a20aa9e3976c48f08d15ba5af63e99317cfb590a Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 22:25:16 +0900 Subject: [PATCH 3/9] =?UTF-8?q?ASAP-409=20IndexedSpace=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../space/port/out/SpaceManagementPort.kt | 17 +---- .../space/service/SpaceCommandService.kt | 27 ++++--- .../space/service/SpaceQueryService.kt | 2 +- .../space/service/SpaceCommandServiceTest.kt | 39 ++++------ .../space/service/SpaceQueryServiceTest.kt | 72 +++++-------------- .../application/space/SpaceMockManager.kt | 7 +- .../asap/domain/space/entity/IndexedSpace.kt | 18 ----- .../com/asap/domain/space/entity/Space.kt | 14 ++++ .../space/service/SpaceIndexValidator.kt | 12 ++-- .../kotlin/com/asap/domain/SpaceFixture.kt | 24 +++++++ .../asap/persistence/jpa/space/SpaceMapper.kt | 14 +--- .../adapter/SpaceManagementJpaAdapter.kt | 59 ++++----------- .../jpa/space/entity/SpaceEntity.kt | 3 +- 13 files changed, 115 insertions(+), 193 deletions(-) delete mode 100644 Domain-Module/src/main/kotlin/com/asap/domain/space/entity/IndexedSpace.kt create mode 100644 Domain-Module/src/testFixtures/kotlin/com/asap/domain/SpaceFixture.kt diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/port/out/SpaceManagementPort.kt b/Application-Module/src/main/kotlin/com/asap/application/space/port/out/SpaceManagementPort.kt index 88c35382..b9973535 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/port/out/SpaceManagementPort.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/port/out/SpaceManagementPort.kt @@ -1,7 +1,6 @@ package com.asap.application.space.port.out import com.asap.domain.common.DomainId -import com.asap.domain.space.entity.IndexedSpace import com.asap.domain.space.entity.MainSpace import com.asap.domain.space.entity.Space @@ -13,13 +12,6 @@ interface SpaceManagementPort { spaceId: DomainId, ): Space - fun getIndexedSpaceNotNull( - userId: DomainId, - spaceId: DomainId, - ): IndexedSpace - - fun getAllIndexedSpace(userId: DomainId): List - fun getAllSpaceBy( userId: DomainId, spaceIds: List, @@ -29,14 +21,9 @@ interface SpaceManagementPort { fun save(space: Space): Space - fun update(space: Space): Space - - fun update(indexedSpace: IndexedSpace): IndexedSpace + fun saveAll(spaces: List): List - fun updateIndexes( - userId: DomainId, - orders: List, - ) + fun update(space: Space): Space fun deleteBy(space: Space) diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt index 4d71f7f8..02df0294 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt @@ -77,30 +77,27 @@ class SpaceCommandService( } override fun update(command: UpdateSpaceUsecase.Command.Index) { - val indexedSpaces = spaceManagementPort.getAllIndexedSpace(DomainId(command.userId)) + val spaces = spaceManagementPort.getAllSpaceBy(DomainId(command.userId)) val changeIndexMap = command.orders.associateBy({ DomainId(it.spaceId) }, { it.index }) try { spaceIndexValidator.validate( - indexedSpaces = indexedSpaces, + spaces = spaces, // todo: space로 수정하기 validateIndex = changeIndexMap, ) } catch (e: DefaultException.InvalidArgumentException) { - throw SpaceException.InvalidSpaceUpdateException() + throw SpaceException.InvalidSpaceUpdateException(message = e.message) } - indexedSpaces.map { + spaces.map { it.updateIndex(changeIndexMap.getValue(it.id)) } - spaceManagementPort.updateIndexes( - userId = DomainId(command.userId), - orders = indexedSpaces, - ) + spaceManagementPort.saveAll(spaces) } private fun reIndexingSpaceOrder(userId: DomainId) { spaceManagementPort - .getAllIndexedSpace(userId) + .getAllSpaceBy(userId) .sortedBy { it.index } .forEachIndexed { index, indexedSpace -> indexedSpace.updateIndex(index) @@ -109,6 +106,16 @@ class SpaceCommandService( } override fun update(command: UpdateSpaceUsecase.Command.Main) { - TODO("Not yet implemented") + val spaces = spaceManagementPort.getAllSpaceBy( + userId = DomainId(command.userId), + ).map { + if(it.id.value == command.spaceId){ + it.updateToMain() + }else{ + it.updateToSub() + } + } + + } } diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceQueryService.kt b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceQueryService.kt index 4a041cee..e64dc805 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceQueryService.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceQueryService.kt @@ -37,7 +37,7 @@ class SpaceQueryService( override fun getAll(query: GetSpaceUsecase.GetAllQuery): GetSpaceUsecase.GetAllResponse { val spaces = - spaceManagementPort.getAllIndexedSpace( + spaceManagementPort.getAllSpaceBy( userId = DomainId(query.userId), ) diff --git a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt index 1e27d7f1..9d44dd45 100644 --- a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt +++ b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt @@ -6,8 +6,8 @@ import com.asap.application.space.port.`in`.DeleteSpaceUsecase import com.asap.application.space.port.`in`.UpdateSpaceNameUsecase import com.asap.application.space.port.`in`.UpdateSpaceUsecase import com.asap.application.space.port.out.SpaceManagementPort +import com.asap.domain.SpaceFixture import com.asap.domain.common.DomainId -import com.asap.domain.space.entity.IndexedSpace import com.asap.domain.space.entity.Space import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec @@ -122,38 +122,23 @@ class SpaceCommandServiceTest : UpdateSpaceUsecase.Command.SpaceOrder("spaceId2", 0), ), ) - val indexedSpaces = + val spaces = listOf( - IndexedSpace( - id = DomainId("spaceId1"), - userId = DomainId("userId"), - name = "space1", - index = 0, - templateType = 1, + SpaceFixture.createSpace( + id = DomainId(spaceUpdateIndexCommand.orders[0].spaceId), + userId = DomainId(spaceUpdateIndexCommand.userId), ), - IndexedSpace( - id = DomainId("spaceId2"), - userId = DomainId("userId"), - name = "space2", - index = 1, - templateType = 1, + SpaceFixture.createSpace( + id = DomainId(spaceUpdateIndexCommand.orders[1].spaceId), + userId = DomainId(spaceUpdateIndexCommand.userId), ), ) - every { spaceManagementPort.getAllIndexedSpace(DomainId(spaceUpdateIndexCommand.userId)) } returns indexedSpaces + every { spaceManagementPort.getAllSpaceBy(DomainId(spaceUpdateIndexCommand.userId)) } returns spaces `when`("유저 아이디, 스페이스 순서가 주어진다면") { spaceCommandService.update(spaceUpdateIndexCommand) then("스페이스 순서를 수정한다") { - indexedSpaces[0].updateIndex(1) - indexedSpaces[1].updateIndex(0) verify { - spaceManagementPort.updateIndexes( - userId = DomainId(spaceUpdateIndexCommand.userId), - orders = - listOf( - indexedSpaces[0], - indexedSpaces[1], - ), - ) + spaceManagementPort.saveAll(spaces) } } } @@ -169,8 +154,8 @@ class SpaceCommandServiceTest : ), ) every { - spaceManagementPort.getAllIndexedSpace(DomainId(invalidCommand.userId)) - } returns indexedSpaces + spaceManagementPort.getAllSpaceBy(DomainId(invalidCommand.userId)) + } returns spaces `when`("인덱스 검증과정에서 예외가 발생한다면") { then("스페이스 순서를 수정하지 않는다") { shouldThrow { diff --git a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceQueryServiceTest.kt b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceQueryServiceTest.kt index a4cb214d..1efbc557 100644 --- a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceQueryServiceTest.kt +++ b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceQueryServiceTest.kt @@ -5,9 +5,9 @@ import com.asap.application.space.port.`in`.GetMainSpaceUsecase import com.asap.application.space.port.`in`.GetSpaceUsecase import com.asap.application.space.port.out.SpaceManagementPort import com.asap.application.user.port.out.UserManagementPort +import com.asap.domain.SpaceFixture import com.asap.domain.UserFixture import com.asap.domain.common.DomainId -import com.asap.domain.space.entity.IndexedSpace import com.asap.domain.space.entity.MainSpace import com.asap.domain.space.entity.Space import io.kotest.core.spec.style.BehaviorSpec @@ -62,41 +62,23 @@ class SpaceQueryServiceTest : } given("모든 스페이스 조회 요청이 들어왔을 때") { - val indexedSpaces = - listOf( - IndexedSpace( - id = DomainId.generate(), - name = "name", - index = 0, - userId = DomainId("userId"), - templateType = 1, - ), - IndexedSpace( - id = DomainId.generate(), - name = "name", - index = 1, - userId = DomainId("userId"), - templateType = 1, - ), - IndexedSpace( - id = DomainId.generate(), - name = "name", - index = 2, - userId = DomainId("userId"), - templateType = 1, - ), + val spaces = (0..2).mapIndexed { index, _ -> + SpaceFixture.createSpace( + userId = DomainId("userId"), + index = index, ) - val indexedSpaceMap = indexedSpaces.associateBy { it.id } + } + val indexedSpaceMap = spaces.associateBy { it.id } val query = GetSpaceUsecase.GetAllQuery( userId = "userId", ) - every { spaceManagementPort.getAllIndexedSpace(DomainId(query.userId)) } returns indexedSpaces + every { spaceManagementPort.getAllSpaceBy(DomainId(query.userId)) } returns spaces every { spaceLetterManagementPort.countSpaceLetterBy(any(), any()) } returns 0 `when`("유저 아이디가 주어진다면") { val response = spaceQueryService.getAll(query) then("모든 스페이스를 반환한다") { - response.spaces.size shouldBe indexedSpaces.size + response.spaces.size shouldBe spaces.size response.spaces.forEach { spaceDetail -> val indexedSpace = indexedSpaceMap[DomainId(spaceDetail.spaceId)] indexedSpace.shouldNotBeNull { @@ -111,42 +93,24 @@ class SpaceQueryServiceTest : } given("행성 모두 조회 요청이 들어왔을 때") { - val indexedSpaces = - listOf( - IndexedSpace( - id = DomainId.generate(), - name = "name", - index = 0, - userId = DomainId("userId"), - templateType = 1, - ), - IndexedSpace( - id = DomainId.generate(), - name = "name", - index = 1, - userId = DomainId("userId"), - templateType = 1, - ), - IndexedSpace( - id = DomainId.generate(), - name = "name", - index = 2, - userId = DomainId("userId"), - templateType = 1, - ), + val spaces = (0..2).mapIndexed { index, _ -> + SpaceFixture.createSpace( + userId = DomainId("userId"), + index = index, ) - val indexedSpaceMap = indexedSpaces.associateBy { it.id } + } + val spaceMap = spaces.associateBy { it.id } val query = GetSpaceUsecase.GetAllQuery( userId = "userId", ) - every { spaceManagementPort.getAllIndexedSpace(DomainId(query.userId)) } returns indexedSpaces + every { spaceManagementPort.getAllSpaceBy(DomainId(query.userId)) } returns spaces `when`("유저 아이디가 주어진다면") { val response = spaceQueryService.getAll(query) then("모든 스페이스를 반환한다") { - response.spaces.size shouldBe indexedSpaces.size + response.spaces.size shouldBe spaces.size response.spaces.forEach { spaceDetail -> - val indexedSpace = indexedSpaceMap[DomainId(spaceDetail.spaceId)] + val indexedSpace = spaceMap[DomainId(spaceDetail.spaceId)] indexedSpace.shouldNotBeNull { this.id shouldBe DomainId(spaceDetail.spaceId) this.name shouldBe spaceDetail.spaceName diff --git a/Application-Module/src/testFixtures/kotlin/com/asap/application/space/SpaceMockManager.kt b/Application-Module/src/testFixtures/kotlin/com/asap/application/space/SpaceMockManager.kt index 4514cce4..ad7aadfc 100644 --- a/Application-Module/src/testFixtures/kotlin/com/asap/application/space/SpaceMockManager.kt +++ b/Application-Module/src/testFixtures/kotlin/com/asap/application/space/SpaceMockManager.kt @@ -18,15 +18,10 @@ class SpaceMockManager( templateType = 0, ) return spaceManagementPort.save(space).also { - spaceManagementPort.getIndexedSpaceNotNull(DomainId(userId), it.id).apply { + spaceManagementPort.getSpaceNotNull(DomainId(userId), it.id).apply { updateIndex(index) spaceManagementPort.update(this) } } } - - fun getSpaceIndexes(userId: String): List> = - spaceManagementPort.getAllIndexedSpace(DomainId(userId)).map { - it.id.value to it.index - } } diff --git a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/IndexedSpace.kt b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/IndexedSpace.kt deleted file mode 100644 index 9b6482ca..00000000 --- a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/IndexedSpace.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.asap.domain.space.entity - -import com.asap.domain.common.Aggregate -import com.asap.domain.common.DomainId - -class IndexedSpace( - id: DomainId, - val userId: DomainId, - val name: String, - var index: Int, - val templateType: Int, - var isMain: Boolean = false, -) : Aggregate(id) { - fun updateIndex(index: Int) { - check(index >= 0) { "Index must be greater than or equal to 0" } - this.index = index - } -} diff --git a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt index 588f09a3..0aa16943 100644 --- a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt +++ b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt @@ -8,6 +8,7 @@ class Space( id: DomainId, val userId: DomainId, var name: String, + var index: Int = 0, val templateType: Int, var isMain: Boolean = false, ) : Aggregate(id) { @@ -32,6 +33,19 @@ class Space( this.name = name } + fun updateToMain() { + this.isMain = true + } + + fun updateToSub() { + this.isMain = false + } + + fun updateIndex(index: Int) { + check(index >= 0) { "Index must be greater than or equal to 0" } + this.index = index + } + fun delete() { this.registerEvent(SpaceEvent.SpaceDeletedEvent(this)) } diff --git a/Domain-Module/src/main/kotlin/com/asap/domain/space/service/SpaceIndexValidator.kt b/Domain-Module/src/main/kotlin/com/asap/domain/space/service/SpaceIndexValidator.kt index 89b64ebe..507ed301 100644 --- a/Domain-Module/src/main/kotlin/com/asap/domain/space/service/SpaceIndexValidator.kt +++ b/Domain-Module/src/main/kotlin/com/asap/domain/space/service/SpaceIndexValidator.kt @@ -2,20 +2,20 @@ package com.asap.domain.space.service import com.asap.common.exception.DefaultException import com.asap.domain.common.DomainId -import com.asap.domain.space.entity.IndexedSpace +import com.asap.domain.space.entity.Space class SpaceIndexValidator { - fun validate(indexedSpaces: List, validateIndex: Map){ - val indexedSpaceSize = indexedSpaces.size + fun validate(spaces: List, validateIndex: Map){ + val spaceSize = spaces.size val indexSet = validateIndex.values.toSet() - if (indexSet.size != indexedSpaceSize) { + if (indexSet.size != spaceSize) { throw DefaultException.InvalidArgumentException("요청 인덱스가 기존 엔덱스와 일치하지 않습니다.") } - if (indexSet.minOrNull() != 0 || indexSet.maxOrNull() != indexedSpaceSize - 1) { + if (indexSet.minOrNull() != 0 || indexSet.maxOrNull() != spaceSize - 1) { throw DefaultException.InvalidArgumentException("인덱스 범위가 기존 인덱스 범위와 일치하지 않습니다.") } - indexedSpaces.forEach { + spaces.forEach { if(validateIndex.containsKey(it.id).not()){ throw DefaultException.InvalidArgumentException("사용자의 스페이스에 포함되지 않은 요청이 있습니다.") } diff --git a/Domain-Module/src/testFixtures/kotlin/com/asap/domain/SpaceFixture.kt b/Domain-Module/src/testFixtures/kotlin/com/asap/domain/SpaceFixture.kt new file mode 100644 index 00000000..d10dc7a2 --- /dev/null +++ b/Domain-Module/src/testFixtures/kotlin/com/asap/domain/SpaceFixture.kt @@ -0,0 +1,24 @@ +package com.asap.domain + +import com.asap.domain.common.DomainId +import com.asap.domain.space.entity.Space + +object SpaceFixture { + fun createSpace( + id: DomainId = DomainId.generate(), + userId: DomainId = DomainId.generate(), + name: String = "test", + templateType: Int = 0, + index : Int = 0, + isMain: Boolean = false, + ): Space { + return Space( + id = id, + userId = userId, + name = name, + templateType = templateType, + index = index, + isMain = isMain + ) + } +} \ No newline at end of file diff --git a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/SpaceMapper.kt b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/SpaceMapper.kt index d38fe559..f6c8a095 100644 --- a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/SpaceMapper.kt +++ b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/SpaceMapper.kt @@ -1,7 +1,6 @@ package com.asap.persistence.jpa.space import com.asap.domain.common.DomainId -import com.asap.domain.space.entity.IndexedSpace import com.asap.domain.space.entity.MainSpace import com.asap.domain.space.entity.Space import com.asap.persistence.jpa.space.entity.SpaceEntity @@ -18,25 +17,18 @@ object SpaceMapper { userId = DomainId(spaceEntity.userId), name = spaceEntity.name, templateType = spaceEntity.templateType, - ) - - fun toIndexedSpace(spaceEntity: SpaceEntity) = - IndexedSpace( - id = DomainId(spaceEntity.id), - userId = DomainId(spaceEntity.userId), - name = spaceEntity.name, - templateType = spaceEntity.templateType, index = spaceEntity.index, + isMain = spaceEntity.isMain, ) fun toSpaceEntity( space: Space, - index: Int, ) = SpaceEntity( id = space.id.value, userId = space.userId.value, name = space.name, templateType = space.templateType, - index = index, + index = space.index, + isMain = space.isMain, ) } diff --git a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt index faa00365..db2f4eab 100644 --- a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt +++ b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt @@ -4,7 +4,6 @@ import com.asap.application.space.exception.SpaceException import com.asap.application.space.port.out.SpaceManagementPort import com.asap.common.event.EventPublisher import com.asap.domain.common.DomainId -import com.asap.domain.space.entity.IndexedSpace import com.asap.domain.space.entity.MainSpace import com.asap.domain.space.entity.Space import com.asap.persistence.jpa.space.SpaceMapper @@ -33,22 +32,6 @@ class SpaceManagementJpaAdapter( SpaceMapper.toSpace(it) } ?: throw SpaceException.SpaceNotFoundException() - override fun getIndexedSpaceNotNull( - userId: DomainId, - spaceId: DomainId, - ): IndexedSpace { - spaceJpaRepository.findActiveSpaceByIdAndUserId(spaceId.value, userId.value)?.let { - return SpaceMapper.toIndexedSpace(it) - } ?: throw SpaceException.SpaceNotFoundException() - } - - override fun getAllIndexedSpace(userId: DomainId): List = - spaceJpaRepository - .findAllActiveSpaceByUserId(userId.value) - .map { - SpaceMapper.toIndexedSpace(it) - }.sortedBy { it.index } - override fun getAllSpaceBy( userId: DomainId, spaceIds: List, @@ -74,7 +57,6 @@ class SpaceManagementJpaAdapter( val entity = SpaceMapper.toSpaceEntity( space = space, - index = -1, ) return spaceJpaRepository .save(entity) @@ -85,6 +67,21 @@ class SpaceManagementJpaAdapter( } } + override fun saveAll(spaces: List): List { + val entities = spaces.map { + SpaceMapper.toSpaceEntity( + space = it, + ) + } + return spaceJpaRepository + .saveAll(entities) + .map { + SpaceMapper.toSpace(it) + }.also { + eventPublisher.publishAll(spaces.flatMap { it.pullEvents() }) + } + } + override fun update(space: Space): Space = spaceJpaRepository.findActiveSpaceByIdAndUserId(space.id.value, space.userId.value)?.let { it.update(space) @@ -95,32 +92,6 @@ class SpaceManagementJpaAdapter( SpaceMapper.toSpace(it) } ?: throw SpaceException.SpaceNotFoundException() - override fun update(indexedSpace: IndexedSpace): IndexedSpace { - spaceJpaRepository.findActiveSpaceByIdAndUserId(indexedSpace.id.value, indexedSpace.userId.value)?.let { - it.index = indexedSpace.index - spaceJpaRepository.save(it) - } ?: throw SpaceException.SpaceNotFoundException() - - eventPublisher.publishAll(indexedSpace.pullEvents()) - - return indexedSpace - } - - override fun updateIndexes( - userId: DomainId, - orders: List, - ) { - val spaces = spaceJpaRepository.findAllActiveSpaceByUserId(userId.value) - orders.forEach { order -> - spaces.find { it.id == order.id.value }?.let { - it.index = order.index - spaceJpaRepository.save(it) - } - } - - eventPublisher.publishAll(orders.flatMap { it.pullEvents() }) - } - override fun deleteBy(space: Space) { spaceJpaRepository.deleteByUserIdAndId( userId = space.userId.value, diff --git a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/entity/SpaceEntity.kt b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/entity/SpaceEntity.kt index 1abc4802..289364cd 100644 --- a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/entity/SpaceEntity.kt +++ b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/entity/SpaceEntity.kt @@ -14,6 +14,7 @@ class SpaceEntity( name: String, templateType: Int, index: Int, + isMain: Boolean, ) : AggregateRoot(id) { @Column(name = "user_id", nullable = false) var userId: String = userId @@ -44,7 +45,7 @@ class SpaceEntity( name = "is_main", nullable = false, ) - var isMain: Boolean = false + var isMain: Boolean = isMain fun update(space: Space) { this.userId = space.userId.value From 0e6188dbb74db52be3fea096561a6848b2170fcf Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 22:28:24 +0900 Subject: [PATCH 4/9] =?UTF-8?q?ASAP-409=20=EC=8A=A4=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=EB=A5=BC=20=EB=A9=94=EC=9D=B8=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=95=98=EB=8A=94=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/space/service/SpaceCommandService.kt | 8 ++++---- .../bootstrap/web/space/controller/SpaceController.kt | 7 ++++++- .../integration/space/SpaceApiIntegrationTest.kt | 9 +++++---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt index 02df0294..86180320 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt @@ -108,14 +108,14 @@ class SpaceCommandService( override fun update(command: UpdateSpaceUsecase.Command.Main) { val spaces = spaceManagementPort.getAllSpaceBy( userId = DomainId(command.userId), - ).map { - if(it.id.value == command.spaceId){ + ).onEach { + if (it.id.value == command.spaceId) { it.updateToMain() - }else{ + } else { it.updateToSub() } } - + spaceManagementPort.saveAll(spaces) } } diff --git a/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/controller/SpaceController.kt b/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/controller/SpaceController.kt index cb871887..914f01c3 100644 --- a/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/controller/SpaceController.kt +++ b/Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/space/controller/SpaceController.kt @@ -92,7 +92,12 @@ class SpaceController( } override fun updateSpaceMain(spaceId: String, userId: String) { - + updateSpaceUsecase.update( + UpdateSpaceUsecase.Command.Main( + userId = userId, + spaceId = spaceId, + ), + ) } override fun deleteSpaces( diff --git a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt index 32805e4a..2292942d 100644 --- a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt +++ b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt @@ -451,10 +451,11 @@ class SpaceApiIntegrationTest( response.andExpect { status { isOk() } } - spaceMockManager.getSpaceIndexes(userId) shouldBe - spaceIndexes - .map { it.spaceId to it.index } - .sortedBy { it.second } + // TODO: port를 통해 조회하고 검증해야함 +// spaceMockManager.getSpaceIndexes(userId) shouldBe +// spaceIndexes +// .map { it.spaceId to it.index } +// .sortedBy { it.second } } @Test From d05221c52707b91a1d6129239b97272e1225cf3f Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 22:42:50 +0900 Subject: [PATCH 5/9] =?UTF-8?q?ASAP-409=20=EA=B8=B0=EC=A1=B4=20"=EC=B2=AB?= =?UTF-8?q?=EB=B2=88=EC=A7=B8=20=ED=96=89=EC=84=B1=EC=9D=B4=EB=A9=B4=20?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=ED=96=89=EC=84=AC=EC=9D=B4=EB=8B=A4"=20?= =?UTF-8?q?=EC=A0=95=EC=B1=85=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../space/service/SpaceCommandService.kt | 54 +++++++++++++------ .../letter/service/LetterQueryServiceTest.kt | 12 ++--- .../space/service/SpaceCommandServiceTest.kt | 14 ++--- .../space/service/SpaceQueryServiceTest.kt | 22 +++----- .../application/space/SpaceMockManager.kt | 4 ++ .../space/SpaceApiIntegrationTest.kt | 7 +-- .../com/asap/domain/space/entity/Space.kt | 4 +- 7 files changed, 65 insertions(+), 52 deletions(-) diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt index 86180320..b12f22f7 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt @@ -24,15 +24,18 @@ class SpaceCommandService( private val spaceIndexValidator: SpaceIndexValidator = SpaceIndexValidator() override fun create(command: CreateSpaceUsecase.Command) { + val userId = DomainId(command.userId) Space .create( - userId = DomainId(command.userId), + userId = userId, name = command.spaceName, templateType = command.templateType, ).apply { spaceManagementPort.save(this) } - reIndexingSpaceOrder(DomainId(command.userId)) + + updateMainSpace(userId) + reIndexingSpaceOrder(userId) } override fun update(command: UpdateSpaceNameUsecase.Command) { @@ -46,27 +49,31 @@ class SpaceCommandService( } override fun deleteOne(command: DeleteSpaceUsecase.DeleteOneCommand) { + val userId = DomainId(command.userId) spaceManagementPort .getSpaceNotNull( - userId = DomainId(command.userId), + userId = userId, spaceId = DomainId(command.spaceId), ).apply { delete() spaceManagementPort.deleteBy(this) } - reIndexingSpaceOrder(DomainId(command.userId)) + updateMainSpace(userId) + reIndexingSpaceOrder(userId) } override fun deleteAllBy(command: DeleteSpaceUsecase.DeleteAllCommand) { + val userId = DomainId(command.userId) spaceManagementPort .getAllSpaceBy( - userId = DomainId(command.userId), + userId = userId, spaceIds = command.spaceIds.map { DomainId(it) }, ).forEach { it.delete() spaceManagementPort.deleteBy(it) } - reIndexingSpaceOrder(DomainId(command.userId)) + updateMainSpace(userId) + reIndexingSpaceOrder(userId) } override fun deleteAllBy(command: DeleteSpaceUsecase.DeleteAllUser) { @@ -95,16 +102,6 @@ class SpaceCommandService( spaceManagementPort.saveAll(spaces) } - private fun reIndexingSpaceOrder(userId: DomainId) { - spaceManagementPort - .getAllSpaceBy(userId) - .sortedBy { it.index } - .forEachIndexed { index, indexedSpace -> - indexedSpace.updateIndex(index) - spaceManagementPort.update(indexedSpace) - } - } - override fun update(command: UpdateSpaceUsecase.Command.Main) { val spaces = spaceManagementPort.getAllSpaceBy( userId = DomainId(command.userId), @@ -118,4 +115,29 @@ class SpaceCommandService( spaceManagementPort.saveAll(spaces) } + + private fun reIndexingSpaceOrder(userId: DomainId) { + val spaces = spaceManagementPort + .getAllSpaceBy(userId) + .sortedBy { it.index } + .onEachIndexed { index, space -> + space.updateIndex(index) + } + spaceManagementPort.saveAll(spaces) + } + + + private fun updateMainSpace(userId: DomainId) { + val spaces = spaceManagementPort.getAllSpaceBy(userId) + + if (spaces.isEmpty()) { + return + } + + if (spaces.size == 1) { + spaces[0].updateToMain() + spaceManagementPort.save(spaces[0]) + return + } + } } diff --git a/Application-Module/src/test/kotlin/com/asap/application/letter/service/LetterQueryServiceTest.kt b/Application-Module/src/test/kotlin/com/asap/application/letter/service/LetterQueryServiceTest.kt index f5d56e9e..18e67b7c 100644 --- a/Application-Module/src/test/kotlin/com/asap/application/letter/service/LetterQueryServiceTest.kt +++ b/Application-Module/src/test/kotlin/com/asap/application/letter/service/LetterQueryServiceTest.kt @@ -7,9 +7,9 @@ import com.asap.application.letter.port.out.SpaceLetterManagementPort import com.asap.application.space.port.out.SpaceManagementPort import com.asap.application.user.port.out.UserManagementPort import com.asap.domain.LetterFixture +import com.asap.domain.SpaceFixture import com.asap.domain.UserFixture import com.asap.domain.common.DomainId -import com.asap.domain.space.entity.Space import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe @@ -96,13 +96,9 @@ class LetterQueryServiceTest : letterId = "letter-id", userId = "user-id", ) - val space = - Space( - id = DomainId.generate(), - name = "space-name", - userId = DomainId(query.userId), - templateType = 1, - ) + val space = SpaceFixture.createSpace( + userId = DomainId(query.userId), + ) val spaceLetter = LetterFixture.generateSpaceLetter(receiverId = DomainId(query.userId), spaceId = space.id) val prevSpaceLetter = LetterFixture.generateSpaceLetter(receiverId = DomainId(query.userId), spaceId = space.id) diff --git a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt index 9d44dd45..cc7fd7c4 100644 --- a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt +++ b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceCommandServiceTest.kt @@ -49,13 +49,13 @@ class SpaceCommandServiceTest : spaceId = "spaceId", name = "newName", ) - val mockSpace = - Space( - id = DomainId(spaceUpdateNameCommand.spaceId), - userId = DomainId(spaceUpdateNameCommand.userId), - name = "oldName", - templateType = 1, - ) + val mockSpace = SpaceFixture.createSpace( + id = DomainId(spaceUpdateNameCommand.spaceId), + userId = DomainId(spaceUpdateNameCommand.userId), + name = "oldName", + templateType = 1, + ) + every { spaceManagementPort.getSpaceNotNull( userId = DomainId(spaceUpdateNameCommand.userId), diff --git a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceQueryServiceTest.kt b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceQueryServiceTest.kt index 1efbc557..b6ca5ccc 100644 --- a/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceQueryServiceTest.kt +++ b/Application-Module/src/test/kotlin/com/asap/application/space/service/SpaceQueryServiceTest.kt @@ -9,7 +9,6 @@ import com.asap.domain.SpaceFixture import com.asap.domain.UserFixture import com.asap.domain.common.DomainId import com.asap.domain.space.entity.MainSpace -import com.asap.domain.space.entity.Space import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe @@ -40,13 +39,9 @@ class SpaceQueryServiceTest : GetMainSpaceUsecase.Query( userId = user.id.value, ) - val space = - Space( - id = mainSpace.id, - name = "name", - userId = user.id, - templateType = 1, - ) + val space = SpaceFixture.createSpace( + userId = user.id, + ) every { spaceManagementPort.getMainSpace(any()) } returns mainSpace every { userManagementPort.getUserNotNull(any()) } returns user every { spaceManagementPort.getSpaceNotNull(any(), any()) } returns space @@ -123,13 +118,10 @@ class SpaceQueryServiceTest : } given("행성 조회 요청이 들어왔을 때") { - val space = - Space( - id = DomainId.generate(), - name = "name", - userId = DomainId("userId"), - templateType = 1, - ) + val space = SpaceFixture.createSpace( + id = DomainId("spaceId"), + userId = DomainId("userId"), + ) val query = GetSpaceUsecase.GetQuery( userId = "userId", diff --git a/Application-Module/src/testFixtures/kotlin/com/asap/application/space/SpaceMockManager.kt b/Application-Module/src/testFixtures/kotlin/com/asap/application/space/SpaceMockManager.kt index ad7aadfc..f9d6510f 100644 --- a/Application-Module/src/testFixtures/kotlin/com/asap/application/space/SpaceMockManager.kt +++ b/Application-Module/src/testFixtures/kotlin/com/asap/application/space/SpaceMockManager.kt @@ -10,13 +10,17 @@ class SpaceMockManager( fun settingSpace( userId: String, index: Int = 0, + isMain: Boolean = false, ): Space { val space = Space.create( userId = DomainId(userId), name = "test", templateType = 0, + index = index, ) + if(isMain) space.updateToMain() + return spaceManagementPort.save(space).also { spaceManagementPort.getSpaceNotNull(DomainId(userId), it.id).apply { updateIndex(index) diff --git a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt index 2292942d..a512adb2 100644 --- a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt +++ b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt @@ -33,7 +33,7 @@ class SpaceApiIntegrationTest( // given val userId = userMockManager.settingUser() val accessToken = jwtMockManager.generateAccessToken(userId) - spaceMockManager.settingSpace(userId) + spaceMockManager.settingSpace(userId, isMain = true) // when val response = mockMvc.get("/api/v1/spaces/main") { @@ -140,13 +140,10 @@ class SpaceApiIntegrationTest( } @Test - fun createSpace_and_get_main_space() { + fun create_first_space_and_get_main_space() { // given val userId = userMockManager.settingUser() val accessToken = jwtMockManager.generateAccessToken(userId) - (0..2).forEach { - spaceMockManager.settingSpace(userId) - } val request = CreateSpaceRequest( spaceName = "createdSpace", diff --git a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt index 0aa16943..bcd128d0 100644 --- a/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt +++ b/Domain-Module/src/main/kotlin/com/asap/domain/space/entity/Space.kt @@ -8,7 +8,7 @@ class Space( id: DomainId, val userId: DomainId, var name: String, - var index: Int = 0, + var index: Int, val templateType: Int, var isMain: Boolean = false, ) : Aggregate(id) { @@ -18,12 +18,14 @@ class Space( userId: DomainId, name: String, templateType: Int, + index: Int = -1, ): Space = Space( id = id, userId = userId, name = name, templateType = templateType, + index = index, ).also { it.registerEvent(SpaceEvent.SpaceCreatedEvent(it)) } From aeff1618b35d127b8aa98ce51b3d05d05c03f9b1 Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 22:46:30 +0900 Subject: [PATCH 6/9] =?UTF-8?q?ASAP-409=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../asap/application/space/service/SpaceCommandService.kt | 2 +- .../integration/space/SpaceApiIntegrationTest.kt | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt index b12f22f7..56866d75 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt @@ -89,7 +89,7 @@ class SpaceCommandService( try { spaceIndexValidator.validate( - spaces = spaces, // todo: space로 수정하기 + spaces = spaces, validateIndex = changeIndexMap, ) } catch (e: DefaultException.InvalidArgumentException) { diff --git a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt index a512adb2..208437d4 100644 --- a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt +++ b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt @@ -8,6 +8,7 @@ import com.asap.bootstrap.web.space.dto.DeleteMultipleSpacesRequest import com.asap.bootstrap.web.space.dto.UpdateSpaceNameRequest import com.asap.bootstrap.web.space.dto.UpdateSpaceOrderRequest import com.asap.domain.common.DomainId +import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder import io.kotest.matchers.maps.haveValue import io.kotest.matchers.shouldBe import io.kotest.matchers.string.haveLength @@ -448,11 +449,8 @@ class SpaceApiIntegrationTest( response.andExpect { status { isOk() } } - // TODO: port를 통해 조회하고 검증해야함 -// spaceMockManager.getSpaceIndexes(userId) shouldBe -// spaceIndexes -// .map { it.spaceId to it.index } -// .sortedBy { it.second } + val spaceIds = spaceManagementPort.getAllSpaceBy(DomainId(userId)).map { it.id.value } + spaceIds shouldContainExactlyInAnyOrder spaceIndexes.map { it.spaceId } } @Test From 709de3f6a5fa5c55ce68fcf861d7255fac7b9990 Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 22:58:32 +0900 Subject: [PATCH 7/9] =?UTF-8?q?ASAP-409=20main=20=ED=96=89=EC=84=B1=20?= =?UTF-8?q?=EC=A1=B0=EC=A0=95=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../space/service/SpaceCommandService.kt | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt index 56866d75..18561a94 100644 --- a/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt +++ b/Application-Module/src/main/kotlin/com/asap/application/space/service/SpaceCommandService.kt @@ -25,27 +25,20 @@ class SpaceCommandService( override fun create(command: CreateSpaceUsecase.Command) { val userId = DomainId(command.userId) - Space - .create( - userId = userId, - name = command.spaceName, - templateType = command.templateType, - ).apply { - spaceManagementPort.save(this) - } + Space.create( + userId = userId, + name = command.spaceName, + templateType = command.templateType, + ).apply { + spaceManagementPort.save(this) + } - updateMainSpace(userId) - reIndexingSpaceOrder(userId) - } + // TODO 동시성 문제가 발생한다면? + if (spaceManagementPort.countByUserId(userId) == 1L) { + updateMainSpace(userId) + } - override fun update(command: UpdateSpaceNameUsecase.Command) { - val space = - spaceManagementPort.getSpaceNotNull( - userId = DomainId(command.userId), - spaceId = DomainId(command.spaceId), - ) - space.updateName(command.name) - spaceManagementPort.update(space) + reIndexingSpaceOrder(userId) } override fun deleteOne(command: DeleteSpaceUsecase.DeleteOneCommand) { @@ -116,6 +109,17 @@ class SpaceCommandService( spaceManagementPort.saveAll(spaces) } + override fun update(command: UpdateSpaceNameUsecase.Command) { + val space = + spaceManagementPort.getSpaceNotNull( + userId = DomainId(command.userId), + spaceId = DomainId(command.spaceId), + ) + + space.updateName(command.name) + spaceManagementPort.update(space) + } + private fun reIndexingSpaceOrder(userId: DomainId) { val spaces = spaceManagementPort .getAllSpaceBy(userId) @@ -134,10 +138,9 @@ class SpaceCommandService( return } - if (spaces.size == 1) { - spaces[0].updateToMain() - spaceManagementPort.save(spaces[0]) - return - } + spaces.forEach { it.updateToSub() } + spaces.first().updateToMain() + + spaceManagementPort.saveAll(spaces) } } From d300cd012ff9cacfa4e4564ef90de4789910761c Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 23:01:22 +0900 Subject: [PATCH 8/9] =?UTF-8?q?ASAP-409=20main=20=ED=96=89=EC=84=B1=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt index db2f4eab..4f12b165 100644 --- a/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt +++ b/Infrastructure-Module/Persistence/src/main/kotlin/com/asap/persistence/jpa/space/adapter/SpaceManagementJpaAdapter.kt @@ -19,7 +19,7 @@ class SpaceManagementJpaAdapter( spaceJpaRepository .findAllActiveSpaceByUserId(userId.value) .first { - it.index == 0 + it.isMain }.let { SpaceMapper.toMainSpace(it) } From 92dd7167208ceafda5e7fdfb825cdd40ca396a20 Mon Sep 17 00:00:00 2001 From: Sim-km Date: Sat, 8 Feb 2025 23:03:03 +0900 Subject: [PATCH 9/9] =?UTF-8?q?ASAP-409=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../space/SpaceApiIntegrationTest.kt | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt index 208437d4..e4dc91dc 100644 --- a/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt +++ b/Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/space/SpaceApiIntegrationTest.kt @@ -65,54 +65,6 @@ class SpaceApiIntegrationTest( } } } - - @Test - fun getMainSpaceId_with_changedIndex() { - // given - val userId = userMockManager.settingUser() - val accessToken = jwtMockManager.generateAccessToken(userId) - val spaceIndexes = - (0..3).map { - val spaceId = spaceMockManager.settingSpace(userId).id.value - UpdateSpaceOrderRequest.SpaceOrder(spaceId, 3 - it) - } - mockMvc.put("/api/v1/spaces/order") { - contentType = MediaType.APPLICATION_JSON - content = objectMapper.writeValueAsString(UpdateSpaceOrderRequest(spaceIndexes)) - header("Authorization", "Bearer $accessToken") - } - // when - val response = - mockMvc.get("/api/v1/spaces/main") { - contentType = MediaType.APPLICATION_JSON - header("Authorization", "Bearer $accessToken") - } - - // then - response.andExpect { - status { isOk() } - jsonPath("$.spaceId") { - exists() - isString() - isNotEmpty() - value(spaceIndexes[3].spaceId) - } - jsonPath("$.username") { - exists() - isString() - isNotEmpty() - } - jsonPath("$.templateType") { - exists() - isNumber() - } - jsonPath("$.spaceName") { - exists() - isString() - isNotEmpty() - } - } - } } @Nested