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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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<SpaceOrder>,
) : Command()

data class SpaceOrder(
val spaceId: String,
val index: Int,
)

data class Main(
val userId: String,
val spaceId: String,
) : Command()
}
}
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -13,13 +12,6 @@ interface SpaceManagementPort {
spaceId: DomainId,
): Space

fun getIndexedSpaceNotNull(
userId: DomainId,
spaceId: DomainId,
): IndexedSpace

fun getAllIndexedSpace(userId: DomainId): List<IndexedSpace>

fun getAllSpaceBy(
userId: DomainId,
spaceIds: List<DomainId>,
Expand All @@ -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<Space>): List<Space>

fun updateIndexes(
userId: DomainId,
orders: List<IndexedSpace>,
)
fun update(space: Space): Space

fun deleteBy(space: Space)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -20,53 +20,53 @@ class SpaceCommandService(
) : CreateSpaceUsecase,
UpdateSpaceNameUsecase,
DeleteSpaceUsecase,
UpdateSpaceIndexUsecase {
UpdateSpaceUsecase {
private val spaceIndexValidator: SpaceIndexValidator = SpaceIndexValidator()

override fun create(command: CreateSpaceUsecase.Command) {
Space
.create(
userId = DomainId(command.userId),
name = command.spaceName,
templateType = command.templateType,
).apply {
spaceManagementPort.save(this)
}
reIndexingSpaceOrder(DomainId(command.userId))
}
val userId = DomainId(command.userId)
Space.create(
userId = userId,
name = command.spaceName,
templateType = command.templateType,
).apply {
spaceManagementPort.save(this)
}

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)
// TODO 동시성 문제가 발생한다면?
if (spaceManagementPort.countByUserId(userId) == 1L) {
updateMainSpace(userId)
}

reIndexingSpaceOrder(userId)
}

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) {
Expand All @@ -76,35 +76,71 @@ class SpaceCommandService(
}
}

override fun update(command: UpdateSpaceIndexUsecase.Command) {
val indexedSpaces = spaceManagementPort.getAllIndexedSpace(DomainId(command.userId))
override fun update(command: UpdateSpaceUsecase.Command.Index) {
val spaces = spaceManagementPort.getAllSpaceBy(DomainId(command.userId))
val changeIndexMap = command.orders.associateBy({ DomainId(it.spaceId) }, { it.index })

try {
spaceIndexValidator.validate(
indexedSpaces = indexedSpaces,
spaces = spaces,
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(
spaceManagementPort.saveAll(spaces)
}

override fun update(command: UpdateSpaceUsecase.Command.Main) {
val spaces = spaceManagementPort.getAllSpaceBy(
userId = DomainId(command.userId),
orders = indexedSpaces,
)
).onEach {
if (it.id.value == command.spaceId) {
it.updateToMain()
} else {
it.updateToSub()
}
}

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) {
spaceManagementPort
.getAllIndexedSpace(userId)
val spaces = spaceManagementPort
.getAllSpaceBy(userId)
.sortedBy { it.index }
.forEachIndexed { index, indexedSpace ->
indexedSpace.updateIndex(index)
spaceManagementPort.update(indexedSpace)
.onEachIndexed { index, space ->
space.updateIndex(index)
}
spaceManagementPort.saveAll(spaces)
}


private fun updateMainSpace(userId: DomainId) {
val spaces = spaceManagementPort.getAllSpaceBy(userId)

if (spaces.isEmpty()) {
return
}

spaces.forEach { it.updateToSub() }
spaces.first().updateToMain()

spaceManagementPort.saveAll(spaces)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class SpaceQueryService(

override fun getAll(query: GetSpaceUsecase.GetAllQuery): GetSpaceUsecase.GetAllResponse {
val spaces =
spaceManagementPort.getAllIndexedSpace(
spaceManagementPort.getAllSpaceBy(
userId = DomainId(query.userId),
)

Expand All @@ -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,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
Loading