49 lines
1.7 KiB
TypeScript
49 lines
1.7 KiB
TypeScript
import { Elysia, t } from "elysia";
|
|
import { requireAuth } from "./auth";
|
|
import sql from "../db";
|
|
|
|
export const checks = new Elysia()
|
|
// Public-ish: token protected, no user auth
|
|
.post("/checks/ingest", async ({ body, headers, error }) => {
|
|
const token = headers["x-monitor-token"];
|
|
if (token !== process.env.MONITOR_TOKEN) return error(401, { error: "Unauthorized" });
|
|
|
|
await sql`
|
|
INSERT INTO check_results (monitor_id, status_code, latency_ms, up, error, meta)
|
|
VALUES (
|
|
${body.monitor_id},
|
|
${body.status_code ?? null},
|
|
${body.latency_ms ?? null},
|
|
${body.up},
|
|
${body.error ?? null},
|
|
${body.meta ? sql.json(body.meta) : null}
|
|
)
|
|
`;
|
|
return { ok: true };
|
|
}, {
|
|
body: t.Object({
|
|
monitor_id: t.String(),
|
|
status_code: t.Optional(t.Number()),
|
|
latency_ms: t.Optional(t.Number()),
|
|
up: t.Boolean(),
|
|
error: t.Optional(t.Nullable(t.String())),
|
|
meta: t.Optional(t.Any()),
|
|
}),
|
|
detail: { summary: "Ingest result (monitor runner)", tags: ["internal"] },
|
|
})
|
|
|
|
// User auth required below
|
|
.use(requireAuth)
|
|
.get("/checks/:monitorId", async ({ accountId, params, query, error }) => {
|
|
const [monitor] = await sql`
|
|
SELECT id FROM monitors WHERE id = ${params.monitorId} AND account_id = ${accountId}
|
|
`;
|
|
if (!monitor) return error(404, { error: "Not found" });
|
|
const limit = Math.min(Number(query.limit ?? 100), 1000);
|
|
return sql`
|
|
SELECT * FROM check_results
|
|
WHERE monitor_id = ${params.monitorId}
|
|
ORDER BY checked_at DESC LIMIT ${limit}
|
|
`;
|
|
}, { detail: { summary: "Get check history", tags: ["checks"] } });
|