module CQRSExample.Notifications ( calculateNotifications , Notification(..) ) where import Data.Aeson (ToJSON(..), object, (.=)) import Data.CQRS.Query (PersistedEvent(..)) import Data.List (nub) import Data.Text (Text) import CQRSExample.Events (Event(..), TaskEvent(..)) -- Notifications. data Notification = AddedTask Text | ArchivedTasks Int | Refresh deriving (Show, Eq, Ord) -- Convert a notification to JSON instance ToJSON Notification where toJSON (AddedTask title) = object [ "type" .= ("added-task" :: Text) , "title" .= title ] toJSON (ArchivedTasks n) = object [ "type" .= ("archived-tasks" :: Text) , "numberOfTasks" .= n ] toJSON Refresh = object [ "type" .= ("refresh" :: Text) ] -- Calculate notifications, given a group of events. calculateNotifications :: [PersistedEvent Event] -> [Notification] calculateNotifications pes = nub $ f1 ++ f2 where f1 = concat $ map (eventNotification . peEvent) pes f2 = case sum $ map (archiveCounter . peEvent) pes of 0 -> [] n -> [ArchivedTasks n] eventNotification (TaskEvent (TaskAdded title)) = [AddedTask title] eventNotification (TaskEvent TaskCompleted) = [Refresh] eventNotification (TaskEvent TaskReopened) = [Refresh] eventNotification (TaskEvent TaskArchived) = [Refresh] archiveCounter :: Event -> Int archiveCounter (TaskEvent (TaskAdded _)) = 0 archiveCounter (TaskEvent TaskArchived) = 1 archiveCounter (TaskEvent TaskCompleted) = 0 archiveCounter (TaskEvent TaskReopened) = 0