-- 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
    create OutboxItemId

    UniqueGroupActor  actor
    UniqueGroupCreate create

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, from resource perspective
------------------------------------------------------------------------------

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

CollabTopicGroup
    collab CollabId
    group  GroupId

    UniqueCollabTopicGroup collab

-------------------------------- 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

-------------------------------- Collab enable -------------------------------

CollabEnable
    collab CollabId
    grant  OutboxItemId

    UniqueCollabEnable      collab
    UniqueCollabEnableGrant grant

-- Component: N/A
-- Project/Team: Witnesses that using the above Grant, the collaborator has
-- sent me a delegator-Grant, which I can now use to extend chains to them

CollabDelegLocal
    enable CollabEnableId
    recip  CollabRecipLocalId
    grant  OutboxItemId

    UniqueCollabDelegLocal      enable
    UniqueCollabDelegLocalRecip recip
    UniqueCollabDelegLocalGrant grant

CollabDelegRemote
    enable CollabEnableId
    recip  CollabRecipRemoteId
    grant  RemoteActivityId

    UniqueCollabDelegRemote      enable
    UniqueCollabDelegRemoteRecip recip
    UniqueCollabDelegRemoteGrant grant

------------------------------------------------------------------------------
-- Collaborators, from person perspective
------------------------------------------------------------------------------

Permit
    person PersonId
    role   Role

-------------------------------- Permit topic --------------------------------

PermitTopicLocal
    permit PermitId

    UniquePermitTopicLocal permit

PermitTopicRepo
    permit PermitTopicLocalId
    repo   RepoId

    UniquePermitTopicRepo permit

PermitTopicDeck
    permit PermitTopicLocalId
    deck   DeckId

    UniquePermitTopicDeck permit

PermitTopicLoom
    permit PermitTopicLocalId
    loom   LoomId

    UniquePermitTopicLoom permit

PermitTopicProject
    permit  PermitTopicLocalId
    project ProjectId

    UniquePermitTopicProject permit

PermitTopicGroup
    permit PermitTopicLocalId
    group  GroupId

    UniquePermitTopicGroup permit

PermitTopicRemote
    permit PermitId
    actor  RemoteActorId

    UniquePermitTopicRemote permit

------------------------------- Permit reason --------------------------------

PermitFulfillsTopicCreation
    permit PermitId

    UniquePermitFulfillsTopicCreation permit

PermitFulfillsInvite
    permit PermitId

    UniquePermitFulfillsInvite permit

PermitFulfillsJoin
    permit PermitId

    UniquePermitFulfillsJoin permit

-- Person's gesture
--
-- Join: Witnesses the initial Join that started the sequence
-- Invite: Witnesses their approval, seeing the topic's accept, and then
--         sending their own accept
-- Create: Records the Create activity that created the topic

PermitPersonGesture
    permit   PermitId
    activity OutboxItemId

    UniquePermitPersonGesture         permit
    UniquePermitPersonGestureActivity activity

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

PermitTopicGestureLocal
    fulfills PermitFulfillsInviteId
    invite   OutboxItemId

    UniquePermitTopicGestureLocal       fulfills
    UniquePermitTopicGestureLocalInvite invite

PermitTopicGestureRemote
    fulfills PermitFulfillsInviteId
    actor    RemoteActorId
    invite   RemoteActivityId

    UniquePermitTopicGestureRemote       fulfills
    UniquePermitTopicGestureRemoteInvite invite

-- Topic's accept
--
-- Join: N/A
-- Invite: Witnesses that the topic saw and approved the Invite

PermitTopicAcceptLocal
    fulfills PermitFulfillsInviteId
    topic    PermitTopicLocalId
    accept   OutboxItemId

    UniquePermitTopicAcceptLocal       fulfills
    UniquePermitTopicAcceptLocalTopic  topic
    UniquePermitTopicAcceptLocalAccept accept

