From 82c7bdd1966c7620dc642000202c7bd117fe181f Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 29 Sep 2026 05:58:36 +0000 Subject: [PATCH] Sync source readiness endpoint --- src/index.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/index.ts b/src/index.ts index 21dd21d..ba63447 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,37 @@ app.get("/health", async (_req, res) => { } }); +app.get("/ready", async (_req, res) => { + try { + const result = await pool.query( + `SELECT s.id, s.name, s.last_synced_at, s.last_error, + COUNT(sig.id)::int AS signal_count + FROM sources s + LEFT JOIN signals sig ON sig.source_id=s.id + GROUP BY s.id,s.name,s.last_synced_at,s.last_error + ORDER BY s.id` + ); + const missing = result.rows + .filter((row: any) => Number(row.signal_count) < 1) + .map((row: any) => row.id); + const errored = result.rows + .filter((row: any) => row.last_error) + .map((row: any) => row.id); + + if (missing.length || errored.length) { + return res.status(503).json({ + ok: false, + missing_sources: missing, + errored_sources: errored, + sources: result.rows + }); + } + return res.json({ ok: true, sources: result.rows }); + } catch (error) { + return res.status(503).json({ ok: false, error: error instanceof Error ? error.message : String(error) }); + } +}); + app.get("/.well-known/oauth-protected-resource", (req, res) => res.json(protectedResourceMetadata(req))); app.get("/.well-known/oauth-protected-resource/api/mcp", (req, res) => res.json(protectedResourceMetadata(req)));