-- This file is part of Vervis.
--
-- Written in 2016, 2018, 2019, 2020, 2022
-- by fr33domlover <fr33domlover@riseup.net>.
--
-- ♡ Copying is an act of love. Please copy, reuse and share.
--
-- The author(s) have dedicated all copyright and related and neighboring
-- rights to this software to the public domain worldwide. This software is
-- distributed without any warranty.
--
-- You should have received a copy of the CC0 Public Domain Dedication along
-- with this software. If not, see
-- <http://creativecommons.org/publicdomain/zero/1.0/>.

-- ========================================================================= --
-- Remote Object
-- ========================================================================= --

Instance
    host Host

    UniqueInstance host

RemoteObject
    instance  InstanceId
    ident     LocalURI
    -- fetched   UTCTime  Maybe

    -- type      Text     Maybe
    -- followers LocalURI Maybe
    -- team      LocalURI Maybe

    UniqueRemoteObject instance ident

RemoteActivity
    ident    RemoteObjectId
    content  PersistJSONObject
    received UTCTime

    UniqueRemoteActivity ident

UnfetchedRemoteActor
    ident RemoteObjectId
    since UTCTime Maybe

    UniqueUnfetchedRemoteActor ident

RemoteActor
    ident      RemoteObjectId
    name       Text Maybe
    inbox      LocalURI
    followers  LocalURI       Maybe
    errorSince UTCTime        Maybe
    type       ActorType

    UniqueRemoteActor ident

RemoteCollection
    ident RemoteObjectId

    UniqueRemoteCollection ident

-- ========================================================================= --
-- Local Actor
-- ========================================================================= --

-------------------------------------------------------------------------------
-- Outbox
-------------------------------------------------------------------------------

Outbox

OutboxItem
    outbox    OutboxId
    activity  PersistJSONObject
    published UTCTime

-------------------------------------------------------------------------------
-- Inbox
-------------------------------------------------------------------------------

Inbox

InboxItem
    unread   Bool
    received UTCTime

InboxItemLocal
    inbox    InboxId
    activity OutboxItemId
    item     InboxItemId

    UniqueInboxItemLocal     inbox activity
    UniqueInboxItemLocalItem item

InboxItemRemote
    inbox    InboxId
    activity RemoteActivityId
    item     InboxItemId

    UniqueInboxItemRemote     inbox activity
    UniqueInboxItemRemoteItem item

-------------------------------------------------------------------------------
-- Followers
-------------------------------------------------------------------------------

FollowerSet

-------------------------------------------------------------------------------
-- Actors
-------------------------------------------------------------------------------

Actor
    name      Text
    desc      Text
    createdAt UTCTime
    inbox     InboxId
    outbox    OutboxId
    followers FollowerSetId
    justCreatedBy ActorId Maybe

    UniqueActorInbox     inbox
    UniqueActorOutbox    outbox
    UniqueActorFollowers followers

SigKey
    actor    ActorId
    material ActorKey

    UniqueSigKey actor

Person
    username            Username
    login               Text
    passphraseHash      ByteString
    email               EmailAddress
    verified            Bool
    verifiedKey         Text
    verifiedKeyCreated  UTCTime
    resetPassKey        Text
    resetPassKeyCreated UTCTime
    actor               ActorId
--  reviewFollow        Bool

    UniquePersonUsername username
    UniquePersonLogin    login
    UniquePersonEmail    email
    UniquePersonActor    actor

-- ========================================================================= --
-- Delivery
-- ========================================================================= --

UnlinkedDelivery
    recipient  UnfetchedRemoteActorId
    activity   OutboxItemId
    forwarding Bool
    running    Bool

    UniqueUnlinkedDelivery recipient activity

Delivery
    recipient  RemoteActorId
    activity   OutboxItemId
    forwarding Bool
    running    Bool

    UniqueDelivery recipient activity

Forwarding
    recipient   RemoteActorId
    activity    RemoteActivityId
    activityRaw ByteString
    signature   ByteString
    forwarder   ActorId
    running     Bool

    UniqueForwarding recipient activity

-- ========================================================================= --
-- ========================================================================= --

-------------------------------------------------------------------------------
-- People
-------------------------------------------------------------------------------

