module Web.Controller.ApiDashboard where import Web.Types import Web.View.ApiDashboard.Show import Generated.Types import IHP.Prelude import IHP.ControllerPrelude import Web.Routes () import Database.PostgreSQL.Simple (Only(..)) instance Controller ApiDashboardController where beforeAction = ensureIsUser action ShowApiDashboardAction = autoRefresh do consumers <- query @ApiConsumer |> orderByAsc #name |> fetch stats <- mapM fetchStats consumers render ShowView { stats } -- | Aggregate per-consumer stats from api_request_log (last 24 hours). fetchStats :: (?modelContext :: ModelContext) => ApiConsumer -> IO ConsumerStats fetchStats consumer = do rows <- sqlQuery "SELECT COUNT(*), \ \ COUNT(*) FILTER (WHERE status_code >= 400), \ \ MAX(requested_at) \ \FROM api_request_log \ \WHERE api_consumer_id = ? \ \ AND requested_at >= NOW() - INTERVAL '24 hours'" (Only consumer.id) case rows of [(total, errs, lastTs)] -> let errRate = if (total :: Int) == 0 then 0.0 else fromIntegral (errs :: Int) / fromIntegral total in pure ConsumerStats { consumer , requests24h = total , errorRate = errRate , lastSeen = lastTs } _ -> pure ConsumerStats { consumer , requests24h = 0 , errorRate = 0.0 , lastSeen = Nothing }