From 44530de5c2647984510d1a2a832c379306680344 Mon Sep 17 00:00:00 2001 From: John Watson Date: Wed, 21 Aug 2024 22:27:15 +0100 Subject: [PATCH] feat: adds real time query against status.systeminit.com Co-authored-by: John Obelenus --- app/web/src/App.vue | 2 - .../components/RealtimeStatusPageState.vue | 62 +++++++++++++++++ .../src/components/StatusBar/StatusBar.vue | 3 + app/web/src/store/realtime/realtime.store.ts | 67 +++++++++++++++++++ 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 app/web/src/components/RealtimeStatusPageState.vue diff --git a/app/web/src/App.vue b/app/web/src/App.vue index 61b508b0d8..a593c322e0 100644 --- a/app/web/src/App.vue +++ b/app/web/src/App.vue @@ -16,7 +16,6 @@ + + + + diff --git a/app/web/src/components/StatusBar/StatusBar.vue b/app/web/src/components/StatusBar/StatusBar.vue index e416d00010..ef52233d55 100644 --- a/app/web/src/components/StatusBar/StatusBar.vue +++ b/app/web/src/components/StatusBar/StatusBar.vue @@ -9,7 +9,9 @@ >
System Initiative +
+
@@ -28,6 +30,7 @@ import * as _ from "lodash-es"; import clsx from "clsx"; import { useChangeSetsStore } from "@/store/change_sets.store"; +import RealtimeStatusPageState from "@/components/RealtimeStatusPageState.vue"; import StatusBarDiffSummary from "./StatusBarDiffSummary.vue"; import StatusBarResourceSummary from "./StatusBarResourceSummary.vue"; import StatusBarQualificationSummary from "./StatusBarQualificationSummary.vue"; diff --git a/app/web/src/store/realtime/realtime.store.ts b/app/web/src/store/realtime/realtime.store.ts index de170e4de1..6b12dc1cc7 100644 --- a/app/web/src/store/realtime/realtime.store.ts +++ b/app/web/src/store/realtime/realtime.store.ts @@ -100,6 +100,72 @@ export const useRealtimeStore = defineStore("realtime", () => { } }); + // TODO(johnrwatson): Fetching status from a public status page JSON representation + // I have a DNS record set up for this but it's giving me grief, I'll come back and amend to + // status-data.systeminit.com + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async function fetchStatusPage(): Promise { + const response = await fetch( + "https://nhzefkyp7l.execute-api.us-east-1.amazonaws.com/data/payload.json", + ); + const data = await response.json(); + return data; + } + + // Custom sort function to sort incidents by severity + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function sortIncidentsBySeverity(incidents: any[]): any[] { + const severityOrder: { [key: string]: number } = { + MAINTENANCE: 4, + UNAVAILABLE: 3, + DEGRADED: 2, + OPERATIONAL: 1, + }; + + return incidents.sort((a, b) => { + const severityA = severityOrder[a.severitySlug?.toUpperCase()] || 5; + const severityB = severityOrder[b.severitySlug?.toUpperCase()] || 5; + return severityA - severityB; + }); + } + + const applicationStatus = ref("operational"); + + // Check whether there is a degraded or outage state against the public statuspage + const statusPageState = async () => { + applicationStatus.value = "operational"; + + try { + const statusData = await fetchStatusPage(); + + const incidents = sortIncidentsBySeverity(statusData.incidents); + + // Loop through each incident after sorting + for (const incident of incidents) { + const resolvedTimestamp = incident.timestamps?.resolved; + + if (incident.components) { + for (const component of incident.components) { + // Check if the incident is unresolved and its severity is relevant + if ( + !resolvedTimestamp && + ["UNAVAILABLE", "DEGRADED", "MAINTENANCE"].includes( + component.condition.toUpperCase(), + ) + ) { + applicationStatus.value = component.condition.toLowerCase(); // Return the lowercased version of severity and break the loop + break; + } + } + } + } + } catch (error) { + reportError(error); + } + }; + + setInterval(statusPageState, 30 * 1000); + // track subscriptions w/ topics, subscribers, etc let subCounter = 0; // const topicSubscriptionCounter = {} as Record; @@ -234,6 +300,7 @@ export const useRealtimeStore = defineStore("realtime", () => { }); return { + applicationStatus, connectionStatus, sendMessage, // subscriptions, // can expose here to show in devtools