PermitTopicAcceptRemote
    fulfills PermitFulfillsInviteId
    topic    PermitTopicRemoteId
    accept   RemoteActivityId

    UniquePermitTopicAcceptRemote       fulfills
    UniquePermitTopicAcceptRemoteTopic  topic
    UniquePermitTopicAcceptRemoteAccept accept

-------------------------------- Permit enable -------------------------------

-- Topic's grant
--
-- Join: Seeing the new-collaborator's Join and existing-collaborator's Accept,
--       the topic has made the link official and sent a direct-grant
-- Invite: Seeing existing-collaborator's Invite and new-collaborator's Accept,
--         the topic has made the link official and sent a direct-grant
-- Create: Upon being created, topic has sent its creator an admin-Grant

PermitTopicEnableLocal
    permit PermitPersonGestureId
    topic  PermitTopicLocalId
    grant  OutboxItemId

    UniquePermitTopicEnableLocal      permit
    UniquePermitTopicEnableLocalTopic topic
    UniquePermitTopicEnableLocalGrant grant

PermitTopicEnableRemote
    permit PermitPersonGestureId
    topic  PermitTopicRemoteId
    grant  RemoteActivityId

    UniquePermitTopicEnableRemote      permit
    UniquePermitTopicEnableRemoteTopic topic
    UniquePermitTopicEnableRemoteGrant grant

----------------------- Permit delegator+extension ---------------------------

-- This section is only for Project or Team topics
-- Person sends delegator-Grant, topic starts sending extension-Grants

-- Witnesses that the person used the direct-Grant to send a delegator-Grant to
-- the topic
PermitPersonSendDelegator
    permit PermitPersonGestureId
    grant  OutboxItemId

    UniquePermitPersonSendDelegator      permit
    UniquePermitPersonSendDelegatorGrant grant

-- Witnesses extension-Grants that the topic has sent, extending chains from
-- its components/subprojects or projects/superteams

PermitTopicExtendLocal
    permit PermitPersonSendDelegatorId
    topic  PermitTopicEnableLocalId
    grant  OutboxItemId

    UniquePermitTopicExtendLocalGrant grant

PermitTopicExtendRemote
    permit PermitPersonSendDelegatorId
    topic  PermitTopicEnableRemoteId
    grant  RemoteActivityId

    UniquePermitTopicExtendRemoteGrant grant

------------------------------------------------------------------------------
-- 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    CollabDelegLocalId
    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    CollabDelegRemoteId
    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

------------------------------------------------------------------------------
-- Inheritance - Receiver tracking her givers
-- (Project tracking its children)
-- (Team tracking its parents)
------------------------------------------------------------------------------

Source
    role Role

SourceHolderProject
    source  SourceId
    project ProjectId

    UniqueSourceHolderProject source

SourceHolderGroup
    source SourceId
    group  GroupId

    UniqueSourceHolderGroup source

-------------------------------- Source topic --------------------------------

SourceTopicLocal
    source SourceId

    UniqueSourceTopicLocal source

SourceTopicProject
    holder SourceHolderProjectId
    topic  SourceTopicLocalId
    child  ProjectId

    UniqueSourceTopicProject      holder
    UniqueSourceTopicProjectTopic topic

SourceTopicGroup
    holder SourceHolderGroupId
    topic  SourceTopicLocalId
    parent GroupId

    UniqueSourceTopicGroup      holder
    UniqueSourceTopicGroupTopic topic

SourceTopicRemote
    source SourceId
    topic  RemoteActorId

    UniqueSourceTopicRemote source

-------------------------------- Source flow ---------------------------------

SourceOriginUs
    source SourceId

    UniqueSourceOriginUs source

SourceOriginThem
    source SourceId

    UniqueSourceOriginThem source