VerifKey
    ident    LocalRefURI
    instance InstanceId
    expires  UTCTime Maybe
    public   PublicVerifKey
    sharer   RemoteActorId Maybe

    UniqueVerifKey instance ident

VerifKeySharedUsage
    key  VerifKeyId
    user RemoteActorId

    UniqueVerifKeySharedUsage key user

--RemoteFollowRequest
--    actor  RemoteActorId
--    target PersonId
--
--    UniqueRemoteFollowRequest actor target
--

FollowRemoteRequest
    person   PersonId
    target   FedURI
    recip    FedURI Maybe
    public   Bool
    activity OutboxItemId

    UniqueFollowRemoteRequest person target
    UniqueFollowRemoteRequestActivity activity

FollowRemote
    actor  ActorId
    recip  RemoteActorId -- actor managing the followed object
    target FedURI        -- the followed object
    public Bool
    follow OutboxItemId
    accept RemoteActivityId

    UniqueFollowRemote       actor target
    UniqueFollowRemoteFollow follow
    UniqueFollowRemoteAccept accept

FollowRequest
    actor  ActorId
    target FollowerSetId
    public Bool
    follow OutboxItemId

    UniqueFollowRequest actor target
    UniqueFollowRequestFollow follow

Follow
    actor  ActorId
    target FollowerSetId
    public Bool
    follow OutboxItemId
    accept OutboxItemId

    UniqueFollow       actor target
    UniqueFollowFollow follow
    UniqueFollowAccept accept

RemoteFollow
    actor  RemoteActorId
    target FollowerSetId
    public Bool
    follow RemoteActivityId
    accept OutboxItemId

    UniqueRemoteFollow actor target
    UniqueRemoteFollowFollow follow
    UniqueRemoteFollowAccept accept

SshKey
    ident   KyIdent
    person  PersonId
    algo    ByteString
    content ByteString

    UniqueSshKey person ident

Group
    actor ActorId

    UniqueGroupActor actor

GroupMember
    person PersonId
    group  GroupId
    role   GroupRole
    joined UTCTime

    UniqueGroupMember person group

-------------------------------------------------------------------------------
-- Projects
-------------------------------------------------------------------------------

Project
    actor  ActorId
    create OutboxItemId

    UniqueProjectActor  actor
    UniqueProjectCreate create

Deck
    actor      ActorId
    workflow   WorkflowId
    nextTicket Int
    wiki       RepoId        Maybe
    create     OutboxItemId

    UniqueDeckActor  actor
    UniqueDeckCreate create

Loom
    nextTicket Int
    actor      ActorId
    repo       RepoId
    create     OutboxItemId

    UniqueLoomActor  actor
    UniqueLoomRepo   repo
    UniqueLoomCreate create

Repo
    vcs        VersionControlSystem
    project    DeckId               Maybe
    mainBranch Text
    actor      ActorId
    create     OutboxItemId
    loom       LoomId               Maybe

    UniqueRepoActor  actor
    UniqueRepoCreate create

-- I removed the 'sharer' field so Workflows don't specify who controls them
-- For now there's no way to create new ones, and what's already in the DB can
-- be publicly experimented with, until I make a plan for federated workflows
Workflow
    ident  WflIdent
    name   Text          Maybe
    desc   Text          Maybe
    scope  WorkflowScope

WorkflowField
    workflow     WorkflowId
    ident        FldIdent
    name         Text
    desc         Text           Maybe
    type         WorkflowFieldType
    enm          WorkflowEnumId Maybe
    required     Bool
    constant     Bool
    filterNew    Bool
    filterTodo   Bool
    filterClosed Bool
    color        Int            Maybe

    UniqueWorkflowField workflow ident

WorkflowEnum
    workflow WorkflowId
    ident    EnmIdent
    name     Text
    desc     Text       Maybe

    UniqueWorkflowEnum workflow ident

WorkflowEnumCtor
    enum WorkflowEnumId
    name Text
    desc Text           Maybe

    UniqueWorkflowEnumCtor enum name

TicketParamText
    ticket TicketId
    field  WorkflowFieldId
    value  Text

    UniqueTicketParamText ticket field

TicketParamEnum
    ticket TicketId
    field  WorkflowFieldId
    value  WorkflowEnumCtorId

    UniqueTicketParamEnum ticket field value

