Files
2026-05-27 23:29:53 +01:00

3.6 KiB

Proposal — Migrate @suaveplan/health-check to genesis

Why

@suaveplan/health-check is the server-tier orchestrator for /health, /ready, and /live endpoints with dependency checks. The upstream package at /mnt/s/web/suaveplan/packages/server/health-check/ predates the genesis enterprise gates: it uses the upstream EventEmitter shape, calls global Date.now()/setTimeout/fetch/node:net directly, has no error-code registry, no OTel self-telemetry, and no Zod boundary validation. This change re-lands the package at packages/observability/monitor/health-check/ (sibling to logger, audit-logging, opentelemetry) at full feature surface with the genesis contract.

What

Land @suaveplan/health-check@0.1.0 with the following feature modules (one per folder, 5-files-per-feature):

  • health-checker/ — HealthChecker orchestrator with EventBus<HealthEventMap> and injectable Clock / TimersLike / LoggerLike
  • http-check/ — createHttpCheck factory with injectable fetchImpl + Clock
  • tcp-check/ — createTcpCheck factory with injectable TcpConnectFn + Clock
  • response-builder/ — ResponseBuilder mapping CheckStatus → HTTP status codes
  • error-codes/ — HEALTH_CHECK_CODES via defineCodes + public-ctor HealthCheckError
  • telemetry/ — OTel meter (health_check_runs_total, health_check_aggregate_status_total, health_check_duration_ms)
  • types/ — shared CheckResult/CheckFn/DependencyCheckConfig/HealthResponse/ReadinessResponse/LivenessResponse/HttpHealthResponse/HttpCheckConfig/TcpCheckConfig/HealthEvent/HealthEventMap

Source mapping

Upstream file Genesis file Notes
src/checker/health-checker.ts src/health-checker/health-checker.ts EventEmitter → EventBus<HealthEventMap>; Clock+TimersLike+LoggerLike injected; Zod-validated options; HealthCheckError on every failure
src/checks/http-check.ts src/http-check/http-check.ts fetchImpl injection replaces global fetch; Zod options
src/checks/tcp-check.ts src/tcp-check/tcp-check.ts TcpConnectFn injection replaces direct node:net.connect; settled-flag guards late events
src/response/response-builder.ts src/response-builder/response-builder.ts Same algorithm, renamed file
src/types/types.ts src/types/types.ts Adds HealthEventMap, TcpConnectFn/TcpSocketLike, HttpCheckConfig.fetchImpl, TcpCheckConfig.connectImpl
src/index.ts src/index.ts Explicit named re-exports only
(none) src/error-codes/error-codes.ts New — required by genesis rule
(none) src/telemetry/telemetry.ts New — required by genesis rule

Deviations from upstream

  1. Upstream uses @suaveplan/events' EventEmitter with variadic tuple payloads. Genesis @suaveplan/events exposes EventBus<TMap> with single-payload emit(type, payload). STATUS_CHANGED therefore emits { previous, current } object instead of two positional args. Exposed as HealthChecker.events.
  2. Upstream calls Date.now() and setTimeout directly. Genesis injects Clock + TimersLike per the universal-tier contract.
  3. Upstream has no error-code registry. Genesis adds HEALTH_CHECK_CODES + public-ctor HealthCheckError.
  4. Upstream HTTP / TCP checks depend on the runtime's global fetch and node:net. Genesis injects them so tests never touch real sockets.
  5. Upstream emits no self-telemetry. Genesis adds a telemetry/ module emitting per-check counters + duration histogram + aggregate-status counter.
  6. Boundary validation: every public option object is now Zod-validated; failures throw HealthCheckError(INVALID_OPTIONS).