-- Our collaborator's gesture
--
-- OriginUs: The Add that started the sequence
-- OriginThem: N/A (they send their Accept but we don't record it)

SourceUsGestureLocal
    us  SourceOriginUsId
    add OutboxItemId

    UniqueSourceUsGestureLocal    us
    UniqueSourceUsGestureLocalAdd add

SourceUsGestureRemote
    us    SourceOriginUsId
    actor RemoteActorId
    add   RemoteActivityId

    UniqueSourceUsGestureRemote    us
    UniqueSourceUsGestureRemoteAdd add

-- Our accept
--
-- OriginUs: I checked the Add and sending my Accept
-- OriginThem: N/A

SourceUsAccept
    us    SourceOriginUsId
    accept OutboxItemId

    UniqueSourceUsAccept       us
    UniqueSourceUsAcceptAccept accept

-- Their collaborator's gesture
--
-- OriginUs: N/A (they send it but we don't record it)
-- OriginThem: The Add that started the sequence

SourceThemGestureLocal
    them SourceOriginThemId
    add  OutboxItemId

    UniqueSourceThemGestureLocal    them
    UniqueSourceThemGestureLocalAdd add

SourceThemGestureRemote
    them  SourceOriginThemId
    actor RemoteActorId
    add   RemoteActivityId

    UniqueSourceThemGestureRemote    them
    UniqueSourceThemGestureRemoteAdd add

-- Their accept
--
-- OriginUs: Seeing our accept and their collaborator's accept, they send their
--           own accept
-- OriginThem: Checking the Add, they send their Accept

SourceThemAcceptLocal
    topic  SourceTopicLocalId
    accept OutboxItemId

    UniqueSourceThemAcceptLocal       topic
    UniqueSourceThemAcceptLocalAccept accept

SourceThemAcceptRemote
    topic  SourceTopicRemoteId
    accept RemoteActivityId

    UniqueSourceThemAcceptRemote       topic
    UniqueSourceThemAcceptRemoteAccept accept

-------------------------------- Source enable -------------------------------

-- Witnesses that, seeing their approval and our collaborator's gesture, I've
-- sent then a delegator-Grant and now officially considering them a source of
-- us
SourceUsSendDelegator
    source SourceId
    grant  OutboxItemId

    UniqueSourceUsSendDelegator      source
    UniqueSourceUsSendDelegatorGrant grant

-- Witnesses that, using the delegator-Grant, they sent us a start-Grant or
-- extension-Grant to delegate further

SourceThemDelegateLocal
    source SourceThemAcceptLocalId
    grant  OutboxItemId

    UniqueSourceThemDelegateLocal      source
    UniqueSourceThemDelegateLocalGrant grant

SourceThemDelegateRemote
    source SourceThemAcceptRemoteId
    grant  RemoteActivityId

    UniqueSourceThemDelegateRemote      source
    UniqueSourceThemDelegateRemoteGrant grant

-- Witnesses that, seeing the delegation from them, I've sent an
-- extension-Grant to a Dest of mine

SourceUsGatherLocal
    deleg SourceUsSendDelegatorId
    dest  DestThemSendDelegatorLocalId
    grant OutboxItemId

    UniqueSourceUsGatherLocal grant

SourceUsGatherRemote
    deleg SourceUsSendDelegatorId
    dest  DestThemSendDelegatorRemoteId
    grant RemoteActivityId

    UniqueSourceUsGatherRemote grant

-- Witnesses that, seeing the delegation from them, I've sent a leaf-Grant to a
-- direct-collaborator of mine

SourceUsLeafLocal
    deleg  SourceUsSendDelegatorId
    collab CollabDelegLocalId
    grant  OutboxItemId

    UniqueSourceUsLeafLocal grant

SourceUsLeafRemote
    deleg  SourceUsSendDelegatorId
    collab CollabDelegRemoteId
    grant  RemoteActivityId

    UniqueSourceUsLeafRemote grant

------------------------------------------------------------------------------
-- Inheritance - Giver tracking her receivers
-- (Project tracking its parents)
-- (Team tracking its children)
------------------------------------------------------------------------------

Dest
    role Role

DestHolderProject
    dest    DestId
    project ProjectId

    UniqueDestHolderProject dest

DestHolderGroup
    dest  DestId
    group GroupId

    UniqueDestHolderGroup dest

---------------------------------- Dest topic --------------------------------

DestTopicLocal
    dest DestId

    UniqueDestTopicLocal dest

DestTopicProject
    holder DestHolderProjectId
    topic  DestTopicLocalId
    parent ProjectId

    UniqueDestTopicProject      holder
    UniqueDestTopicProjectTopic topic

DestTopicGroup
    holder DestHolderGroupId
    topic  DestTopicLocalId
    child  GroupId

    UniqueDestTopicGroup      holder
    UniqueDestTopicGroupTopic topic

DestTopicRemote
    dest  DestId
    topic RemoteActorId

    UniqueDestTopicRemote dest

---------------------------------- Dest flow ---------------------------------

DestOriginUs
    dest DestId

    UniqueDestOriginUs dest

DestOriginThem
    dest DestId

    UniqueDestOriginThem dest

-- Our collaborator's gesture
--
-- OriginUs: The Add that started the sequence
-- OriginThem: Seeing the Add and their Accept, my collaborator has sent her
--             Accept

DestUsGestureLocal
    dest     DestId
    activity OutboxItemId

    UniqueDestUsGestureLocal         dest
    UniqueDestUsGestureLocalActivity activity

DestUsGestureRemote
    dest     DestId
    actor    RemoteActorId
    activity RemoteActivityId

    UniqueDestUsGestureRemote         dest
    UniqueDestUsGestureRemoteActivity activity

-- Our accept
--
-- OriginUs: Checking my collaborator's Add, I sent my Accept
-- OriginThem: Seeing the Add, their Accept and my collaborator's Accept, I
--             sent my Accept

DestUsAccept
    dest DestId
    accept OutboxItemId

    UniqueDestUsAccept       dest
    UniqueDestUsAcceptAccept accept

-- Their collaborator's gesture
--
-- OriginUs: N/A (they send it but we don't record it)
-- OriginThem: The Add that started the sequence

DestThemGestureLocal
    them DestOriginThemId
    add  OutboxItemId

    UniqueDestThemGestureLocal    them
    UniqueDestThemGestureLocalAdd add

DestThemGestureRemote
    them  DestOriginThemId
    actor RemoteActorId
    add   RemoteActivityId

    UniqueDestThemGestureRemote    them
    UniqueDestThemGestureRemoteAdd add

-- Their accept
--
-- OriginUs: N/A
-- OriginThem: Seeing their collaborator's Add, they sent an Accept

DestThemAcceptLocal
    them   DestOriginThemId
    topic  DestTopicLocalId
    accept OutboxItemId

    UniqueDestThemAcceptLocal       them
    UniqueDestThemAcceptLocalTopic  topic
    UniqueDestThemAcceptLocalAccept accept

DestThemAcceptRemote
    them   DestOriginThemId
    topic  DestTopicRemoteId
    accept RemoteActivityId

    UniqueDestThemAcceptRemote       them
    UniqueDestThemAcceptRemoteTopic  topic
    UniqueDestThemAcceptRemoteAccept accept

---------------------------------- Dest enable -------------------------------

-- Witnesses that, seeing our approval and their collaborator's gesture,
-- they've sent us a delegator-Grant, and we now officially consider them a
-- dest of us

DestThemSendDelegatorLocal
    dest  DestUsAcceptId
    topic DestTopicLocalId
    grant OutboxItemId

    UniqueDestThemSendDelegatorLocal      dest
    UniqueDestThemSendDelegatorLocalTopic topic
    UniqueDestThemSendDelegatorLocalGrant grant

DestThemSendDelegatorRemote
    dest  DestUsAcceptId
    topic DestTopicRemoteId
    grant RemoteActivityId

    UniqueDestThemSendDelegatorRemote      dest
    UniqueDestThemSendDelegatorRemoteTopic topic
    UniqueDestThemSendDelegatorRemoteGrant grant