feat(health): add consistent /health and /auth/health endpoints to provider API#2579
feat(health): add consistent /health and /auth/health endpoints to provider API#2579goastler wants to merge 2 commits into
Conversation
… frictionless refactor (#2576) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ovider API Adds HealthApiPaths enum, HealthResponse, and AuthHealthResponse types to @prosopo/types. Implements GET /health (public) and GET /auth/health (JWT auth) on the Provider API for consistent service health checks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds standardized health-check endpoints to the Provider API and corresponding shared path/response types in @prosopo/types, enabling both a public liveness probe and an authenticated, more detailed health response.
Changes:
- Added
HealthApiPathsplusHealthResponse/AuthHealthResponseschemas & types in@prosopo/types. - Implemented public
GET /healthreturning{ alive: true, timestamp }. - Implemented authenticated
GET /auth/healthreturning health +{ version, uptimeSeconds, name }, and wired it into the Provider API.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/types/src/provider/api.ts | Introduces shared health endpoint paths and typed response schemas for provider health endpoints. |
| packages/provider/src/api/startProviderApi.ts | Wires auth middleware + new authenticated health router into the provider API app. |
| packages/provider/src/api/public.ts | Adds the new public /health endpoint to the existing public router. |
| packages/provider/src/api/authHealth.ts | Adds a new router implementing the authenticated /auth/health endpoint. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| router.get(HealthApiPaths.Health, (req, res) => { | ||
| const response: HealthResponse = { | ||
| alive: true, | ||
| timestamp: new Date().toISOString(), | ||
| }; | ||
| res.json(response); | ||
| }); |
| export function authHealthRouter(env: ProviderEnvironment): Router { | ||
| const router = express.Router(); | ||
|
|
||
| router.get(HealthApiPaths.AuthHealth, (req, res) => { | ||
| const response: AuthHealthResponse = { | ||
| alive: true, | ||
| timestamp: new Date().toISOString(), | ||
| version, | ||
| uptimeSeconds: process.uptime(), | ||
| name: "provider", | ||
| }; | ||
| res.json(response); | ||
| }); |
| apiApp.use("/auth", authMiddleware(env.pair, env.authAccount)); | ||
| apiApp.use(authHealthRouter(env)); |
forgetso
left a comment
There was a problem hiding this comment.
Review: /health & /auth/health on Provider API
Companion to prosopo/captcha-private#3372 — leaving the bulk of the cross-service review there.
Provider-specific concerns
-
Overlap with
/healthz. After this merges the provider exposes bothPublicApiPaths.Healthz(/healthz→ plainOK) andHealthApiPaths.Health(/health→ JSON). These do the same job. Recommend droppingPublicApiPaths.Healthzand migrating these call sites:docker/docker-compose.provider.yml:28,63— Docker healthchecks for provider1/provider2 (curl/healthz)demos/cypress-shared/scripts/wait-for-services.ts:23architecture.mmd:34(theHealthz[\"GET /healthz\"]node)- In captcha-private:
deploy-production.sh:48,.github/workflows/deploy-procaptcha-bundle.yml:179-182,packages/infrastructure/ansible/playbooks/provider.yml:196,packages/e2e/src/utils/start-services.ts:55,packages/e2e/src/utils/restart-services.ts:47,packages/e2e/E2E_TESTING_GUIDE.md
The new JSON response would need a string compare in the docker/curl healthchecks (e.g.
curl --fail localhost:9229/health | grep -q '\"alive\":true'), or just rely on the 200 status. -
apiApp.use(\"/auth\", authMiddleware(...))atstartProviderApi.tsreserves the entire/auth/*prefix for JWT-authenticated routes. That's a sensible convention but worth calling out explicitly so future contributors don't accidentally mount a public route there. Consider a comment, or splitting into/auth/healthmount instead of a path-prefixuse. -
Type-only import ordering —
import { authHealthRouter } from \"./authHealth.js\";instartProviderApi.tsis inserted out of alphabetical order relative to neighbouring imports. Biome will likely flag it. -
envparameter is unused inauthHealthRouter(env: ProviderEnvironment)— drop the parameter unless something concrete is planned (e.g. surfacing DB/Redis readiness inAuthHealthResponse, which would actually be more useful thanprocess.uptime()for monitoring). -
No tests for the new endpoints — a small fixture asserting
200for/healthand200/401for/auth/healthwould be valuable. -
Auth scheme consistency note — in the captcha-private PR,
monitoring's/auth/healthuses a static bearer token (HEALTH_API_TOKEN) instead of JWT. Worth aligning all three services on the same auth method (JWT recommended) so a single probe token works platform-wide.
Summary
HealthApiPathsenum,HealthResponse, andAuthHealthResponsetypes to@prosopo/typesGET /health(public, returns{ alive: true, timestamp }) on the Provider APIGET /auth/health(JWT auth required, returns health + version, uptime, service name) on the Provider APIRelated to prosopo/captcha-private#1469