From 88a61ba97fa0e5a73b649fa422857adc45752bac Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 15 Aug 2024 00:02:26 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=E3=82=BF=E3=82=A4=E3=83=A0?= =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=83=B3=E3=82=92=E8=AA=AD=E3=82=81=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/application/post/ActorDetail.kt | 5 +- .../post/GetPostDetailApplicationService.kt | 24 +++------ .../core/application/post/PostDetail.kt | 4 +- .../core/application/timeline/ReadTimeline.kt | 11 ++++ .../ReadTimelineApplicationService.kt | 47 +++++++++++++++++ .../relationship/RelationshipRepository.kt | 12 +++++ .../TimelineObjectDetail.kt | 45 ++++++++++++----- .../post/DefaultPostReadAccessControl.kt | 50 +++++++++++++++++-- .../core/external/timeline/TimelineStore.kt | 4 +- .../ExposedRelationshipRepository.kt | 20 ++++++++ .../timeline/AbstractTimelineStore.kt | 24 +++++++-- .../timeline/DefaultTimelineStore.kt | 18 +++++-- .../timeline/DefaultTimelineStoreTest.kt | 8 +++ 13 files changed, 224 insertions(+), 48 deletions(-) create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimeline.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/ActorDetail.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/ActorDetail.kt index b678c549..dab9ccce 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/ActorDetail.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/ActorDetail.kt @@ -1,14 +1,12 @@ package dev.usbharu.hideout.core.application.post import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.domain.model.instance.Instance import dev.usbharu.hideout.core.domain.model.media.Media import java.net.URI data class ActorDetail( val actorId: Long, val instanceId: Long, - val instanceName: String, val name: String, val domain: String, val screenName: String, @@ -17,11 +15,10 @@ data class ActorDetail( val icon: URI?, ) { companion object { - fun of(actor: Actor, instance: Instance, iconMedia: Media?): ActorDetail { + fun of(actor: Actor, iconMedia: Media?): ActorDetail { return ActorDetail( actor.id.id, actor.instance.instanceId, - instance.name.name, actor.name.name, actor.domain.domain, actor.screenName.screenName, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/GetPostDetailApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/GetPostDetailApplicationService.kt index fef7fd6c..792e5d36 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/GetPostDetailApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/GetPostDetailApplicationService.kt @@ -5,8 +5,6 @@ import dev.usbharu.hideout.core.application.shared.AbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository -import dev.usbharu.hideout.core.domain.model.instance.Instance -import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository import dev.usbharu.hideout.core.domain.model.media.Media import dev.usbharu.hideout.core.domain.model.media.MediaRepository import dev.usbharu.hideout.core.domain.model.post.PostId @@ -21,7 +19,6 @@ class GetPostDetailApplicationService( transaction: Transaction, private val postRepository: PostRepository, private val actorRepository: ActorRepository, - private val instanceRepository: InstanceRepository, private val mediaRepository: MediaRepository, private val iPostReadAccessControl: IPostReadAccessControl ) : AbstractApplicationService( @@ -36,8 +33,6 @@ class GetPostDetailApplicationService( } val actor = actorRepository.findById(post.actorId) ?: throw InternalServerException("Actor ${post.actorId} not found.") - val instance = instanceRepository.findById(post.instanceId) - ?: throw InternalServerException("Instance ${post.instanceId} not found.") val iconMedia = actor.icon?.let { mediaRepository.findById(it) } @@ -46,19 +41,17 @@ class GetPostDetailApplicationService( return PostDetail.of( post, actor, - instance, iconMedia, mediaList, - post.replyId?.let { fetchChild(it, actor, instance, iconMedia, principal) }, - post.repostId?.let { fetchChild(it, actor, instance, iconMedia, principal) }, - post.moveTo?.let { fetchChild(it, actor, instance, iconMedia, principal) }, + post.replyId?.let { fetchChild(it, actor, iconMedia, principal) }, + post.repostId?.let { fetchChild(it, actor, iconMedia, principal) }, + post.moveTo?.let { fetchChild(it, actor, iconMedia, principal) }, ) } private suspend fun fetchChild( postId: PostId, actor: Actor, - instance: Instance, iconMedia: Media?, principal: Principal ): PostDetail? { @@ -68,21 +61,16 @@ class GetPostDetailApplicationService( return null } - val (first, second: Instance, third) = if (actor.id != post.actorId) { - Triple( - actorRepository.findById(post.actorId) ?: return null, - instanceRepository.findById(actor.instance) ?: return null, - actor.icon?.let { mediaRepository.findById(it) } - ) + val (first, third) = if (actor.id != post.actorId) { + (actorRepository.findById(post.actorId) ?: return null) to actor.icon?.let { mediaRepository.findById(it) } } else { - Triple(actor, instance, iconMedia) + actor to iconMedia } val mediaList = mediaRepository.findByIds(post.mediaIds) return PostDetail.of( post, first, - second, third, mediaList ) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/PostDetail.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/PostDetail.kt index f3be33d8..6c0630a8 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/PostDetail.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/post/PostDetail.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.core.application.post import dev.usbharu.hideout.core.domain.model.actor.Actor -import dev.usbharu.hideout.core.domain.model.instance.Instance import dev.usbharu.hideout.core.domain.model.media.Media import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.Visibility @@ -30,7 +29,6 @@ data class PostDetail( fun of( post: Post, actor: Actor, - instance: Instance, iconMedia: Media?, mediaList: List, reply: PostDetail? = null, @@ -39,7 +37,7 @@ data class PostDetail( ): PostDetail { return PostDetail( id = post.id.id, - actor = ActorDetail.of(actor, instance, iconMedia), + actor = ActorDetail.of(actor, iconMedia), overview = post.overview?.overview, text = post.text, content = post.content.content, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimeline.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimeline.kt new file mode 100644 index 00000000..40e11367 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimeline.kt @@ -0,0 +1,11 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.domain.model.support.page.Page + +data class ReadTimeline( + val timelineId: Long, + val mediaOnly: Boolean, + val localOnly: Boolean, + val remoteOnly: Boolean, + val page: Page +) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt new file mode 100644 index 00000000..92ccb96e --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt @@ -0,0 +1,47 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.post.PostId +import dev.usbharu.hideout.core.domain.model.support.page.PaginationList +import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.support.timelineobjectdetail.TimelineObjectDetail +import dev.usbharu.hideout.core.domain.model.timeline.TimelineId +import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository +import dev.usbharu.hideout.core.external.timeline.ReadTimelineOption +import dev.usbharu.hideout.core.external.timeline.TimelineStore +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service + +@Service +class ReadTimelineApplicationService( + private val timelineStore: TimelineStore, + private val timelineRepository: TimelineRepository, + transaction: Transaction +) : + AbstractApplicationService>(transaction, logger) { + override suspend fun internalExecute( + command: ReadTimeline, + principal: Principal + ): PaginationList { + val findById = timelineRepository.findById(TimelineId(command.timelineId)) + ?: throw IllegalArgumentException("Timeline ${command.timelineId} not found.") + + val readTimelineOption = ReadTimelineOption( + command.mediaOnly, + command.localOnly, + command.remoteOnly + ) + + return timelineStore.readTimeline( + findById, + readTimelineOption, + command.page, + principal, + ) + } + + companion object { + private val logger = LoggerFactory.getLogger(ReadTimelineApplicationService::class.java) + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt index 1e854326..59587c87 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt @@ -22,6 +22,18 @@ interface RelationshipRepository { suspend fun save(relationship: Relationship): Relationship suspend fun delete(relationship: Relationship) suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship? + suspend fun findByActorIdsAndTargetIdAndBlocking( + actorIds: List, + targetId: ActorId, + blocking: Boolean + ): List + + suspend fun findByActorIdAndTargetIdsAndFollowing( + actorId: ActorId, + targetIds: List, + following: Boolean + ): List + suspend fun findByTargetId( targetId: ActorId, option: FindRelationshipOption? = null, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/timelineobjectdetail/TimelineObjectDetail.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/timelineobjectdetail/TimelineObjectDetail.kt index a3039380..e0381014 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/timelineobjectdetail/TimelineObjectDetail.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/timelineobjectdetail/TimelineObjectDetail.kt @@ -1,6 +1,7 @@ package dev.usbharu.hideout.core.domain.model.support.timelineobjectdetail import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.media.Media import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.model.timelineobject.TimelineObject @@ -14,11 +15,17 @@ data class TimelineObjectDetail( val postId: PostId, val timelineUserDetail: UserDetail, val post: Post, + val postMedias: List, val postActor: Actor, + val postActorIconMedia: Media?, val replyPost: Post?, + val replyPostMedias: List?, val replyPostActor: Actor?, + val replyPostActorIconMedia: Media?, val repostPost: Post?, + val repostPostMedias: List?, val repostPostActor: Actor?, + val repostPostActorIconMedia: Media?, val isPureRepost: Boolean, val lastUpdateAt: Instant, val hasMediaInRepost: Boolean, @@ -29,27 +36,39 @@ data class TimelineObjectDetail( timelineObject: TimelineObject, timelineUserDetail: UserDetail, post: Post, + postMedias: List, postActor: Actor, + postActorIconMedia: Media?, replyPost: Post?, + replyPostMedias: List?, replyPostActor: Actor?, + replyPostActorIconMedia: Media?, repostPost: Post?, + repostPostMedias: List?, repostPostActor: Actor?, + repostPostActorIconMedia: Media?, warnFilter: List ): TimelineObjectDetail { return TimelineObjectDetail( - timelineObject.id, - post.id, - timelineUserDetail, - post, - postActor, - replyPost, - replyPostActor, - repostPost, - repostPostActor, - timelineObject.isPureRepost, - timelineObject.lastUpdatedAt, - timelineObject.hasMediaInRepost, - warnFilter + id = timelineObject.id, + postId = post.id, + timelineUserDetail = timelineUserDetail, + post = post, + postMedias = postMedias, + postActor = postActor, + postActorIconMedia = postActorIconMedia, + replyPost = replyPost, + replyPostMedias = replyPostMedias, + replyPostActor = replyPostActor, + replyPostActorIconMedia = replyPostActorIconMedia, + repostPost = repostPost, + repostPostMedias = repostPostMedias, + repostPostActor = repostPostActor, + repostPostActorIconMedia = repostPostActorIconMedia, + isPureRepost = timelineObject.isPureRepost, + lastUpdateAt = timelineObject.lastUpdatedAt, + hasMediaInRepost = timelineObject.hasMediaInRepost, + warnFilter = warnFilter ) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/post/DefaultPostReadAccessControl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/post/DefaultPostReadAccessControl.kt index c0466054..97b78c5a 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/post/DefaultPostReadAccessControl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/post/DefaultPostReadAccessControl.kt @@ -10,6 +10,7 @@ import org.springframework.stereotype.Component interface IPostReadAccessControl { suspend fun isAllow(post: Post, principal: Principal): Boolean + suspend fun areAllows(postList: List, principal: Principal): List } @Component @@ -22,9 +23,9 @@ class DefaultPostReadAccessControl(private val relationshipRepository: Relations } val relationship = ( - relationshipRepository.findByActorIdAndTargetId(post.actorId, principal.actorId) - ?: Relationship.default(post.actorId, principal.actorId) - ) + relationshipRepository.findByActorIdAndTargetId(post.actorId, principal.actorId) + ?: Relationship.default(post.actorId, principal.actorId) + ) // ブロックされてたら見れない if (relationship.blocking) { @@ -57,4 +58,47 @@ class DefaultPostReadAccessControl(private val relationshipRepository: Relations // その他の場合は見れない return false } + + override suspend fun areAllows(postList: List, principal: Principal): List { + val actorIds = postList.map { it.actorId } + val relationshipList = + relationshipRepository.findByActorIdsAndTargetIdAndBlocking(actorIds, principal.actorId, true) + .map { it.actorId } + val inverseRelationshipList = + relationshipRepository.findByActorIdAndTargetIdsAndFollowing(principal.actorId, actorIds, true) + .map { it.actorId } + + fun internalAllow(post: Post): Boolean { + // ポスト主は無条件で見れる + if (post.actorId == principal.actorId) { + return true + } + + if (relationshipList.contains(post.actorId)) { + return false + } + + if (post.visibility == Visibility.PUBLIC || post.visibility == Visibility.UNLISTED) { + return true + } + + if (principal is Anonymous) { + return false + } + + if (post.visibility == Visibility.DIRECT && post.visibleActors.contains(principal.actorId)) { + return true + } + + if (post.visibility == Visibility.FOLLOWERS && inverseRelationshipList.contains(principal.actorId)) { + return true + } + return false + } + + return postList + .filter { + internalAllow(it) + } + } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/timeline/TimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/timeline/TimelineStore.kt index a9536a6c..23db5074 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/timeline/TimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/external/timeline/TimelineStore.kt @@ -4,6 +4,7 @@ import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.model.support.page.Page import dev.usbharu.hideout.core.domain.model.support.page.PaginationList +import dev.usbharu.hideout.core.domain.model.support.principal.Principal import dev.usbharu.hideout.core.domain.model.support.timelineobjectdetail.TimelineObjectDetail import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship @@ -22,6 +23,7 @@ interface TimelineStore { suspend fun readTimeline( timeline: Timeline, option: ReadTimelineOption? = null, - page: Page? = null + page: Page? = null, + principal: Principal ): PaginationList } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt index 8de364aa..35021733 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt @@ -67,6 +67,26 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve }.singleOrNull()?.toRelationships() } + override suspend fun findByActorIdsAndTargetIdAndBlocking( + actorIds: List, + targetId: ActorId, + blocking: Boolean + ): List = query { + Relationships.selectAll().where { + Relationships.actorId inList actorIds.map { it.id } and (Relationships.targetActorId eq targetId.id) + }.map { it.toRelationships() } + } + + override suspend fun findByActorIdAndTargetIdsAndFollowing( + actorId: ActorId, + targetIds: List, + following: Boolean + ): List = query { + Relationships.selectAll().where { + Relationships.actorId eq actorId.id and (Relationships.targetActorId inList targetIds.map { it.id }) + }.map { it.toRelationships() } + } + override suspend fun findByTargetId( targetId: ActorId, option: FindRelationshipOption?, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt index 564f188a..149ffb26 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt @@ -4,11 +4,14 @@ import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.filter.Filter import dev.usbharu.hideout.core.domain.model.filter.FilteredPost +import dev.usbharu.hideout.core.domain.model.media.Media +import dev.usbharu.hideout.core.domain.model.media.MediaId import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.domain.model.support.page.Page import dev.usbharu.hideout.core.domain.model.support.page.PaginationList +import dev.usbharu.hideout.core.domain.model.support.principal.Principal import dev.usbharu.hideout.core.domain.model.support.timelineobjectdetail.TimelineObjectDetail import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.TimelineId @@ -105,7 +108,7 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe protected abstract suspend fun getPostsByTimelineRelationshipList(timelineRelationshipList: List): List - protected abstract suspend fun getPostsByPostId(postIds: List): List + protected abstract suspend fun getPostsByPostId(postIds: List, principal: Principal): List protected abstract suspend fun getTimelineObject( timelineId: TimelineId, @@ -205,7 +208,8 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe override suspend fun readTimeline( timeline: Timeline, option: ReadTimelineOption?, - page: Page? + page: Page?, + principal: Principal ): PaginationList { val timelineObjectList = getTimelineObject(timeline.id, option, page) val lastUpdatedAt = timelineObjectList.minBy { it.lastUpdatedAt }.lastUpdatedAt @@ -216,7 +220,8 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe getPostsByPostId( timelineObjectList.map { it.postId - } + timelineObjectList.mapNotNull { it.repostId } + timelineObjectList.mapNotNull { it.replyId } + } + timelineObjectList.mapNotNull { it.repostId } + timelineObjectList.mapNotNull { it.replyId }, + principal ) val userDetails = getUserDetails(timelineObjectList.map { it.userDetailId }) @@ -232,24 +237,35 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe post.id to applyFilters(post, newerFilters) } + val mediaMap = getMedias(posts.flatMap { it.mediaIds } + actors.mapNotNull { it.value.icon }) + return PaginationList( timelineObjectList.mapNotNull { val timelineUserDetail = userDetails[it.userDetailId] ?: return@mapNotNull null val actor = actors[it.postActorId] ?: return@mapNotNull null val post = postMap[it.postId] ?: return@mapNotNull null + val postMedias = post.post.mediaIds.mapNotNull { mediaId -> mediaMap[mediaId] } val reply = postMap[it.replyId] + val replyMedias = reply?.post?.mediaIds?.mapNotNull { mediaId -> mediaMap[mediaId] } val replyActor = actors[it.replyActorId] val repost = postMap[it.repostId] + val repostMedias = repost?.post?.mediaIds?.mapNotNull { mediaId -> mediaMap[mediaId] } val repostActor = actors[it.repostActorId] TimelineObjectDetail.of( timelineObject = it, timelineUserDetail = timelineUserDetail, post = post.post, + postMedias = postMedias, postActor = actor, + postActorIconMedia = mediaMap[actor.icon], replyPost = reply?.post, + replyPostMedias = replyMedias, replyPostActor = replyActor, + replyPostActorIconMedia = mediaMap[replyActor?.icon], repostPost = repost?.post, + repostPostMedias = repostMedias, repostPostActor = repostActor, + repostPostActorIconMedia = mediaMap[repostActor?.icon], warnFilter = it.warnFilters + post.filterResults.map { TimelineObjectWarnFilter( it.filter.id, @@ -265,5 +281,7 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe protected abstract suspend fun getActors(actorIds: List): Map + protected abstract suspend fun getMedias(mediaIds: List): Map + protected abstract suspend fun getUserDetails(userDetailIdList: List): Map } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt index 95c0b11a..8781b862 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt @@ -8,12 +8,16 @@ import dev.usbharu.hideout.core.domain.model.filter.Filter import dev.usbharu.hideout.core.domain.model.filter.FilterContext import dev.usbharu.hideout.core.domain.model.filter.FilterRepository import dev.usbharu.hideout.core.domain.model.filter.FilteredPost +import dev.usbharu.hideout.core.domain.model.media.Media +import dev.usbharu.hideout.core.domain.model.media.MediaId +import dev.usbharu.hideout.core.domain.model.media.MediaRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.domain.model.support.page.Page import dev.usbharu.hideout.core.domain.model.support.page.PaginationList +import dev.usbharu.hideout.core.domain.model.support.principal.Principal import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.TimelineId import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository @@ -24,6 +28,7 @@ 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.filter.FilterDomainService +import dev.usbharu.hideout.core.domain.service.post.IPostReadAccessControl import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService import dev.usbharu.hideout.core.external.timeline.ReadTimelineOption import org.springframework.stereotype.Component @@ -40,7 +45,9 @@ open class DefaultTimelineStore( private val defaultTimelineStoreConfig: DefaultTimelineStoreConfig, private val internalTimelineObjectRepository: InternalTimelineObjectRepository, private val userDetailRepository: UserDetailRepository, - private val actorRepository: ActorRepository + private val actorRepository: ActorRepository, + private val mediaRepository: MediaRepository, + private val postIPostReadAccessControl: IPostReadAccessControl ) : AbstractTimelineStore(idGenerateService) { override suspend fun getTimelines(actorId: ActorId): List { return timelineRepository.findByIds( @@ -99,8 +106,9 @@ open class DefaultTimelineStore( return timelineRelationshipList.flatMap { getActorPost(it.actorId, visibilities(it)) } } - override suspend fun getPostsByPostId(postIds: List): List { - return postRepository.findAllById(postIds) + override suspend fun getPostsByPostId(postIds: List, principal: Principal): List { + val findAllById = postRepository.findAllById(postIds) + return postIPostReadAccessControl.areAllows(findAllById, principal) } override suspend fun getTimelineObject( @@ -131,6 +139,10 @@ open class DefaultTimelineStore( return actorRepository.findAllById(actorIds).associateBy { it.id } } + override suspend fun getMedias(mediaIds: List): Map { + return mediaRepository.findByIds(mediaIds).associateBy { it.id } + } + override suspend fun getUserDetails(userDetailIdList: List): Map { return userDetailRepository.findAllById(userDetailIdList).associateBy { it.id } } diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStoreTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStoreTest.kt index ca243c63..e70b1fe1 100644 --- a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStoreTest.kt +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStoreTest.kt @@ -3,6 +3,7 @@ package dev.usbharu.hideout.core.infrastructure.timeline import dev.usbharu.hideout.core.config.DefaultTimelineStoreConfig import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.filter.* +import dev.usbharu.hideout.core.domain.model.media.MediaRepository import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.domain.model.post.TestPostFactory import dev.usbharu.hideout.core.domain.model.post.Visibility @@ -16,6 +17,7 @@ import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible 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.filter.FilterDomainService +import dev.usbharu.hideout.core.domain.service.post.IPostReadAccessControl import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat @@ -56,6 +58,12 @@ class DefaultTimelineStoreTest { @Mock lateinit var actorRepository: ActorRepository + @Mock + lateinit var mediaRepository: MediaRepository + + @Mock + lateinit var iPostReadAccessControl: IPostReadAccessControl + @Spy val defaultTimelineStoreConfig = DefaultTimelineStoreConfig(500) From 711084e366d3ae9b91452ebf39c2d44348d79ca1 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 15 Aug 2024 18:22:56 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=E3=82=BF=E3=82=A4=E3=83=A0?= =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=83=B3=E3=82=92=E8=AA=AD=E3=82=81=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...isterLocalUserSetHomeTimelineSubscriber.kt | 10 ++++ .../TimelinePostCreateSubscriber.kt | 11 +++-- .../ReadTimelineApplicationService.kt | 44 +++++++++++++++-- .../hideout/core/config/SecurityConfig.kt | 2 +- .../web/timeline/TimelineController.kt | 48 +++++++++++++++++++ .../templates/fragments-timeline.html | 21 ++++++++ .../resources/templates/homeTimeline.html | 12 +++++ 7 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt create mode 100644 hideout-core/src/main/resources/templates/fragments-timeline.html create mode 100644 hideout-core/src/main/resources/templates/homeTimeline.html diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt new file mode 100644 index 00000000..2ccceab5 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt @@ -0,0 +1,10 @@ +package dev.usbharu.hideout.core.application.domainevent.subscribers + +class RegisterLocalUserSetHomeTimelineSubscriber(private val domainEventSubscriber: DomainEventSubscriber) : + Subscriber { + init { + domainEventSubscriber.subscribe<>() + } +} + +//todo userdetailにdomain event付けて createのイベントで反応させる タイムラインを新しく一つ作って userdetailのhometimelineに紐づけて自分自身をtimleine relationshipに入れる \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt index 28b0004a..8262fcc5 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt @@ -2,17 +2,18 @@ package dev.usbharu.hideout.core.application.domainevent.subscribers import dev.usbharu.hideout.core.domain.event.post.PostEvent import dev.usbharu.hideout.core.domain.event.post.PostEventBody +import dev.usbharu.hideout.core.external.timeline.TimelineStore import org.slf4j.LoggerFactory import org.springframework.stereotype.Component @Component -class TimelinePostCreateSubscriber(domainEventSubscriber: DomainEventSubscriber) : Subscriber { +class TimelinePostCreateSubscriber( + private val timelineStore: TimelineStore, + domainEventSubscriber: DomainEventSubscriber +) : Subscriber { init { domainEventSubscriber.subscribe(PostEvent.CREATE.eventName) { - val post = it.body.getPost() - val actor = it.body.getActor() - - logger.info("New Post! : {}", post) + timelineStore.addPost(it.body.getPost()) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt index 92ccb96e..17b9b5ae 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt @@ -1,11 +1,11 @@ package dev.usbharu.hideout.core.application.timeline +import dev.usbharu.hideout.core.application.post.PostDetail import dev.usbharu.hideout.core.application.shared.AbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.model.support.page.PaginationList import dev.usbharu.hideout.core.domain.model.support.principal.Principal -import dev.usbharu.hideout.core.domain.model.support.timelineobjectdetail.TimelineObjectDetail import dev.usbharu.hideout.core.domain.model.timeline.TimelineId import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository import dev.usbharu.hideout.core.external.timeline.ReadTimelineOption @@ -19,11 +19,11 @@ class ReadTimelineApplicationService( private val timelineRepository: TimelineRepository, transaction: Transaction ) : - AbstractApplicationService>(transaction, logger) { + AbstractApplicationService>(transaction, logger) { override suspend fun internalExecute( command: ReadTimeline, principal: Principal - ): PaginationList { + ): PaginationList { val findById = timelineRepository.findById(TimelineId(command.timelineId)) ?: throw IllegalArgumentException("Timeline ${command.timelineId} not found.") @@ -33,12 +33,48 @@ class ReadTimelineApplicationService( command.remoteOnly ) - return timelineStore.readTimeline( + val timeline = timelineStore.readTimeline( findById, readTimelineOption, command.page, principal, ) + + val postDetailList = timeline.map { + + val reply = if (it.replyPost != null) { + PostDetail.of( + it.replyPost, + it.replyPostActor!!, + it.replyPostActorIconMedia, + it.replyPostMedias.orEmpty() + ) + } else { + null + } + + val repost = if (it.repostPost != null) { + PostDetail.of( + it.repostPost, + it.repostPostActor!!, + it.repostPostActorIconMedia, + it.repostPostMedias.orEmpty() + ) + } else { + null + } + + PostDetail.of( + it.post, + it.postActor, + it.postActorIconMedia, + it.postMedias, + reply, + repost + ) + } + + return PaginationList(postDetailList, timeline.next, timeline.prev) } companion object { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/config/SecurityConfig.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/config/SecurityConfig.kt index ae7504a2..25f9690d 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/config/SecurityConfig.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/config/SecurityConfig.kt @@ -52,7 +52,7 @@ import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint @Configuration -@EnableWebSecurity(debug = true) +@EnableWebSecurity(debug = false) class SecurityConfig { @Bean fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder() diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt new file mode 100644 index 00000000..ebb3b86f --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt @@ -0,0 +1,48 @@ +package dev.usbharu.hideout.core.interfaces.web.timeline + +import dev.usbharu.hideout.core.application.exception.InternalServerException +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.application.timeline.ReadTimeline +import dev.usbharu.hideout.core.application.timeline.ReadTimelineApplicationService +import dev.usbharu.hideout.core.domain.model.support.page.Page +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository +import dev.usbharu.hideout.core.infrastructure.springframework.SpringSecurityFormLoginPrincipalContextHolder +import org.springframework.stereotype.Controller +import org.springframework.ui.Model +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestParam + +@Controller +class TimelineController( + private val readTimelineApplicationService: ReadTimelineApplicationService, + private val userDetailRepository: UserDetailRepository, + private val springSecurityFormLoginPrincipalContextHolder: SpringSecurityFormLoginPrincipalContextHolder, + private val transaction: Transaction +) { + @GetMapping("/home") + suspend fun homeTimeline(model: Model, @RequestParam sinceId: String?, @RequestParam maxId: String?): String { + val principal = springSecurityFormLoginPrincipalContextHolder.getPrincipal() + val userDetail = transaction.transaction { + userDetailRepository.findByActorId(principal.actorId.id) + ?: throw InternalServerException("UserDetail not found.") + } + + val homeTimelineId = userDetail.homeTimelineId!! + val execute = readTimelineApplicationService.execute( + ReadTimeline( + timelineId = homeTimelineId.value, + mediaOnly = false, + localOnly = false, + remoteOnly = false, + page = Page.of( + maxId = maxId?.toLongOrNull(), + sinceId = sinceId?.toLongOrNull() + ) + ), principal + ) + + model.addAttribute("timeline", execute) + + return "homeTimeline" + } +} \ No newline at end of file diff --git a/hideout-core/src/main/resources/templates/fragments-timeline.html b/hideout-core/src/main/resources/templates/fragments-timeline.html new file mode 100644 index 00000000..f1f2b3cb --- /dev/null +++ b/hideout-core/src/main/resources/templates/fragments-timeline.html @@ -0,0 +1,21 @@ + + + + + Title + + + + +
+ +
+
+ +
+
+ +
+
+ + \ No newline at end of file diff --git a/hideout-core/src/main/resources/templates/homeTimeline.html b/hideout-core/src/main/resources/templates/homeTimeline.html new file mode 100644 index 00000000..baac1330 --- /dev/null +++ b/hideout-core/src/main/resources/templates/homeTimeline.html @@ -0,0 +1,12 @@ + + + + + Title + + + + + \ No newline at end of file From 8d244b74c1675dbaa725d0b2d9269431317342c7 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 16 Aug 2024 02:49:48 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=E3=83=AD=E3=83=BC=E3=82=AB?= =?UTF-8?q?=E3=83=AB=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=E6=99=82=E3=81=AB=E8=87=AA=E5=8B=95=E3=81=A7=E3=83=9B=E3=83=BC?= =?UTF-8?q?=E3=83=A0=E3=82=BF=E3=82=A4=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E7=AD=89=E3=82=92=E4=BD=9C=E6=88=90=E3=81=99=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../subscribers/RegisterHomeTimeline.kt | 5 ++ ...isterLocalUserSetHomeTimelineSubscriber.kt | 18 +++++- ...isterTimelineSetTimelineStoreSubscriber.kt | 21 +++++++ .../TimelinePostCreateSubscriber.kt | 10 ++-- .../TimelineRelationshipFollowSubscriber.kt | 2 +- ...rRegisterHomeTimelineApplicationService.kt | 40 ++++++++++++++ .../core/application/timeline/AddPost.kt | 5 ++ .../application/timeline/RegisterTimeline.kt | 8 +++ ...melineToTimelineStoreApplicationService.kt | 29 ++++++++++ .../application/timeline/SetTimleineStore.kt | 5 ++ .../TimelineAddPostApplicationService.kt | 29 ++++++++++ .../UserRegisterTimelineApplicationService.kt | 37 +++++++++++++ .../core/domain/event/actor/ActorEvent.kt | 5 +- .../core/domain/event/post/PostEvent.kt | 10 ++-- .../domain/event/timeline/TimelineEvent.kt | 12 +++- .../event/userdetail/UserDetailEvent.kt | 29 ++++++++++ .../core/domain/model/timeline/Timeline.kt | 20 +++++++ .../domain/model/userdetails/UserDetail.kt | 13 +++-- .../DomainEventPublishableRepository.kt | 4 ++ .../UserDetailRepositoryImpl.kt | 55 +++++++++++-------- .../SpringFrameworkDomainEventPublisher.kt | 6 ++ .../SpringFrameworkDomainEventSubscriber.kt | 7 +++ 22 files changed, 328 insertions(+), 42 deletions(-) create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterHomeTimeline.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/AddPost.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/RegisterTimeline.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimleineStore.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt create mode 100644 hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterHomeTimeline.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterHomeTimeline.kt new file mode 100644 index 00000000..9f2ce4b0 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterHomeTimeline.kt @@ -0,0 +1,5 @@ +package dev.usbharu.hideout.core.application.domainevent.subscribers + +data class RegisterHomeTimeline( + val userDetailId: Long +) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt index 2ccceab5..49ed5925 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt @@ -1,9 +1,23 @@ package dev.usbharu.hideout.core.application.domainevent.subscribers -class RegisterLocalUserSetHomeTimelineSubscriber(private val domainEventSubscriber: DomainEventSubscriber) : +import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailEvent +import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailEventBody +import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous +import org.springframework.stereotype.Component + +@Component +class RegisterLocalUserSetHomeTimelineSubscriber( + domainEventSubscriber: DomainEventSubscriber, + private val userRegisterHomeTimelineApplicationService: UserRegisterHomeTimelineApplicationService +) : Subscriber { init { - domainEventSubscriber.subscribe<>() + domainEventSubscriber.subscribe(UserDetailEvent.CREATE.eventName) { + userRegisterHomeTimelineApplicationService.execute( + RegisterHomeTimeline(it.body.getUserDetail().id), + Anonymous + ) + } } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt new file mode 100644 index 00000000..f1a93dfa --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt @@ -0,0 +1,21 @@ +package dev.usbharu.hideout.core.application.domainevent.subscribers + +import dev.usbharu.hideout.core.application.timeline.SetTimelineToTimelineStoreApplicationService +import dev.usbharu.hideout.core.application.timeline.SetTimleineStore +import dev.usbharu.hideout.core.domain.event.timeline.TimelineEvent +import dev.usbharu.hideout.core.domain.event.timeline.TimelineEventBody +import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous +import org.springframework.stereotype.Component + +@Component +class RegisterTimelineSetTimelineStoreSubscriber( + domainEventSubscriber: DomainEventSubscriber, + private val setTimelineToTimelineStoreApplicationService: SetTimelineToTimelineStoreApplicationService +) : + Subscriber { + init { + domainEventSubscriber.subscribe(TimelineEvent.CREATE.eventName) { + setTimelineToTimelineStoreApplicationService.execute(SetTimleineStore(it.body.getTimelineId()), Anonymous) + } + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt index 8262fcc5..dfcc87ad 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelinePostCreateSubscriber.kt @@ -1,19 +1,21 @@ package dev.usbharu.hideout.core.application.domainevent.subscribers +import dev.usbharu.hideout.core.application.timeline.AddPost +import dev.usbharu.hideout.core.application.timeline.TimelineAddPostApplicationService import dev.usbharu.hideout.core.domain.event.post.PostEvent import dev.usbharu.hideout.core.domain.event.post.PostEventBody -import dev.usbharu.hideout.core.external.timeline.TimelineStore +import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous import org.slf4j.LoggerFactory import org.springframework.stereotype.Component @Component class TimelinePostCreateSubscriber( - private val timelineStore: TimelineStore, - domainEventSubscriber: DomainEventSubscriber + private val timelineAddPostApplicationService: TimelineAddPostApplicationService, + domainEventSubscriber: DomainEventSubscriber, ) : Subscriber { init { domainEventSubscriber.subscribe(PostEvent.CREATE.eventName) { - timelineStore.addPost(it.body.getPost()) + timelineAddPostApplicationService.execute(AddPost(it.body.getPostId()), Anonymous) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipFollowSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipFollowSubscriber.kt index 4f4cdf0b..bc13d823 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipFollowSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/TimelineRelationshipFollowSubscriber.kt @@ -32,7 +32,7 @@ class TimelineRelationshipFollowSubscriber( AddTimelineRelationship( TimelineRelationship( TimelineRelationshipId(idGenerateService.generateId()), - userDetail.homeTimelineId, + userDetail.homeTimelineId!!, relationship.targetActorId, Visible.FOLLOWERS ) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt new file mode 100644 index 00000000..5394e998 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt @@ -0,0 +1,40 @@ +package dev.usbharu.hideout.core.application.domainevent.subscribers + +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.timeline.* +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository +import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class UserRegisterHomeTimelineApplicationService( + private val userDetailRepository: UserDetailRepository, + private val timelineRepository: TimelineRepository, + private val idGenerateService: IdGenerateService, transaction: Transaction, +) : AbstractApplicationService(transaction, logger) { + override suspend fun internalExecute(command: RegisterHomeTimeline, principal: Principal) { + + val userDetail = (userDetailRepository.findById(UserDetailId(command.userDetailId)) + ?: throw IllegalArgumentException("UserDetail ${command.userDetailId} not found.")) + + val timeline = Timeline.create( + TimelineId(idGenerateService.generateId()), + UserDetailId(command.userDetailId), + TimelineName("System-LocalUser-HomeTimeline-${command.userDetailId}"), + TimelineVisibility.PRIVATE, + true + ) + timelineRepository.save(timeline) + userDetail.homeTimelineId = timeline.id + + userDetailRepository.save(userDetail) + } + + companion object { + private val logger = LoggerFactory.getLogger(UserRegisterHomeTimelineApplicationService::class.java) + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/AddPost.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/AddPost.kt new file mode 100644 index 00000000..bae9fc85 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/AddPost.kt @@ -0,0 +1,5 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.domain.model.post.PostId + +data class AddPost(val postId: PostId) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/RegisterTimeline.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/RegisterTimeline.kt new file mode 100644 index 00000000..4283e651 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/RegisterTimeline.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.domain.model.timeline.TimelineVisibility + +data class RegisterTimeline( + val timelineName: String, + val visibility: TimelineVisibility +) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt new file mode 100644 index 00000000..f47fcc0f --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt @@ -0,0 +1,29 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository +import dev.usbharu.hideout.core.external.timeline.TimelineStore +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class SetTimelineToTimelineStoreApplicationService( + transaction: Transaction, + private val timelineStore: TimelineStore, + private val timelineRepository: TimelineRepository +) : + AbstractApplicationService( + transaction, logger + ) { + override suspend fun internalExecute(command: SetTimleineStore, principal: Principal) { + val findById = timelineRepository.findById(command.timelineId) + ?: throw IllegalArgumentException("Timeline ${command.timelineId} not found") + timelineStore.addTimeline(findById, emptyList()) + } + + companion object { + private val logger = LoggerFactory.getLogger(SetTimelineToTimelineStoreApplicationService::class.java) + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimleineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimleineStore.kt new file mode 100644 index 00000000..a2257489 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimleineStore.kt @@ -0,0 +1,5 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.domain.model.timeline.TimelineId + +data class SetTimleineStore(val timelineId: TimelineId) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt new file mode 100644 index 00000000..8c907a61 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt @@ -0,0 +1,29 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.post.PostRepository +import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.external.timeline.TimelineStore +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class TimelineAddPostApplicationService( + private val timelineStore: TimelineStore, + private val postRepository: PostRepository, + transaction: Transaction +) : AbstractApplicationService( + transaction, + logger +) { + override suspend fun internalExecute(command: AddPost, principal: Principal) { + val findById = postRepository.findById(command.postId) + ?: throw IllegalArgumentException("Post ${command.postId} not found.") + timelineStore.addPost(findById) + } + + companion object { + private val logger = LoggerFactory.getLogger(TimelineAddPostApplicationService::class.java) + } +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt new file mode 100644 index 00000000..0660c020 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt @@ -0,0 +1,37 @@ +package dev.usbharu.hideout.core.application.timeline + +import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService +import dev.usbharu.hideout.core.application.shared.Transaction +import dev.usbharu.hideout.core.domain.model.support.principal.LocalUser +import dev.usbharu.hideout.core.domain.model.timeline.Timeline +import dev.usbharu.hideout.core.domain.model.timeline.TimelineId +import dev.usbharu.hideout.core.domain.model.timeline.TimelineName +import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository +import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component + +@Component +class UserRegisterTimelineApplicationService( + private val idGenerateService: IdGenerateService, + private val timelineRepository: TimelineRepository, + transaction: Transaction +) : + LocalUserAbstractApplicationService(transaction, logger) { + override suspend fun internalExecute(command: RegisterTimeline, principal: LocalUser): TimelineId { + val timeline = Timeline.create( + id = TimelineId(idGenerateService.generateId()), + userDetailId = principal.userDetailId, + name = TimelineName(command.timelineName), + visibility = command.visibility, + isSystem = false + ) + + timelineRepository.save(timeline) + return timeline.id + } + + companion object { + private val logger = LoggerFactory.getLogger(UserRegisterTimelineApplicationService::class.java) + } +} \ No newline at end of file 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 98f2918a..b4239620 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 @@ -17,6 +17,7 @@ package dev.usbharu.hideout.core.domain.event.actor import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody @@ -24,13 +25,13 @@ class ActorDomainEventFactory(private val actor: Actor) { fun createEvent(actorEvent: ActorEvent): DomainEvent { return DomainEvent.create( actorEvent.eventName, - ActorEventBody(actor), + ActorEventBody(actor.id), actorEvent.collectable ) } } -class ActorEventBody(actor: Actor) : DomainEventBody( +class ActorEventBody(actor: ActorId) : DomainEventBody( mapOf( "actor" to actor ), diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/post/PostEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/post/PostEvent.kt index 52423afd..dd64669b 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/post/PostEvent.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/post/PostEvent.kt @@ -17,7 +17,9 @@ package dev.usbharu.hideout.core.domain.event.post import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.post.Post +import dev.usbharu.hideout.core.domain.model.post.PostId import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody @@ -25,14 +27,14 @@ class PostDomainEventFactory(private val post: Post, private val actor: Actor? = fun createEvent(postEvent: PostEvent): DomainEvent { return DomainEvent.create( postEvent.eventName, - PostEventBody(post, actor) + PostEventBody(post.id, actor?.id) ) } } -class PostEventBody(post: Post, actor: Actor?) : DomainEventBody(mapOf("post" to post, "actor" to actor)) { - fun getPost(): Post = toMap()["post"] as Post - fun getActor(): Actor? = toMap()["actor"] as Actor? +class PostEventBody(post: PostId, actor: ActorId?) : DomainEventBody(mapOf("post" to post, "actor" to actor)) { + fun getPostId(): PostId = toMap()["post"] as PostId + fun getActorId(): ActorId? = toMap()["actor"] as ActorId? } enum class PostEvent(val eventName: String) { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/timeline/TimelineEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/timeline/TimelineEvent.kt index a6d53cf6..af552cfc 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/timeline/TimelineEvent.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/timeline/TimelineEvent.kt @@ -1,16 +1,22 @@ package dev.usbharu.hideout.core.domain.event.timeline import dev.usbharu.hideout.core.domain.model.timeline.Timeline +import dev.usbharu.hideout.core.domain.model.timeline.TimelineId import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody class TimelineEventFactory(private val timeline: Timeline) { fun createEvent(timelineEvent: TimelineEvent): DomainEvent = - DomainEvent.create(timelineEvent.eventName, TimelineEventBody(timeline)) + DomainEvent.create(timelineEvent.eventName, TimelineEventBody(timeline.id)) } -class TimelineEventBody(timeline: Timeline) : DomainEventBody(mapOf("timeline" to timeline)) +class TimelineEventBody(timelineId: TimelineId) : DomainEventBody(mapOf("timeline" to timelineId)) { + fun getTimelineId(): TimelineId { + return toMap()["timeline"] as TimelineId + } +} enum class TimelineEvent(val eventName: String) { - CHANGE_VISIBILITY("ChangeVisibility") + CHANGE_VISIBILITY("ChangeVisibility"), + CREATE("TimelineCreate") } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt new file mode 100644 index 00000000..7493e943 --- /dev/null +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt @@ -0,0 +1,29 @@ +package dev.usbharu.hideout.core.domain.event.userdetail + +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody + +class UserDetailDomainEventFactory(private val userDetail: UserDetail) { + fun createEvent(userDetailEvent: UserDetailEvent): DomainEvent { + return DomainEvent.create( + userDetailEvent.eventName, + UserDetailEventBody(userDetail.id) + ) + } +} + +class UserDetailEventBody(userDetail: UserDetailId) : DomainEventBody( + mapOf( + "userDetail" to userDetail + ) +) { + fun getUserDetail(): UserDetailId { + return toMap()["userDetail"] as UserDetailId + } +} + +enum class UserDetailEvent(val eventName: String) { + CREATE("UserDetailCreate"), +} \ No newline at end of file diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt index 955b1621..7f09a103 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/timeline/Timeline.kt @@ -25,4 +25,24 @@ class Timeline( var name = name private set + + companion object { + fun create( + id: TimelineId, + userDetailId: UserDetailId, + name: TimelineName, + visibility: TimelineVisibility, + isSystem: Boolean + ): Timeline { + val timeline = Timeline( + id = id, + userDetailId = userDetailId, + name = name, + visibility = visibility, + isSystem = isSystem + ) + timeline.addDomainEvent(TimelineEventFactory(timeline).createEvent(TimelineEvent.CREATE)) + return timeline + } + } } 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 a272176f..4cd447a7 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 @@ -16,18 +16,21 @@ package dev.usbharu.hideout.core.domain.model.userdetails +import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailDomainEventFactory +import dev.usbharu.hideout.core.domain.event.userdetail.UserDetailEvent import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.timeline.TimelineId +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable import java.time.Instant -class UserDetail private constructor( +class UserDetail( val id: UserDetailId, val actorId: ActorId, var password: UserDetailHashedPassword, var autoAcceptFolloweeFollowRequest: Boolean, var lastMigration: Instant? = null, - val homeTimelineId: TimelineId? -) { + var homeTimelineId: TimelineId? +) : DomainEventStorable() { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -49,7 +52,7 @@ class UserDetail private constructor( lastMigration: Instant? = null, homeTimelineId: TimelineId? = null ): UserDetail { - return UserDetail( + val userDetail = UserDetail( id, actorId, password, @@ -57,6 +60,8 @@ class UserDetail private constructor( lastMigration, homeTimelineId ) + userDetail.addDomainEvent(UserDetailDomainEventFactory(userDetail).createEvent(UserDetailEvent.CREATE)) + return userDetail } } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt index 3b385984..ff9776bc 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt @@ -2,12 +2,16 @@ package dev.usbharu.hideout.core.domain.shared.repository import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable +import org.jetbrains.exposed.sql.transactions.TransactionManager import org.springframework.stereotype.Repository @Repository interface DomainEventPublishableRepository { val domainEventPublisher: DomainEventPublisher suspend fun update(entity: T) { + println(entity.getDomainEvents().joinToString()) + val current = TransactionManager.current() + current.registerInterceptor() entity.getDomainEvents().distinctBy { if (it.collectable) { it.name diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt index dc9f5908..b3ed024f 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt @@ -22,6 +22,8 @@ import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailHashedPassword import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository +import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher +import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.javatime.timestamp @@ -30,34 +32,43 @@ import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository -class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() { +class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPublisher) : UserDetailRepository, + AbstractRepository(), DomainEventPublishableRepository { override val logger: Logger get() = Companion.logger - override suspend fun save(userDetail: UserDetail): UserDetail = query { - val singleOrNull = - UserDetails.selectAll().where { UserDetails.id eq userDetail.id.id }.forUpdate().singleOrNull() - if (singleOrNull == null) { - UserDetails.insert { - it[id] = userDetail.id.id - it[actorId] = userDetail.actorId.id - it[password] = userDetail.password.password - it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest - it[lastMigration] = userDetail.lastMigration - } - } else { - UserDetails.update({ UserDetails.id eq userDetail.id.id }) { - it[actorId] = userDetail.actorId.id - it[password] = userDetail.password.password - it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest - it[lastMigration] = userDetail.lastMigration + override suspend fun save(userDetail: UserDetail): UserDetail { + val userDetail1 = query { + val singleOrNull = + UserDetails.selectAll().where { UserDetails.id eq userDetail.id.id }.forUpdate().singleOrNull() + if (singleOrNull == null) { + UserDetails.insert { + it[id] = userDetail.id.id + it[actorId] = userDetail.actorId.id + it[password] = userDetail.password.password + it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest + it[lastMigration] = userDetail.lastMigration + } + } else { + UserDetails.update({ UserDetails.id eq userDetail.id.id }) { + it[actorId] = userDetail.actorId.id + it[password] = userDetail.password.password + it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest + it[lastMigration] = userDetail.lastMigration + } } + + userDetail } - return@query userDetail + update(userDetail) + return userDetail1 } - override suspend fun delete(userDetail: UserDetail): Unit = query { - UserDetails.deleteWhere { id eq userDetail.id.id } + override suspend fun delete(userDetail: UserDetail): Unit { + query { + UserDetails.deleteWhere { id eq userDetail.id.id } + } + update(userDetail) } override suspend fun findByActorId(actorId: Long): UserDetail? = query { @@ -89,7 +100,7 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() { } } - private fun userDetail(it: ResultRow) = UserDetail.create( + private fun userDetail(it: ResultRow) = UserDetail( UserDetailId(it[UserDetails.id]), ActorId(it[UserDetails.actorId]), UserDetailHashedPassword(it[UserDetails.password]), diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventPublisher.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventPublisher.kt index 40794c1e..bf442ea2 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventPublisher.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventPublisher.kt @@ -18,6 +18,7 @@ package dev.usbharu.hideout.core.infrastructure.springframework.domainevent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher +import org.slf4j.LoggerFactory import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Component @@ -25,6 +26,11 @@ import org.springframework.stereotype.Component class SpringFrameworkDomainEventPublisher(private val applicationEventPublisher: ApplicationEventPublisher) : DomainEventPublisher { override suspend fun publishEvent(domainEvent: DomainEvent<*>) { + logger.trace("Publish ${domainEvent.id} ${domainEvent.name}") applicationEventPublisher.publishEvent(domainEvent) } + + companion object { + private val logger = LoggerFactory.getLogger(SpringFrameworkDomainEventPublisher::class.java) + } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventSubscriber.kt index 6c5a148d..64d7c6a0 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/domainevent/SpringFrameworkDomainEventSubscriber.kt @@ -4,6 +4,7 @@ import dev.usbharu.hideout.core.application.domainevent.subscribers.DomainEventC import dev.usbharu.hideout.core.application.domainevent.subscribers.DomainEventSubscriber import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody +import org.slf4j.LoggerFactory import org.springframework.context.event.EventListener import org.springframework.stereotype.Component @@ -18,11 +19,17 @@ class SpringFrameworkDomainEventSubscriber : DomainEventSubscriber { @EventListener suspend fun onDomainEventPublished(domainEvent: DomainEvent<*>) { + logger.trace("Domain Event Published: $domainEvent") map[domainEvent.name]?.forEach { try { it.invoke(domainEvent) } catch (e: Exception) { + logger.error("", e) } } } + + companion object { + private val logger = LoggerFactory.getLogger(SpringFrameworkDomainEventSubscriber::class.java) + } } From e9d776f71aadd91e248fb1171af4b2ba2774a36e Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 16 Aug 2024 14:25:26 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=E3=83=88=E3=83=A9=E3=83=B3?= =?UTF-8?q?=E3=82=B6=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AE=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=81=A7=E6=AD=A3=E5=B8=B8=E3=81=AB=E3=83=89=E3=83=A1?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=82=A4=E3=83=99=E3=83=B3=E3=83=88=E3=82=92?= =?UTF-8?q?=E5=8F=97=E3=81=91=E5=8F=96=E3=81=A3=E3=81=9F=E3=81=82=E3=81=A8?= =?UTF-8?q?=E3=81=AE=E5=87=A6=E7=90=86=E3=82=92=E5=AE=9F=E8=A1=8C=E3=81=A7?= =?UTF-8?q?=E3=81=8D=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=E5=95=8F=E9=A1=8C?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DomainEventPublishableRepository.kt | 4 ---- .../exposedrepository/AbstractRepository.kt | 21 +++++++++++++++++-- ...osedActorInstanceRelationshipRepository.kt | 10 +++++++-- .../ExposedActorRepository.kt | 9 ++++++-- .../ExposedPostRepository.kt | 18 +++++++++++----- .../ExposedRelationshipRepository.kt | 10 +++++++-- .../ExposedTimelineRepository.kt | 11 ++++++++-- .../UserDetailRepositoryImpl.kt | 13 +++++++++--- 8 files changed, 74 insertions(+), 22 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt index ff9776bc..3b385984 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/shared/repository/DomainEventPublishableRepository.kt @@ -2,16 +2,12 @@ package dev.usbharu.hideout.core.domain.shared.repository import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable -import org.jetbrains.exposed.sql.transactions.TransactionManager import org.springframework.stereotype.Repository @Repository interface DomainEventPublishableRepository { val domainEventPublisher: DomainEventPublisher suspend fun update(entity: T) { - println(entity.getDomainEvents().joinToString()) - val current = TransactionManager.current() - current.registerInterceptor() entity.getDomainEvents().distinctBy { if (it.collectable) { it.name diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt index 4d578f90..6a746eea 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/AbstractRepository.kt @@ -17,6 +17,10 @@ package dev.usbharu.hideout.core.infrastructure.exposedrepository import dev.usbharu.hideout.core.domain.exception.SpringDataAccessExceptionSQLExceptionTranslator +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.slf4j.MDCContext +import org.jetbrains.exposed.sql.Transaction +import org.jetbrains.exposed.sql.statements.StatementInterceptor import org.jetbrains.exposed.sql.transactions.TransactionManager import org.slf4j.Logger import org.springframework.beans.factory.annotation.Value @@ -35,7 +39,20 @@ abstract class AbstractRepository { @Value("\${hideout.debug.trace-query-call:false}") private var traceQueryCall: Boolean = false - protected suspend fun query(block: () -> T): T = try { + class TransactionInterceptor(private val transaction: Transaction) { + + fun onComplete(block: suspend (transaction: Transaction) -> Unit) { + transaction.registerInterceptor(object : StatementInterceptor { + override fun afterCommit(transaction: Transaction) { + runBlocking(MDCContext()) { + block(transaction) + } + } + }) + } + } + + protected suspend fun query(block: TransactionInterceptor.() -> T): T = try { if (traceQueryCall) { @Suppress("ThrowingExceptionsWithoutMessageOrCause") logger.trace( @@ -49,7 +66,7 @@ ${Throwable().stackTrace.joinToString("\n")} ) } - block.invoke() + block.invoke(TransactionInterceptor(TransactionManager.current())) } catch (e: SQLException) { if (traceQueryException) { logger.trace("FAILED EXECUTE SQL", e) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorInstanceRelationshipRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorInstanceRelationshipRepository.kt index 61bccf73..7aee838c 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorInstanceRelationshipRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorInstanceRelationshipRepository.kt @@ -45,8 +45,11 @@ class ExposedActorInstanceRelationshipRepository(override val domainEventPublish it[muting] = actorInstanceRelationship.muting it[doNotSendPrivate] = actorInstanceRelationship.doNotSendPrivate } + onComplete { + update(actorInstanceRelationship) + } } - update(actorInstanceRelationship) + return actorInstanceRelationship } @@ -56,8 +59,11 @@ class ExposedActorInstanceRelationshipRepository(override val domainEventPublish actorId eq actorInstanceRelationship.actorId.id and (instanceId eq actorInstanceRelationship.instanceId.instanceId) } + onComplete { + update(actorInstanceRelationship) + } } - update(actorInstanceRelationship) + } override suspend fun findByActorIdAndInstanceId( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorRepository.kt index 96e663e2..0eb7047c 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorRepository.kt @@ -59,8 +59,11 @@ class ExposedActorRepository( this[ActorsAlsoKnownAs.actorId] = actor.id.id this[ActorsAlsoKnownAs.alsoKnownAs] = it.id } + onComplete { + update(actor) + } } - update(actor) + return actor } @@ -68,8 +71,10 @@ class ExposedActorRepository( query { Actors.deleteWhere { id eq actor.id.id } ActorsAlsoKnownAs.deleteWhere { actorId eq actor.id.id } + onComplete { + update(actor) + } } - update(actor) } override suspend fun findById(id: ActorId): Actor? { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt index e3598182..357ce015 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt @@ -98,8 +98,11 @@ class ExposedPostRepository( this[PostsVisibleActors.postId] = post.id.id this[PostsVisibleActors.actorId] = it.id } + onComplete { + update(post) + } } - update(post) + return post } @@ -148,9 +151,11 @@ class ExposedPostRepository( this[PostsVisibleActors.postId] = it.first this[PostsVisibleActors.actorId] = it.second } - } - posts.forEach { - update(it) + onComplete { + posts.forEach { + update(it) + } + } } return posts } @@ -195,8 +200,11 @@ class ExposedPostRepository( Posts.deleteWhere { id eq post.id.id } + onComplete { + update(post) + } } - update(post) + } override suspend fun findByActorIdAndVisibilityInList( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt index 35021733..96ddef0f 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt @@ -47,8 +47,11 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve it[followRequesting] = relationship.followRequesting it[mutingFollowRequest] = relationship.mutingFollowRequest } + onComplete { + update(relationship) + } } - update(relationship) + return relationship } @@ -57,8 +60,11 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve Relationships.deleteWhere { actorId eq relationship.actorId.id and (targetActorId eq relationship.targetActorId.id) } + onComplete { + update(relationship) + } } - update(relationship) + } override suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship? = query { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt index ecf93bb1..d884bbf1 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt @@ -24,8 +24,12 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu it[visibility] = timeline.visibility.name it[isSystem] = timeline.isSystem } + onComplete { + update(timeline) + } } - update(timeline) + + return timeline } @@ -34,8 +38,11 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu Timelines.deleteWhere { Timelines.id eq timeline.id.value } + onComplete { + update(timeline) + } } - update(timeline) + } override suspend fun findByIds(ids: List): List { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt index b3ed024f..a508a07a 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt @@ -48,6 +48,7 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub it[password] = userDetail.password.password it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest it[lastMigration] = userDetail.lastMigration + it[homeTimelineId] = userDetail.homeTimelineId?.value } } else { UserDetails.update({ UserDetails.id eq userDetail.id.id }) { @@ -55,20 +56,26 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub it[password] = userDetail.password.password it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest it[lastMigration] = userDetail.lastMigration + it[homeTimelineId] = userDetail.homeTimelineId?.value } } - + onComplete { + update(userDetail) + } userDetail } - update(userDetail) + return userDetail1 } override suspend fun delete(userDetail: UserDetail): Unit { query { UserDetails.deleteWhere { id eq userDetail.id.id } + onComplete { + update(userDetail) + } } - update(userDetail) + } override suspend fun findByActorId(actorId: Long): UserDetail? = query { From e1787423e81ac004004544141fa92ef6b8f88eb2 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 16 Aug 2024 15:02:32 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=E8=87=AA=E5=88=86=E8=87=AA?= =?UTF-8?q?=E8=BA=AB=E3=82=92=E3=83=9B=E3=83=BC=E3=83=A0=E3=82=BF=E3=82=A4?= =?UTF-8?q?=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3=E3=81=AB=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...rRegisterHomeTimelineApplicationService.kt | 14 ++++++++ .../src/main/resources/application.yml | 12 +++---- .../resources/db/migration/V1__Init_DB.sql | 34 +++++++++++++++++-- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt index 5394e998..6119370b 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt @@ -4,6 +4,10 @@ import dev.usbharu.hideout.core.application.shared.AbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.support.principal.Principal import dev.usbharu.hideout.core.domain.model.timeline.* +import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship +import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipId +import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository +import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import dev.usbharu.hideout.core.domain.shared.id.IdGenerateService @@ -15,6 +19,7 @@ class UserRegisterHomeTimelineApplicationService( private val userDetailRepository: UserDetailRepository, private val timelineRepository: TimelineRepository, private val idGenerateService: IdGenerateService, transaction: Transaction, + private val timelineRelationshipRepository: TimelineRelationshipRepository ) : AbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: RegisterHomeTimeline, principal: Principal) { @@ -31,6 +36,15 @@ class UserRegisterHomeTimelineApplicationService( timelineRepository.save(timeline) userDetail.homeTimelineId = timeline.id + val timelineRelationship = TimelineRelationship( + TimelineRelationshipId(idGenerateService.generateId()), + timeline.id, + userDetail.actorId, + Visible.DIRECT + ) + + timelineRelationshipRepository.save(timelineRelationship) + userDetailRepository.save(userDetail) } diff --git a/hideout-core/src/main/resources/application.yml b/hideout-core/src/main/resources/application.yml index c4bcecdd..371565d4 100644 --- a/hideout-core/src/main/resources/application.yml +++ b/hideout-core/src/main/resources/application.yml @@ -20,6 +20,12 @@ hideout: spring: + data: + mongodb: + auto-index-creation: true + host: localhost + port: 27017 + database: hideout jmx: enabled: false jackson: @@ -31,12 +37,6 @@ spring: url: "jdbc:postgresql:hideout" username: "postgres" password: "password" - data: - mongodb: - auto-index-creation: true - host: localhost - port: 27017 - database: hideout servlet: multipart: max-file-size: 40MB diff --git a/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql index e7330e1b..dd9dfa5c 100644 --- a/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql +++ b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql @@ -81,7 +81,7 @@ create table timelines ); create table if not exists user_details ( - id bigserial primary key, + id bigint primary key, actor_id bigint not null unique, password varchar(255) not null, auto_accept_followee_follow_request boolean not null, @@ -286,4 +286,34 @@ create table if not exists actor_instance_relationships PRIMARY KEY (actor_id, instance_id), constraint fk_actor_instance_relationships_actor_id__id foreign key (actor_id) references actors (id) on delete cascade on update cascade, constraint fk_actor_instance_relationships_instance_id__id foreign key (instance_id) references instance (id) on delete cascade on update cascade -); \ No newline at end of file +); + +create table if not exists timeline_relationships +( + id bigint primary key, + timeline_id bigint not null, + actor_id bigint not null, + visible varchar(100) not null, + constraint fk_timeline_relationships_timeline_id__id foreign key (timeline_id) references timelines (id) on delete cascade on update cascade, + constraint fk_timeline_relationships_actor_id__id foreign key (actor_id) references actors (id) on delete cascade on update cascade + +); + +create table if not exists filters +( + id bigint primary key, + user_id bigint not null, + name varchar(255) not null, + context varchar(500) not null, + action varchar(255) not null, + constraint fk_filters_user_id__id foreign key (user_id) references user_details (id) on delete cascade on update cascade +); + +create table if not exists filter_keywords +( + id bigint primary key, + filter_id bigint not null, + keyword varchar(1000) not null, + mode varchar(100) not null, + constraint fk_filter_keywords_filter_id__id foreign key (filter_id) references filters (id) on delete cascade on update cascade +) \ No newline at end of file From d53cdca9e5aea16e93905282368dc3d2bf6fd317 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 16 Aug 2024 15:10:53 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=E3=83=9B=E3=83=BC=E3=83=A0?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3=E3=81=8C?= =?UTF-8?q?=E8=AA=AD=E3=82=81=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/domain/model/filter/FilterRepository.kt | 1 - .../exposedrepository/ExposedFilterRepository.kt | 14 +++++++------- .../timeline/DefaultTimelineStore.kt | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterRepository.kt index fe65b133..5c4d11ee 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterRepository.kt @@ -8,6 +8,5 @@ interface FilterRepository { suspend fun findByFilterKeywordId(filterKeywordId: FilterKeywordId): Filter? suspend fun findByFilterId(filterId: FilterId): Filter? - suspend fun findByUserDetailId(userDetailId: UserDetailId): List } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt index ae06094f..765641f1 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt @@ -59,22 +59,22 @@ class ExposedFilterRepository(private val filterQueryMapper: QueryMapper Filters.deleteWhere { id eq filter.id.id } } - override suspend fun findByFilterKeywordId(filterKeywordId: FilterKeywordId): Filter? { + override suspend fun findByFilterKeywordId(filterKeywordId: FilterKeywordId): Filter? = query { val filterId = FilterKeywords .selectAll() .where { FilterKeywords.id eq filterKeywordId.id } - .firstOrNull()?.get(FilterKeywords.filterId) ?: return null + .firstOrNull()?.get(FilterKeywords.filterId) ?: return@query null val where = Filters.selectAll().where { Filters.id eq filterId } - return filterQueryMapper.map(where).firstOrNull() + return@query filterQueryMapper.map(where).firstOrNull() } - override suspend fun findByFilterId(filterId: FilterId): Filter? { + override suspend fun findByFilterId(filterId: FilterId): Filter? = query { val where = Filters.selectAll().where { Filters.id eq filterId.id } - return filterQueryMapper.map(where).firstOrNull() + return@query filterQueryMapper.map(where).firstOrNull() } - override suspend fun findByUserDetailId(userDetailId: UserDetailId): List { - return Filters.selectAll().where { Filters.userId eq userDetailId.id }.let(filterQueryMapper::map) + override suspend fun findByUserDetailId(userDetailId: UserDetailId): List = query { + return@query Filters.selectAll().where { Filters.userId eq userDetailId.id }.let(filterQueryMapper::map) } companion object { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt index 8781b862..974ad7ec 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt @@ -67,7 +67,7 @@ open class DefaultTimelineStore( } override suspend fun getNewerFilters(userDetailId: UserDetailId, lastUpdateAt: Instant): List { - TODO("Not yet implemented") + return filterRepository.findByUserDetailId(userDetailId) } override suspend fun applyFilters(post: Post, filters: List): FilteredPost { From 11e2eb1e108f46271ca8673e13d79ec40bac1b3b Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 17 Aug 2024 18:21:32 +0900 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20=E3=83=9A=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=83=B3=E3=82=B0=E3=81=8C=E5=8B=95=E3=81=8F=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MongoInternalTimelineObjectRepository.kt | 48 ++++++++++++++++--- .../timeline/AbstractTimelineStore.kt | 8 ++++ .../timeline/DefaultTimelineStore.kt | 25 ++++++++++ .../InternalTimelineObjectRepository.kt | 11 +++++ .../web/timeline/TimelineController.kt | 11 ++++- hideout-core/src/main/resources/log4j2.xml | 6 ++- .../messages/hideout-web-messages.properties | 2 + .../hideout-web-messages_en_US.properties | 2 + .../hideout-web-messages_ja_JP.properties | 2 + .../templates/fragments-timeline.html | 12 +++-- 10 files changed, 111 insertions(+), 16 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoInternalTimelineObjectRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoInternalTimelineObjectRepository.kt index 6f77882c..f289ec5c 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoInternalTimelineObjectRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/mongorepository/MongoInternalTimelineObjectRepository.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList +import org.springframework.data.annotation.Id import org.springframework.data.domain.Sort import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.mapping.Document @@ -61,6 +62,22 @@ class MongoInternalTimelineObjectRepository( springDataMongoTimelineObjectRepository.deleteByTimelineId(timelineId.value) } + override suspend fun findByTimelineIdAndPostIdGT(timelineId: TimelineId, postId: PostId): TimelineObject? { + return springDataMongoTimelineObjectRepository.findFirstByTimelineIdAndPostIdGreaterThanOrderByIdAsc( + timelineId.value, + postId.id + ) + ?.toTimelineObject() + } + + override suspend fun findByTimelineIdAndPostIdLT(timelineId: TimelineId, postId: PostId): TimelineObject? { + return springDataMongoTimelineObjectRepository.findFirstByTimelineIdAndPostIdLessThanOrderByIdDesc( + timelineId.value, + postId.id + ) + ?.toTimelineObject() + } + override suspend fun findByTimelineId( timelineId: TimelineId, internalTimelineObjectOption: InternalTimelineObjectOption?, @@ -70,12 +87,12 @@ class MongoInternalTimelineObjectRepository( if (page?.minId != null) { query.with(Sort.by(Sort.Direction.ASC, "postCreatedAt")) - page.minId?.let { query.addCriteria(Criteria.where("id").gt(it)) } - page.maxId?.let { query.addCriteria(Criteria.where("id").lt(it)) } + page.minId?.let { query.addCriteria(Criteria.where("postId").gt(it)) } + page.maxId?.let { query.addCriteria(Criteria.where("postId").lt(it)) } } else { query.with(Sort.by(Sort.Direction.DESC, "postCreatedAt")) - page?.sinceId?.let { query.addCriteria(Criteria.where("id").gt(it)) } - page?.maxId?.let { query.addCriteria(Criteria.where("id").lt(it)) } + page?.sinceId?.let { query.addCriteria(Criteria.where("postId").gt(it)) } + page?.maxId?.let { query.addCriteria(Criteria.where("postId").lt(it)) } } page?.limit?.let { query.limit(it) } @@ -83,16 +100,23 @@ class MongoInternalTimelineObjectRepository( val timelineObjects = mongoTemplate.find(query, SpringDataMongoTimelineObject::class.java).map { it.toTimelineObject() } + val objectList = if (page?.minId != null) { + timelineObjects.reversed() + } else { + timelineObjects + } + return PaginationList( - timelineObjects, - timelineObjects.lastOrNull()?.postId, - timelineObjects.firstOrNull()?.postId + objectList, + objectList.lastOrNull()?.postId, + objectList.firstOrNull()?.postId ) } } @Document data class SpringDataMongoTimelineObject( + @Id val id: Long, val userDetailId: Long, val timelineId: Long, @@ -194,4 +218,14 @@ interface SpringDataMongoTimelineObjectRepository : CoroutineCrudRepository + + suspend fun findFirstByTimelineIdAndPostIdGreaterThanOrderByIdAsc( + timelineId: Long, + postId: Long + ): SpringDataMongoTimelineObject? + + suspend fun findFirstByTimelineIdAndPostIdLessThanOrderByIdDesc( + timelineId: Long, + postId: Long + ): SpringDataMongoTimelineObject? } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt index 149ffb26..f0be54f8 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/AbstractTimelineStore.kt @@ -205,6 +205,11 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe removeTimelineObject(timeline.id) } + protected abstract suspend fun getNextPaging( + timelineId: TimelineId, + page: Page? + ): PaginationList + override suspend fun readTimeline( timeline: Timeline, option: ReadTimelineOption?, @@ -212,6 +217,9 @@ abstract class AbstractTimelineStore(private val idGenerateService: IdGenerateSe principal: Principal ): PaginationList { val timelineObjectList = getTimelineObject(timeline.id, option, page) + if (timelineObjectList.isEmpty()) { + return getNextPaging(timeline.id, page) + } val lastUpdatedAt = timelineObjectList.minBy { it.lastUpdatedAt }.lastUpdatedAt val newerFilters = getNewerFilters(timeline.userDetailId, lastUpdatedAt) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt index 974ad7ec..182ed506 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt @@ -18,6 +18,7 @@ import dev.usbharu.hideout.core.domain.model.post.Visibility import dev.usbharu.hideout.core.domain.model.support.page.Page import dev.usbharu.hideout.core.domain.model.support.page.PaginationList import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.support.timelineobjectdetail.TimelineObjectDetail import dev.usbharu.hideout.core.domain.model.timeline.Timeline import dev.usbharu.hideout.core.domain.model.timeline.TimelineId import dev.usbharu.hideout.core.domain.model.timeline.TimelineRepository @@ -135,6 +136,30 @@ open class DefaultTimelineStore( ) } + override suspend fun getNextPaging( + timelineId: TimelineId, + page: Page? + ): PaginationList { + if (page?.maxId != null) { + return PaginationList( + emptyList(), + null, + internalTimelineObjectRepository.findByTimelineIdAndPostIdLT(timelineId, PostId(page.maxId!!))?.postId + ?: PostId(0) + ) + } else if (page?.minId != null) { + return PaginationList( + emptyList(), + internalTimelineObjectRepository.findByTimelineIdAndPostIdGT(timelineId, PostId(page.minId!!))?.postId + ?: PostId(Long.MAX_VALUE), + null + ) + } + return PaginationList(emptyList(), page?.maxId?.let { PostId(it) }, page?.minId?.let { PostId(it) }) + + + } + override suspend fun getActors(actorIds: List): Map { return actorRepository.findAllById(actorIds).associateBy { it.id } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/InternalTimelineObjectRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/InternalTimelineObjectRepository.kt index 3f26cbab..c0cf4ac6 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/InternalTimelineObjectRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/InternalTimelineObjectRepository.kt @@ -19,6 +19,17 @@ interface InternalTimelineObjectRepository { suspend fun deleteByTimelineIdAndActorId(timelineId: TimelineId, actorId: ActorId) suspend fun deleteByTimelineId(timelineId: TimelineId) + + /** + * 指定したTimelineIdより大きく、近いものを返す + */ + suspend fun findByTimelineIdAndPostIdGT(timelineId: TimelineId, postId: PostId): TimelineObject? + + /** + * 指定したTimelineIdより小さく、近いものを返す + */ + suspend fun findByTimelineIdAndPostIdLT(timelineId: TimelineId, postId: PostId): TimelineObject? + suspend fun findByTimelineId( timelineId: TimelineId, internalTimelineObjectOption: InternalTimelineObjectOption? = null, diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt index ebb3b86f..8b6da2ad 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt @@ -20,7 +20,12 @@ class TimelineController( private val transaction: Transaction ) { @GetMapping("/home") - suspend fun homeTimeline(model: Model, @RequestParam sinceId: String?, @RequestParam maxId: String?): String { + suspend fun homeTimeline( + model: Model, + @RequestParam sinceId: String?, + @RequestParam maxId: String?, + @RequestParam minId: String? + ): String { val principal = springSecurityFormLoginPrincipalContextHolder.getPrincipal() val userDetail = transaction.transaction { userDetailRepository.findByActorId(principal.actorId.id) @@ -36,7 +41,9 @@ class TimelineController( remoteOnly = false, page = Page.of( maxId = maxId?.toLongOrNull(), - sinceId = sinceId?.toLongOrNull() + sinceId = sinceId?.toLongOrNull(), + minId = minId?.toLongOrNull(), + limit = 20 ) ), principal ) diff --git a/hideout-core/src/main/resources/log4j2.xml b/hideout-core/src/main/resources/log4j2.xml index 3a225230..978d338a 100644 --- a/hideout-core/src/main/resources/log4j2.xml +++ b/hideout-core/src/main/resources/log4j2.xml @@ -6,12 +6,14 @@ - + - + + + \ No newline at end of file diff --git a/hideout-core/src/main/resources/messages/hideout-web-messages.properties b/hideout-core/src/main/resources/messages/hideout-web-messages.properties index 6bc6f623..c22c2992 100644 --- a/hideout-core/src/main/resources/messages/hideout-web-messages.properties +++ b/hideout-core/src/main/resources/messages/hideout-web-messages.properties @@ -1,6 +1,8 @@ common.audio=\u30AA\u30FC\u30C7\u30A3\u30AA common.audio-download-link=\u97F3\u58F0\u30D5\u30A1\u30A4\u30EB\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9 +common.empty=\u8868\u793A\u3059\u308B\u3082\u306E\u304C\u3042\u308A\u307E\u305B\u3093 common.media-original-link=\u30AA\u30EA\u30B8\u30CA\u30EB +common.paging-load=\u3082\u3063\u3068\u898B\u308B common.thumbnail=\u30B5\u30E0\u30CD\u30A4\u30EB common.unknwon-file-type=\u4E0D\u660E\u306A\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F common.video=\u52D5\u753B diff --git a/hideout-core/src/main/resources/messages/hideout-web-messages_en_US.properties b/hideout-core/src/main/resources/messages/hideout-web-messages_en_US.properties index 1f1223cb..f32efecd 100644 --- a/hideout-core/src/main/resources/messages/hideout-web-messages_en_US.properties +++ b/hideout-core/src/main/resources/messages/hideout-web-messages_en_US.properties @@ -1,6 +1,8 @@ common.audio=Audio common.audio-download-link=Download the audio. +common.empty=Empty common.media-original-link=original +common.paging-load=Show more common.thumbnail=thumbnail common.unknwon-file-type=Unknown filetype common.video=Video diff --git a/hideout-core/src/main/resources/messages/hideout-web-messages_ja_JP.properties b/hideout-core/src/main/resources/messages/hideout-web-messages_ja_JP.properties index 6bc6f623..c22c2992 100644 --- a/hideout-core/src/main/resources/messages/hideout-web-messages_ja_JP.properties +++ b/hideout-core/src/main/resources/messages/hideout-web-messages_ja_JP.properties @@ -1,6 +1,8 @@ common.audio=\u30AA\u30FC\u30C7\u30A3\u30AA common.audio-download-link=\u97F3\u58F0\u30D5\u30A1\u30A4\u30EB\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9 +common.empty=\u8868\u793A\u3059\u308B\u3082\u306E\u304C\u3042\u308A\u307E\u305B\u3093 common.media-original-link=\u30AA\u30EA\u30B8\u30CA\u30EB +common.paging-load=\u3082\u3063\u3068\u898B\u308B common.thumbnail=\u30B5\u30E0\u30CD\u30A4\u30EB common.unknwon-file-type=\u4E0D\u660E\u306A\u30D5\u30A1\u30A4\u30EB\u5F62\u5F0F common.video=\u52D5\u753B diff --git a/hideout-core/src/main/resources/templates/fragments-timeline.html b/hideout-core/src/main/resources/templates/fragments-timeline.html index f1f2b3cb..f08d6715 100644 --- a/hideout-core/src/main/resources/templates/fragments-timeline.html +++ b/hideout-core/src/main/resources/templates/fragments-timeline.html @@ -7,14 +7,16 @@ -
- + +
- + +
-
- + From 29ff1269cec83219a702813c73024699efdf8f73 Mon Sep 17 00:00:00 2001 From: usbharu Date: Sat, 17 Aug 2024 10:52:33 +0000 Subject: [PATCH 8/8] style: fix lint (CI) --- .../RegisterLocalUserSetHomeTimelineSubscriber.kt | 2 +- .../RegisterTimelineSetTimelineStoreSubscriber.kt | 2 +- .../UserRegisterHomeTimelineApplicationService.kt | 12 +++++++----- .../timeline/ReadTimelineApplicationService.kt | 3 +-- .../SetTimelineToTimelineStoreApplicationService.kt | 5 +++-- .../timeline/TimelineAddPostApplicationService.kt | 2 +- .../UserRegisterTimelineApplicationService.kt | 2 +- .../core/domain/event/userdetail/UserDetailEvent.kt | 2 +- .../service/post/DefaultPostReadAccessControl.kt | 6 +++--- .../ExposedActorInstanceRelationshipRepository.kt | 1 - .../exposedrepository/ExposedPostRepository.kt | 1 - .../ExposedRelationshipRepository.kt | 1 - .../exposedrepository/ExposedTimelineRepository.kt | 2 -- .../exposedrepository/UserDetailRepositoryImpl.kt | 9 +++++---- .../infrastructure/timeline/DefaultTimelineStore.kt | 2 -- .../interfaces/web/timeline/TimelineController.kt | 5 +++-- 16 files changed, 27 insertions(+), 30 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt index 49ed5925..868ec419 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterLocalUserSetHomeTimelineSubscriber.kt @@ -21,4 +21,4 @@ class RegisterLocalUserSetHomeTimelineSubscriber( } } -//todo userdetailにdomain event付けて createのイベントで反応させる タイムラインを新しく一つ作って userdetailのhometimelineに紐づけて自分自身をtimleine relationshipに入れる \ No newline at end of file +// todo userdetailにdomain event付けて createのイベントで反応させる タイムラインを新しく一つ作って userdetailのhometimelineに紐づけて自分自身をtimleine relationshipに入れる diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt index f1a93dfa..246795c6 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/RegisterTimelineSetTimelineStoreSubscriber.kt @@ -18,4 +18,4 @@ class RegisterTimelineSetTimelineStoreSubscriber( setTimelineToTimelineStoreApplicationService.execute(SetTimleineStore(it.body.getTimelineId()), Anonymous) } } -} \ No newline at end of file +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt index 6119370b..3caa2ec0 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/domainevent/subscribers/UserRegisterHomeTimelineApplicationService.kt @@ -18,13 +18,15 @@ import org.springframework.stereotype.Component class UserRegisterHomeTimelineApplicationService( private val userDetailRepository: UserDetailRepository, private val timelineRepository: TimelineRepository, - private val idGenerateService: IdGenerateService, transaction: Transaction, + private val idGenerateService: IdGenerateService, + transaction: Transaction, private val timelineRelationshipRepository: TimelineRelationshipRepository ) : AbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: RegisterHomeTimeline, principal: Principal) { - - val userDetail = (userDetailRepository.findById(UserDetailId(command.userDetailId)) - ?: throw IllegalArgumentException("UserDetail ${command.userDetailId} not found.")) + val userDetail = ( + userDetailRepository.findById(UserDetailId(command.userDetailId)) + ?: throw IllegalArgumentException("UserDetail ${command.userDetailId} not found.") + ) val timeline = Timeline.create( TimelineId(idGenerateService.generateId()), @@ -51,4 +53,4 @@ class UserRegisterHomeTimelineApplicationService( companion object { private val logger = LoggerFactory.getLogger(UserRegisterHomeTimelineApplicationService::class.java) } -} \ No newline at end of file +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt index 17b9b5ae..88fabe9f 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/ReadTimelineApplicationService.kt @@ -41,7 +41,6 @@ class ReadTimelineApplicationService( ) val postDetailList = timeline.map { - val reply = if (it.replyPost != null) { PostDetail.of( it.replyPost, @@ -80,4 +79,4 @@ class ReadTimelineApplicationService( companion object { private val logger = LoggerFactory.getLogger(ReadTimelineApplicationService::class.java) } -} \ No newline at end of file +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt index f47fcc0f..139b6b55 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/SetTimelineToTimelineStoreApplicationService.kt @@ -15,7 +15,8 @@ class SetTimelineToTimelineStoreApplicationService( private val timelineRepository: TimelineRepository ) : AbstractApplicationService( - transaction, logger + transaction, + logger ) { override suspend fun internalExecute(command: SetTimleineStore, principal: Principal) { val findById = timelineRepository.findById(command.timelineId) @@ -26,4 +27,4 @@ class SetTimelineToTimelineStoreApplicationService( companion object { private val logger = LoggerFactory.getLogger(SetTimelineToTimelineStoreApplicationService::class.java) } -} \ No newline at end of file +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt index 8c907a61..c00b54ef 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/TimelineAddPostApplicationService.kt @@ -26,4 +26,4 @@ class TimelineAddPostApplicationService( companion object { private val logger = LoggerFactory.getLogger(TimelineAddPostApplicationService::class.java) } -} \ No newline at end of file +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt index 0660c020..5b0af07c 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserRegisterTimelineApplicationService.kt @@ -34,4 +34,4 @@ class UserRegisterTimelineApplicationService( companion object { private val logger = LoggerFactory.getLogger(UserRegisterTimelineApplicationService::class.java) } -} \ No newline at end of file +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt index 7493e943..792b475c 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/event/userdetail/UserDetailEvent.kt @@ -26,4 +26,4 @@ class UserDetailEventBody(userDetail: UserDetailId) : DomainEventBody( enum class UserDetailEvent(val eventName: String) { CREATE("UserDetailCreate"), -} \ No newline at end of file +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/post/DefaultPostReadAccessControl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/post/DefaultPostReadAccessControl.kt index 97b78c5a..0b82ee76 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/post/DefaultPostReadAccessControl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/service/post/DefaultPostReadAccessControl.kt @@ -23,9 +23,9 @@ class DefaultPostReadAccessControl(private val relationshipRepository: Relations } val relationship = ( - relationshipRepository.findByActorIdAndTargetId(post.actorId, principal.actorId) - ?: Relationship.default(post.actorId, principal.actorId) - ) + relationshipRepository.findByActorIdAndTargetId(post.actorId, principal.actorId) + ?: Relationship.default(post.actorId, principal.actorId) + ) // ブロックされてたら見れない if (relationship.blocking) { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorInstanceRelationshipRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorInstanceRelationshipRepository.kt index 7aee838c..76d80efd 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorInstanceRelationshipRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedActorInstanceRelationshipRepository.kt @@ -63,7 +63,6 @@ class ExposedActorInstanceRelationshipRepository(override val domainEventPublish update(actorInstanceRelationship) } } - } override suspend fun findByActorIdAndInstanceId( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt index 357ce015..78dcbbff 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt @@ -204,7 +204,6 @@ class ExposedPostRepository( update(post) } } - } override suspend fun findByActorIdAndVisibilityInList( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt index 96ddef0f..73675308 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedRelationshipRepository.kt @@ -64,7 +64,6 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve update(relationship) } } - } override suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship? = query { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt index d884bbf1..3bd964f7 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedTimelineRepository.kt @@ -29,7 +29,6 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu } } - return timeline } @@ -42,7 +41,6 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu update(timeline) } } - } override suspend fun findByIds(ids: List): List { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt index a508a07a..1169e109 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/UserDetailRepositoryImpl.kt @@ -32,8 +32,10 @@ import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository -class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPublisher) : UserDetailRepository, - AbstractRepository(), DomainEventPublishableRepository { +class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPublisher) : + UserDetailRepository, + AbstractRepository(), + DomainEventPublishableRepository { override val logger: Logger get() = Companion.logger @@ -68,14 +70,13 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub return userDetail1 } - override suspend fun delete(userDetail: UserDetail): Unit { + override suspend fun delete(userDetail: UserDetail) { query { UserDetails.deleteWhere { id eq userDetail.id.id } onComplete { update(userDetail) } } - } override suspend fun findByActorId(actorId: Long): UserDetail? = query { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt index 182ed506..2a704496 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/timeline/DefaultTimelineStore.kt @@ -156,8 +156,6 @@ open class DefaultTimelineStore( ) } return PaginationList(emptyList(), page?.maxId?.let { PostId(it) }, page?.minId?.let { PostId(it) }) - - } override suspend fun getActors(actorIds: List): Map { diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt index 8b6da2ad..fe88f560 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/interfaces/web/timeline/TimelineController.kt @@ -45,11 +45,12 @@ class TimelineController( minId = minId?.toLongOrNull(), limit = 20 ) - ), principal + ), + principal ) model.addAttribute("timeline", execute) return "homeTimeline" } -} \ No newline at end of file +}