// The read-only, unauthenticated projection of published incidents — // consumed by goonk's /failures page at build and runtime. Never touches // an incident until it has been explicitly published (see // routes/incidents.mjs's publish/unpublish action); an unpublished // incident is invisible here regardless of how much of it is filled in. import { publicIncident, publicDetail, publicMarkdown } from '../views.mjs'; const jsonHeaders = { 'content-type': 'application/json; charset=utf-8', 'access-control-allow-origin': '*', 'cache-control': 'public, max-age=60', }; export function createPublicFailuresRoutes(db) { async function handle(req, res, path) { if (req.method !== 'GET') return false; if (path === '/api/v1/public/failures') { const rows = db .prepare("SELECT * FROM incidents WHERE published_at<>'' ORDER BY detected_at DESC") .all(); res.writeHead(200, jsonHeaders).end( JSON.stringify({ schemaVersion: 1, generatedAt: new Date().toISOString(), failures: rows.map(publicIncident), }), ); return true; } const md = path.match(/^\/api\/v1\/public\/failures\/([^/]+)\.md$/); if (md) { const x = db .prepare("SELECT * FROM incidents WHERE public_slug=? AND published_at<>''") .get(decodeURIComponent(md[1])); if (!x) { res.writeHead(404).end('Not found'); return true; } res .writeHead(200, { ...jsonHeaders, 'content-type': 'text/markdown; charset=utf-8' }) .end(publicMarkdown(x)); return true; } const detail = path.match(/^\/api\/v1\/public\/failures\/([^/]+)$/); if (detail) { const x = db .prepare("SELECT * FROM incidents WHERE public_slug=? AND published_at<>''") .get(decodeURIComponent(detail[1])); if (!x) { res .writeHead(404, { 'content-type': 'application/json; charset=utf-8', 'access-control-allow-origin': '*', }) .end('{"error":"not_found"}'); return true; } res .writeHead(200, jsonHeaders) .end(JSON.stringify({ schemaVersion: 1, failure: publicDetail(x) })); return true; } return false; } return { handle }; }