TicketParamClass
    ticket TicketId
    field  WorkflowFieldId

    UniqueTicketParamClass ticket field

Ticket
    number      Int           Maybe
    created     UTCTime
    title       Text
    source      PandocMarkdown
    description HTML
    discuss     DiscussionId
    followers   FollowerSetId
    accept      OutboxItemId

    -- UniqueTicket project number
    UniqueTicketDiscuss   discuss
    UniqueTicketFollowers followers
    UniqueTicketAccept    accept

TicketAssignee
    ticket TicketId
    person PersonId

    UniqueTicketAssignee ticket person

TicketDeck
    ticket TicketId
    deck   DeckId

    UniqueTicketDeck ticket

TicketLoom
    ticket TicketId
    loom   LoomId
    branch Text     Maybe

    UniqueTicketLoom ticket

MergeOriginLocal
    ticket TicketLoomId
    repo   RepoId
    branch Text Maybe

    UniqueMergeOriginLocal ticket

MergeOriginRemote
    ticket TicketLoomId
    repo   RemoteActorId

    UniqueMergeOriginRemote ticket

MergeOriginRemoteBranch
    merge MergeOriginRemoteId
    ident LocalURI Maybe
    name  Text

    UniqueMergeOriginRemoteBranch merge

TicketAuthorLocal
    ticket TicketId
    author PersonId
    open   OutboxItemId

    UniqueTicketAuthorLocal     ticket
    UniqueTicketAuthorLocalOpen open

TicketAuthorRemote
    ticket TicketId
    author RemoteActorId
    open   RemoteActivityId

    UniqueTicketAuthorRemote     ticket
    UniqueTicketAuthorRemoteOpen open

Bundle
    ticket TicketLoomId
    auto   Bool

Patch
    bundle  BundleId
    created UTCTime
    type    PatchMediaType
    content Text

RemoteTicketDependency
    ident  RemoteObjectId
    child  TicketId
    accept RemoteActivityId

    UniqueRemoteTicketDependency       ident
    UniqueRemoteTicketDependencyAccept accept

LocalTicketDependency
    parent  TicketId
    created UTCTime
    accept  OutboxItemId

    UniqueLocalTicketDependencyAccept accept

TicketDependencyChildLocal
    dep   LocalTicketDependencyId
    child TicketId

    UniqueTicketDependencyChildLocal dep

TicketDependencyChildRemote
    dep   LocalTicketDependencyId
    child RemoteObjectId

    UniqueTicketDependencyChildRemote dep

TicketDependencyAuthorLocal
    dep    LocalTicketDependencyId
    author PersonId
    open   OutboxItemId

    UniqueTicketDependencyAuthorLocal     dep
    UniqueTicketDependencyAuthorLocalOpen open

TicketDependencyAuthorRemote
    dep    LocalTicketDependencyId
    author RemoteActorId
    open   RemoteActivityId

    UniqueTicketDependencyAuthorRemote     dep
    UniqueTicketDependencyAuthorRemoteOpen open

TicketClaimRequest
    person  PersonId
    ticket  TicketId
    message Text     -- Assume this is Pandoc Markdown
    created UTCTime

    UniqueTicketClaimRequest person ticket

TicketResolve
    ticket TicketId
    accept OutboxItemId

    UniqueTicketResolve ticket
    UniqueTicketResolveAccept accept

TicketResolveLocal
    ticket   TicketResolveId
    activity OutboxItemId

    UniqueTicketResolveLocal ticket
    UniqueTicketResolveLocalActivity activity

TicketResolveRemote
    ticket   TicketResolveId
    activity RemoteActivityId
    actor    RemoteActorId

    UniqueTicketResolveRemote ticket
    UniqueTicketResolveRemoteActivity activity

Discussion

RemoteDiscussion
    ident   RemoteObjectId
    discuss DiscussionId

    UniqueRemoteDiscussionIdent ident
    UniqueRemoteDiscussion      discuss

Message
    created UTCTime
    source  PandocMarkdown
    content HTML
    parent  MessageId    Maybe
    root    DiscussionId

LocalMessage
    author         ActorId
    rest           MessageId
    create         OutboxItemId
    unlinkedParent FedURI    Maybe

    UniqueLocalMessage rest
    UniqueLocalMessageCreate create

