content: {-# LANGUAGE StandaloneDeriving #-}
  {-# LANGUAGE TemplateHaskell #-}
  
  module Bank.Models
    ( BankEvent (..)
    , BankCommand (..)
    , accountEventSerializer
    , accountCommandSerializer
    , accountBankProjection
    , accountBankCommandHandler
    , customerEventSerializer
    , customerCommandSerializer
    , customerBankProjection
    , customerBankCommandHandler
    , module X
    ) where
  
  import Data.Aeson.TH
  import SumTypes.TH
  
  import Eventful
  import Eventful.TH
  
  import Bank.Json
  import Bank.Models.Account as X
  import Bank.Models.Customer as X
  
  constructSumType "BankEvent" (defaultSumTypeOptions { sumTypeOptionsTagOptions = ConstructTagName (++ "Event") }) $
    concat
    [ accountEvents
    , customerEvents
    ]
  
  deriving instance Show BankEvent
  deriving instance Eq BankEvent
  
  deriveJSON (defaultOptions { constructorTagModifier = dropSuffix "Event" }) ''BankEvent
  
  constructSumType "BankCommand" (defaultSumTypeOptions { sumTypeOptionsTagOptions = ConstructTagName (++ "Command") }) $
    concat
    [ accountCommands
    , customerCommands
    ]
  
  deriving instance Show BankCommand
  deriving instance Eq BankCommand
  
  mkSumTypeSerializer "accountEventSerializer" ''AccountEvent ''BankEvent
  mkSumTypeSerializer "accountCommandSerializer" ''AccountCommand ''BankCommand
  
  accountBankProjection :: Projection Account BankEvent
  accountBankProjection = serializedProjection accountProjection accountEventSerializer
  
  accountBankCommandHandler :: CommandHandler Account BankEvent BankCommand
  accountBankCommandHandler = serializedCommandHandler accountCommandHandler accountEventSerializer accountCommandSerializer
  
  mkSumTypeSerializer "customerEventSerializer" ''CustomerEvent ''BankEvent
  mkSumTypeSerializer "customerCommandSerializer" ''CustomerCommand ''BankCommand
  
  customerBankProjection :: Projection Customer BankEvent
  customerBankProjection = serializedProjection customerProjection customerEventSerializer
  
  customerBankCommandHandler :: CommandHandler Customer BankEvent BankCommand
  customerBankCommandHandler = serializedCommandHandler customerCommandHandler customerEventSerializer customerCommandSerializer
  