packages feed

keiro-dsl-0.17.0.0: test/conformance-intake-delegated/Generated/HospitalCapacity/IncidentInbox/Inbox.hs

-- @generated by keiro-dsl 0.17.0.0 (language keiro-dsl 6) from intake incidentInbox; do not edit.
module Generated.HospitalCapacity.IncidentInbox.Inbox
  ( InboxFailure (..)
  , IncidentInboxOutcome (..)
  , IncidentInboxDisposition (..)
  , inboxDedupePolicy
  , inboxIdempotence
  , runInboxIntake
  , inboxDispositionFor
  , inboxDisposition
  ) where

import Data.Text (Text)
import Effectful (Eff, IOE, (:>))
import Keiro.Inbox (runInboxDelegated)
import Keiro.Inbox.Types (DelegatedOutcome, InboxDedupePolicy (..), InboxError, InboxIdempotence (..), InboxResult (..), KafkaDeliveryRef, RetryDelay (..))
import Keiro.Integration.Event (IntegrationEvent)
import Keiro.Telemetry (KeiroMetrics)

-- The dedupe policy (hole-kind 4), lowered to the live InboxDedupePolicy.
inboxDedupePolicy :: InboxDedupePolicy
inboxDedupePolicy = PreferIntegrationMessageId

-- | The downstream state machine owns the durable dedupe receipt.
inboxIdempotence :: InboxIdempotence
inboxIdempotence = IdempotenceDelegated

-- | Run this intake without reading or writing the Keiro inbox table.
runInboxIntake ::
  IOE :> es =>
  Maybe KeiroMetrics ->
  IntegrationEvent ->
  Maybe KafkaDeliveryRef ->
  (Text -> IntegrationEvent -> Eff es (DelegatedOutcome a)) ->
  Eff es (Either InboxError (InboxResult a))
runInboxIntake metrics event delivery =
  runInboxDelegated metrics inboxDedupePolicy event delivery

-- Runtime failure detail retained when the inbox wrapper reports a failed handler attempt.
data InboxFailure = InboxFailure
  { reason :: !Text
  , attempt :: !(Maybe Int)
  }
  deriving stock (Eq, Show)

-- Every classification named by the spec. Keeping this closed makes the
-- generated table exhaustive and gives handler holes typed inputs.
data IncidentInboxOutcome
  = IncidentInboxProcessed
  | IncidentInboxDuplicate
  | IncidentInboxInProgress
  | IncidentInboxPreviouslyFailed
  | IncidentInboxDecodeFailed
  | IncidentInboxDedupeFailed
  | IncidentInboxStoreFailed
  deriving stock (Eq, Show)

-- The service's declared acknowledgement decision, including its details.
data IncidentInboxDisposition
  = InboxAccept
  | InboxRetryAfter !RetryDelay !(Maybe InboxFailure)
  | InboxDeadLetter !(Maybe Text) !(Maybe InboxFailure)
  deriving stock (Eq, Show)

-- The complete disposition table (hole-kind 2).
inboxDispositionFor :: IncidentInboxOutcome -> IncidentInboxDisposition
inboxDispositionFor outcome = case outcome of
  IncidentInboxProcessed -> InboxAccept
  IncidentInboxDuplicate -> InboxAccept
  IncidentInboxInProgress -> InboxRetryAfter (RetryDelay 5) Nothing
  IncidentInboxPreviouslyFailed -> InboxDeadLetter (Just "previous inbox failure") Nothing
  IncidentInboxDecodeFailed -> InboxDeadLetter Nothing Nothing
  IncidentInboxDedupeFailed -> InboxDeadLetter Nothing Nothing
  IncidentInboxStoreFailed -> InboxRetryAfter (RetryDelay 5) Nothing

-- Lower the LIVE Keiro.Inbox.Types.InboxResult without an open fallback.
inboxDisposition :: InboxResult a -> IncidentInboxDisposition
inboxDisposition r = case r of
  InboxProcessed _ -> inboxDispositionFor IncidentInboxProcessed
  InboxDuplicate -> inboxDispositionFor IncidentInboxDuplicate
  InboxInProgress -> inboxDispositionFor IncidentInboxInProgress
  InboxPreviouslyFailed failureReason ->
    maybe (inboxDispositionFor IncidentInboxPreviouslyFailed)
      (\reason -> attachFailure (InboxFailure reason Nothing) (inboxDispositionFor IncidentInboxPreviouslyFailed))
      failureReason
  InboxHandlerFailed reason attempts ->
    attachFailure (InboxFailure reason (Just attempts)) (inboxDispositionFor IncidentInboxStoreFailed)

attachFailure :: InboxFailure -> IncidentInboxDisposition -> IncidentInboxDisposition
attachFailure failure disposition = case disposition of
  InboxRetryAfter delay _ -> InboxRetryAfter delay (Just failure)
  InboxDeadLetter reason _ -> InboxDeadLetter reason (Just failure)
  InboxAccept -> InboxAccept