Repository navigation
Add a machine-readable health/status contract so monitoring tools can act without screen-grazing text #288
Description
Problem
src/health/health.service.ts returns HealthResponseDto from three endpoints — /health/live (line 25), /health/ready (42), /health/startup (70) — with status, timestamp, uptime, and a components map of ComponentStatusDto. The implementation is careful: it checks the database and Redis in parallel (Promise.all, lines 36-39), honours HEALTH_CHECK_TIMEOUT_MS (22-24), and treats Redis as @Optional().
The gap is the vocabulary. What values can status take? Is it a string, or an enum? Is the whole components map guaranteed present, or per-probe? Is a failing component distinguishable from an absent one? A monitoring integration cannot reliably branch on any of that, so in practice operators read the raw JSON to work out whether the service is degraded or down.
docs/kubernetes-health-probes.md exists and presumably documents the probe contract — check it against the DTO, since drift here is likely.
Suggested Direction
- Document the status vocabulary explicitly as an enum in the DTO:
up/degraded/down/unknown.@nestjs/terminusis already a dependency and has a well-established health-indicator vocabulary to align with. - Make the contract explicit in the DTO —
@ApiPropertywithenumandexampleon every field, so the generated OpenAPI spec and SDKs carry the vocabulary rather than leaving consumers to infer it. - Document the difference between the three probes in
docs/kubernetes-health-probes.md:live(process up),ready(can serve traffic),startup(initialised). Getting these wrong is a classic source of restart loops. - Standardise the HTTP status mapping. Readiness should return
503when a required dependency is down so orchestrators act without parsing the body;200withstatus: "down"in the body is easy to ignore. - Ensure every response has the same shape, including on failure, so a client parses one structure.
Constraints
- Liveness must not depend on external services, or a database blip restarts every pod. Check that
getLiveness()stays cheap — it currently does (lines 27-36), which is correct. - Keep
HEALTH_CHECK_TIMEOUT_MSconfigurable and respect it; a probe that hangs is worse than one that fails. - Do not leak internal hostnames, connection strings, or version details in a publicly reachable health endpoint.
src/health/health.controller.spec.tsandhealth.service.spec.tsexist and must keep passing.
Acceptance Criteria
- Status values are a documented enum in
ComponentStatusDto/HealthResponseDto. - Every field carries
@ApiPropertywith enum/example metadata. -
/health/live,/health/ready, and/health/startupare documented with their distinct purposes. - A failing required dependency yields
503from/health/ready. - All three responses share one shape, including on failure.
- No internal hostnames or credentials appear in any health response.
-
docs/kubernetes-health-probes.mdmatches the implementation.
Activity
rupesh-kumar-sah commentedon Oct 9, 2026
I would like to tackle this issue. Using React 18/19, here is my proposed roadmap:
health.service.spec.ts.Please assign this issue to me. I will deliver a clean, well-tested, and production-ready PR promptly!
grantfox-oss commentedon Oct 10, 2026
🎉 This issue has been marked as completed on GrantFox!
@syntaxsuuvam-spec's PR #298 was approved and merged by @memplethee-lab.
🏆 @syntaxsuuvam-spec: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (70 total points). Track your full progress on GrantFox.
👏 Great work, @syntaxsuuvam-spec! Keep contributing to SourceXXL.