Skip to content

feat: add /api/health/dependencies probes#455

Merged
greatest0fallt1me merged 1 commit into
Predictify-org:mainfrom
ValJnr-dev1:task/health-deps
Jul 25, 2026
Merged

feat: add /api/health/dependencies probes#455
greatest0fallt1me merged 1 commit into
Predictify-org:mainfrom
ValJnr-dev1:task/health-deps

Conversation

@ValJnr-dev1

Copy link
Copy Markdown
Contributor

Summary

Implements #301 — dependency health probes at /api/health/dependencies.


What was added

GET /api/health/dependencies

Probes all four external dependencies in parallel and returns a per-system snapshot.

HTTP Status Meaning
200 All four probes pass (ok)
207 At least one probe is degraded, none down
503 At least one probe is down

Response shape:

{
  "status": "ok",
  "correlationId": "<uuid>",
  "checkedAt": "2026-07-24T22:00:00.000Z",
  "dependencies": {
    "postgres":     { "status": "ok", "latencyMs": 3  },
    "sorobanRpc":   { "status": "ok", "latencyMs": 12 },
    "horizon":      { "status": "ok", "latencyMs": 8  },
    "webhookQueue": { "status": "ok", "latencyMs": 1  }
  }
}

Files changed

File Change
src/routes/health/dependencies.ts New — factory createDependenciesRouter({ probeFn })
src/index.ts Mount at /api/health/dependencies
tests/healthDependencies.test.ts New — 25 tests
docs/health-dependencies.md New — API runbook

Design notes

  • Injectable probeFn — all external I/O is encapsulated in the injected function, making the route fully testable without real infrastructure (same pattern as health/ready.ts).
  • Uncached — unlike /healthz/dependencies, this endpoint always runs a fresh probe. Callers that want caching can use getCachedDependencyHealth() directly.
  • No auth — response contains no sensitive data. Production deployments should restrict access at the infra level (VPC/ALB).
  • Structured logging — every request emits a health_dependencies_check_complete pino log line with correlationId, composite status, per-probe status, and elapsed ms.

Test output

PASS tests/healthDependencies.test.ts
  HTTP status codes
    ✓ returns 200 when all dependencies are ok
    ✓ returns 207 when at least one dependency is degraded (none down)
    ✓ returns 207 when all dependencies are degraded
    ✓ returns 503 when any dependency is down
    ✓ returns 503 when multiple dependencies are down
    ✓ returns 503 when a degraded + down mix exists (down wins)
  response body — status field
    ✓ body.status is 'ok' when all pass
    ✓ body.status is 'degraded' when degraded (no down)
    ✓ body.status is 'down' when any probe is down
  response shape
    ✓ includes all required top-level fields
    ✓ dependencies contains all four systems
    ✓ each dependency entry contains status and latencyMs
    ✓ checkedAt is a valid ISO-8601 timestamp
    ✓ includes per-dependency latency values from the probe
    ✓ includes error field when a probe is down
    ✓ does not expose error field when probe is ok
  correlationId
    ✓ echoes the x-correlation-id header when provided
    ✓ generates a UUID when x-correlation-id is not provided
    ✓ generates a UUID when x-correlation-id is an empty string
    ✓ correlationId differs between requests when not supplied
  authentication
    ✓ does not require an Authorization header
    ✓ ignores a supplied Authorization header (does not change the response)
  error handling
    ✓ returns 500 and propagates to errorHandler when probeFn throws
    ✓ calls probeFn exactly once per request
  default router
    ✓ exports a default dependenciesRouter as a valid Express router

Tests: 25 passed, 25 total

Lint: ✅ clean (eslint src/**/*.ts exit 0)

Closes #301

Add GET /api/health/dependencies endpoint.

- src/routes/health/dependencies.ts — factory createDependenciesRouter()
  with injectable ProbeFn for full testability; mirrors the pattern of
  health/ready.ts
- 200/207/503 driven by composite status (ok/degraded/down)
- x-correlation-id header echoed; UUID generated when absent
- Structured pino logging on every request
- src/index.ts — mounts the router at /api/health/dependencies
- tests/healthDependencies.test.ts — 25 tests: status codes (6),
  response body shape (7), correlationId (4), auth (2), error
  handling (2), default export (1)
- docs/health-dependencies.md — full API runbook

Lint: clean  Tests: 25 passed, 25 total

Closes Predictify-org#301
@drips-wave

drips-wave Bot commented Jul 24, 2026

Copy link
Copy Markdown

@ValJnr-dev1 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@greatest0fallt1me
greatest0fallt1me merged commit 91f7de6 into Predictify-org:main Jul 25, 2026
@greatest0fallt1me

Copy link
Copy Markdown
Contributor

Perfect. LGTM ✨ merging now.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add /api/health/dependencies probes

2 participants