From d77679a849193166391658cf99be524823692f03 Mon Sep 17 00:00:00 2001 From: VPS 4 Builder Date: Wed, 17 Jun 2026 12:58:48 +0200 Subject: [PATCH] =?UTF-8?q?feat(api):=20GET=20/api/health=20=E2=80=94=20st?= =?UTF-8?q?atus=20do=20backend=20+=20banco=20+=20cache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Público, sem auth. Checa Postgres (crítico → HTTP 503 se down) e Dragonfly/Redis (opcional → "degraded" mas 200; "disabled" se cache off). Inclui version/commit/ environment (de BUILD_INFO) e uptime_s. Sem vazar mensagens de erro. Co-Authored-By: Claude Opus 4.8 --- backend/server.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/backend/server.js b/backend/server.js index ff8fb82..c6b9773 100644 --- a/backend/server.js +++ b/backend/server.js @@ -181,6 +181,41 @@ const BUILD_INFO = { }; app.get('/api/version', (req, res) => res.json(BUILD_INFO)); +// Health check (público, sem auth) — status do backend + dependências. +// Banco é crítico (down => HTTP 503); cache é opcional (down => "degraded", mas 200). +app.get('/api/health', async (req, res) => { + const checks = {}; + try { + const t = Date.now(); + await pool.query('SELECT 1'); + checks.database = { status: 'ok', latency_ms: Date.now() - t }; + } catch { + checks.database = { status: 'down' }; + } + try { + if (redis) { + const t = Date.now(); + await redis.ping(); + checks.cache = { status: 'ok', latency_ms: Date.now() - t }; + } else { + checks.cache = { status: 'disabled' }; + } + } catch { + checks.cache = { status: 'down' }; + } + const dbOk = checks.database.status === 'ok'; + const cacheDegraded = checks.cache.status === 'down'; + const status = !dbOk ? 'down' : (cacheDegraded ? 'degraded' : 'ok'); + res.status(dbOk ? 200 : 503).json({ + status, + version: BUILD_INFO.version, + commit: BUILD_INFO.commit, + environment: BUILD_INFO.environment, + uptime_s: Math.round(process.uptime()), + checks, + }); +}); + // ============================================================================= // SECURITY MIDDLEWARE: Tenant Guard // =============================================================================