Skip to content

feat(health): add multi-service health check endpoint#611

Merged
KanishJebaMathewM merged 5 commits into
KanishJebaMathewM:mainfrom
nyxsky404:feat/580-health-check-endpoint
Jun 18, 2026
Merged

feat(health): add multi-service health check endpoint#611
KanishJebaMathewM merged 5 commits into
KanishJebaMathewM:mainfrom
nyxsky404:feat/580-health-check-endpoint

Conversation

@nyxsky404

@nyxsky404 nyxsky404 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

What

Adds GET /api/health that checks each backend dependency and returns a structured status report.

Response shape

Healthy (HTTP 200):

{
  "status": "ok",
  "services": {
    "supabase": "connected",
    "mongodb": "connected",
    "redis": "connected",
    "firebase": "configured",
    "polygon": "configured"
  },
  "uptime": 1234.5
}

Degraded (HTTP 503) when Supabase or MongoDB fail — Redis, Firebase, and Polygon failures are non-critical.

Service checks

Service Method
Supabase SELECT on profiles table
MongoDB admin().ping()
Redis PING command
Firebase checks if Admin SDK was initialised
Polygon checks if POLYGON_RPC_URL env var is set

Checks are lightweight and run in parallel via Promise.all.

Files changed

  • backend/api/src/routes/healthRoutes.js (new)
  • backend/api/src/index.js — replace static health stub with new router
  • docker-compose.yml — add healthcheck on the api service

Closes #580

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced the main health endpoint (/api/health) to run checks against core backend services in parallel and report overall status as ok or degraded (returning 503 when critical dependencies are unavailable), including uptime.
    • Added/strengthened a liveness endpoint at /api/health/live that always returns 200 with status: ok and uptime.
  • Infrastructure

    • Improved the API container health check to repeatedly probe /api/health/live to better detect availability.

- Create GET /api/health that checks Supabase (SELECT), MongoDB (admin ping),
  Redis (PING command), Firebase (init flag), and Polygon (env var presence)
- Returns HTTP 200 with status "ok" when all critical services are up;
  HTTP 503 with status "degraded" when Supabase or MongoDB fail
- Includes process uptime in every response
- Replace the previous static /api/health stub in index.js with the new router
- Add Docker Compose healthcheck on the api service using the new endpoint

Closes KanishJebaMathewM#580
Copilot AI review requested due to automatic review settings June 17, 2026 14:50
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 768e594b-0c96-4ae8-ac60-127a6372e806

📥 Commits

Reviewing files that changed from the base of the PR and between 2bdec0a and 8effd57.

📒 Files selected for processing (1)
  • backend/api/src/routes/healthRoutes.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/api/src/routes/healthRoutes.js

📝 Walkthrough

Walkthrough

A new healthRoutes.js Express router is introduced with per-service connectivity helpers for Supabase, MongoDB, Redis, Firebase Admin, and Polygon RPC, plus a dedicated liveness probe. The existing inline health handler in index.js is replaced by mounting this router at /api/health. A Docker Compose healthcheck is added to probe the endpoint via wget with fallback to curl.

Changes

Multi-Service Health Check Endpoint

Layer / File(s) Summary
Health route: service checkers and endpoints
backend/api/src/routes/healthRoutes.js
Router with timeout wrapper (withTimeout()) and concurrent connectivity helpers: checkSupabase() queries profiles table, checkMongo() uses admin().ping(), checkRedis() expects PONG. Firebase and Polygon helpers report presence as configured or not_configured. GET / runs checks concurrently within 400ms timeout, builds services map, returns HTTP 503 with degraded if Supabase or MongoDB are failed or not_configured, otherwise HTTP 200 with ok and includes uptime. GET /live liveness route always returns HTTP 200 with { status: 'ok', uptime } independent of dependency checks. Router is the default export.
App mounting and Docker healthcheck
backend/api/src/index.js, docker-compose.yml
Imports healthRoutes and mounts it at /api/health, removing the previous 12-line inline handler. Adds healthcheck to the api service in docker-compose.yml that probes http://localhost:5000/api/health/live using wget with curl fallback, configured with 30s interval, 5s timeout, 5 retries, and 15s start period.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant healthRouter as healthRoutes
  participant Supabase
  participant MongoDB
  participant Redis

  Client->>healthRouter: GET /api/health
  par Concurrent dependency checks
    healthRouter->>Supabase: select from profiles
    healthRouter->>MongoDB: admin().ping()
    healthRouter->>Redis: ping()
  end
  Supabase-->>healthRouter: connected | failed | not_configured
  MongoDB-->>healthRouter: connected | failed | not_configured
  Redis-->>healthRouter: connected | failed | not_configured
  healthRouter-->>Client: 200 ok or 503 degraded with services map and uptime
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 Hop, hop! The services all speak,
Supabase, Mongo — healthy this week!
Redis pings back with a cheerful PONG,
Firebase and Polygon hum along.
One endpoint to rule them all so neat,
Docker says "healthy!" — the check is complete! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(health): add multi-service health check endpoint' clearly summarizes the main change of implementing a comprehensive health check endpoint for monitoring multiple backend services.
Linked Issues check ✅ Passed All core requirements from issue #580 are implemented: the endpoint verifies Supabase, MongoDB, Redis, Firebase, and Polygon connectivity; returns appropriate HTTP status codes (200 for ok, 503 for degraded); includes uptime and services status in responses; requires no authentication; and integrates with Docker via healthcheck configuration.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the health check endpoint specified in issue #580: the new healthRoutes.js file, updates to index.js to register the routes, and docker-compose.yml health check configuration.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

