diff --git a/apps/api/src/cache/monitor-list.ts b/apps/api/src/cache/monitor-list.ts index 729bf70..d2eb6b5 100644 --- a/apps/api/src/cache/monitor-list.ts +++ b/apps/api/src/cache/monitor-list.ts @@ -3,7 +3,7 @@ // this cache each poll re-runs a 500-row scan against `monitors` with an array // predicate, which dominates the api's Postgres traffic at any real fleet size. // -// The list almost never changes between polls — monitor create/edit/delete is at +// The list almost never changes between polls - monitor create/edit/delete is at // most a few times per hour. So we memoize per-region with a short TTL and bust // the cache from the monitor mutation handlers so edits are visible instantly. @@ -54,7 +54,7 @@ export async function getMonitorsForRegion(region: string): Promise { // after `boundary` will be picked up on the next pass. const boundary = new Date(); - // GROUP BY 1,2,4 (ordinals) instead of repeating the date_trunc expression — + // GROUP BY 1,2,4 (ordinals) instead of repeating the date_trunc expression - // when the unit is a $-bound parameter, Postgres won't recognize the two // expressions as identical and will reject the column. Ordinals are safe. // @@ -91,7 +91,7 @@ async function rollupSinceWatermark(bucket: BucketType): Promise { // One-shot recompute over an arbitrary window, fully overwriting matched rows. // Used for the startup backfill and the "still empty after backfill" force-run. // Takes an explicit upper boundary so the caller can capture it BEFORE running -// the recompute and use the same value for the watermark write afterwards — +// the recompute and use the same value for the watermark write afterwards - // any ping with checked_at > boundary is guaranteed to be outside this window // and will be picked up by the first incremental pass instead. This closes // the race where a ping ingested between boundary capture and the SELECT @@ -137,7 +137,7 @@ export async function startRollupJob() { // Startup backfill. Capture the boundary FIRST, then run the one-shot // recompute bounded by it. The watermark is then set to the same boundary, // so any ping with checked_at > boundary is guaranteed to be picked up by - // the first incremental pass — never folded in twice and never missed. + // the first incremental pass - never folded in twice and never missed. try { const boundary = new Date(); const [h, d] = await Promise.all([ @@ -150,7 +150,7 @@ export async function startRollupJob() { setWatermark("daily", boundary), ]); } catch (e) { - console.error("[rollup] backfill FAILED — rollup table will be empty until fixed:", e); + console.error("[rollup] backfill FAILED - rollup table will be empty until fixed:", e); } // Force-run check: if any bucket type is still empty after the backfill, @@ -159,7 +159,7 @@ export async function startRollupJob() { try { for (const b of ["hourly", "daily"] as BucketType[]) { if (await rollupIsEmpty(b)) { - console.log(`[rollup] ${b} still empty — forcing incremental aggregation`); + console.log(`[rollup] ${b} still empty - forcing incremental aggregation`); // Reset watermark so the pass picks up everything in retention. await setWatermark(b, new Date(0)); await rollupSinceWatermark(b); @@ -170,7 +170,7 @@ export async function startRollupJob() { } // Periodic incremental refreshes. Each pass scans only pings newer than the - // last watermark, so the work is proportional to the delta — not the bucket + // last watermark, so the work is proportional to the delta - not the bucket // size. Hourly runs frequently so the current-hour bar appears quickly for // fresh monitors; daily can run less often. setInterval(() => { rollupSinceWatermark("hourly").catch((e) => console.warn("[rollup] hourly failed:", e)); }, 30 * 1000); // every 30s diff --git a/apps/api/src/routes/internal.ts b/apps/api/src/routes/internal.ts index 55bcd82..dae702d 100644 --- a/apps/api/src/routes/internal.ts +++ b/apps/api/src/routes/internal.ts @@ -108,13 +108,13 @@ export const internal = new Elysia({ prefix: "/internal", detail: { hide: true } const lookaheadMs = Math.min(Number(params.get('lookahead_ms') || 2000), 10000); // No JOIN, no state lookup. The check schedule for a monitor is purely - // a function of its created_at and interval_s — every interval since + // a function of its created_at and interval_s - every interval since // creation is a tick. We pull all enabled monitors that match this // region, compute the next tick in JS, and return the ones whose next // tick falls within the lookahead window. // // The monitor list itself is memoized in apps/api/src/cache/monitor-list.ts - // with a 5s TTL — runners poll this endpoint roughly once a second per + // with a 5s TTL - runners poll this endpoint roughly once a second per // region, but the underlying list almost never changes between polls. The // cache is busted from monitor create/patch/delete/toggle so edits show up // immediately. diff --git a/apps/api/src/routes/monitors.ts b/apps/api/src/routes/monitors.ts index 5e2f719..3d7a0b6 100644 --- a/apps/api/src/routes/monitors.ts +++ b/apps/api/src/routes/monitors.ts @@ -17,7 +17,7 @@ const MonitorBody = t.Object({ retry_interval_s: t.Optional(t.Number({ minimum: 1, maximum: 600, default: 30, description: "Seconds between retries" })), resend_interval: t.Optional(t.Number({ minimum: 0, maximum: 1000, default: 0, description: "Re-alert every Nth consecutive down beat. 0 = never resend." })), cert_alert_days: t.Optional(t.Number({ minimum: 0, maximum: 365, default: 0, description: "Alert when TLS cert is within N days of expiry. 0 disables (default)." })), - query: t.Optional(t.Any({ description: "PingQL query — filter conditions for up/down" })), + query: t.Optional(t.Any({ description: "PingQL query - filter conditions for up/down" })), regions: t.Optional(t.Array(t.String(), { description: "Regions to run checks from. Empty array = all regions." })), channel_ids: t.Optional(t.Array(t.String(), { description: "Notification channel IDs to attach to this monitor." })), tags: t.Optional(t.Array(t.String({ pattern: "^[a-z0-9][a-z0-9-]{0,40}$" }), { description: "Lowercase tag slugs for grouping. Replaces the existing tag set." })), diff --git a/apps/api/src/routes/pings.ts b/apps/api/src/routes/pings.ts index 7713100..27df6a6 100644 --- a/apps/api/src/routes/pings.ts +++ b/apps/api/src/routes/pings.ts @@ -61,7 +61,7 @@ export const ingest = new Elysia() // notifications never carry an empty label. const region = body.region && body.region.length > 0 ? body.region : 'default'; - // The monitor lookup and the per-region state lookup are independent — + // The monitor lookup and the per-region state lookup are independent - // the state row's primary key doesn't depend on anything from the monitor // row. Fire them in parallel to halve the wall-clock cost on the hottest // path in the system. (Combining them into a JOIN is a wash on a warm diff --git a/apps/api/src/routes/status_pages.ts b/apps/api/src/routes/status_pages.ts index b8b3121..b01ebf1 100644 --- a/apps/api/src/routes/status_pages.ts +++ b/apps/api/src/routes/status_pages.ts @@ -39,7 +39,7 @@ const StatusPageBody = t.Object({ }))), }); -// Strip @import and expression() from custom CSS — basic sanity, not a full +// Strip @import and expression() from custom CSS - basic sanity, not a full // parser. The CSS still runs in the visitor's browser; this just blocks the // most common smuggling vectors. function sanitizeCss(css: string | null | undefined): string | null { @@ -63,7 +63,7 @@ async function replaceGroupsAndMonitors( await sql`DELETE FROM status_page_groups WHERE status_page_id = ${pageId}`; } // Single bulk INSERT instead of one round-trip per group. The RETURNING set - // comes back in INSERT order, which equals the array order — that lets us + // comes back in INSERT order, which equals the array order - that lets us // map index → id without a follow-up SELECT. Mirrors the bulk insert pattern // used by the monitors block right below. const groupIds: string[] = []; diff --git a/apps/api/src/utils/ssrf.ts b/apps/api/src/utils/ssrf.ts index f223dd7..234a867 100644 --- a/apps/api/src/utils/ssrf.ts +++ b/apps/api/src/utils/ssrf.ts @@ -21,7 +21,7 @@ function isPrivateIP(ip: string): boolean { if (second >= 16 && second <= 31) return true; } - // IPv6 — normalize: strip zone ID (%eth0) and lowercase + // IPv6 - normalize: strip zone ID (%eth0) and lowercase const ip6 = ip.replace(/%.*$/, "").toLowerCase(); if (ip6 === "::1" || ip6 === "::") return true; if (ip6.startsWith("fe80")) return true; // fe80::/10 link-local @@ -29,7 +29,7 @@ function isPrivateIP(ip: string): boolean { if (ip6.startsWith("fd00:ec2::")) return true; // AWS EC2 metadata IPv6 if (ip6 === "::ffff:127.0.0.1") return true; if (ip6.startsWith("::ffff:")) { - // IPv4-mapped IPv6 — extract the IPv4 part and re-check + // IPv4-mapped IPv6 - extract the IPv4 part and re-check const v4 = ip6.slice(7); return isPrivateIP(v4); } @@ -55,7 +55,7 @@ export async function validateMonitorUrl(url: string): Promise { } if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { - return `Blocked scheme: ${parsed.protocol} — only http: and https: are allowed`; + return `Blocked scheme: ${parsed.protocol} - only http: and https: are allowed`; } const hostname = parsed.hostname.toLowerCase(); diff --git a/apps/pay/src/monitor.test.ts b/apps/pay/src/monitor.test.ts index aaaf0f2..6942b05 100644 --- a/apps/pay/src/monitor.test.ts +++ b/apps/pay/src/monitor.test.ts @@ -29,7 +29,7 @@ describe("insertIntoStack", () => { .toEqual([{ plan: "pro", remaining_days: 50 }]); }); - test("merges same plan — null wins (lifetime)", () => { + test("merges same plan - null wins (lifetime)", () => { const stack = [{ plan: "lifetime", remaining_days: null }]; expect(insertIntoStack(stack, { plan: "lifetime", remaining_days: null })) .toEqual([{ plan: "lifetime", remaining_days: null }]); @@ -92,7 +92,7 @@ describe("computeApplyPlan", () => { expect(result.plan_stack).toEqual([{ plan: "lifetime", remaining_days: null }]); }); - test("pro4x (15d left) buys lifetime — goes to stack", () => { + test("pro4x (15d left) buys lifetime - goes to stack", () => { const acc = { plan: "pro4x", plan_expires_at: daysFromNow(15), plan_stack: [] }; const result = computeApplyPlan(acc, { plan: "lifetime", months: null }, now); expect(result.plan).toBe("pro4x"); // stays active (higher tier) @@ -121,7 +121,7 @@ describe("computeApplyPlan", () => { expect(result.plan_stack).toEqual([]); }); - test("free with existing stack — preserves stack", () => { + test("free with existing stack - preserves stack", () => { const acc = { plan: "free", plan_expires_at: null, plan_stack: [{ plan: "lifetime", remaining_days: null }] }; const result = computeApplyPlan(acc, { plan: "pro", months: 1 }, now); expect(result.plan).toBe("pro"); diff --git a/apps/pay/src/monitor.ts b/apps/pay/src/monitor.ts index fed6eea..a5baeaa 100644 --- a/apps/pay/src/monitor.ts +++ b/apps/pay/src/monitor.ts @@ -33,7 +33,7 @@ async function refreshMaps() { } async function recordTx(paymentId: number, address: string, txid: string, amount: number, confirmed: boolean) { - // Verify the payment exists and the address matches — prevents stale in-memory state + // Verify the payment exists and the address matches - prevents stale in-memory state // from attributing transactions to the wrong payment const [payment] = await sql` SELECT id FROM payments WHERE id = ${paymentId} AND address = ${address} diff --git a/apps/pay/src/receipt.ts b/apps/pay/src/receipt.ts index f9c0658..0487892 100644 --- a/apps/pay/src/receipt.ts +++ b/apps/pay/src/receipt.ts @@ -16,7 +16,7 @@ export async function generateReceipt(paymentId: number): Promise { const paidDate = payment.paid_at ? new Date(payment.paid_at).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" }) - : "—"; + : "-"; const createdDate = new Date(payment.created_at).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" }); const planNames: Record = { pro: "Pro", pro2x: "Pro 2x", pro4x: "Pro 4x", lifetime: "Lifetime" }; const planName = planNames[payment.plan] || payment.plan; diff --git a/apps/status/src/auth.ts b/apps/status/src/auth.ts index 3c2d737..9c18855 100644 --- a/apps/status/src/auth.ts +++ b/apps/status/src/auth.ts @@ -1,7 +1,7 @@ // Password gate for protected status pages. We sign a short-lived cookie with // the page id + a tag derived from the current password hash + an expiry, so // a successful password unlock survives across page loads without us having -// to hit Postgres on every request — and so changing the page password +// to hit Postgres on every request - and so changing the page password // invalidates every cookie issued under the old password. // // Cookie format: ... diff --git a/apps/status/src/cache.ts b/apps/status/src/cache.ts index 8103f05..96843a5 100644 --- a/apps/status/src/cache.ts +++ b/apps/status/src/cache.ts @@ -1,7 +1,7 @@ // Tiny in-memory TTL cache keyed by string. Status pages serve the same payload // to many visitors during an outage; we don't want every page hit to fan out to // Postgres. The cache is per-process; behind a load balancer each replica fills -// independently, which is fine — short TTLs converge quickly. +// independently, which is fine - short TTLs converge quickly. interface Entry { value: T; expires: number } diff --git a/apps/status/src/data.ts b/apps/status/src/data.ts index 869ea6d..f6009c9 100644 --- a/apps/status/src/data.ts +++ b/apps/status/src/data.ts @@ -1,5 +1,5 @@ // Loads the read-only data needed to render a public status page. NEVER reads -// the raw `pings` table — uses `monitor_region_state` for current state and +// the raw `pings` table - uses `monitor_region_state` for current state and // `monitor_uptime_rollup` for historical uptime windows. import sql from "./db"; @@ -46,12 +46,12 @@ export interface MonitorRow { // etc.) must never leak to anonymous visitors via the JSON endpoint. // Group correlator. Emitted as the matching group's `position` index // (0-based string), NOT the underlying UUID, so the JSON doesn't leak - // internal IDs. The HTML render works the same either way — it just + // internal IDs. The HTML render works the same either way - it just // looks up groups by this token. group_id: string | null; position: number; display_mode: "compact" | "expanded"; // resolved (per-monitor override → page default → 'expanded') - // 'paused' means the monitor was disabled in the dashboard — the runner has + // 'paused' means the monitor was disabled in the dashboard - the runner has // stopped checking it, and the public page should treat it as planned // maintenance rather than an outage. current_state: "up" | "down" | "unknown" | "paused"; @@ -64,7 +64,7 @@ export interface MonitorRow { } // Multi-window uptime (24h / 7d / 30d / 90d) is now derived from the same -// rollup row set that loadMonitors pulls for the bar chart — see the in-JS +// rollup row set that loadMonitors pulls for the bar chart - see the in-JS // aggregation pass below. This used to be a second SQL round-trip running // four FILTER aggregates that redid arithmetic the raw bucket rows already // contained. @@ -116,9 +116,9 @@ export async function loadMonitors( // Step 1: page → monitors with display overrides + group + position. Pull // m.enabled too so we can render disabled monitors as "Maintenance" on the // public page (the runner stops checking them when disabled, so their - // region_states would otherwise drift to a stale "up" — visitors should + // region_states would otherwise drift to a stale "up" - visitors should // see this as planned downtime, not phantom uptime). - // Deliberately do NOT select m.url — see the MonitorRow comment for why the + // Deliberately do NOT select m.url - see the MonitorRow comment for why the // raw target URL must never reach the public payload. const monitorRows = await sql` SELECT @@ -160,7 +160,7 @@ export async function loadMonitors( // // Union of all of those is "hourly back N hours OR daily back N days" with // N chosen to cover whichever consumer needs the widest window. The rows - // are then partitioned by purpose entirely in JS — no second round-trip, + // are then partitioned by purpose entirely in JS - no second round-trip, // no duplicate FILTER aggregates inside Postgres. const bucket: BucketType = barFrequency; const count = Math.max(1, Math.min(180, barCount)); @@ -270,7 +270,7 @@ export async function loadMonitors( const mid = r.monitor_id; const bt: BucketType = r.bucket_type; - // Bar chart accumulators — only rows matching the configured bar frequency. + // Bar chart accumulators - only rows matching the configured bar frequency. if (bt === bucket) { if (!barIndexed[mid]) barIndexed[mid] = {}; const slot = barIndexed[mid]![startIso] ?? { total: 0, up: 0 }; @@ -292,7 +292,7 @@ export async function loadMonitors( } // Multi-window uptime accumulators. 24h uses hourly buckets; 7d/30d/90d - // use daily buckets — same as the old loadMultiWindowUptime SQL did. + // use daily buckets - same as the old loadMultiWindowUptime SQL did. // Strict `<` to match the old SQL's `bucket_start > now() - interval`. const wt = initWindowTotals(mid); if (bt === "hourly" && nowMs - startMs < ms24h) { @@ -319,7 +319,7 @@ export async function loadMonitors( // Sort the latency sparkline rows by ts ASC per monitor (the unified query // sorts by bucket_type then region then bucket_start, so the per-monitor // hourly subset is already ordered within a region but interleaved across - // regions — this normalises it the same way the old separate query did). + // regions - this normalises it the same way the old separate query did). for (const mid of Object.keys(latByMonitor)) { latByMonitor[mid]!.sort((a, b) => a.ts.localeCompare(b.ts)); } @@ -372,7 +372,7 @@ export async function loadMonitors( } // Multi-window uptime is a straight read from the windowTotals accumulator. - // We deliberately do NOT round to 2 decimals here — the formatter on the + // We deliberately do NOT round to 2 decimals here - the formatter on the // public page truncates (not rounds) to 2 decimals so a value like 99.9999% // doesn't visually round up to "100.00%". Pre-rounding here would erase that // information before the formatter ever sees it. @@ -396,7 +396,7 @@ export async function loadMonitors( const anyUp = region_states.some((s) => s.state === "up"); current_state = anyDown ? "down" : anyUp ? "up" : "unknown"; } - // A disabled monitor is in operator-declared maintenance — runner has + // A disabled monitor is in operator-declared maintenance - runner has // stopped checking it. Override whatever the last region state was so the // public page reads "Maintenance" instead of a stale "Operational". if (m.enabled === false) current_state = "paused"; @@ -405,7 +405,7 @@ export async function loadMonitors( if (buckets.length > 0) { const tot = buckets.reduce((a, b) => a + b.total, 0); const upT = buckets.reduce((a, b) => a + b.up, 0); - // Full precision — the display layer truncates (not rounds) to 2 decimals + // Full precision - the display layer truncates (not rounds) to 2 decimals // so any downtime, however small, never visually rounds up to 100%. uptime_pct = tot > 0 ? (100 * upT / tot) : null; } @@ -487,7 +487,7 @@ export interface MonitorDetailPayload { export async function loadMonitorDetail(slug: string, monitorId: string, window?: Window): Promise { const page = await loadStatusPage(slug); if (!page) return null; - // Existence check only — confirm the monitor is actually attached to this + // Existence check only - confirm the monitor is actually attached to this // page. The bulk loader below produces the full payload; this query exists // purely so we can return null on a wrong slug/monitor combo without firing // the bigger query at all. @@ -499,7 +499,7 @@ export async function loadMonitorDetail(slug: string, monitorId: string, window? if (!link) return null; const win = (window ?? page.default_window) as Window; - // Reuse the bulk loader with a single-monitor list — keeps the bucket/state + // 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 // position-as-string token), matching what /:slug.json emits. @@ -556,10 +556,10 @@ export async function loadMonitorDetail(slug: string, monitorId: string, window? // The shape we actually expose to anonymous visitors. Computed by stripping // internal IDs and any field a public consumer doesn't need from the row -// types — see redactPageForPublic / redactGroupsAndMonitors below. +// types - see redactPageForPublic / redactGroupsAndMonitors below. // // custom_css and analytics_html are kept here even though they're noisy to -// JSON consumers, because the HTML render reads from this same object — and +// JSON consumers, because the HTML render reads from this same object - and // they're already publicly visible in the rendered HTML, so dropping them // from JSON wouldn't actually add any privacy. export interface PublicPageView { @@ -626,7 +626,7 @@ function redactPageForPublic(p: StatusPageRow): PublicPageView { // Replace each group's UUID with its position-as-string. Monitors carry the // same token in their group_id field, so the consumer can still join them -// — they just see opaque "0", "1", "2" tokens instead of internal UUIDs. +// - they just see opaque "0", "1", "2" tokens instead of internal UUIDs. function redactGroupsAndMonitors( groups: GroupRow[], monitors: MonitorRow[], diff --git a/apps/status/src/db.ts b/apps/status/src/db.ts index c73d70d..d1ab222 100644 --- a/apps/status/src/db.ts +++ b/apps/status/src/db.ts @@ -1,4 +1,4 @@ -// Read-only Postgres client. The status service does NOT run migrations — +// Read-only Postgres client. The status service does NOT run migrations - // schema is owned by apps/api. This file just opens a connection. import postgres from "postgres"; diff --git a/apps/status/src/index.ts b/apps/status/src/index.ts index e482e51..dae32ae 100644 --- a/apps/status/src/index.ts +++ b/apps/status/src/index.ts @@ -38,7 +38,7 @@ function clientIp(req: Request): string { } // 404s must NOT be cached by browsers or Cloudflare. The same URL frequently -// flips between "200 with data" and "404 not-found" — for example when an +// flips between "200 with data" and "404 not-found" - for example when an // operator adds a password to a previously-public page, or when a slug // changes, or when a monitor is removed. If Cloudflare cached a 404 (default // behaviour for unspecified Cache-Control on 404 responses) the operator @@ -81,7 +81,7 @@ function isAuthorised(page: { id: string; password_hash: string | null }, req: R if (!page.password_hash) return true; // Pass the current password_hash so verifyAuthCookie can derive the // expected pwTag and reject any cookie that was issued under a previous - // password — i.e. rotating the password evicts every existing session. + // password - i.e. rotating the password evicts every existing session. return verifyAuthCookie(req.headers.get("cookie"), page.id, page.password_hash); } @@ -95,7 +95,7 @@ function splitSlugAndFormat(raw: string): { slug: string; format: "html" | "json } async function renderHtml(slug: string, request: Request): Promise { - // Page row is fetched fresh on every request — never cached. The page row + // Page row is fetched fresh on every request - never cached. The page row // carries the live password_hash + index_search + display config; an // operator changing any of those in the dashboard must take effect // immediately, not after a TTL window. The single PK lookup is sub-ms, @@ -103,7 +103,7 @@ async function renderHtml(slug: string, request: Request): Promise { const page = await loadStatusPage(slug); if (!page) return notFound(); if (!isAuthorised(page, request)) { - // Do NOT pass page.title to the password template — that would let any + // Do NOT pass page.title to the password template - that would let any // OSINT scraper iterating slugs harvest the human-readable name of every // private page without ever authenticating. Slug is fine: it's already // in the URL the visitor typed. @@ -115,7 +115,7 @@ async function renderHtml(slug: string, request: Request): Promise { const payload = await cached(`payload:${slug}`, 15, () => loadPagePayload(slug)); if (!payload) return notFound(); const html = eta.render("page", { ...payload, expandJsHash, appCssHash }); - // Password-protected pages MUST be private — never let an edge cache or + // Password-protected pages MUST be private - never let an edge cache or // shared proxy hold a copy that some other visitor could pull. Public // pages keep the 15s shared cache for performance under viral hits. const cacheControl = page.password_hash @@ -146,7 +146,7 @@ async function renderJson(slug: string, request: Request, win?: Window): Promise const cacheKey = `payload:${slug}:${win ?? page.default_window}`; const payload = await cached(cacheKey, 15, () => loadPagePayload(slug, win)); if (!payload) return jsonNotFound(); - // Password-protected JSON must be private — same reasoning as renderHtml. + // Password-protected JSON must be private - same reasoning as renderHtml. const cacheControl = page.password_hash ? "private, no-store, must-revalidate" : "public, max-age=15, s-maxage=15"; @@ -182,11 +182,11 @@ async function renderRssResp(slug: string, request: Request): Promise } const app = new Elysia() - // No status page lives at the root — show the same 404 visitors get for any + // No status page lives at the root - show the same 404 visitors get for any // unknown slug, so a stray hit on the apex doesn't leak service identity. .get("/", () => notFound()) - // Static expand.js — cached aggressively, hash-busted via query string. + // Static expand.js - cached aggressively, hash-busted via query string. .get("/_static/expand.js", () => new Response(Bun.file(expandJsPath), { headers: { "content-type": "application/javascript; charset=utf-8", @@ -194,7 +194,7 @@ const app = new Elysia() }, })) - // Static app.css — same caching contract as expand.js. The query string in + // Static app.css - same caching contract as expand.js. The query string in // the tag is the file's MD5 hash, so deploys propagate immediately // even though the asset itself is marked immutable for a year. .get("/_static/app.css", () => new Response(Bun.file(appCssPath), { @@ -204,7 +204,7 @@ const app = new Elysia() }, })) - // Single public route — dispatches HTML / JSON / RSS by extension on the slug. + // Single public route - dispatches HTML / JSON / RSS by extension on the slug. .get("/:slug", async ({ params, request, query }) => { const { slug, format } = splitSlugAndFormat(params.slug); if (!allow(slug, clientIp(request))) return rateLimited(); @@ -214,7 +214,7 @@ const app = new Elysia() }) // Public SVG badge. Password-protected pages 404 here so an unauthenticated - // shields-style embed can't reveal a private page's current state — and + // shields-style embed can't reveal a private page's current state - and // crucially can't even confirm whether a private slug exists, since the // 404 is identical to a totally bogus slug. .get("/:slug/badge.svg", async ({ params, request }) => { @@ -240,7 +240,7 @@ const app = new Elysia() // Per-monitor detail JSON for the click-to-expand UI in compact mode. // Path is /:slug/monitor/:idWithExt where idWithExt is e.g. "abc123.json". - // We strip the .json suffix in the handler — same trick as the slug route to + // We strip the .json suffix in the handler - same trick as the slug route to // dodge memoirist's "two params at the same position" rule. .get("/:slug/monitor/:idWithExt", async ({ params, request, query }) => { if (!allow(params.slug, clientIp(request))) return rateLimited(); @@ -320,8 +320,8 @@ const app = new Elysia() const port = Number(process.env.STATUS_PORT ?? 3003); const server = Bun.serve({ port, - // Wrap app.handle in a try/catch so any unexpected throw — Postgres - // connection blip, template render error, missing env var, etc. — turns + // Wrap app.handle in a try/catch so any unexpected throw - Postgres + // connection blip, template render error, missing env var, etc. - turns // into a generic 500 with an opaque body. Without this wrapper Bun's // default error path may include framework details, file paths, or stack // traces in the response, which would leak internal layout to anyone who diff --git a/apps/status/src/rate-limit.ts b/apps/status/src/rate-limit.ts index 6b21534..413d9c2 100644 --- a/apps/status/src/rate-limit.ts +++ b/apps/status/src/rate-limit.ts @@ -1,6 +1,6 @@ // Per-(slug, IP) token bucket. 30 requests in a 10s window. Cheap, in-memory, // resets on process restart. Behind a load balancer each replica enforces its -// own bucket — that's fine, the goal is "stop a hostile script from melting one +// own bucket - that's fine, the goal is "stop a hostile script from melting one // box", not perfect distributed accounting. interface Bucket { tokens: number; refillAt: number } diff --git a/apps/status/src/render/rss.ts b/apps/status/src/render/rss.ts index 5cd7a56..a449fd3 100644 --- a/apps/status/src/render/rss.ts +++ b/apps/status/src/render/rss.ts @@ -32,7 +32,7 @@ export async function renderRss(page: StatusPageRow, baseUrl: string): Promise block AFTER this + not a build artifact) - kept in a separate