Repository: hasura/graphql-engine
File: server/src-lib/Hasura/Eventing/ScheduledTrigger.hs (Haskell)

Code before:
  , cesScheduledTime :: !UTCTime
  } deriving (Show, Eq)

data CronEventPartial
  = CronEventPartial
  { cepId            :: !CronEventId
  , cepName          :: !TriggerName
  , cepScheduledTime :: !UTCTime
  , cepTries         :: !Int
  } deriving (Show, Eq)

data ScheduledEventFull
  = ScheduledEventFull
  { sefId            :: !ScheduledEventId
  , sefName          :: !(Maybe TriggerName)
  -- ^ sefName is the name of the cron trigger.
  -- A one-off scheduled event is not associated with a name, so in that
  -- case, 'sefName' will be @Nothing@
  , sefScheduledTime :: !UTCTime
  , sefTries         :: !Int
  , sefWebhook       :: !Text
  , sefPayload       :: !J.Value
  , sefRetryConf     :: !STRetryConf
  , sefHeaders       :: ![EventHeaderInfo]
  , sefComment       :: !(Maybe Text)
  , sefCreatedAt     :: !(Maybe UTCTime)
  -- ^ sefCreatedAt is the time at which the event was created,
  -- In case of one-off scheduled events, it's the time at which
  -- the user created the event and in case of cron triggers, the
  -- graphql-engine generator, generates the cron events, the
  -- `created_at` is just an implementation detail, so we
  -- don't send it
  } deriving (Show, Eq)
$(J.deriveToJSON (J.aesonDrop 3 J.snakeCase) {J.omitNothingFields = True} ''ScheduledEventFull)

data OneOffScheduledEvent
  = OneOffScheduledEvent
  { ooseId            :: !OneOffScheduledEventId
  , ooseScheduledTime :: !UTCTime
  , ooseTries         :: !Int
  , ooseWebhook       :: !InputWebhook
  , oosePayload       :: !(Maybe J.Value)
  , ooseRetryConf     :: !STRetryConf
  , ooseHeaderConf    :: ![HeaderConf]
  , ooseComment       :: !(Maybe Text)
  , ooseCreatedAt     :: !UTCTime
  } deriving (Show, Eq)
$(J.deriveToJSON (J.aesonDrop 4 J.snakeCase) {J.omitNothingFields = True} ''OneOffScheduledEvent)

-- | The 'ScheduledEventType' data type is needed to differentiate
--   between a 'CronScheduledEvent' and 'OneOffScheduledEvent' scheduled

Review comment (suggestion):
This is arguable so I leave it up to you. But it feels the internal representation of `ScheduledEventFull` can have `UTCTime` for both cron and one-off events.

We can avoid exposing it in the payload for cron events because it is not user-facing.

This would mean we change the type to `sefCreatedAt     :: !UTCTime` and add the comment for `sewpCreatedAt`.


Code after:
  , cesScheduledTime :: !UTCTime
  } deriving (Show, Eq)

data CronEventPartial
  = CronEventPartial
  { cepId            :: !CronEventId
  , cepName          :: !TriggerName
  , cepScheduledTime :: !UTCTime
  , cepTries         :: !Int
  , cepCreatedAt     :: !UTCTime
  -- ^ cepCreatedAt is the time at which the cron event generator
  -- created the cron event
  } deriving (Show, Eq)

data ScheduledEventFull
  = ScheduledEventFull
  { sefId            :: !ScheduledEventId
  , sefName          :: !(Maybe TriggerName)
  -- ^ sefName is the name of the cron trigger.
  -- A one-off scheduled event is not associated with a name, so in that
  -- case, 'sefName' will be @Nothing@
  , sefScheduledTime :: !UTCTime
  , sefTries         :: !Int
  , sefWebhook       :: !Text
  , sefPayload       :: !J.Value
  , sefRetryConf     :: !STRetryConf
  , sefHeaders       :: ![EventHeaderInfo]
  , sefComment       :: !(Maybe Text)
  , sefCreatedAt     :: !UTCTime
  } deriving (Show, Eq)
$(J.deriveToJSON (J.aesonDrop 3 J.snakeCase) {J.omitNothingFields = True} ''ScheduledEventFull)

data OneOffScheduledEvent
  = OneOffScheduledEvent
  { ooseId            :: !OneOffScheduledEventId
  , ooseScheduledTime :: !UTCTime
  , ooseTries         :: !Int
  , ooseWebhook       :: !InputWebhook
  , oosePayload       :: !(Maybe J.Value)
  , ooseRetryConf     :: !STRetryConf
  , ooseHeaderConf    :: ![HeaderConf]
  , ooseComment       :: !(Maybe Text)
  , ooseCreatedAt     :: !UTCTime
  } deriving (Show, Eq)
$(J.deriveToJSON (J.aesonDrop 4 J.snakeCase) {J.omitNothingFields = True} ''OneOffScheduledEvent)

-- | The 'ScheduledEventType' data type is needed to differentiate
--   between a 'CronScheduledEvent' and 'OneOffScheduledEvent' scheduled
--   event because they both have different configurations
--   and they live in different tables.
data ScheduledEventType =