🎉 Thank you for your contribution! Your pull request has been received and will be reviewed shortly.

If you enjoy the project, please consider giving the repository a ⭐. You can also follow my GitHub profile to stay updated on future open-source projects.

Thanks for being part of the community! 🚀

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR introduces a richer /api/health endpoint that reports dependency status and wires it into Docker Compose healthchecks.

Changes:

  • Added a Docker Compose healthcheck for the API service hitting GET /api/health
  • Introduced backend/api/src/routes/healthRoutes.js to check Supabase/Mongo/Redis + configuration flags
  • Replaced the inline /api/health handler in index.js with the new router

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
docker-compose.yml Adds container healthcheck that calls the API health endpoint
backend/api/src/routes/healthRoutes.js New health route that probes backing services and returns a summarized status
backend/api/src/index.js Registers the new health router and removes the old inline handler

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread backend/api/src/routes/healthRoutes.js Outdated
Comment thread backend/api/src/routes/healthRoutes.js Outdated
Comment thread backend/api/src/routes/healthRoutes.js
Comment thread docker-compose.yml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/api/src/routes/healthRoutes.js`:
- Around line 55-59: The Promise.all call that combines checkSupabase(),
checkMongo(), and checkRedis() lacks timeout protection, which means any hung
dependency check can block the entire health endpoint. Wrap each individual
dependency check function (checkSupabase, checkMongo, checkRedis) with an
explicit timeout mechanism that rejects if the check takes longer than a
specified duration (e.g., 100-200ms). Alternatively, wrap the entire Promise.all
with a timeout guard to ensure the health check completes within the 500ms
health probe expectation. Apply the same timeout protection to the duplicate
Promise.all call mentioned at lines 75-79.
- Around line 69-73: The criticalFailed variable currently only checks if
supabaseStatus or mongoStatus equals 'failed', but it should also treat
'not_configured' as a critical condition. Update the criticalFailed condition to
include checks for both 'failed' and 'not_configured' states for both
supabaseStatus and mongoStatus variables so that misconfigured critical
dependencies result in a degraded status and HTTP 503 response instead of HTTP
200.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4eab91a9-fa5e-4400-8602-9bef263199ab

📥 Commits

Reviewing files that changed from the base of the PR and between 1fe31d6 and 1cd787e.

📒 Files selected for processing (3)
  • backend/api/src/index.js
  • backend/api/src/routes/healthRoutes.js
  • docker-compose.yml

Comment thread backend/api/src/routes/healthRoutes.js
Comment thread backend/api/src/routes/healthRoutes.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
backend/api/src/routes/healthRoutes.js (2)

73-74: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Treat not_configured critical dependencies as degraded.

Currently only 'failed' triggers degraded status. If Supabase or MongoDB is 'not_configured', the endpoint returns HTTP 200, which hides critical dependency misconfiguration from readiness checks. This was flagged in a previous review and remains unresolved.

🛡️ Proposed fix to include not_configured
+  const criticalUnhealthy = ['failed', 'not_configured'];
   const criticalFailed =
-    supabaseStatus === 'failed' || mongoStatus === 'failed';
+    criticalUnhealthy.includes(supabaseStatus) ||
+    criticalUnhealthy.includes(mongoStatus);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/api/src/routes/healthRoutes.js` around lines 73 - 74, The
`criticalFailed` variable in the health check route currently only checks if
supabaseStatus or mongoStatus equals 'failed', but it should also treat
'not_configured' as a critical failure condition. Update the condition to
include checks for both 'failed' and 'not_configured' statuses for both Supabase
and MongoDB, so that misconfigured dependencies are properly reported as
degraded instead of returning HTTP 200 and hiding the configuration issue from
readiness checks.