RemoteMessage
    author     RemoteActorId
    ident      RemoteObjectId
    rest       MessageId
    create     RemoteActivityId
    lostParent FedURI            Maybe

    UniqueRemoteMessageIdent  ident
    UniqueRemoteMessage       rest
    UniqueRemoteMessageCreate create


------------------------------------------------------------------------------
-- Collaborators
------------------------------------------------------------------------------

Collab
    role Role

-------------------------------- Collab reason -------------------------------

CollabFulfillsLocalTopicCreation
    collab CollabId

    UniqueCollabFulfillsLocalTopicCreation collab

CollabFulfillsInvite
    collab CollabId
    accept OutboxItemId

    UniqueCollabFulfillsInvite       collab
    UniqueCollabFulfillsInviteAccept accept

CollabInviterLocal
    collab CollabFulfillsInviteId
    invite OutboxItemId

    UniqueCollabInviterLocal       collab
    UniqueCollabInviterLocalInvite invite

CollabInviterRemote
    collab CollabFulfillsInviteId
    actor  RemoteActorId
    invite RemoteActivityId

    UniqueCollabInviterRemote       collab
    UniqueCollabInviterRemoteInvite invite

CollabFulfillsJoin
    collab CollabId

    UniqueCollabFulfillsJoin collab

CollabApproverLocal
    collab CollabFulfillsJoinId
    accept OutboxItemId

    UniqueCollabApproverLocal       collab
    UniqueCollabApproverLocalAccept accept

CollabApproverRemote
    collab CollabFulfillsJoinId
    actor  RemoteActorId
    accept RemoteActivityId

    UniqueCollabApproverRemote       collab
    UniqueCollabApproverRemoteAccept accept

CollabRecipLocalJoin
    collab   CollabRecipLocalId
    fulfills CollabFulfillsJoinId
    join     OutboxItemId

    UniqueCollabRecipLocalJoinCollab   collab
    UniqueCollabRecipLocalJoinFulfills fulfills
    UniqueCollabRecipLocalJoinJoin     join

CollabRecipRemoteJoin
    collab   CollabRecipRemoteId
    fulfills CollabFulfillsJoinId
    join     RemoteActivityId

    UniqueCollabRecipRemoteJoinCollab   collab
    UniqueCollabRecipRemoteJoinFulfills fulfills
    UniqueCollabRecipRemoteJoinJoin     join

-------------------------------- Collab topic --------------------------------

CollabTopicRepo
    collab CollabId
    repo   RepoId

    UniqueCollabTopicRepo collab

CollabTopicDeck
    collab CollabId
    deck   DeckId

    UniqueCollabTopicDeck collab

CollabTopicLoom
    collab CollabId
    loom   LoomId

    UniqueCollabTopicLoom collab

CollabTopicProject
    collab  CollabId
    project ProjectId

    UniqueCollabTopicProject collab

CollabEnable
    collab CollabId
    grant  OutboxItemId

    UniqueCollabEnable      collab
    UniqueCollabEnableGrant grant

-------------------------------- Collab recipient ----------------------------

CollabRecipLocal
    collab CollabId
    person PersonId

    UniqueCollabRecipLocal collab

CollabRecipLocalAccept
    collab CollabRecipLocalId
    invite CollabFulfillsInviteId
    accept OutboxItemId

    UniqueCollabRecipLocalAcceptCollab collab
    UniqueCollabRecipLocalAcceptInvite invite
    UniqueCollabRecipLocalAcceptAccept accept

CollabRecipRemote
    collab CollabId
    actor  RemoteActorId

    UniqueCollabRecipRemote collab

CollabRecipRemoteAccept
    collab CollabRecipRemoteId
    invite CollabFulfillsInviteId
    accept RemoteActivityId

    UniqueCollabRecipRemoteAcceptCollab collab
    UniqueCollabRecipRemoteAcceptInvite invite
    UniqueCollabRecipRemoteAcceptAccept accept

------------------------------------------------------------------------------
-- Components, from project perspective
------------------------------------------------------------------------------

Component
    project ProjectId
    role    Role

------------------------------ Component reason ------------------------------

ComponentOriginAdd
    component ComponentId

    UniqueComponentOriginAdd component

ComponentOriginInvite
    component ComponentId

    UniqueComponentOriginInvite component

