@startuml

class Thread {
    + type Result[A] = Either[ThreadError, A]
    + id: ThreadId

    + def joinAdministratorIds(value: AdministratorIds, senderId: AccountId, at: Instant): Result[Thread]
    + def leaveAdministratorIds(value: AdministratorIds, senderId: AccountId, at: Instant): Result[Thread]
    + def getAdministratorIds(senderId: AccountId): Result[AdministratorIds]

    + def joinMemberIds(value: MemberIds, senderId: AccountId, at: Instant): Result[Thread]
    + def leaveMemberIds(value: MemberIds, senderId: AccountId, at: Instant): Result[Thread]
    + def getMemberIds(senderId: AccountId): Result[MemberIds]

    + def addMessages(values: Messages, at: Instant): Result[Thread]
    + def removeMessages(values: MessageIds, removerId: AccountId, at: Instant): Result[(Thread, MessageIds)]
    + def getMessages(senderId: AccountId): Result[Messages]

    + def destroy(senderId: AccountId, at: Instant): Result[Thread]
}

abstract class ThreadEvent {
    + id: ThreadEventId
    + threadId: ThreadId
    + createAt: Instant
}

class ThreadCreated extends ThreadEvent
class ThreadDestroyed extends ThreadEvent
class AdministratorIdsJoined extends ThreadEvent
class AdministratorIdsLeft extends ThreadEvent
class MemberIdsJoined extends ThreadEvent
class MemberIdsLeft extends ThreadEvent
class MessagesAdded extends ThreadEvent
class MessagesRemoved extends ThreadEvent

@enduml