8-15: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clear timeout timer to prevent resource leak.

The setTimeout timer is never cleared when the promise resolves first. While not critical for infrequent health checks, this creates a minor resource leak.

🧹 Proposed fix to clear timer
 function withTimeout(promise) {
+  let timer;
   return Promise.race([
     promise,
     new Promise((_, reject) =>
-      setTimeout(() => reject(new Error('timeout')), CHECK_TIMEOUT_MS)
+      timer = setTimeout(() => reject(new Error('timeout')), CHECK_TIMEOUT_MS)
     ),
-  ]);
+  ]).finally(() => clearTimeout(timer));
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/api/src/routes/healthRoutes.js` around lines 8 - 15, The withTimeout
function creates a setTimeout that is never cleared when the main promise
resolves first, causing a resource leak. Store the timeout ID returned by
setTimeout and use clearTimeout to clear it after the Promise.race completes.
This can be done by adding a .finally() block or by wrapping the entire
Promise.race result to ensure the timer is cleared regardless of which promise
wins the race.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/api/src/routes/healthRoutes.js`:
- Line 6: The CHECK_TIMEOUT_MS constant is set to 3000ms, which exceeds the
performance requirement of 500ms for total health check completion. Reduce the
value of the CHECK_TIMEOUT_MS constant from 3000 to approximately 300-400ms to
ensure individual health checks complete quickly enough that the total endpoint
response remains within the 500ms budget, accounting for parallel execution and
orchestration overhead.

---

Duplicate comments:
In `@backend/api/src/routes/healthRoutes.js`:
- Around line 73-74: The `criticalFailed` variable in the health check route
currently only checks if supabaseStatus or mongoStatus equals 'failed', but it
should also treat 'not_configured' as a critical failure condition. Update the
condition to include checks for both 'failed' and 'not_configured' statuses for
both Supabase and MongoDB, so that misconfigured dependencies are properly
reported as degraded instead of returning HTTP 200 and hiding the configuration
issue from readiness checks.
- Around line 8-15: The withTimeout function creates a setTimeout that is never
cleared when the main promise resolves first, causing a resource leak. Store the
timeout ID returned by setTimeout and use clearTimeout to clear it after the
Promise.race completes. This can be done by adding a .finally() block or by
wrapping the entire Promise.race result to ensure the timer is cleared
regardless of which promise wins the race.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 41570f96-373e-4d3d-a212-e21ac771b9a6

📥 Commits

Reviewing files that changed from the base of the PR and between 1cd787e and ff9dd42.

📒 Files selected for processing (2)
  • backend/api/src/routes/healthRoutes.js
  • docker-compose.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker-compose.yml

Comment thread backend/api/src/routes/healthRoutes.js Outdated
@nyxsky404

Copy link
Copy Markdown
Contributor Author

CI failures: Flutter Customer and Driver checks are pre-existing failures on main itself

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/api/src/routes/healthRoutes.js`:
- Line 6: The CHECK_TIMEOUT_MS constant at line 6 parses the environment
variable without validating the result, which can lead to invalid timeout values
like NaN, negative numbers, or Infinity. After parsing the
HEALTHCHECK_TIMEOUT_MS environment variable with Number(), add validation to
ensure the resulting value is a valid, positive, finite number. If the parsed
value fails validation (is NaN, negative, or not finite), fall back to the
default value of 400. This ensures the timeout configuration is always valid
before being used in health check operations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d4295d89-9f82-4fd2-9d6c-425ac3e3b082

📥 Commits

Reviewing files that changed from the base of the PR and between ff9dd42 and 2bdec0a.

📒 Files selected for processing (1)
  • backend/api/src/routes/healthRoutes.js

Comment thread backend/api/src/routes/healthRoutes.js Outdated
@KanishJebaMathewM KanishJebaMathewM merged commit 122d7d5 into KanishJebaMathewM:main Jun 18, 2026
5 of 7 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🎉 Thank you for your contribution!

Your pull request has been merged successfully. We appreciate your work and look forward to your future contributions. 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

# [INTEGRATION] Implement Multi-Service Health Check Endpoint

3 participants