Openstatus www.openstatus.dev

chore: update seed for stpg contribution (#1486)

* chore: seed

* fix: link

authored by

Maximilian Kaske and committed by
GitHub
e67f4452 840df35f

+186 -88
+2
apps/status-page/.env.example
··· 11 11 12 12 NEXT_PUBLIC_SENTRY_DSN='' 13 13 14 + # used for contributions to fill the monitor tracker with data 15 + NOOP_UPTIME="true" 14 16 15 17 # https://turbo.build/repo/docs/crafting-your-repository/using-environment-variables#loose-mode 16 18 TURBO_ENV_MODE=loose
+3 -3
apps/status-page/src/components/status-page/status-tracker.tsx
··· 319 319 return ( 320 320 <Link 321 321 key={event.id} 322 - href={`${ 323 - prefix ? `/${prefix}` : "" 324 - }/events/report/${event.id}`} 322 + href={`${prefix ? `/${prefix}` : ""}/events/${ 323 + event.type 324 + }/${event.id}`} 325 325 > 326 326 {content} 327 327 </Link>
+8 -2
packages/api/src/router/statusPage.ts
··· 311 311 monitorId: m.monitor.id, 312 312 }); 313 313 const rawData = statusDataByMonitorId.get(monitorId) || []; 314 - const filledData = fillStatusDataFor45Days(rawData, monitorId); 314 + const filledData = 315 + process.env.NOOP_UPTIME === "true" 316 + ? fillStatusDataFor45DaysNoop({ errorDays: [], degradedDays: [] }) 317 + : fillStatusDataFor45Days(rawData, monitorId); 315 318 const processedData = setDataByType({ 316 319 events, 317 320 data: filledData, ··· 334 337 335 338 // NOTE: used for the theme store 336 339 getNoopUptime: publicProcedure.query(async () => { 337 - const data = fillStatusDataFor45DaysNoop(); 340 + const data = fillStatusDataFor45DaysNoop({ 341 + errorDays: [4], 342 + degradedDays: [40], 343 + }); 338 344 const processedData = setDataByType({ 339 345 events: [ 340 346 {
+18 -9
packages/api/src/router/statusPage.utils.ts
··· 63 63 ); 64 64 } 65 65 66 - export function fillStatusDataFor45DaysNoop(): Array<StatusData> { 67 - const data: StatusData[] = Array.from({ length: 45 }, (_, i) => ({ 68 - day: new Date(new Date().setDate(new Date().getDate() - i)).toISOString(), 69 - count: 1, 70 - ok: [4, 40].includes(i) ? 0 : 1, 71 - degraded: i === 40 ? 1 : 0, 72 - error: i === 4 ? 1 : 0, 73 - monitorId: "1", 74 - })); 66 + export function fillStatusDataFor45DaysNoop({ 67 + errorDays, 68 + degradedDays, 69 + }: { 70 + errorDays: number[]; 71 + degradedDays: number[]; 72 + }): Array<StatusData> { 73 + const issueDays = [...errorDays, ...degradedDays]; 74 + const data: StatusData[] = Array.from({ length: 45 }, (_, i) => { 75 + return { 76 + day: new Date(new Date().setDate(new Date().getDate() - i)).toISOString(), 77 + count: 1, 78 + ok: issueDays.includes(i) ? 0 : 1, 79 + degraded: degradedDays.includes(i) ? 1 : 0, 80 + error: errorDays.includes(i) ? 1 : 0, 81 + monitorId: "1", 82 + }; 83 + }); 75 84 return fillStatusDataFor45Days(data, "1"); 76 85 } 77 86
+155 -74
packages/db/src/seed.mts
··· 1 1 import { createClient } from "@libsql/client"; 2 - import { eq } from "drizzle-orm"; 3 2 import { drizzle } from "drizzle-orm/libsql"; 4 3 5 4 import { env } from "../env.mjs"; ··· 136 135 .values({ 137 136 id: 1, 138 137 workspaceId: 1, 139 - title: "Test Page", 140 - description: "hello", 138 + title: "Acme Inc.", 139 + description: "Get informed about our services.", 141 140 icon: "https://www.openstatus.dev/favicon.ico", 142 141 slug: "status", 143 142 customDomain: "", ··· 180 179 }) 181 180 .onConflictDoNothing() 182 181 .run(); 182 + 183 183 await db 184 184 .insert(notificationsToMonitors) 185 185 .values({ monitorId: 1, notificationId: 1 }) 186 186 .onConflictDoNothing() 187 187 .run(); 188 + 189 + // Status Report 1 - Resolved incident from 7 days ago 190 + const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); 191 + const sevenDaysAgoPlus30Min = new Date( 192 + sevenDaysAgo.getTime() + 30 * 60 * 1000, 193 + ); 194 + const sevenDaysAgoPlus90Min = new Date( 195 + sevenDaysAgo.getTime() + 90 * 60 * 1000, 196 + ); 197 + const sevenDaysAgoPlus120Min = new Date( 198 + sevenDaysAgo.getTime() + 120 * 60 * 1000, 199 + ); 188 200 189 201 await db 190 202 .insert(statusReport) ··· 192 204 id: 1, 193 205 workspaceId: 1, 194 206 pageId: 1, 195 - title: "Test Status Report", 196 - status: "investigating", 197 - updatedAt: new Date(), 207 + title: "API Gateway Degraded Performance", 208 + status: "resolved", 209 + updatedAt: sevenDaysAgoPlus120Min, 198 210 }) 199 211 .onConflictDoNothing() 200 212 .run(); 201 213 202 214 await db 203 215 .insert(statusReportUpdate) 204 - .values({ 205 - id: 1, 206 - statusReportId: 1, 207 - status: "investigating", 208 - message: "Message", 209 - date: new Date(), 210 - }) 216 + .values([ 217 + { 218 + id: 1, 219 + statusReportId: 1, 220 + status: "investigating", 221 + message: 222 + "We are investigating reports of slow API response times affecting some customers.", 223 + date: sevenDaysAgo, 224 + }, 225 + { 226 + id: 2, 227 + statusReportId: 1, 228 + status: "identified", 229 + message: 230 + "We have identified the issue as a database connection pool exhaustion and are working on a fix.", 231 + date: sevenDaysAgoPlus30Min, 232 + }, 233 + { 234 + id: 3, 235 + statusReportId: 1, 236 + status: "monitoring", 237 + message: 238 + "A fix has been deployed and we are monitoring the system. Response times are returning to normal.", 239 + date: sevenDaysAgoPlus90Min, 240 + }, 241 + { 242 + id: 4, 243 + statusReportId: 1, 244 + status: "resolved", 245 + message: 246 + "All systems are operating normally. The issue has been fully resolved.", 247 + date: sevenDaysAgoPlus120Min, 248 + }, 249 + ]) 211 250 .onConflictDoNothing() 212 251 .run(); 213 252 253 + // Status Report 2 - Ongoing incident from 2 hours ago 254 + const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000); 255 + const oneHourAgo = new Date(Date.now() - 1 * 60 * 60 * 1000); 256 + const twentyMinutesAgo = new Date(Date.now() - 20 * 60 * 1000); 257 + 214 258 await db 215 259 .insert(statusReport) 216 260 .values({ 217 261 id: 2, 218 262 workspaceId: 1, 219 263 pageId: 1, 220 - title: "Test Status Report", 221 - status: "investigating", 222 - updatedAt: new Date(), 264 + title: "Increased Error Rates on Monitoring Checks", 265 + status: "resolved", 266 + updatedAt: oneHourAgo, 223 267 }) 224 268 .onConflictDoNothing() 225 269 .run(); 226 270 227 271 await db 228 272 .insert(statusReportUpdate) 229 - .values({ 230 - id: 2, 231 - statusReportId: 2, 232 - status: "investigating", 233 - message: "Message", 234 - date: new Date(), 235 - }) 273 + .values([ 274 + { 275 + id: 5, 276 + statusReportId: 2, 277 + status: "investigating", 278 + message: 279 + "We are seeing elevated error rates on some monitoring checks and are investigating the root cause.", 280 + date: twoHoursAgo, 281 + }, 282 + { 283 + id: 6, 284 + statusReportId: 2, 285 + status: "monitoring", 286 + message: 287 + "We have applied a fix and are monitoring the situation. Error rates are decreasing.", 288 + date: oneHourAgo, 289 + }, 290 + { 291 + id: 7, 292 + statusReportId: 2, 293 + status: "resolved", 294 + message: 295 + "Everything is under control, we continue to monitor the situation.", 296 + date: twentyMinutesAgo, 297 + }, 298 + ]) 236 299 .onConflictDoNothing() 237 300 .run(); 238 301 302 + // Maintenance windows spread across 30 days 303 + const twentyDaysAgo = new Date(Date.now() - 20 * 24 * 60 * 60 * 1000); 304 + const twentyDaysAgoPlus2Hours = new Date( 305 + twentyDaysAgo.getTime() + 2 * 60 * 60 * 1000, 306 + ); 307 + 308 + const fiveDaysFromNow = new Date(Date.now() + 5 * 24 * 60 * 60 * 1000); 309 + const fiveDaysFromNowPlus4Hours = new Date( 310 + fiveDaysFromNow.getTime() + 4 * 60 * 60 * 1000, 311 + ); 312 + 239 313 await db 240 314 .insert(maintenance) 241 - .values({ 242 - id: 1, 243 - workspaceId: 1, 244 - title: "Test Maintenance", 245 - message: "Test message", 246 - from: new Date(), 247 - to: new Date(Date.now() + 1000), 248 - pageId: 1, 249 - }) 315 + .values([ 316 + { 317 + id: 1, 318 + workspaceId: 1, 319 + title: "Database Migration and Optimization", 320 + message: 321 + "We will be performing database maintenance to improve performance. Some queries may be slower during this window.", 322 + from: twentyDaysAgo, 323 + to: twentyDaysAgoPlus2Hours, 324 + pageId: 1, 325 + }, 326 + { 327 + id: 2, 328 + workspaceId: 1, 329 + title: "Infrastructure Upgrade", 330 + message: 331 + "We will be upgrading our monitoring infrastructure to the latest version. Expect brief interruptions in data collection.", 332 + from: fiveDaysFromNow, 333 + to: fiveDaysFromNowPlus4Hours, 334 + pageId: 1, 335 + }, 336 + ]) 250 337 .onConflictDoNothing() 251 338 .run(); 252 339 253 340 await db 254 341 .insert(maintenancesToMonitors) 255 - .values({ 256 - maintenanceId: 1, 257 - monitorId: 1, 258 - }) 342 + .values([ 343 + { 344 + maintenanceId: 1, 345 + monitorId: 1, 346 + }, 347 + ]) 259 348 .onConflictDoNothing() 260 349 .run(); 261 350 ··· 264 353 .values([ 265 354 { 266 355 monitorId: 1, 267 - statusReportId: 2, 268 - }, 269 - { 270 - monitorId: 2, 271 356 statusReportId: 2, 272 357 }, 273 358 ]) 274 359 .onConflictDoNothing() 275 360 .run(); 276 361 277 - await db 278 - .insert(incidentTable) 279 - .values({ 280 - id: 1, 281 - workspaceId: 1, 282 - monitorId: 1, 283 - createdAt: new Date(), 284 - startedAt: new Date(), 285 - }) 286 - .onConflictDoNothing() 287 - .run(); 362 + // Incidents - realistic past incidents that were resolved 363 + const fifteenDaysAgo = new Date(Date.now() - 15 * 24 * 60 * 60 * 1000); 364 + const fifteenDaysAgoPlus2Hours = new Date( 365 + fifteenDaysAgo.getTime() + 2 * 60 * 60 * 1000, 366 + ); 367 + 368 + const threeDaysAgo = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000); 369 + const threeDaysAgoPlus20Min = new Date( 370 + threeDaysAgo.getTime() + 20 * 60 * 1000, 371 + ); 288 372 289 373 await db 290 374 .insert(incidentTable) 291 - .values({ 292 - id: 2, 293 - workspaceId: 1, 294 - monitorId: 1, 295 - createdAt: new Date(), 296 - startedAt: new Date(Date.now() + 1000), 297 - }) 298 - .onConflictDoNothing() 299 - .run(); 300 - // on status update 301 - await db 302 - .update(statusReport) 303 - .set({ status: "monitoring" }) 304 - .where(eq(statusReport.id, 1)); 305 - await db 306 - .insert(statusReportUpdate) 307 - .values({ 308 - id: 3, 309 - statusReportId: 1, 310 - status: "monitoring", 311 - message: "test", 312 - date: new Date(), 313 - }) 375 + .values([ 376 + { 377 + id: 1, 378 + workspaceId: 1, 379 + monitorId: 1, 380 + createdAt: fifteenDaysAgo, 381 + startedAt: fifteenDaysAgo, 382 + acknowledgedAt: new Date(fifteenDaysAgo.getTime() + 5 * 60 * 1000), 383 + resolvedAt: fifteenDaysAgoPlus2Hours, 384 + }, 385 + { 386 + id: 2, 387 + workspaceId: 1, 388 + monitorId: 1, 389 + createdAt: threeDaysAgo, 390 + startedAt: threeDaysAgo, 391 + acknowledgedAt: new Date(threeDaysAgo.getTime() + 2 * 60 * 1000), 392 + resolvedAt: threeDaysAgoPlus20Min, 393 + }, 394 + ]) 314 395 .onConflictDoNothing() 315 396 .run(); 316 397