-- Component collaborators's gesture
--
-- Add: Witnesses the initial Add that started the sequence
-- Invite: N/A (they send their Accept but we don't record it)

ComponentGestureLocal
    origin ComponentOriginAddId
    add    OutboxItemId

    UniqueComponentGestureLocal    origin
    UniqueComponentGestureLocalAdd add

ComponentGestureRemote
    origin ComponentOriginAddId
    actor  RemoteActorId
    add    RemoteActivityId

    UniqueComponentGestureRemote    origin
    UniqueComponentGestureRemoteAdd add

-- Component's accept
--
-- Add: Witnesses that the component saw and approved the Add
-- Invite: Witnesses that the component saw project's accept and component
--         collaborator's accept, and sent its own accept

ComponentAcceptLocal
    ident  ComponentLocalId
    accept OutboxItemId

    UniqueComponentAcceptLocal       ident
    UniqueComponentAcceptLocalAccept accept

ComponentAcceptRemote
    ident     ComponentRemoteId
    accept    RemoteActivityId

    UniqueComponentAcceptRemote       ident
    UniqueComponentAcceptRemoteAccept accept

-- Project collaborator's gesture
--
-- Add: Witnesses their approval, seeing the component's accept
-- Invite: Witnesses the initial Invite that started the sequence

ComponentProjectGestureLocal
    component ComponentId
    activity  OutboxItemId

    UniqueComponentProjectGestureLocal         component
    UniqueComponentProjectGestureLocalActivity activity

ComponentProjectGestureRemote
    component ComponentId
    actor     RemoteActorId
    activity  RemoteActivityId

    UniqueComponentProjectGestureRemote         component
    UniqueComponentProjectGestureRemoteActivity activity

-- Project's accept
--
-- Add: N/A
-- Invite: Witnesses that the project saw and approved the Invite

ComponentProjectAccept
    origin ComponentOriginInviteId
    accept OutboxItemId

    UniqueComponentProjectAccept       origin
    UniqueComponentProjectAcceptAccept accept

----------------------------- Component identity -----------------------------

ComponentLocal
    component ComponentId

    UniqueComponentLocal component

ComponentLocalRepo
    component ComponentLocalId
    repo      RepoId

    UniqueComponentLocalRepo component

ComponentLocalDeck
    component ComponentLocalId
    deck      DeckId

    UniqueComponentLocalDeck component

ComponentLocalLoom
    component ComponentLocalId
    loom      LoomId

    UniqueComponentLocalLoom component

ComponentRemote
    component ComponentId
    actor     RemoteActorId

    UniqueComponentRemote component

------------------------------ Component enable ------------------------------

-- Witnesses that, seeing the project collaborator approval on the Add or the
-- component approval on the Invite, the project has sent the component a Grant
-- with the "delegator" role and now officially considering it a component of
-- the project
ComponentEnable
    component ComponentId
    grant     OutboxItemId

    UniqueComponentEnable      component
    UniqueComponentEnableGrant grant

-- Witnesses that the component used the delegator Grant to send an admin
-- delegation to the project, to extend the delegation further
ComponentDelegateLocal
    component ComponentLocalId
    grant     OutboxItemId

    UniqueComponentDelegateLocal      component
    UniqueComponentDelegateLocalGrant grant

-- Witnesses that the component used the delegator Grant to send an admin
-- delegation to the project, to extend the delegation further
ComponentDelegateRemote
    component ComponentRemoteId
    grant     RemoteActivityId

    UniqueComponentDelegateRemote      component
    UniqueComponentDelegateRemoteGrant grant

-- Witnesses that the project has extended a given delegation to a given
-- direct collaborator
ComponentFurtherLocal
    component ComponentEnableId
    collab    CollabRecipLocalId
    grant     OutboxItemId

    UniqueComponentFurtherLocal      component collab
    UniqueComponentFurtherLocalGrant grant

-- Witnesses that the project has extended a given delegation to a given
-- direct collaborator
ComponentFurtherRemote
    component ComponentEnableId
    collab    CollabRecipRemoteId
    grant     OutboxItemId

    UniqueComponentFurtherRemote      component collab
    UniqueComponentFurtherRemoteGrant grant

------------------------------------------------------------------------------
-- Components, from component perspective
------------------------------------------------------------------------------

Stem
    role Role

-------------------------------- Stem identity -------------------------------

StemIdentRepo
    stem StemId
    repo      RepoId

    UniqueStemIdentRepo stem

StemIdentDeck
    stem StemId
    deck      DeckId

    UniqueStemIdentDeck stem

StemIdentLoom
    stem StemId
    loom      LoomId

    UniqueStemIdentLoom stem

-------------------------------- Stem project --------------------------------

StemProjectLocal
    stem    StemId
    project ProjectId

    UniqueStemProjectLocal stem

StemProjectRemote
    stem    StemId
    project RemoteActorId

    UniqueStemProjectRemote stem

--------------------------------- Stem reason --------------------------------

StemOriginAdd
    stem StemId

    UniqueStemOriginAdd stem

StemOriginInvite
    stem StemId

    UniqueStemOriginInvite stem

-- Component collaborators's gesture
--
-- Add: Witnesses the initial Add that started the sequence
-- Invite: Witnesses their approval, seeing the project's accept

StemComponentGestureLocal
    stem     StemId
    activity OutboxItemId

    UniqueStemComponentGestureLocal         stem
    UniqueStemComponentGestureLocalActivity activity

StemComponentGestureRemote
    stem    StemId
    actor   RemoteActorId
    activity RemoteActivityId

    UniqueStemComponentGestureRemote         stem
    UniqueStemComponentGestureRemoteActivity activity

-- Component's accept
--
-- Add: Witnesses that the component saw and approved the initial Add
-- Invite: Witnesses that the component saw project's accept and component
--         collaborator's accept, and sent its own accept

StemComponentAccept
    stem   StemId
    accept OutboxItemId

    UniqueStemComponentAccept       stem
    UniqueStemComponentAcceptAccept accept

-- Project collaborator's gesture
--
-- Add: N/A (it happens but we don't record it)
-- Invite: Witnesses the initial Invite that started the sequence

StemProjectGestureLocal
    origin  StemOriginInviteId
    invite  OutboxItemId

    UniqueStemProjectGestureLocal         origin
    UniqueStemProjectGestureLocalInvite   invite

StemProjectGestureRemote
    origin  StemOriginInviteId
    actor   RemoteActorId
    invite  RemoteActivityId

    UniqueStemProjectGestureRemote         origin
    UniqueStemProjectGestureRemoteInvite   invite

-- Project's accept
--
-- Add: N/A
-- Invite: Witnesses that the project saw and approved the Invite

StemProjectAcceptLocal
    origin  StemOriginInviteId
    project StemProjectLocalId
    accept  OutboxItemId

    UniqueStemProjectAcceptLocal        origin
    UniqueStemProjectAcceptLocalProject project
    UniqueStemProjectAcceptLocalAccept  accept

StemProjectAcceptRemote
    origin  StemOriginInviteId
    project StemProjectRemoteId
    accept  RemoteActivityId

    UniqueStemProjectAcceptRemote        origin
    UniqueStemProjectAcceptRemoteProject project
    UniqueStemProjectAcceptRemoteAccept  accept

------------------------------ Stem enable ------------------------------

-- Project's grant
--
-- Add: Seeing component's accept and project collaborator's accept, the
--      project has made the link official and sent a delegator grant
-- Invite: Seeing project collaborator's Invite and component's accept, the
--         project has made the link official and sent a delegator grant

StemProjectGrantLocal
    stem    StemComponentAcceptId
    project StemProjectLocalId
    grant   OutboxItemId

    UniqueStemProjectGrantLocal        stem
    UniqueStemProjectGrantLocalProject project
    UniqueStemProjectGrantLocalGrant   grant

StemProjectGrantRemote
    stem    StemComponentAcceptId
    project StemProjectRemoteId
    grant   RemoteActivityId

    UniqueStemProjectGrantRemote        stem
    UniqueStemProjectGrantRemoteProject project
    UniqueStemProjectGrantRemoteGrant   grant

-- Witnesses that the stem used the delegator Grant to send an admin
-- delegation to the project, to extend the delegation further
StemDelegateLocal
    stem  StemComponentAcceptId
    grant OutboxItemId

    UniqueStemDelegateLocal      stem
    UniqueStemDelegateLocalGrant grant