git.iko.soy/typeable/pagerduty
on develop help sign in
Adding full log entries API
commit0b18055ef35530257773ed6dd38b65c8298dbc92 authorBrendan Hay <brendan.g.hay@gmail.com> dateThu 2 Oct 2014, 13:38 (12 years ago) parentd784bca
5 files changed+471−61
pagerduty.cabal+4−4 src/Network/PagerDuty/REST/Alerts.hs+10−11 src/Network/PagerDuty/REST/LogEntries.hs+433−41 src/Network/PagerDuty/REST/Services.hs+3−2 src/Network/PagerDuty/Types.hs+21−3
pagerduty.cabal+4−4
@@ -33,19 +33,19 @@ library
3333-- Control.Monad.Trans.PagerDuty
3434 -- , Network.PagerDuty.Integration
3535 -- , Network.PagerDuty.REST
36− -- , Network.PagerDuty.REST.Alerts
36+-- Network.PagerDuty.REST.Alerts
3737 -- , Network.PagerDuty.REST.EscalationPolicies
3838 -- , Network.PagerDuty.REST.Incidents
39− -- , Network.PagerDuty.REST.LogEntries
39+ Network.PagerDuty.REST.LogEntries
4040 -- , Network.PagerDuty.REST.MaintenanceWindows
41− Network.PagerDuty.REST.Reports
41+ , Network.PagerDuty.REST.Reports
4242 -- , Network.PagerDuty.REST.Schedules
4343 -- , Network.PagerDuty.REST.Services
4444 -- , Network.PagerDuty.REST.Users
4545 -- , Network.PagerDuty.REST.Webhooks
4646
4747
48−-- other-modules:
48+ other-modules:
4949 Network.PagerDuty.Generics
5050 , Network.PagerDuty.IO
5151 , Network.PagerDuty.Options
src/Network/PagerDuty/REST/Alerts.hs+10−11
@@ -1,6 +1,7 @@
11{-# LANGUAGE DataKinds #-}
22{-# LANGUAGE OverloadedStrings #-}
33{-# LANGUAGE TemplateHaskell #-}
4+{-# LANGUAGE TypeFamilies #-}
45
56-- Module : Network.PagerDuty.REST.Alerts
67-- Copyright : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
@@ -56,7 +57,7 @@ data AlertType
5657 | Push
5758 deriving (Eq, Show)
5859
59−deriveJSON ''AlertType
60+deriveNullary ''AlertType
6061
6162data Alert = Alert
6263 { _alertId :: AlertId
@@ -66,20 +67,18 @@ data Alert = Alert
6667 , _alertAddress :: Address
6768 } deriving (Eq, Show)
6869
69−deriveJSON ''Alert
70−makeLenses ''Alert
70+deriveRecord ''Alert
7171
7272data ListAlerts = ListAlerts
7373 { _laSince' :: Date
7474 , _laUntil' :: Date
7575 , _laFilter' :: Maybe AlertType
76− , _laTimeZone' :: Maybe TimeZone
76+ , _laTimeZone' :: Maybe TZ
7777 } deriving (Eq, Show)
7878
7979instance Paginate ListAlerts
8080
81−deriveJSON ''ListAlerts
82−makeLenses ''ListAlerts
81+deriveQuery ''ListAlerts
8382
8483-- | List existing alerts for a given time range, optionally filtered by type
8584-- (SMS, Email, Phone, or Push).
@@ -100,15 +99,15 @@ listAlerts s u =
10099 & unwrap .~ key "alerts"
101100
102101-- | The start of the date range over which you want to search.
103−laSince :: Lens' (Request ListAlerts s r) Date
104−laSince = upd.laSince'
102+laSince :: Lens' (Request ListAlerts s r) UTCTime
103+laSince = upd.laSince'._Date
105104
106105-- | The end of the date range over which you want to search.
107106-- This should be in the same format as 'since'.
108107--
109108-- The size of the date range must be less than 3 months.
110−laUntil :: Lens' (Request ListAlerts s r) Date
111−laUntil = upd.laUntil'
109+laUntil :: Lens' (Request ListAlerts s r) UTCTime
110+laUntil = upd.laUntil'._Date
112111
113112-- | Returns only the alerts of the said 'AlertType' type.
114113laFilter :: Lens' (Request ListAlerts s r) (Maybe AlertType)
@@ -118,4 +117,4 @@ laFilter = upd.laFilter'
118117--
119118-- Defaults to account time zone.
120119laTimeZone :: Lens' (Request ListAlerts s r) (Maybe TimeZone)
121−laTimeZone = upd.laTimeZone'
120+laTimeZone = upd.laTimeZone'._TZ
src/Network/PagerDuty/REST/LogEntries.hs+433−41
@@ -1,5 +1,8 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE TemplateHaskell #-}
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE StandaloneDeriving #-}
4+{-# LANGUAGE TemplateHaskell #-}
5+{-# LANGUAGE TypeFamilies #-}
36
47-- Module : Network.PagerDuty.REST.LogEntries
58-- Copyright : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
@@ -19,9 +22,111 @@
1922-- acknowledged or resolved it, amongst a few other things.
2023module Network.PagerDuty.REST.LogEntries
2124 (
25+ -- * List Log Entries
26+ ListLogs
27+ , listLogs
28+ , listUserLogs
29+ , listIncidentLogs
30+ , llTimeZone
31+ , llSince
32+ , llUntil
33+ , llIsOverview
2234
35+ -- * Get Log Entry
36+ , GetLog
37+ , getLog
38+ , glTimeZone
39+
40+ -- * Channels
41+ , Channel (..)
42+ , _ChanNagios
43+ , _ChanAPI
44+ , _ChanEmail
45+ , _ChanUserEmail
46+ , _ChanWebTrigger
47+ , _ChanSMS
48+ , _ChanWeb
49+ , _ChanNote
50+ , _ChanAuto
51+ , _ChanTimeout
52+
53+ -- ** Nagios
54+ , NagiosChannel
55+ , ncSummary
56+ , ncHost
57+ , ncService
58+ , ncState
59+ , ncDetails
60+
61+ -- ** API
62+ , APIChannel
63+ , acSummary
64+ , acServiceKey
65+ , acDescription
66+ , acIncidentKey
67+ , acDetails
68+
69+ -- ** Email
70+ , EmailType (..)
71+ , EmailChannel
72+ , ecSummary
73+ , ecTo
74+ , ecFrom
75+ , ecSubject
76+ , ecBody
77+ , ecBodyContentType
78+ , ecRawUrl
79+ , ecHtmlUrl
80+
81+ -- ** Web Trigger
82+ , WebTriggerChannel
83+ , wcSummary
84+ , wcSubject
85+ , wcDetails
86+
87+ -- * Entries
88+ , Entry (..)
89+ , _LogEntry
90+ , _NotifyEntry
91+
92+ -- ** Logs
93+ , LogEntryType (..)
94+ , LogEntry
95+ , leId
96+ , leType
97+ , leCreatedAt
98+ , leNote
99+ , leAssignedUser
100+ , leChannel
101+
102+ -- ** Notifications
103+ , NotifyEntry
104+ , neCreatedAt
105+ , neUser
106+ , neNotification
107+
108+ , NotificationType (..)
109+ , NotificationStatus (..)
110+
111+ , Notification
112+ , nType
113+ , nStatus
114+ , nAddress
23115 ) where
24116
117+import Control.Applicative
118+import Control.Lens
119+import Data.Aeson
120+import Data.Aeson.Lens
121+import Data.Default
122+import qualified Data.HashMap.Strict as Map
123+import Data.Text (Text)
124+import qualified Data.Text as Text
125+import Data.Time
126+import Network.HTTP.Types
127+import Network.PagerDuty.TH
128+import Network.PagerDuty.Types
129+
25130logs :: Path
26131logs = "log_entries"
27132
@@ -32,53 +137,339 @@ includes =
32137 , ("include[]", Just "service")
33138 ]
34139
35−data LogEntry = LogEntry
36− deriving (Eq, Show)
140+data NagiosChannel = NagiosChannel
141+ { _ncSummary :: Text
142+ , _ncHost :: Text
143+ , _ncService :: Maybe Text
144+ , _ncState :: Text
145+ , _ncDetails :: Object
146+ } deriving (Eq, Show)
147+
148+deriveJSON ''NagiosChannel
149+
150+-- | Same as host.
151+makeLens "_ncSummary" ''NagiosChannel
152+
153+-- | Nagios host.
154+makeLens "_ncHost" ''NagiosChannel
155+
156+-- | Nagios service that created the event, if applicable.
157+makeLens "_ncService" ''NagiosChannel
158+
159+-- | State the caused the event.
160+makeLens "_ncState" ''NagiosChannel
161+
162+-- | Additional details of the incident.
163+makeLens "_ncDetails" ''NagiosChannel
164+
165+data APIChannel = APIChannel
166+ { _acSummary :: Text
167+ , _acServiceKey :: ServiceKey
168+ , _acDescription :: Text
169+ , _acIncidentKey :: IncidentKey
170+ , _acDetails :: Object
171+ } deriving (Eq, Show)
172+
173+deriveJSON ''APIChannel
174+
175+-- | Same as description.
176+makeLens "_acSummary" ''APIChannel
177+
178+-- | API service key.
179+makeLens "_acServiceKey" ''APIChannel
180+
181+-- | Description of the event.
182+makeLens "_acDescription" ''APIChannel
183+
184+-- | Incident deduping string.
185+makeLens "_acIncidentKey" ''APIChannel
186+
187+-- | Additional details of the incident, if any.
188+makeLens "_acDetails" ''APIChannel
189+
190+data EmailType
191+ = Plain
192+ | HTML
193+ deriving (Eq, Show)
194+
195+deriveNullary ''EmailType
196+
197+data EmailChannel = EmailChannel
198+ { _ecSummary :: Text
199+ , _ecTo :: Text
200+ , _ecFrom :: Text
201+ , _ecSubject :: Text
202+ , _ecBody :: Text
203+ , _ecBodyContentType :: EmailType
204+ , _ecRawUrl :: Text
205+ , _ecHtmlUrl :: Maybe Text
206+ } deriving (Eq, Show)
207+
208+deriveJSON ''EmailChannel
209+
210+-- | Same as subject.
211+makeLens "_ecSummary" ''EmailChannel
212+
213+-- | To address of the email.
214+makeLens "_ecTo" ''EmailChannel
215+
216+-- | From address of the email.
217+makeLens "_ecFrom" ''EmailChannel
218+
219+-- | Subject of the email.
220+makeLens "_ecSubject" ''EmailChannel
221+
222+-- | Body of the email.
223+makeLens "_ecBody" ''EmailChannel
224+
225+-- | Content type of the email body.
226+makeLens "_ecBodyContentType" ''EmailChannel
227+
228+-- | URL for raw text of email.
229+makeLens "_ecRawUrl" ''EmailChannel
230+
231+-- | URL for html rendered version of the email.
232+--
233+-- Only present if content_type is 'HTML'.
234+makeLens "_ecHtmlUrl" ''EmailChannel
235+
236+data WebTriggerChannel = WebTriggerChannel
237+ { _wcSummary :: Text
238+ , _wcSubject :: Text
239+ , _wcDetails :: Maybe Text
240+ } deriving (Eq, Show)
241+
242+deriveJSON ''WebTriggerChannel
37243
38−data GetLogs
39− { _leTimeZone' :: Maybe TimeZone
40− , _leSince' :: Maybe Date
41− , _leUntil' :: Maybe Date
42− , _leIsOverview' :: Bool
244+-- | Same as subject.
245+makeLens "_wcSummary" ''WebTriggerChannel
246+
247+-- | Subject of the web trigger.
248+makeLens "_wcSubject" ''WebTriggerChannel
249+
250+-- | Details about the web trigger.
251+makeLens "_wcDetails" ''WebTriggerChannel
252+
253+-- | Representation of the means by which the action was channeled.
254+data Channel
255+ = ChanNagios NagiosChannel
256+ | ChanAPI APIChannel
257+ | ChanEmail EmailChannel
258+ | ChanUserEmail User EmailChannel
259+ | ChanWebTrigger User WebTriggerChannel
260+ | ChanSMS User
261+ | ChanWeb User
262+ | ChanNote User
263+ | ChanAuto
264+ | ChanTimeout
265+ deriving (Eq, Show)
266+
267+makePrisms ''Channel
268+
269+instance FromJSON Channel where
270+ parseJSON = withObject "agent+channel" $ \o -> do
271+ t <- o .: "channel" >>= (.: "type")
272+ let u = Map.member "user" o
273+ case t of
274+ -- service
275+ "email" | not u -> ChanEmail <$> o .: "channel"
276+ "nagios" -> ChanNagios <$> o .: "channel"
277+ "api" -> ChanAPI <$> o .: "channel"
278+ -- user
279+ "email" | u -> ChanUserEmail <$> o .: "user" <*> o .: "channel"
280+ "web_trigger" -> ChanWebTrigger <$> o .: "user" <*> o .: "channel"
281+ "sms" -> ChanSMS <$> o .: "user"
282+ "web" -> ChanWeb <$> o .: "user"
283+ "note" -> ChanNote <$> o .: "user"
284+ -- empty
285+ "auto" -> pure ChanAuto
286+ "timeout" -> pure ChanTimeout
287+ _ -> fail $
288+ "unrecognised service channel type: " ++ Text.unpack t
289+
290+data LogEntryType
291+ = Trigger
292+ -- ^ The incident was triggered.
293+ | Acknowledge
294+ -- ^ The incident was acknowledged.
295+ | Unacknowledge
296+ -- ^ The incident was unacknowledged.
297+ | Resolve
298+ -- ^ The incident was resolved.
299+ | Escalate
300+ -- ^ The incident was escalated.
301+ | Assign
302+ -- ^ The incident was assigned to a user.
303+ | Annotate
304+ -- ^ A note was added to the incident.
305+ | ReachTriggerLimit
306+ -- ^ The incident has reached the log entry trigger limit and
307+ -- will not create any more.
308+ | RepeatEscalationPath
309+ -- ^ The incident has reached the end of its escalation policy
310+ -- and will restart.
311+ | ExhaustEscalationPath
312+ -- ^ The incident has cycled through its escalation policy the
313+ -- max allowed number of times.
314+ | Notify
315+ -- ^ A user was notified.
316+ deriving (Eq, Show)
317+
318+deriveNullary ''LogEntryType
319+
320+-- | The raw log event.
321+data LogEntry = LogEntry'
322+ { _leId :: LogEntryId
323+ , _leType :: LogEntryType
324+ , _leCreatedAt :: Date
325+ , _leNote :: Maybe Text
326+ , _leAssignedUser :: Maybe User
327+ , _leChannel :: Channel
328+ } deriving (Eq, Show)
329+
330+instance FromJSON LogEntry where
331+ parseJSON = withObject "log_entry" $ \o -> do
332+ LogEntry' <$> o .: "id"
333+ <*> o .: "type"
334+ <*> o .: "created_at"
335+ <*> o .:? "note"
336+ <*> o .:? "assigned_user"
337+ <*> parseJSON (Object o)
338+
339+-- | Id of the log entry.
340+makeLens "_leId" ''LogEntry
341+
342+-- | Time at which the log entry was created.
343+makeLens "_leCreatedAt" ''LogEntry
344+
345+-- | The type of the log entry.
346+makeLens "_leType" ''LogEntry
347+
348+-- | Optional field containing an action note, if one was included
349+-- with the action.
350+makeLens "_leNote" ''LogEntry
351+
352+-- | Only for assign, escalate log entries. The user to which the incident is
353+-- assigned.
354+makeLens "_leAssignedUser" ''LogEntry
355+
356+-- | Representation of the means by which the action was channeled and the
357+-- possible perfomer of this action.
358+makeLens "_leChannel" ''LogEntry
359+
360+data NotificationType
361+ = SMS
362+ | Email
363+ | Phone
364+ | IosPushNotification
365+ deriving (Eq, Show)
366+
367+deriveNullary ''NotificationType
368+
369+data NotificationStatus
370+ = Success
371+ | Blocked
372+ | Busy
373+ | Failed
374+ | NoAnswer
375+ | BadAddress
376+ deriving (Eq, Show)
377+
378+deriveNullary ''NotificationStatus
379+
380+data Notification = Notification
381+ { _nType :: !NotificationType
382+ , _nStatus :: !NotificationStatus
383+ , _nAddress :: Address
43384 } deriving (Eq, Show)
44385
45−instance Paginated GetLogs
386+deriveJSON ''Notification
387+
388+-- | Type of notification.
389+makeLens "_nType" ''Notification
46390
47−deriveJSON ''LogEntry
48−makeLenses ''LogEntry
391+-- | The current status of the notification.
392+makeLens "_nStatus" ''Notification
393+
394+-- | The address to which the notification was sent. I.e., an email address,
395+-- phone number, or iPhone name.
396+makeLens "_nAddress" ''Notification
397+
398+-- | Notify log entries correspond to notifications sent to users. They have a
399+-- distinct format from action log entries.
400+data NotifyEntry = NotifyEntry'
401+ { _neCreatedAt' :: Date
402+ , _neUser' :: User
403+ , _neNotification' :: Notification
404+ } deriving (Eq, Show)
405+
406+deriveRecord ''NotifyEntry
407+
408+-- | Time at which the log entry was created
409+neCreatedAt :: Lens' NotifyEntry UTCTime
410+neCreatedAt = neCreatedAt'._Date
411+
412+-- | User who was notified
413+neUser :: Lens' NotifyEntry User
414+neUser = neUser'
415+
416+-- | Object representing the notification itself
417+neNotification :: Lens' NotifyEntry Notification
418+neNotification = neNotification'
419+
420+data Entry
421+ = LogEntry LogEntry
422+ -- ^ Log entries come in a wide variety of types. Most types use this format,
423+ -- the exception being the 'NotifyEntry' type.
424+ | NotifyEntry NotifyEntry
425+ -- ^ A user was notified.
426+ deriving (Eq, Show)
427+
428+makePrisms ''Entry
429+
430+data ListLogs = ListLogs
431+ { _llTimeZone' :: TZ
432+ , _llSince' :: Maybe Date
433+ , _llUntil' :: Maybe Date
434+ , _llIsOverview' :: Bool'
435+ } deriving (Eq, Show)
436+
437+instance Paginate ListLogs
438+
439+deriveQuery ''ListLogs
49440
50441-- | Time zone in which dates in the result will be rendered.
51442--
52443-- Defaults to UTC.
53−leTimeZone :: Lens' (Request LogEntry s b) TimeZone
54−leTimeZone = upd.leTimeZone'
444+llTimeZone :: Lens' (Request ListLogs s b) TimeZone
445+llTimeZone = upd.llTimeZone'._TZ
55446
56447-- | The start of the date range over which you want to search.
57−leSince :: Lens' (Request LogEntry s b) (Maybe Date)
58−leSince = upd.leSince'
448+llSince :: Lens' (Request ListLogs s b) (Maybe UTCTime)
449+llSince = upd.llSince'.mapping _Date
59450
60451-- | The end of the date range over which you want to search.
61−leUntil :: Lens' (Request LogEntry s b) (Maybe Date)
62−leUntil = upd.leUntil'
452+llUntil :: Lens' (Request ListLogs s b) (Maybe UTCTime)
453+llUntil = upd.llUntil'.mapping _Date
63454
64−-- | If true, will only return log entries of type trigger, acknowledge, or resolve.
455+-- | If true, will only return log entries of type trigger, acknowlldge, or resolve.
65456--
66457-- Defaults to false.
67−leIsOverview :: Lens' (Request LogEntry s b) Bool
68−leIsOverview = upd.leIsOverview'
458+llIsOverview :: Lens' (Request ListLogs s b) Bool
459+llIsOverview = upd.llIsOverview'._B
69460
70461-- | List all incident log entries across the entire account.
71462--
72463-- @GET \/log_entries@
73464--
74465-- See: <http://developer.pagerduty.com/documentation/rest/log_entries/list>
75−listLogs :: Request GetLogs s [LogEntry]
466+listLogs :: Request ListLogs s [LogEntry]
76467listLogs =
77− mk GetLogs
78− { _leTimeZone' = def
79− , _leSince' = Nothing
80− , _leUntil' = Nothing
81− , _leIsOverview' = False
468+ mk ListLogs
469+ { _llTimeZone' = def
470+ , _llSince' = Nothing
471+ , _llUntil' = Nothing
472+ , _llIsOverview' = B False
82473 } & path .~ logs
83474 & query .~ includes
84475 & unwrap .~ key "log_entries"
@@ -88,7 +479,7 @@ listLogs =
88479-- @GET \/users\/\:user_id\/log_entries@
89480--
90481-- See: <http://developer.pagerduty.com/documentation/rest/log_entries/user_log_entries>
91−listUserLogs :: UserId -> Request GetLogs s [LogEntry]
482+listUserLogs :: UserId -> Request ListLogs s [LogEntry]
92483listUserLogs u = listLogs & path .~ "users" % u % logs
93484
94485-- | List all incident log entries for a specific incident.
@@ -96,19 +487,14 @@ listUserLogs u = listLogs & path .~ "users" % u % logs
96487-- @GET \/incidents\/\:incident_id\/log_entries@
97488--
98489-- See: <http://developer.pagerduty.com/documentation/rest/log_entries/incident_log_entries>
99−listIncidentLogs :: Request GetLogs s [LogEntry]
100−listIncidentLogs i = listLogs & path .~ "incidents" % u % logs
490+listIncidentLogs :: IncidentKey -> Request ListLogs s [LogEntry]
491+listIncidentLogs i = listLogs & path .~ "incidents" % i % logs
101492
102−newtype GetLogEntry = GetLogEntry
103− { _gleTimeZone' :: TimeZone
493+newtype GetLog = GetLog
494+ { _glTimeZone' :: TZ
104495 } deriving (Eq, Show)
105496
106−deriveJSON ''GetLogEntry
107−makeLenses ''GetLogEntry
108−
109−-- | Time zone in which dates in the result will be rendered.
110−--
111−-- Defaults to UTC.
497+deriveQuery ''GetLog
112498
113499-- | Get details for a specific incident log entry. This method provides additional
114500-- information you can use to get at raw event data.
@@ -116,9 +502,15 @@ makeLenses ''GetLogEntry
116502-- @GET \/log_entries\/\:id@
117503--
118504-- See: <http://developer.pagerduty.com/documentation/rest/log_entries/show>
119−getLog :: LogEntryId -> Request GetLogEntry s LogEntry
505+getLog :: LogEntryId -> Request GetLog s LogEntry
120506getLog l =
121− mk GetLogEntry
122− { _gleTimeZone' = def
507+ mk GetLog
508+ { _glTimeZone' = def
123509 } & path .~ logs % l
124510 & query .~ includes
511+
512+-- | Time zone in which dates in the result will be rendered.
513+--
514+-- Defaults to UTC.
515+glTimeZone :: Lens' (Request GetLog s b) TimeZone
516+glTimeZone = upd.glTimeZone'._TZ
src/Network/PagerDuty/REST/Services.hs+3−2
@@ -116,6 +116,7 @@ import Control.Lens
116116import Data.Aeson.Lens
117117import Data.ByteString.Builder (Builder)
118118import Data.Text (Text)
119+import Data.Time
119120import Network.HTTP.Types
120121import Network.PagerDuty.TH
121122import Network.PagerDuty.Types
@@ -354,7 +355,7 @@ makeLens "_svcEmailFilters" ''Service
354355makeLens "_svcSeverityFilter" ''Service
355356
356357newtype ListServices = ListServices
357− { _lsTimeZone' :: Maybe TimeZone
358+ { _lsTimeZone' :: Maybe TZ
358359 } deriving (Eq, Show)
359360
360361instance Paginate ListServices
@@ -379,7 +380,7 @@ listServices =
379380--
380381-- Defaults to account default time zone.
381382lsTimeZone :: Lens' (Request ListServices s r) (Maybe TimeZone)
382−lsTimeZone = upd.lsTimeZone'
383+lsTimeZone = upd.lsTimeZone'._TZ
383384
384385data CreateService = CreateService
385386 { _csName' :: Text
src/Network/PagerDuty/Types.hs+21−3
@@ -70,9 +70,23 @@ import Network.HTTP.Types.QueryLike
7070import Network.PagerDuty.TH
7171import System.Locale
7272
73+-- FIXME: Verify IncidentId/IncidentKey .. *Id/*Key are actually different or needed
74+
75+newtype Bool' = B Bool
76+ deriving (Eq, Show)
77+
78+deriveJSON ''Bool'
79+makePrisms ''Bool'
80+
81+instance QueryValueLike Bool' where
82+ toQueryValue (B True) = Just "true"
83+ toQueryValue (B False) = Just "false"
84+
7385newtype Date = Date { unDate :: UTCTime }
7486 deriving (Eq, Ord, Show)
7587
88+makePrisms ''Date
89+
7690instance FromJSON Date where
7791 parseJSON = fmap Date . parseJSON
7892
@@ -88,7 +102,9 @@ instance QueryValueLike Date where
88102 toQueryValue = Just . toByteString'
89103
90104newtype TZ = TZ { unTZ :: TimeZone }
91− deriving (Eq, Ord, Show)
105+ deriving (Eq, Show)
106+
107+makePrisms ''TZ
92108
93109instance FromJSON TZ where
94110 parseJSON = undefined
@@ -331,6 +347,8 @@ instance QueryValueLike (Id a) where
331347 toQueryValue = Just . toByteString'
332348
333349type AlertId = Id "alert"
350+type EmailFilterId = Id "email-filter"
351+type LogEntryId = Id "log-entry"
334352type PolicyId = Id "policy"
335353type RequesterId = Id "requester"
336354type RuleId = Id "rule"
@@ -338,7 +356,6 @@ type ScheduleId = Id "schedule"
338356type ServiceId = Id "service"
339357type TargetId = Id "target"
340358type UserId = Id "user"
341−type EmailFilterId = Id "email-filter"
342359type VendorId = Id "vendor"
343360
344361data Empty = Empty
@@ -359,6 +376,7 @@ newtype Address = Address Text
359376 deriving (Eq, Show)
360377
361378deriveJSON ''Address
379+makePrisms ''Address
362380
363381instance ToByteString Address where
364382 builder (Address a) = builder a
@@ -375,7 +393,7 @@ data User = User
375393 , _userRole :: Text
376394 , _userAvatarUrl :: Text
377395 , _userUrl :: Text
378− , _userInvitationSent :: Bool
396+ , _userInvitationSent :: Bool'
379397 } deriving (Eq, Show)
380398
381399deriveRecord ''User