packages feed

cqrs-example-0.9.0: src/CQRSExample/Notifications.hs

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