module CQRSExample.Instances ( ) where import CQRSExample.Aggregates import CQRSExample.Events import Data.CQRS (Eventable(..)) import qualified Data.Map as M import qualified Data.Set as S import qualified Data.Text as T instance Eventable Project Event where applyEvent (ProjectEvent projectEvent) project_ = go projectEvent project_ where go (ProjectCreated name shortDesc) UninitializedProject = ActiveProject name shortDesc -- Project changes to "active". go (ProjectCreated _ _ ) (ActiveProject _ _) = error "Invalid ProjectCreated event for project that already exists" go (ProjectRenamed _ ) UninitializedProject = error "Cannot rename uninitialized project" go (ProjectRenamed name) project@(ActiveProject _ _) = project { projectName = name } applyEvent (TaskEvent _) project = project applyEvent (UserEvent _) project = project applyEvent (SiteEvent _) project = project instance Eventable Task Event where applyEvent (ProjectEvent _) task = task applyEvent (TaskEvent taskEvent) project_ = go taskEvent project_ where go (TaskAdded pId tsd _ _ _) UninitializedTask = ActiveTask pId tsd T.empty M.empty go (TaskAdded _ _ _ _ _) (ActiveTask _ _ _ _) = error "Cannot add task which already exists" go (TaskStarred _) task = task go (TaskUnstarred _) task = task go (RecordedWorkUnit _ _ _ _ _) UninitializedTask = error "Cannot record work on uninitialized task" go (RecordedWorkUnit wuId wuDay wuDuration wuComment wuUserId) task@(ActiveTask _ _ _ workUnits) = task { taskWorkUnits = M.insert wuDay (WorkUnit wuId wuComment wuDuration wuUserId) workUnits } applyEvent (UserEvent _) task = task applyEvent (SiteEvent _) task = task instance Eventable User Event where applyEvent (ProjectEvent _) user = user applyEvent (TaskEvent _) user = user applyEvent (UserEvent userEvent) user = go userEvent user where go (UserCreated _ _ _ _) (ActiveUser _ _ _ _) = error "User already exists" go (UserCreated ucUserName ucPassword ucFirstName ucLastName) UninitializedUser = ActiveUser ucUserName ucPassword ucFirstName ucLastName applyEvent (SiteEvent _) user = user instance Eventable Site Event where applyEvent (ProjectEvent _) site = site applyEvent (TaskEvent _) site = site applyEvent (UserEvent _) site = site applyEvent (SiteEvent siteEvent) site_ = go siteEvent site_ where go (UserRegistered ucUserName) site = site { sUserNames = S.insert ucUserName $ sUserNames site }