Decouple OutboxItem from Person via a new table named Outbox
This commit is contained in:
parent
6452d239f2
commit
499479b662
8 changed files with 113 additions and 34 deletions
|
@ -35,14 +35,18 @@ Person
|
||||||
resetPassKeyCreated UTCTime
|
resetPassKeyCreated UTCTime
|
||||||
about Text
|
about Text
|
||||||
inbox InboxId
|
inbox InboxId
|
||||||
|
outbox OutboxId
|
||||||
|
|
||||||
UniquePersonIdent ident
|
UniquePersonIdent ident
|
||||||
UniquePersonLogin login
|
UniquePersonLogin login
|
||||||
UniquePersonEmail email
|
UniquePersonEmail email
|
||||||
UniquePersonInbox inbox
|
UniquePersonInbox inbox
|
||||||
|
UniquePersonOutbox outbox
|
||||||
|
|
||||||
|
Outbox
|
||||||
|
|
||||||
OutboxItem
|
OutboxItem
|
||||||
person PersonId
|
outbox OutboxId
|
||||||
activity PersistActivity
|
activity PersistActivity
|
||||||
published UTCTime
|
published UTCTime
|
||||||
|
|
||||||
|
|
26
migrations/2019_06_15.model
Normal file
26
migrations/2019_06_15.model
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
Person
|
||||||
|
ident Int64
|
||||||
|
login Text
|
||||||
|
passphraseHash ByteString
|
||||||
|
email Text
|
||||||
|
verified Bool
|
||||||
|
verifiedKey Text
|
||||||
|
verifiedKeyCreated UTCTime
|
||||||
|
resetPassKey Text
|
||||||
|
resetPassKeyCreated UTCTime
|
||||||
|
about Text
|
||||||
|
inbox Int64
|
||||||
|
outbox OutboxId
|
||||||
|
|
||||||
|
UniquePersonIdent ident
|
||||||
|
UniquePersonLogin login
|
||||||
|
UniquePersonEmail email
|
||||||
|
UniquePersonInbox inbox
|
||||||
|
|
||||||
|
Outbox
|
||||||
|
|
||||||
|
OutboxItem
|
||||||
|
person PersonId
|
||||||
|
outbox OutboxId
|
||||||
|
activity PersistJSONObject
|
||||||
|
published UTCTime
|
|
@ -162,8 +162,8 @@ createNoteC host (Note mluNote luAttrib aud muParent muContext mpublished source
|
||||||
federation <- getsYesod $ appFederation . appSettings
|
federation <- getsYesod $ appFederation . appSettings
|
||||||
unless (federation || null remoteRecips) $
|
unless (federation || null remoteRecips) $
|
||||||
throwE "Federation disabled, but remote recipients specified"
|
throwE "Federation disabled, but remote recipients specified"
|
||||||
(lmid, obid, doc, remotesHttp) <- runDBExcept $ do
|
(lmid, obiid, doc, remotesHttp) <- runDBExcept $ do
|
||||||
(pid, shrUser) <- verifyIsLoggedInUser luAttrib "Note attributed to different actor"
|
(pid, obid, shrUser) <- verifyIsLoggedInUser luAttrib "Note attributed to different actor"
|
||||||
(did, meparent, mcollections) <- case mticket of
|
(did, meparent, mcollections) <- case mticket of
|
||||||
Just (shr, prj, num) -> do
|
Just (shr, prj, num) -> do
|
||||||
mt <- lift $ runMaybeT $ do
|
mt <- lift $ runMaybeT $ do
|
||||||
|
@ -231,13 +231,13 @@ createNoteC host (Note mluNote luAttrib aud muParent muContext mpublished source
|
||||||
\ commented on a #
|
\ commented on a #
|
||||||
<a href=#{renderFedURI uContext}>ticket</a>.
|
<a href=#{renderFedURI uContext}>ticket</a>.
|
||||||
|]
|
|]
|
||||||
(lmid, obid, doc) <- lift $ insertMessage luAttrib shrUser pid uContext did muParent meparent source content summary
|
(lmid, obiid, doc) <- lift $ insertMessage luAttrib shrUser pid obid uContext did muParent meparent source content summary
|
||||||
moreRemotes <- deliverLocal pid obid localRecips mcollections
|
moreRemotes <- deliverLocal pid obiid localRecips mcollections
|
||||||
unless (federation || null moreRemotes) $
|
unless (federation || null moreRemotes) $
|
||||||
throwE "Federation disabled but remote collection members found"
|
throwE "Federation disabled but remote collection members found"
|
||||||
remotesHttp <- lift $ deliverRemoteDB (furiHost uContext) obid remoteRecips moreRemotes
|
remotesHttp <- lift $ deliverRemoteDB (furiHost uContext) obiid remoteRecips moreRemotes
|
||||||
return (lmid, obid, doc, remotesHttp)
|
return (lmid, obiid, doc, remotesHttp)
|
||||||
lift $ forkWorker "Outbox POST handler: async HTTP delivery" $ deliverRemoteHttp (furiHost uContext) obid doc remotesHttp
|
lift $ forkWorker "Outbox POST handler: async HTTP delivery" $ deliverRemoteHttp (furiHost uContext) obiid doc remotesHttp
|
||||||
return lmid
|
return lmid
|
||||||
where
|
where
|
||||||
nonEmptyE :: Monad m => [a] -> e -> ExceptT e m (NonEmpty a)
|
nonEmptyE :: Monad m => [a] -> e -> ExceptT e m (NonEmpty a)
|
||||||
|
@ -401,20 +401,24 @@ createNoteC host (Note mluNote luAttrib aud muParent muContext mpublished source
|
||||||
verifyOnlySharers :: LocalRecipientSet -> ExceptT Text Handler [ShrIdent]
|
verifyOnlySharers :: LocalRecipientSet -> ExceptT Text Handler [ShrIdent]
|
||||||
verifyOnlySharers lrs = catMaybes <$> traverse (atMostSharer "Note with remote context but local project-related recipients") lrs
|
verifyOnlySharers lrs = catMaybes <$> traverse (atMostSharer "Note with remote context but local project-related recipients") lrs
|
||||||
|
|
||||||
verifyIsLoggedInUser :: LocalURI -> Text -> ExceptT Text AppDB (PersonId, ShrIdent)
|
verifyIsLoggedInUser
|
||||||
|
:: LocalURI
|
||||||
|
-> Text
|
||||||
|
-> ExceptT Text AppDB (PersonId, OutboxId, ShrIdent)
|
||||||
verifyIsLoggedInUser lu t = do
|
verifyIsLoggedInUser lu t = do
|
||||||
Entity pid p <- requireVerifiedAuth
|
Entity pid p <- requireVerifiedAuth
|
||||||
s <- lift $ getJust $ personIdent p
|
s <- lift $ getJust $ personIdent p
|
||||||
route2local <- getEncodeRouteLocal
|
route2local <- getEncodeRouteLocal
|
||||||
let shr = sharerIdent s
|
let shr = sharerIdent s
|
||||||
if route2local (SharerR shr) == lu
|
if route2local (SharerR shr) == lu
|
||||||
then return (pid, shr)
|
then return (pid, personOutbox p, shr)
|
||||||
else throwE t
|
else throwE t
|
||||||
|
|
||||||
insertMessage
|
insertMessage
|
||||||
:: LocalURI
|
:: LocalURI
|
||||||
-> ShrIdent
|
-> ShrIdent
|
||||||
-> PersonId
|
-> PersonId
|
||||||
|
-> OutboxId
|
||||||
-> FedURI
|
-> FedURI
|
||||||
-> DiscussionId
|
-> DiscussionId
|
||||||
-> Maybe FedURI
|
-> Maybe FedURI
|
||||||
|
@ -423,7 +427,7 @@ createNoteC host (Note mluNote luAttrib aud muParent muContext mpublished source
|
||||||
-> Text
|
-> Text
|
||||||
-> Html
|
-> Html
|
||||||
-> AppDB (LocalMessageId, OutboxItemId, Doc Activity)
|
-> AppDB (LocalMessageId, OutboxItemId, Doc Activity)
|
||||||
insertMessage luAttrib shrUser pid uContext did muParent meparent source content summary = do
|
insertMessage luAttrib shrUser pid obid uContext did muParent meparent source content summary = do
|
||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
mid <- insert Message
|
mid <- insert Message
|
||||||
{ messageCreated = now
|
{ messageCreated = now
|
||||||
|
@ -454,28 +458,28 @@ createNoteC host (Note mluNote luAttrib aud muParent muContext mpublished source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tempUri = LocalURI "" ""
|
tempUri = LocalURI "" ""
|
||||||
obid <- insert OutboxItem
|
obiid <- insert OutboxItem
|
||||||
{ outboxItemPerson = pid
|
{ outboxItemOutbox = obid
|
||||||
, outboxItemActivity = PersistJSON $ activity tempUri tempUri
|
, outboxItemActivity = PersistJSON $ activity tempUri tempUri
|
||||||
, outboxItemPublished = now
|
, outboxItemPublished = now
|
||||||
}
|
}
|
||||||
lmid <- insert LocalMessage
|
lmid <- insert LocalMessage
|
||||||
{ localMessageAuthor = pid
|
{ localMessageAuthor = pid
|
||||||
, localMessageRest = mid
|
, localMessageRest = mid
|
||||||
, localMessageCreate = obid
|
, localMessageCreate = obiid
|
||||||
, localMessageUnlinkedParent =
|
, localMessageUnlinkedParent =
|
||||||
case meparent of
|
case meparent of
|
||||||
Just (Right uParent) -> Just uParent
|
Just (Right uParent) -> Just uParent
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
}
|
}
|
||||||
route2local <- getEncodeRouteLocal
|
route2local <- getEncodeRouteLocal
|
||||||
obhid <- encodeKeyHashid obid
|
obihid <- encodeKeyHashid obiid
|
||||||
lmhid <- encodeKeyHashid lmid
|
lmhid <- encodeKeyHashid lmid
|
||||||
let luAct = route2local $ OutboxItemR shrUser obhid
|
let luAct = route2local $ OutboxItemR shrUser obihid
|
||||||
luNote = route2local $ MessageR shrUser lmhid
|
luNote = route2local $ MessageR shrUser lmhid
|
||||||
doc = activity luAct luNote
|
doc = activity luAct luNote
|
||||||
update obid [OutboxItemActivity =. PersistJSON doc]
|
update obiid [OutboxItemActivity =. PersistJSON doc]
|
||||||
return (lmid, obid, doc)
|
return (lmid, obiid, doc)
|
||||||
|
|
||||||
-- Deliver to local recipients. For local users, find in DB and deliver.
|
-- Deliver to local recipients. For local users, find in DB and deliver.
|
||||||
-- For local collections, expand them, deliver to local users, and return a
|
-- For local collections, expand them, deliver to local users, and return a
|
||||||
|
|
|
@ -410,22 +410,25 @@ handleSharerInbox
|
||||||
-> Activity
|
-> Activity
|
||||||
-> ExceptT Text Handler Text
|
-> ExceptT Text Handler Text
|
||||||
handleSharerInbox _now shrRecip (Left pidAuthor) _raw activity = do
|
handleSharerInbox _now shrRecip (Left pidAuthor) _raw activity = do
|
||||||
(shrActivity, obid) <- do
|
(shrActivity, obiid) <- do
|
||||||
route <-
|
route <-
|
||||||
case decodeRouteLocal $ activityId activity of
|
case decodeRouteLocal $ activityId activity of
|
||||||
Nothing -> throwE "Local activity: Not a valid route"
|
Nothing -> throwE "Local activity: Not a valid route"
|
||||||
Just r -> return r
|
Just r -> return r
|
||||||
case route of
|
case route of
|
||||||
OutboxItemR shr obkhid ->
|
OutboxItemR shr obikhid ->
|
||||||
(shr,) <$> decodeKeyHashidE obkhid "Local activity: ID is invalid hashid"
|
(shr,) <$> decodeKeyHashidE obikhid "Local activity: ID is invalid hashid"
|
||||||
_ -> throwE "Local activity: Not an activity route"
|
_ -> throwE "Local activity: Not an activity route"
|
||||||
runDBExcept $ do
|
runDBExcept $ do
|
||||||
Entity pidRecip personRecip <- lift $ do
|
Entity pidRecip personRecip <- lift $ do
|
||||||
sid <- getKeyBy404 $ UniqueSharer shrRecip
|
sid <- getKeyBy404 $ UniqueSharer shrRecip
|
||||||
getBy404 $ UniquePersonIdent sid
|
getBy404 $ UniquePersonIdent sid
|
||||||
mob <- lift $ get obid
|
mobi <- lift $ get obiid
|
||||||
ob <- fromMaybeE mob "Local activity: No such ID in DB"
|
obi <- fromMaybeE mobi "Local activity: No such ID in DB"
|
||||||
let pidOutbox = outboxItemPerson ob
|
mpidOutbox <-
|
||||||
|
lift $ getKeyBy $ UniquePersonOutbox $ outboxItemOutbox obi
|
||||||
|
pidOutbox <-
|
||||||
|
fromMaybeE mpidOutbox "Local activity not in a user outbox"
|
||||||
p <- lift $ getJust pidOutbox
|
p <- lift $ getJust pidOutbox
|
||||||
s <- lift $ getJust $ personIdent p
|
s <- lift $ getJust $ personIdent p
|
||||||
unless (sharerIdent s == shrActivity) $
|
unless (sharerIdent s == shrActivity) $
|
||||||
|
@ -437,7 +440,7 @@ handleSharerInbox _now shrRecip (Left pidAuthor) _raw activity = do
|
||||||
else lift $ do
|
else lift $ do
|
||||||
ibiid <- insert $ InboxItem True
|
ibiid <- insert $ InboxItem True
|
||||||
let ibid = personInbox personRecip
|
let ibid = personInbox personRecip
|
||||||
miblid <- insertUnique $ InboxItemLocal ibid obid ibiid
|
miblid <- insertUnique $ InboxItemLocal ibid obiid ibiid
|
||||||
let recip = shr2text shrRecip
|
let recip = shr2text shrRecip
|
||||||
case miblid of
|
case miblid of
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
|
|
|
@ -589,6 +589,7 @@ instance AccountDB AccountPersistDB' where
|
||||||
return $ Left $ mr $ MsgUsernameExists name
|
return $ Left $ mr $ MsgUsernameExists name
|
||||||
Right sid -> do
|
Right sid -> do
|
||||||
ibid <- insert Inbox
|
ibid <- insert Inbox
|
||||||
|
obid <- insert Outbox
|
||||||
let defTime = UTCTime (ModifiedJulianDay 0) 0
|
let defTime = UTCTime (ModifiedJulianDay 0) 0
|
||||||
person = Person
|
person = Person
|
||||||
{ personIdent = sid
|
{ personIdent = sid
|
||||||
|
@ -602,6 +603,7 @@ instance AccountDB AccountPersistDB' where
|
||||||
, personResetPassKeyCreated = defTime
|
, personResetPassKeyCreated = defTime
|
||||||
, personAbout = ""
|
, personAbout = ""
|
||||||
, personInbox = ibid
|
, personInbox = ibid
|
||||||
|
, personOutbox = obid
|
||||||
}
|
}
|
||||||
pid <- insert person
|
pid <- insert person
|
||||||
return $ Right $ Entity pid person
|
return $ Right $ Entity pid person
|
||||||
|
|
|
@ -369,9 +369,10 @@ getOutboxR :: ShrIdent -> Handler TypedContent
|
||||||
getOutboxR shr = do
|
getOutboxR shr = do
|
||||||
(total, pages, mpage) <- runDB $ do
|
(total, pages, mpage) <- runDB $ do
|
||||||
sid <- getKeyBy404 $ UniqueSharer shr
|
sid <- getKeyBy404 $ UniqueSharer shr
|
||||||
pid <- getKeyBy404 $ UniquePersonIdent sid
|
p <- getValBy404 $ UniquePersonIdent sid
|
||||||
let countAllItems = count [OutboxItemPerson ==. pid]
|
let obid = personOutbox p
|
||||||
selectItems off lim = selectList [OutboxItemPerson ==. pid] [Desc OutboxItemId, OffsetBy off, LimitTo lim]
|
countAllItems = count [OutboxItemOutbox ==. obid]
|
||||||
|
selectItems off lim = selectList [OutboxItemOutbox ==. obid] [Desc OutboxItemId, OffsetBy off, LimitTo lim]
|
||||||
getPageAndNavCount countAllItems selectItems
|
getPageAndNavCount countAllItems selectItems
|
||||||
let here = OutboxR shr
|
let here = OutboxR shr
|
||||||
encodeRouteLocal <- getEncodeRouteLocal
|
encodeRouteLocal <- getEncodeRouteLocal
|
||||||
|
@ -423,14 +424,14 @@ getOutboxR shr = do
|
||||||
defaultLayout $(widgetFile "person/outbox")
|
defaultLayout $(widgetFile "person/outbox")
|
||||||
|
|
||||||
getOutboxItemR :: ShrIdent -> KeyHashid OutboxItem -> Handler TypedContent
|
getOutboxItemR :: ShrIdent -> KeyHashid OutboxItem -> Handler TypedContent
|
||||||
getOutboxItemR shr obkhid = do
|
getOutboxItemR shr obikhid = do
|
||||||
obid <- decodeKeyHashid404 obkhid
|
obiid <- decodeKeyHashid404 obikhid
|
||||||
doc <- runDB $ do
|
doc <- runDB $ do
|
||||||
sid <- getKeyBy404 $ UniqueSharer shr
|
sid <- getKeyBy404 $ UniqueSharer shr
|
||||||
pid <- getKeyBy404 $ UniquePersonIdent sid
|
p <- getValBy404 $ UniquePersonIdent sid
|
||||||
ob <- get404 obid
|
obi <- get404 obiid
|
||||||
unless (outboxItemPerson ob == pid) notFound
|
unless (outboxItemOutbox obi == personOutbox p) notFound
|
||||||
return $ persistJSONValue $ outboxItemActivity ob
|
return $ persistJSONValue $ outboxItemActivity obi
|
||||||
selectRep $ do
|
selectRep $ do
|
||||||
provideAP $ pure doc
|
provideAP $ pure doc
|
||||||
provideRep $ defaultLayout $
|
provideRep $ defaultLayout $
|
||||||
|
|
|
@ -788,6 +788,37 @@ changes hLocal ctx =
|
||||||
-- 115
|
-- 115
|
||||||
, addUnique "TicketAuthorLocal" $
|
, addUnique "TicketAuthorLocal" $
|
||||||
Unique "UniqueTicketAuthorLocaleOffer" ["offer"]
|
Unique "UniqueTicketAuthorLocaleOffer" ["offer"]
|
||||||
|
-- 116
|
||||||
|
, addEntity $ ST.Entity "Outbox" [] []
|
||||||
|
-- 117
|
||||||
|
, addFieldRefRequired'
|
||||||
|
"Person"
|
||||||
|
Outbox20190615
|
||||||
|
(Just $ do
|
||||||
|
pids <- selectKeysList ([] :: [Filter Person20190615]) []
|
||||||
|
for_ pids $ \ pid -> do
|
||||||
|
obid <- insert Outbox20190615
|
||||||
|
update pid [Person20190615Outbox =. obid]
|
||||||
|
)
|
||||||
|
"outbox"
|
||||||
|
"Outbox"
|
||||||
|
-- 118
|
||||||
|
, addUnique "Person" $ Unique "UniquePersonOutbox" ["outbox"]
|
||||||
|
-- 119
|
||||||
|
, addFieldRefRequired'
|
||||||
|
"OutboxItem"
|
||||||
|
Outbox20190615
|
||||||
|
(Just $ do
|
||||||
|
obiids <- selectList ([] :: [Filter OutboxItem20190615]) []
|
||||||
|
for_ obiids $ \ (Entity obiid obi) -> do
|
||||||
|
person <- getJust $ outboxItem20190615Person obi
|
||||||
|
let obid = person20190615Outbox person
|
||||||
|
update obiid [OutboxItem20190615Outbox =. obid]
|
||||||
|
)
|
||||||
|
"outbox"
|
||||||
|
"Outbox"
|
||||||
|
-- 120
|
||||||
|
, removeField "OutboxItem" "person"
|
||||||
]
|
]
|
||||||
|
|
||||||
migrateDB
|
migrateDB
|
||||||
|
|
|
@ -91,6 +91,11 @@ module Vervis.Migration.Model
|
||||||
, Ticket20190612Generic (..)
|
, Ticket20190612Generic (..)
|
||||||
, Ticket20190612
|
, Ticket20190612
|
||||||
, TicketAuthorLocal20190612Generic (..)
|
, TicketAuthorLocal20190612Generic (..)
|
||||||
|
, Person20190615Generic (..)
|
||||||
|
, Person20190615
|
||||||
|
, Outbox20190615Generic (..)
|
||||||
|
, OutboxItem20190615Generic (..)
|
||||||
|
, OutboxItem20190615
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
@ -199,3 +204,6 @@ makeEntitiesMigration "20190610"
|
||||||
|
|
||||||
makeEntitiesMigration "20190612"
|
makeEntitiesMigration "20190612"
|
||||||
$(modelFile "migrations/2019_06_12.model")
|
$(modelFile "migrations/2019_06_12.model")
|
||||||
|
|
||||||
|
makeEntitiesMigration "20190615"
|
||||||
|
$(modelFile "migrations/2019_06_15.model")
|
||||||
|
|
Loading…
Reference in a new issue