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.