Implement all vendor integrations, WAN graphs, and FortiGate health panel
- Wire up 26 vendor providers: Atlassian Statuspage API, Status.io, Instatus, AWS RSS feeds, Apple/Google JSON feeds, M365 Graph API, and synthetic checks - Add 11 new providers: AWS, Cloudflare, SmartPass, School Dismissal Manager, SherpaDesk, Classkick, ClassDojo, Savvas, Study Island, Promethean, RAZ-Kids - Rename Local Infrastructure → Internet (TCP check to 8.8.8.8:53) - Add WAN throughput graph section: dual-link canvas graphs (Crown Castle + Comcast) polling FortiGate REST API every 30s with 30-min rolling history - Add FortiGate health card: uptime, CPU %, memory % from FortiOS API - Add /api/throughput and /api/fortigate-health endpoints - Add README with setup instructions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,58 @@
|
||||
export const name = "Apple";
|
||||
export const url = "https://www.apple.com/support/systemstatus/";
|
||||
|
||||
const STATUS_URL =
|
||||
"https://www.apple.com/support/systemstatus/data/system_status_en_US.js";
|
||||
|
||||
// eventStatus values that mean the event is no longer active
|
||||
const RESOLVED_STATUSES = new Set(["resolved", "completed"]);
|
||||
|
||||
// statusType → dashboard status (Performance issues = degraded, outages = outage)
|
||||
function mapStatusType(statusType) {
|
||||
const t = (statusType ?? "").toLowerCase();
|
||||
if (t === "outage") return "outage";
|
||||
return "degraded"; // Performance, Maintenance, or anything else
|
||||
}
|
||||
|
||||
export async function checkStatus() {
|
||||
const res = await fetch(STATUS_URL);
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`Apple status request failed (${res.status})`);
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
const services = data.services ?? [];
|
||||
|
||||
// Collect services with active (unresolved) events
|
||||
const affected = [];
|
||||
let overall = "operational";
|
||||
|
||||
for (const svc of services) {
|
||||
const activeEvents = (svc.events ?? []).filter(
|
||||
(e) => !RESOLVED_STATUSES.has((e.eventStatus ?? "").toLowerCase())
|
||||
);
|
||||
|
||||
if (activeEvents.length === 0) continue;
|
||||
|
||||
for (const event of activeEvents) {
|
||||
const mapped = mapStatusType(event.statusType);
|
||||
if (mapped === "outage" || overall === "operational") {
|
||||
overall = mapped;
|
||||
}
|
||||
affected.push(`${svc.serviceName}: ${event.message ?? event.statusType}`);
|
||||
}
|
||||
}
|
||||
|
||||
const message =
|
||||
affected.length > 0
|
||||
? affected.join(" | ")
|
||||
: "All services operating normally.";
|
||||
|
||||
return {
|
||||
name,
|
||||
status: "operational",
|
||||
message: "All services running normally.",
|
||||
status: overall,
|
||||
message,
|
||||
lastUpdated: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user