From e67f4452e6db626d9f5ab30ea90f054576033361 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Fri, 24 Oct 2025 19:57:07 +0200 Subject: [PATCH] chore: update seed for stpg contribution (#1486) * chore: seed * fix: link --- apps/status-page/.env.example | 2 + .../components/status-page/status-tracker.tsx | 6 +- packages/api/src/router/statusPage.ts | 10 +- packages/api/src/router/statusPage.utils.ts | 27 ++- packages/db/src/seed.mts | 229 ++++++++++++------ 5 files changed, 186 insertions(+), 88 deletions(-) diff --git a/apps/status-page/.env.example b/apps/status-page/.env.example index bcb71e06..13be461d 100644 --- a/apps/status-page/.env.example +++ b/apps/status-page/.env.example @@ -11,6 +11,8 @@ DATABASE_AUTH_TOKEN=any-token NEXT_PUBLIC_SENTRY_DSN='' +# used for contributions to fill the monitor tracker with data +NOOP_UPTIME="true" # https://turbo.build/repo/docs/crafting-your-repository/using-environment-variables#loose-mode TURBO_ENV_MODE=loose diff --git a/apps/status-page/src/components/status-page/status-tracker.tsx b/apps/status-page/src/components/status-page/status-tracker.tsx index d3aab830..81dfbd80 100644 --- a/apps/status-page/src/components/status-page/status-tracker.tsx +++ b/apps/status-page/src/components/status-page/status-tracker.tsx @@ -319,9 +319,9 @@ export function StatusTracker({ data }: { data: UptimeData }) { return ( {content} diff --git a/packages/api/src/router/statusPage.ts b/packages/api/src/router/statusPage.ts index 9fdb2b50..0d14a615 100644 --- a/packages/api/src/router/statusPage.ts +++ b/packages/api/src/router/statusPage.ts @@ -311,7 +311,10 @@ export const statusPageRouter = createTRPCRouter({ monitorId: m.monitor.id, }); const rawData = statusDataByMonitorId.get(monitorId) || []; - const filledData = fillStatusDataFor45Days(rawData, monitorId); + const filledData = + process.env.NOOP_UPTIME === "true" + ? fillStatusDataFor45DaysNoop({ errorDays: [], degradedDays: [] }) + : fillStatusDataFor45Days(rawData, monitorId); const processedData = setDataByType({ events, data: filledData, @@ -334,7 +337,10 @@ export const statusPageRouter = createTRPCRouter({ // NOTE: used for the theme store getNoopUptime: publicProcedure.query(async () => { - const data = fillStatusDataFor45DaysNoop(); + const data = fillStatusDataFor45DaysNoop({ + errorDays: [4], + degradedDays: [40], + }); const processedData = setDataByType({ events: [ { diff --git a/packages/api/src/router/statusPage.utils.ts b/packages/api/src/router/statusPage.utils.ts index 9ab04b54..115613de 100644 --- a/packages/api/src/router/statusPage.utils.ts +++ b/packages/api/src/router/statusPage.utils.ts @@ -63,15 +63,24 @@ export function fillStatusDataFor45Days( ); } -export function fillStatusDataFor45DaysNoop(): Array { - const data: StatusData[] = Array.from({ length: 45 }, (_, i) => ({ - day: new Date(new Date().setDate(new Date().getDate() - i)).toISOString(), - count: 1, - ok: [4, 40].includes(i) ? 0 : 1, - degraded: i === 40 ? 1 : 0, - error: i === 4 ? 1 : 0, - monitorId: "1", - })); +export function fillStatusDataFor45DaysNoop({ + errorDays, + degradedDays, +}: { + errorDays: number[]; + degradedDays: number[]; +}): Array { + const issueDays = [...errorDays, ...degradedDays]; + const data: StatusData[] = Array.from({ length: 45 }, (_, i) => { + return { + day: new Date(new Date().setDate(new Date().getDate() - i)).toISOString(), + count: 1, + ok: issueDays.includes(i) ? 0 : 1, + degraded: degradedDays.includes(i) ? 1 : 0, + error: errorDays.includes(i) ? 1 : 0, + monitorId: "1", + }; + }); return fillStatusDataFor45Days(data, "1"); } diff --git a/packages/db/src/seed.mts b/packages/db/src/seed.mts index 9219d7a0..7053c3d1 100644 --- a/packages/db/src/seed.mts +++ b/packages/db/src/seed.mts @@ -1,5 +1,4 @@ import { createClient } from "@libsql/client"; -import { eq } from "drizzle-orm"; import { drizzle } from "drizzle-orm/libsql"; import { env } from "../env.mjs"; @@ -136,8 +135,8 @@ async function main() { .values({ id: 1, workspaceId: 1, - title: "Test Page", - description: "hello", + title: "Acme Inc.", + description: "Get informed about our services.", icon: "https://www.openstatus.dev/favicon.ico", slug: "status", customDomain: "", @@ -180,82 +179,172 @@ async function main() { }) .onConflictDoNothing() .run(); + await db .insert(notificationsToMonitors) .values({ monitorId: 1, notificationId: 1 }) .onConflictDoNothing() .run(); + // Status Report 1 - Resolved incident from 7 days ago + const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); + const sevenDaysAgoPlus30Min = new Date( + sevenDaysAgo.getTime() + 30 * 60 * 1000, + ); + const sevenDaysAgoPlus90Min = new Date( + sevenDaysAgo.getTime() + 90 * 60 * 1000, + ); + const sevenDaysAgoPlus120Min = new Date( + sevenDaysAgo.getTime() + 120 * 60 * 1000, + ); + await db .insert(statusReport) .values({ id: 1, workspaceId: 1, pageId: 1, - title: "Test Status Report", - status: "investigating", - updatedAt: new Date(), + title: "API Gateway Degraded Performance", + status: "resolved", + updatedAt: sevenDaysAgoPlus120Min, }) .onConflictDoNothing() .run(); await db .insert(statusReportUpdate) - .values({ - id: 1, - statusReportId: 1, - status: "investigating", - message: "Message", - date: new Date(), - }) + .values([ + { + id: 1, + statusReportId: 1, + status: "investigating", + message: + "We are investigating reports of slow API response times affecting some customers.", + date: sevenDaysAgo, + }, + { + id: 2, + statusReportId: 1, + status: "identified", + message: + "We have identified the issue as a database connection pool exhaustion and are working on a fix.", + date: sevenDaysAgoPlus30Min, + }, + { + id: 3, + statusReportId: 1, + status: "monitoring", + message: + "A fix has been deployed and we are monitoring the system. Response times are returning to normal.", + date: sevenDaysAgoPlus90Min, + }, + { + id: 4, + statusReportId: 1, + status: "resolved", + message: + "All systems are operating normally. The issue has been fully resolved.", + date: sevenDaysAgoPlus120Min, + }, + ]) .onConflictDoNothing() .run(); + // Status Report 2 - Ongoing incident from 2 hours ago + const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000); + const oneHourAgo = new Date(Date.now() - 1 * 60 * 60 * 1000); + const twentyMinutesAgo = new Date(Date.now() - 20 * 60 * 1000); + await db .insert(statusReport) .values({ id: 2, workspaceId: 1, pageId: 1, - title: "Test Status Report", - status: "investigating", - updatedAt: new Date(), + title: "Increased Error Rates on Monitoring Checks", + status: "resolved", + updatedAt: oneHourAgo, }) .onConflictDoNothing() .run(); await db .insert(statusReportUpdate) - .values({ - id: 2, - statusReportId: 2, - status: "investigating", - message: "Message", - date: new Date(), - }) + .values([ + { + id: 5, + statusReportId: 2, + status: "investigating", + message: + "We are seeing elevated error rates on some monitoring checks and are investigating the root cause.", + date: twoHoursAgo, + }, + { + id: 6, + statusReportId: 2, + status: "monitoring", + message: + "We have applied a fix and are monitoring the situation. Error rates are decreasing.", + date: oneHourAgo, + }, + { + id: 7, + statusReportId: 2, + status: "resolved", + message: + "Everything is under control, we continue to monitor the situation.", + date: twentyMinutesAgo, + }, + ]) .onConflictDoNothing() .run(); + // Maintenance windows spread across 30 days + const twentyDaysAgo = new Date(Date.now() - 20 * 24 * 60 * 60 * 1000); + const twentyDaysAgoPlus2Hours = new Date( + twentyDaysAgo.getTime() + 2 * 60 * 60 * 1000, + ); + + const fiveDaysFromNow = new Date(Date.now() + 5 * 24 * 60 * 60 * 1000); + const fiveDaysFromNowPlus4Hours = new Date( + fiveDaysFromNow.getTime() + 4 * 60 * 60 * 1000, + ); + await db .insert(maintenance) - .values({ - id: 1, - workspaceId: 1, - title: "Test Maintenance", - message: "Test message", - from: new Date(), - to: new Date(Date.now() + 1000), - pageId: 1, - }) + .values([ + { + id: 1, + workspaceId: 1, + title: "Database Migration and Optimization", + message: + "We will be performing database maintenance to improve performance. Some queries may be slower during this window.", + from: twentyDaysAgo, + to: twentyDaysAgoPlus2Hours, + pageId: 1, + }, + { + id: 2, + workspaceId: 1, + title: "Infrastructure Upgrade", + message: + "We will be upgrading our monitoring infrastructure to the latest version. Expect brief interruptions in data collection.", + from: fiveDaysFromNow, + to: fiveDaysFromNowPlus4Hours, + pageId: 1, + }, + ]) .onConflictDoNothing() .run(); await db .insert(maintenancesToMonitors) - .values({ - maintenanceId: 1, - monitorId: 1, - }) + .values([ + { + maintenanceId: 1, + monitorId: 1, + }, + ]) .onConflictDoNothing() .run(); @@ -266,51 +355,43 @@ async function main() { monitorId: 1, statusReportId: 2, }, - { - monitorId: 2, - statusReportId: 2, - }, ]) .onConflictDoNothing() .run(); - await db - .insert(incidentTable) - .values({ - id: 1, - workspaceId: 1, - monitorId: 1, - createdAt: new Date(), - startedAt: new Date(), - }) - .onConflictDoNothing() - .run(); + // Incidents - realistic past incidents that were resolved + const fifteenDaysAgo = new Date(Date.now() - 15 * 24 * 60 * 60 * 1000); + const fifteenDaysAgoPlus2Hours = new Date( + fifteenDaysAgo.getTime() + 2 * 60 * 60 * 1000, + ); + + const threeDaysAgo = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000); + const threeDaysAgoPlus20Min = new Date( + threeDaysAgo.getTime() + 20 * 60 * 1000, + ); await db .insert(incidentTable) - .values({ - id: 2, - workspaceId: 1, - monitorId: 1, - createdAt: new Date(), - startedAt: new Date(Date.now() + 1000), - }) - .onConflictDoNothing() - .run(); - // on status update - await db - .update(statusReport) - .set({ status: "monitoring" }) - .where(eq(statusReport.id, 1)); - await db - .insert(statusReportUpdate) - .values({ - id: 3, - statusReportId: 1, - status: "monitoring", - message: "test", - date: new Date(), - }) + .values([ + { + id: 1, + workspaceId: 1, + monitorId: 1, + createdAt: fifteenDaysAgo, + startedAt: fifteenDaysAgo, + acknowledgedAt: new Date(fifteenDaysAgo.getTime() + 5 * 60 * 1000), + resolvedAt: fifteenDaysAgoPlus2Hours, + }, + { + id: 2, + workspaceId: 1, + monitorId: 1, + createdAt: threeDaysAgo, + startedAt: threeDaysAgo, + acknowledgedAt: new Date(threeDaysAgo.getTime() + 2 * 60 * 1000), + resolvedAt: threeDaysAgoPlus20Min, + }, + ]) .onConflictDoNothing() .run(); -- 2.51.2