From c2e8c0ca1f4adabc8d557f08f2a5d80be28db37f Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 28 May 2024 00:18:44 +0900 Subject: [PATCH] wip --- .../core/domain/event/actor/ActorEvent.kt | 4 ++ .../hideout/core/domain/model/actor/Actor2.kt | 43 ++++++++++++++++--- .../domain/model/actor/Actor2Repository.kt | 2 +- .../domain/model/actor/ActorDescription.kt | 2 +- .../core/domain/model/post/Post2Repository.kt | 4 ++ .../domain/model/userdetails/UserDetail.kt | 38 ++++++++++------ .../domain/model/userdetails/UserDetailId.kt | 20 +++++++++ .../LocalActorMigrationCheckDomainService.kt | 35 +++++++++++++++ .../DeleteLocalActorApplicationService.kt | 17 +++++++- .../MigrationLocalActorApplicationService.kt | 36 ++++++++++++++-- .../RegisterLocalActorApplicationService.kt | 8 +++- .../SuspendLocalActorApplicationService.kt | 18 ++++++-- .../UnsuspendLocalActorApplicationService.kt | 18 +++++++- 13 files changed, 211 insertions(+), 34 deletions(-) create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetailId.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/actor/local/LocalActorMigrationCheckDomainService.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/actor/ActorEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/actor/ActorEvent.kt index 62e0d9e9..a35fda34 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/actor/ActorEvent.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/actor/ActorEvent.kt @@ -38,4 +38,8 @@ class ActorEventBody(actor: Actor2) : DomainEventBody( enum class ActorEvent(val eventName: String) { update("ActorUpdate"), delete("ActorDelete"), + checkUpdate("ActorCheckUpdate"), + move("ActorMove"), + actorSuspend("ActorSuspend"), + actorUnsuspend("ActorUnsuspend"), } \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor2.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor2.kt index cc4f96ae..06655269 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor2.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor2.kt @@ -17,8 +17,7 @@ package dev.usbharu.hideout.core.domain.model.actor import dev.usbharu.hideout.core.domain.event.actor.ActorDomainEventFactory -import dev.usbharu.hideout.core.domain.event.actor.ActorEvent.delete -import dev.usbharu.hideout.core.domain.event.actor.ActorEvent.update +import dev.usbharu.hideout.core.domain.event.actor.ActorEvent.* import dev.usbharu.hideout.core.domain.model.instance.InstanceId import dev.usbharu.hideout.core.domain.model.shared.Domain import dev.usbharu.hideout.core.domain.model.shared.domainevent.DomainEventStorable @@ -38,20 +37,46 @@ class Actor2 private constructor( val privateKey: ActorPrivateKey? = null, val createdAt: Instant, val keyId: ActorKeyId, - val followersEndpoint: URI, - val followingEndpoint: URI, + val followersEndpoint: URI?, + val followingEndpoint: URI?, val instance: InstanceId, var locked: Boolean, var followersCount: ActorRelationshipCount?, var followingCount: ActorRelationshipCount?, var postsCount: ActorPostsCount, var lastPostDate: Instant? = null, - var suspend: Boolean, + suspend: Boolean, + var lastUpdate: Instant = createdAt, + alsoKnownAs: List = emptyList(), + moveTo: ActorId? = null, ) : DomainEventStorable() { - val emojis - get() = screenName.emojis + var suspend = suspend + set(value) { + if (field != value && value) { + addDomainEvent(ActorDomainEventFactory(this).createEvent(actorSuspend)) + } else if (field != value && !value) { + addDomainEvent(ActorDomainEventFactory(this).createEvent(actorUnsuspend)) + } + field = value + } + var alsoKnownAs = alsoKnownAs + set(value) { + require(value.find { it == id } == null) + field = value.distinct() + } + + var moveTo = moveTo + set(value) { + require(moveTo != id) + addDomainEvent(ActorDomainEventFactory(this).createEvent(move)) + field = value + } + + + val emojis + get() = screenName.emojis + description.emojis var description = description set(value) { @@ -69,6 +94,10 @@ class Actor2 private constructor( addDomainEvent(ActorDomainEventFactory(this).createEvent(delete)) } + fun checkUpdate() { + addDomainEvent(ActorDomainEventFactory(this).createEvent(checkUpdate)) + } + abstract class Actor2Factory { protected suspend fun create( id: ActorId, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor2Repository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor2Repository.kt index 10c21a63..ddfccccd 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor2Repository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/Actor2Repository.kt @@ -18,6 +18,6 @@ package dev.usbharu.hideout.core.domain.model.actor interface Actor2Repository { suspend fun save(actor: Actor2): Actor2 - suspend fun deleteById(actor: ActorId) + suspend fun delete(actor: Actor2) suspend fun findById(id: ActorId): Actor2? } \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorDescription.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorDescription.kt index 3050836d..4064d241 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorDescription.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/actor/ActorDescription.kt @@ -19,7 +19,7 @@ package dev.usbharu.hideout.core.domain.model.actor import dev.usbharu.hideout.core.domain.model.emoji.EmojiId -class ActorDescription private constructor(private val description: String, private val emojis: List) { +class ActorDescription private constructor(val description: String, val emojis: List) { abstract class ActorDescriptionFactory { protected suspend fun create(description: String, emojis: List): ActorDescription = ActorDescription(description, emojis) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post2Repository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post2Repository.kt index 91961a6f..f2bffd9a 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post2Repository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post2Repository.kt @@ -16,8 +16,12 @@ package dev.usbharu.hideout.core.domain.model.post +import dev.usbharu.hideout.core.domain.model.actor.ActorId + interface Post2Repository { suspend fun save(post: Post2): Post2 + suspend fun saveAll(posts: List): List suspend fun findById(id: PostId): Post2? + suspend fun findByActorId(id: ActorId): List suspend fun deleteById(id: PostId) } \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt index 19c32158..52016f71 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetail.kt @@ -17,32 +17,44 @@ package dev.usbharu.hideout.core.domain.model.userdetails import dev.usbharu.hideout.core.domain.model.actor.ActorId +import java.time.Instant -class UserDetail( +class UserDetail private constructor( + val id: UserDetailId, val actorId: ActorId, var password: UserDetailHashedPassword, var autoAcceptFolloweeFollowRequest: Boolean, + var lastMigration: Instant? = null, ) { + + companion object { + fun create( + id: UserDetailId, + actorId: ActorId, + password: UserDetailHashedPassword, + autoAcceptFolloweeFollowRequest: Boolean = false, + lastMigration: Instant? = null, + ): UserDetail { + return UserDetail( + id, + actorId, + password, + autoAcceptFolloweeFollowRequest, + lastMigration + ) + } + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false other as UserDetail - return actorId == other.actorId + return id == other.id } override fun hashCode(): Int { - return actorId.hashCode() - } - - companion object { - fun create( - actorId: ActorId, - password: UserDetailHashedPassword, - autoAcceptFolloweeFollowRequest: Boolean = false, - ): UserDetail { - return UserDetail(actorId, password, autoAcceptFolloweeFollowRequest) - } + return id.hashCode() } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetailId.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetailId.kt new file mode 100644 index 00000000..cc048546 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/userdetails/UserDetailId.kt @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.domain.model.userdetails + +@JvmInline +value class UserDetailId(val id: Long) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/actor/local/LocalActorMigrationCheckDomainService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/actor/local/LocalActorMigrationCheckDomainService.kt new file mode 100644 index 00000000..01fd5aeb --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/actor/local/LocalActorMigrationCheckDomainService.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 usbharu + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.usbharu.hideout.core.domain.service.actor.local + +import dev.usbharu.hideout.core.domain.model.actor.Actor2 + +interface LocalActorMigrationCheckDomainService { + suspend fun canAccountMigration(from: Actor2, to: Actor2): AccountMigrationCheck +} + +sealed class AccountMigrationCheck( + val canMigration: Boolean, +) { + class CanAccountMigration : AccountMigrationCheck(true) + + class CircularReferences(val message: String) : AccountMigrationCheck(false) + + class SelfReferences : AccountMigrationCheck(false) + + class AlreadyMoved(val message: String) : AccountMigrationCheck(false) +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/DeleteLocalActorApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/DeleteLocalActorApplicationService.kt index c1160fc3..be22d34d 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/DeleteLocalActorApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/DeleteLocalActorApplicationService.kt @@ -16,10 +16,23 @@ package dev.usbharu.hideout.core.usecase.actor +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository import dev.usbharu.hideout.core.domain.model.actor.ActorId +import org.springframework.stereotype.Service -class DeleteLocalActorApplicationService { - suspend fun delete(actorId: ActorId, executor: ActorId) { +@Service +class DeleteLocalActorApplicationService( + private val transaction: Transaction, + private val actor2Repository: Actor2Repository, +) { + suspend fun delete(actorId: Long, executor: ActorId) { + transaction.transaction { + val id = ActorId(actorId) + val findById = actor2Repository.findById(id)!! + findById.delete() + actor2Repository.delete(findById) + } } } \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/MigrationLocalActorApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/MigrationLocalActorApplicationService.kt index ee853538..a7dc73bd 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/MigrationLocalActorApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/MigrationLocalActorApplicationService.kt @@ -16,10 +16,40 @@ package dev.usbharu.hideout.core.usecase.actor +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository import dev.usbharu.hideout.core.domain.model.actor.ActorId +import dev.usbharu.hideout.core.domain.service.actor.local.AccountMigrationCheck.* +import dev.usbharu.hideout.core.domain.service.actor.local.LocalActorMigrationCheckDomainService +import org.springframework.stereotype.Service + +@Service +class MigrationLocalActorApplicationService( + private val transaction: Transaction, + private val actor2Repository: Actor2Repository, + private val localActorMigrationCheckDomainService: LocalActorMigrationCheckDomainService, +) { + suspend fun migration(from: Long, to: Long, executor: ActorId) { + transaction.transaction { + + val fromActorId = ActorId(from) + val toActorId = ActorId(to) + + val fromActor = actor2Repository.findById(fromActorId)!! + val toActor = actor2Repository.findById(toActorId)!! + + val canAccountMigration = localActorMigrationCheckDomainService.canAccountMigration(fromActor, toActor) + when (canAccountMigration) { + is AlreadyMoved -> TODO() + is CanAccountMigration -> { + fromActor.moveTo = toActorId + actor2Repository.save(fromActor) + } + + is CircularReferences -> TODO() + is SelfReferences -> TODO() + } + } -class MigrationLocalActorApplicationService { - suspend fun migration(from: ActorId, to: ActorId, executor: ActorId) { - TODO() } } \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/RegisterLocalActorApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/RegisterLocalActorApplicationService.kt index 7127d8a9..d93a7c0a 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/RegisterLocalActorApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/RegisterLocalActorApplicationService.kt @@ -18,9 +18,11 @@ package dev.usbharu.hideout.core.usecase.actor import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.application.service.id.IdGenerateService import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import dev.usbharu.hideout.core.domain.service.actor.local.LocalActorDomainService import dev.usbharu.hideout.core.domain.service.userdetail.UserDetailDomainService @@ -37,6 +39,7 @@ class RegisterLocalActorApplicationService( private val applicationConfig: ApplicationConfig, private val userDetailDomainService: UserDetailDomainService, private val userDetailRepository: UserDetailRepository, + private val idGenerateService: IdGenerateService, ) { suspend fun register(registerLocalActor: RegisterLocalActor) { transaction.transaction { @@ -54,8 +57,9 @@ class RegisterLocalActorApplicationService( ) actor2Repository.save(actor) val userDetail = UserDetail.create( - actor.id, - userDetailDomainService.hashPassword(registerLocalActor.password), + id = UserDetailId(idGenerateService.generateId()), + actorId = actor.id, + password = userDetailDomainService.hashPassword(registerLocalActor.password), ) userDetailRepository.save(userDetail) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/SuspendLocalActorApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/SuspendLocalActorApplicationService.kt index 1961ce0f..08c78483 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/SuspendLocalActorApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/SuspendLocalActorApplicationService.kt @@ -16,13 +16,25 @@ package dev.usbharu.hideout.core.usecase.actor +import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository import dev.usbharu.hideout.core.domain.model.actor.ActorId +import org.springframework.stereotype.Service -class SuspendLocalActorApplicationService(private val actor2Repository: Actor2Repository) { +@Service +class SuspendLocalActorApplicationService( + private val transaction: Transaction, + private val actor2Repository: Actor2Repository, +) { suspend fun suspend(actorId: Long, executor: ActorId) { - val findById = actor2Repository.findById(ActorId(actorId))!! + transaction.transaction { + + val id = ActorId(actorId) + + val findById = actor2Repository.findById(id)!! + findById.suspend = true + } + - findById.suspend = true } } \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/UnsuspendLocalActorApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/UnsuspendLocalActorApplicationService.kt index e87d9b0d..962e9e2b 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/UnsuspendLocalActorApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/usecase/actor/UnsuspendLocalActorApplicationService.kt @@ -16,8 +16,22 @@ package dev.usbharu.hideout.core.usecase.actor +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.model.actor.Actor2Repository import dev.usbharu.hideout.core.domain.model.actor.ActorId +import org.springframework.stereotype.Service -interface UnsuspendLocalActorApplicationService { - suspend fun unsuspend(actorId: ActorId, executor: ActorId) +@Service +class UnsuspendLocalActorApplicationService( + private val transaction: Transaction, + private val actor2Repository: Actor2Repository, +) { + suspend fun unsuspend(actorId: Long, executor: Long) { + transaction.transaction { + val findById = actor2Repository.findById(ActorId(actorId))!! + + findById.suspend = false + } + + } } \ No newline at end of file