diff --git a/apps/api/src/routes/status_pages.ts b/apps/api/src/routes/status_pages.ts index 9a1d44b..caa0318 100644 --- a/apps/api/src/routes/status_pages.ts +++ b/apps/api/src/routes/status_pages.ts @@ -3,7 +3,6 @@ import { requireAuth } from "./auth"; import sql from "../db"; const Theme = t.Union([t.Literal("auto"), t.Literal("light"), t.Literal("dark")]); -const Window = t.Union([t.Literal("24h"), t.Literal("7d"), t.Literal("30d"), t.Literal("90d")]); const DisplayMode = t.Union([t.Literal("compact"), t.Literal("expanded")]); const BarFrequency = t.Union([t.Literal("hourly"), t.Literal("daily")]); @@ -17,7 +16,6 @@ const StatusPageBody = t.Object({ show_powered_by: t.Optional(t.Boolean()), show_response_time: t.Optional(t.Boolean()), show_cert_expiry: t.Optional(t.Boolean()), - default_window: t.Optional(Window), display_mode: t.Optional(DisplayMode), bar_frequency: t.Optional(BarFrequency), bar_count: t.Optional(t.Number({ minimum: 1, maximum: 180 })), @@ -118,7 +116,7 @@ export const statusPages = new Elysia({ prefix: "/pages" }) .get("/", async ({ accountId }) => { return sql` - SELECT id, slug, title, description, theme, default_window, created_at, updated_at + SELECT id, slug, title, description, theme, created_at, updated_at FROM status_pages WHERE account_id = ${accountId} ORDER BY created_at DESC @@ -133,7 +131,7 @@ export const statusPages = new Elysia({ prefix: "/pages" }) [row] = await sql` INSERT INTO status_pages ( account_id, slug, title, description, theme, password_hash, index_search, - show_powered_by, show_response_time, show_cert_expiry, default_window, display_mode, + show_powered_by, show_response_time, show_cert_expiry, display_mode, bar_frequency, bar_count, custom_css, footer_text, og_image_url, analytics_html, auto_refresh_s ) @@ -141,7 +139,7 @@ export const statusPages = new Elysia({ prefix: "/pages" }) ${accountId}, ${body.slug}, ${body.title}, ${body.description ?? null}, ${body.theme ?? 'auto'}, ${password_hash}, ${body.index_search ?? true}, ${body.show_powered_by ?? true}, ${body.show_response_time ?? true}, - ${body.show_cert_expiry ?? false}, ${body.default_window ?? '24h'}, ${body.display_mode ?? 'expanded'}, + ${body.show_cert_expiry ?? false}, ${body.display_mode ?? 'expanded'}, ${body.bar_frequency ?? 'daily'}, ${body.bar_count ?? 90}, ${css}, ${body.footer_text ?? null}, ${body.og_image_url ?? null}, ${body.analytics_html ?? null}, ${body.auto_refresh_s ?? 60} @@ -197,7 +195,6 @@ export const statusPages = new Elysia({ prefix: "/pages" }) show_powered_by = COALESCE(${body.show_powered_by ?? null}, show_powered_by), show_response_time = COALESCE(${body.show_response_time ?? null}, show_response_time), show_cert_expiry = COALESCE(${body.show_cert_expiry ?? null}, show_cert_expiry), - default_window = COALESCE(${body.default_window ?? null}, default_window), display_mode = COALESCE(${body.display_mode ?? null}, display_mode), bar_frequency = COALESCE(${body.bar_frequency ?? null}, bar_frequency), bar_count = COALESCE(${body.bar_count ?? null}, bar_count), diff --git a/apps/shared/db.ts b/apps/shared/db.ts index 89dde2a..a174da8 100644 --- a/apps/shared/db.ts +++ b/apps/shared/db.ts @@ -130,7 +130,6 @@ export async function migrate(sql: any) { show_powered_by BOOLEAN NOT NULL DEFAULT true, show_response_time BOOLEAN NOT NULL DEFAULT true, show_cert_expiry BOOLEAN NOT NULL DEFAULT false, - default_window TEXT NOT NULL DEFAULT '24h', display_mode TEXT NOT NULL DEFAULT 'expanded', bar_frequency TEXT NOT NULL DEFAULT 'daily', bar_count INTEGER NOT NULL DEFAULT 90, diff --git a/apps/status/src/data.ts b/apps/status/src/data.ts index f6009c9..4605a53 100644 --- a/apps/status/src/data.ts +++ b/apps/status/src/data.ts @@ -19,7 +19,6 @@ export interface StatusPageRow { show_powered_by: boolean; show_response_time:boolean; show_cert_expiry: boolean; - default_window: Window; display_mode: "compact" | "expanded"; bar_frequency: BucketType; bar_count: number; @@ -56,7 +55,7 @@ export interface MonitorRow { // maintenance rather than an outage. current_state: "up" | "down" | "unknown" | "paused"; region_states: Array<{ region: string; state: "up" | "down" | "unknown"; updated_at: string | null }>; - uptime_pct: number | null; // for the page's default_window + uptime_pct: number | null; uptime: MultiWindowUptime; // 24h / 7d / 30d / 90d row buckets: Array<{ start: string; total: number; up: number; avg_latency: number | null }>; // bar chart input avg_latency: number | null; @@ -498,7 +497,7 @@ export async function loadMonitorDetail(slug: string, monitorId: string, window? `; if (!link) return null; - const win = (window ?? page.default_window) as Window; + const win = (window ?? '24h') as Window; // Reuse the bulk loader with a single-monitor list - keeps the bucket/state // logic in one place. Cheap because we're querying for one ID. We also need // the page's groups so we can redact the monitor's group_id (UUID → public @@ -571,7 +570,6 @@ export interface PublicPageView { show_powered_by: boolean; show_response_time: boolean; show_cert_expiry: boolean; - default_window: Window; display_mode: "compact" | "expanded"; bar_frequency: BucketType; bar_count: number; @@ -611,7 +609,6 @@ function redactPageForPublic(p: StatusPageRow): PublicPageView { show_powered_by: p.show_powered_by, show_response_time: p.show_response_time, show_cert_expiry: p.show_cert_expiry, - default_window: p.default_window, display_mode: p.display_mode, bar_frequency: p.bar_frequency, bar_count: p.bar_count, @@ -648,7 +645,7 @@ function redactGroupsAndMonitors( export async function loadPagePayload(slug: string, window?: Window): Promise { const page = await loadStatusPage(slug); if (!page) return null; - const win = (window ?? page.default_window) as Window; + const win = (window ?? '24h') as Window; const [rawGroups, rawMonitors, incidents] = await Promise.all([ loadGroups(page.id), loadMonitors(page.id, win, page.display_mode, page.bar_frequency, page.bar_count), diff --git a/apps/status/src/index.ts b/apps/status/src/index.ts index dae32ae..748718c 100644 --- a/apps/status/src/index.ts +++ b/apps/status/src/index.ts @@ -143,7 +143,7 @@ async function renderJson(slug: string, request: Request, win?: Window): Promise // fall back to HTML scraping (which gets the password form, also a 401-ish // signal but more expensive to parse and less stable). if (!page || !isAuthorised(page, request)) return jsonNotFound(); - const cacheKey = `payload:${slug}:${win ?? page.default_window}`; + const cacheKey = `payload:${slug}:${win ?? '24h'}`; const payload = await cached(cacheKey, 15, () => loadPagePayload(slug, win)); if (!payload) return jsonNotFound(); // Password-protected JSON must be private - same reasoning as renderHtml. diff --git a/apps/status/src/views/page.ejs b/apps/status/src/views/page.ejs index f29e109..285ddb6 100644 --- a/apps/status/src/views/page.ejs +++ b/apps/status/src/views/page.ejs @@ -207,8 +207,7 @@ Maintenance <% } else { %> <% if (page.show_response_time && m.avg_latency != null) { %><%= m.avg_latency %>ms<% } %> - <% const winKey = page.default_window === '24h' ? 'd24' : page.default_window === '7d' ? 'd7' : page.default_window === '30d' ? 'd30' : 'd90'; %> - <%= fmtUptime(u[winKey]) %> + <%= fmtUptime(m.uptime_pct) %> <% } %> @@ -286,7 +285,7 @@ - + <% if (page.auto_refresh_s > 0) { %> diff --git a/apps/web/src/routes/dashboard.ts b/apps/web/src/routes/dashboard.ts index 67fd0f1..0a1ebed 100644 --- a/apps/web/src/routes/dashboard.ts +++ b/apps/web/src/routes/dashboard.ts @@ -683,7 +683,7 @@ export const dashboard = new Elysia() const resolved = await getAccountId(cookie, headers); if (!resolved?.accountId) return redirect("/dashboard"); const pages = await sql` - SELECT id, slug, title, description, theme, default_window + SELECT id, slug, title, description, theme FROM status_pages WHERE account_id = ${resolved.accountId} ORDER BY created_at DESC `; @@ -734,7 +734,7 @@ export const dashboard = new Elysia() title: b.title, description: b.description || null, theme: b.theme || "auto", - default_window: b.default_window || "24h", + display_mode: b.display_mode || "expanded", bar_frequency: b.bar_frequency || "daily", bar_count: Number(b.bar_count) || 90, @@ -767,7 +767,6 @@ export const dashboard = new Elysia() title: b.title, description: b.description || null, theme: b.theme || "auto", - default_window: b.default_window || "24h", display_mode: b.display_mode || "expanded", bar_frequency: b.bar_frequency || "daily", bar_count: Number(b.bar_count) || 90, diff --git a/apps/web/src/views/docs.ejs b/apps/web/src/views/docs.ejs index 4d41cfa..d59ec65 100644 --- a/apps/web/src/views/docs.ejs +++ b/apps/web/src/views/docs.ejs @@ -294,7 +294,6 @@ Content-Type: application/json themestring?auto, light, or dark. Default auto. passwordstring?Plain text, hashed at write time. Pass null to clear. display_modestring?compact or expanded. Default expanded. - default_windowstring?24h, 7d, 30d, or 90d. Default 24h. bar_frequencystring?hourly or daily. Default daily. bar_countnumber?How many bars to show (1-180). Default 90. auto_refresh_snumber?Auto-refresh interval in seconds (10-3600). Default 60. diff --git a/apps/web/src/views/status-page-edit.ejs b/apps/web/src/views/status-page-edit.ejs index ede029a..52cf733 100644 --- a/apps/web/src/views/status-page-edit.ejs +++ b/apps/web/src/views/status-page-edit.ejs @@ -61,14 +61,6 @@ <% }) %> -
- - -