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

3.9 KiB

OpenSpec Change: enterprise-server-health-check

  • Change ID: enterprise-server-health-check
  • Package: @suaveplan/health-check
  • Category: server/infra
  • Target path: server/infra/health-check
  • Status: PROPOSED
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/health-check.md

Summary

Deliver @suaveplan/health-check on the genesis branch from scratch at enterprise quality. The package provides a framework-agnostic health check system that exposes /health, /ready, and /live HTTP endpoints following Kubernetes probe conventions. A HealthRegistry holds named HealthCheck functions; an HealthServer runs a lightweight HTTP server returning structured JSON responses. Individual checks can have configurable timeouts, retry counts, and cache TTLs. Genesis adds Zod schemas, @suaveplan/error codes, OTel counters per check result, structured logging, and 100% test coverage via both unit and integration tests.


Current-state audit (genesis)

Does not exist on genesis — fresh build.


Available workspace deps on genesis

Package Role
@suaveplan/error (workspace:^) Typed HEALTH_CHECK.* error codes
@suaveplan/types (workspace:^) LoggerLike, Clock
@suaveplan/logger (workspace:^) Structured logs
zod (catalog:forms) Options validation
@opentelemetry/api (catalog:observability) Counters + histograms
tslib (catalog:build) Runtime helpers

Public API surface

class HealthRegistry {
  register(name: string, check: HealthCheckFn, options?: CheckOptions): void
  unregister(name: string): void
  runAll(): Promise<HealthReport>
  runCheck(name: string): Promise<CheckResult>
}

class HealthServer {
  constructor(registry: HealthRegistry, options?: HealthServerOptions)
  start(): Promise<void>
  stop(): Promise<void>
  address(): { host: string; port: number } | undefined
}

function createHealthRegistry(): HealthRegistry
function createHealthServer(registry: HealthRegistry, options?: HealthServerOptions): HealthServer

type HealthCheckFn = (signal: AbortSignal) => Promise<void>   // throws = unhealthy

interface CheckOptions {
  timeout?: number        // ms, default: 5000
  critical?: boolean      // if true, failure marks overall status 'unhealthy'
  cacheTtlMs?: number     // reuse last result for this duration
}

interface CheckResult {
  name: string
  status: 'healthy' | 'unhealthy' | 'degraded'
  duration: number        // ms
  error?: string
  cachedAt?: number
}

interface HealthReport {
  status: 'healthy' | 'unhealthy' | 'degraded'
  checks: CheckResult[]
  timestamp: number
}

interface HealthServerOptions {
  port?: number          // default: 3001
  host?: string          // default: '0.0.0.0'
  path?: {
    health?: string      // default: '/health'
    ready?: string       // default: '/ready'
    live?: string        // default: '/live'
  }
  logger?: LoggerLike
}

type HealthCheckErrorCode =
  | 'HEALTH_CHECK_TIMEOUT'
  | 'HEALTH_CHECK_NOT_FOUND'
  | 'HEALTH_SERVER_START_FAILED'

function registerHealthCheckErrorCodes(): void

File layout

server/infra/health-check/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    error-codes.ts
    constants/index.ts
    types/
      health-check.types.ts
      health-check.types.md
    registry/
      health-registry/
        health-registry.ts
        health-registry.md
        health-registry.types.ts
        health-registry.test.ts
        index.ts
    server/
      health-server/
        health-server.ts
        health-server.md
        health-server.types.ts
        health-server.test.ts
        index.ts
  tests/
    integration.test.ts

Impact

Downstream: all server packages use @suaveplan/health-check to register their own checks. This is a core infrastructure primitive.

Prerequisites on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/logger.