mirror of https://github.com/usbharu/Hideout.git
feat: アカウント作成時に自動でホームタイムラインを作成するように
This commit is contained in:
parent
8e84c8e59c
commit
e728b0f990
|
@ -63,6 +63,9 @@ class RegisterLocalActorApplicationService(
|
|||
id = UserDetailId(idGenerateService.generateId()),
|
||||
actorId = actor.id,
|
||||
password = userDetailDomainService.hashPassword(command.password),
|
||||
autoAcceptFolloweeFollowRequest = false,
|
||||
lastMigration = null,
|
||||
homeTimelineId = null
|
||||
)
|
||||
userDetailRepository.save(userDetail)
|
||||
return actor.url
|
||||
|
|
|
@ -7,4 +7,4 @@ interface DomainEventSubscriber {
|
|||
fun <T : DomainEventBody> subscribe(eventName: String, domainEventConsumer: DomainEventConsumer<T>)
|
||||
}
|
||||
|
||||
typealias DomainEventConsumer<T> = (DomainEvent<T>) -> Unit
|
||||
typealias DomainEventConsumer<T> = suspend (DomainEvent<T>) -> Unit
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package dev.usbharu.hideout.core.application.domainevent.subscribers
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.DomainEventCommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
|
||||
import dev.usbharu.hideout.core.application.timeline.AddTimelineRelationship
|
||||
import dev.usbharu.hideout.core.application.timeline.UserAddTimelineRelationshipApplicationService
|
||||
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEvent
|
||||
import dev.usbharu.hideout.core.domain.event.relationship.RelationshipEventBody
|
||||
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.Visible
|
||||
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 TimelineRelationshipFollowSubscriber(
|
||||
private val userAddTimelineRelationshipApplicationService: UserAddTimelineRelationshipApplicationService,
|
||||
private val idGenerateService: IdGenerateService,
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
domainEventSubscriber: DomainEventSubscriber
|
||||
) : Subscriber {
|
||||
|
||||
init {
|
||||
domainEventSubscriber.subscribe<RelationshipEventBody>(RelationshipEvent.FOLLOW.eventName) {
|
||||
val relationship = it.body.getRelationship()
|
||||
val userDetail = userDetailRepository.findByActorId(relationship.actorId.id) ?: throw Exception()
|
||||
if (userDetail.homeTimelineId == null) {
|
||||
logger.warn("Home timeline for ${relationship.actorId} is not found")
|
||||
return@subscribe
|
||||
}
|
||||
userAddTimelineRelationshipApplicationService.execute(
|
||||
AddTimelineRelationship(
|
||||
TimelineRelationship(
|
||||
TimelineRelationshipId(idGenerateService.generateId()),
|
||||
userDetail.homeTimelineId,
|
||||
relationship.targetActorId,
|
||||
Visible.FOLLOWERS
|
||||
)
|
||||
), DomainEventCommandExecutor("", object : UserDetailGettableCommandExecutor {
|
||||
override val userDetailId: Long
|
||||
get() = userDetail.id.id
|
||||
override val executor: String
|
||||
get() = userDetail.id.id.toString()
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(TimelineRelationshipFollowSubscriber::class.java)
|
||||
}
|
||||
|
||||
}
|
|
@ -23,3 +23,8 @@ interface CommandExecutor {
|
|||
interface UserDetailGettableCommandExecutor : CommandExecutor {
|
||||
val userDetailId: Long
|
||||
}
|
||||
|
||||
data class DomainEventCommandExecutor(
|
||||
override val executor: String,
|
||||
val commandExecutor: CommandExecutor?
|
||||
) : CommandExecutor
|
|
@ -0,0 +1,7 @@
|
|||
package dev.usbharu.hideout.core.application.timeline
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
|
||||
|
||||
data class AddTimelineRelationship(
|
||||
val timelineRelationship: TimelineRelationship
|
||||
)
|
|
@ -0,0 +1,26 @@
|
|||
package dev.usbharu.hideout.core.application.timeline
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UserAddTimelineRelationshipApplicationService(
|
||||
private val timelineRelationshipRepository: TimelineRelationshipRepository,
|
||||
transaction: Transaction
|
||||
) :
|
||||
AbstractApplicationService<AddTimelineRelationship, Unit>(
|
||||
transaction, logger
|
||||
) {
|
||||
override suspend fun internalExecute(command: AddTimelineRelationship, executor: CommandExecutor) {
|
||||
timelineRelationshipRepository.save(command.timelineRelationship)
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserAddTimelineRelationshipApplicationService::class.java)
|
||||
}
|
||||
}
|
|
@ -25,7 +25,11 @@ class RelationshipEventFactory(private val relationship: Relationship) {
|
|||
DomainEvent.create(relationshipEvent.eventName, RelationshipEventBody(relationship))
|
||||
}
|
||||
|
||||
class RelationshipEventBody(relationship: Relationship) : DomainEventBody(mapOf("relationship" to relationship))
|
||||
class RelationshipEventBody(relationship: Relationship) : DomainEventBody(mapOf("relationship" to relationship)) {
|
||||
fun getRelationship(): Relationship {
|
||||
return toMap()["relationship"] as Relationship
|
||||
}
|
||||
}
|
||||
|
||||
enum class RelationshipEvent(val eventName: String) {
|
||||
FOLLOW("RelationshipFollow"),
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package dev.usbharu.hideout.core.domain.model.userdetails
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||
import java.time.Instant
|
||||
|
||||
class UserDetail private constructor(
|
||||
|
@ -25,6 +26,7 @@ class UserDetail private constructor(
|
|||
var password: UserDetailHashedPassword,
|
||||
var autoAcceptFolloweeFollowRequest: Boolean,
|
||||
var lastMigration: Instant? = null,
|
||||
val homeTimelineId: TimelineId?
|
||||
) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
@ -45,13 +47,15 @@ class UserDetail private constructor(
|
|||
password: UserDetailHashedPassword,
|
||||
autoAcceptFolloweeFollowRequest: Boolean = false,
|
||||
lastMigration: Instant? = null,
|
||||
homeTimelineId: TimelineId?
|
||||
): UserDetail {
|
||||
return UserDetail(
|
||||
id,
|
||||
actorId,
|
||||
password,
|
||||
autoAcceptFolloweeFollowRequest,
|
||||
lastMigration
|
||||
lastMigration,
|
||||
homeTimelineId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||
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
|
||||
|
@ -64,13 +65,7 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() {
|
|||
.selectAll().where { UserDetails.actorId eq actorId }
|
||||
.singleOrNull()
|
||||
?.let {
|
||||
UserDetail.create(
|
||||
UserDetailId(it[UserDetails.id]),
|
||||
ActorId(it[UserDetails.actorId]),
|
||||
UserDetailHashedPassword(it[UserDetails.password]),
|
||||
it[UserDetails.autoAcceptFolloweeFollowRequest],
|
||||
it[UserDetails.lastMigration]
|
||||
)
|
||||
userDetail(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,13 +74,7 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() {
|
|||
.selectAll().where { UserDetails.id eq id }
|
||||
.singleOrNull()
|
||||
?.let {
|
||||
UserDetail.create(
|
||||
UserDetailId(it[UserDetails.id]),
|
||||
ActorId(it[UserDetails.actorId]),
|
||||
UserDetailHashedPassword(it[UserDetails.password]),
|
||||
it[UserDetails.autoAcceptFolloweeFollowRequest],
|
||||
it[UserDetails.lastMigration]
|
||||
)
|
||||
userDetail(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,16 +84,19 @@ class UserDetailRepositoryImpl : UserDetailRepository, AbstractRepository() {
|
|||
.selectAll()
|
||||
.where { UserDetails.id inList idList.map { it.id } }
|
||||
.map {
|
||||
UserDetail.create(
|
||||
userDetail(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun userDetail(it: ResultRow) = UserDetail.create(
|
||||
UserDetailId(it[UserDetails.id]),
|
||||
ActorId(it[UserDetails.actorId]),
|
||||
UserDetailHashedPassword(it[UserDetails.password]),
|
||||
it[UserDetails.autoAcceptFolloweeFollowRequest],
|
||||
it[UserDetails.lastMigration]
|
||||
it[UserDetails.lastMigration],
|
||||
it[UserDetails.homeTimelineId]?.let { it1 -> TimelineId(it1) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserDetailRepositoryImpl::class.java)
|
||||
|
@ -117,5 +109,6 @@ object UserDetails : Table("user_details") {
|
|||
val password = varchar("password", 255)
|
||||
val autoAcceptFolloweeFollowRequest = bool("auto_accept_followee_follow_request")
|
||||
val lastMigration = timestamp("last_migration").nullable()
|
||||
val homeTimelineId = long("home_timeline_id").references(Timelines.id).nullable()
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class SpringFrameworkDomainEventSubscriber : DomainEventSubscriber {
|
|||
}
|
||||
|
||||
@EventListener
|
||||
fun onDomainEventPublished(domainEvent: DomainEvent<*>) {
|
||||
suspend fun onDomainEventPublished(domainEvent: DomainEvent<*>) {
|
||||
map[domainEvent.name]?.forEach {
|
||||
try {
|
||||
it.invoke(domainEvent)
|
||||
|
|
Loading…
Reference in New Issue