Skip to content

fix(constructs): emit numeric gRPC health-check status from healthCheckStatus() (SIM-307)#1406

Open
danielpaulus wants to merge 1 commit into
mainfrom
daniel/sim-307-grpc-healthcheck-status-label
Open

fix(constructs): emit numeric gRPC health-check status from healthCheckStatus() (SIM-307)#1406
danielpaulus wants to merge 1 commit into
mainfrom
daniel/sim-307-grpc-healthcheck-status-label

Conversation

@danielpaulus

Copy link
Copy Markdown
Contributor

What & why

Fixes SIM-307. GrpcAssertionBuilder.healthCheckStatus() returned a GeneralAssertionBuilder (free string target), so the CLI's own documented example healthCheckStatus().equals('SERVING') shipped target: "SERVING" to the API. The go-runner evaluates gRPC health status numerically (strconv.Atoi(target)), so "SERVING" returns "Invalid. Target health status is not a number" — the advertised example built a permanently-failing check. Only the webapp normalized the label→number; the CLI/raw-API path shipped a broken check.

Root cause: healthCheckStatus() used a string builder while the sibling statusCode() correctly uses NumericAssertionBuilder.

Changes

  • healthCheckStatus() now returns a dedicated HealthCheckStatusAssertionBuilder exposing only .equals()/.notEquals() (the only comparisons the runner supports for health status), accepting a GrpcHealthStatus label or the raw 0|1|2|3 enum and emitting the numeric wire target. The label→number map (UNKNOWN:0, SERVING:1, NOT_SERVING:2, SERVICE_UNKNOWN:3) mirrors the webapp's grpcHealthStatusTargetByLabel — single source of truth, reused by codegen + validation. The documented .equals('SERVING') example now works and matches what's stored (no IaC drift).
  • Codegen reverse-maps the number→label so an imported check with target:'1' round-trips to healthCheckStatus().equals('SERVING'); unmappable/legacy targets fall back to a raw assertion object literal so generated code always type-checks.
  • Validation flags a GRPC_HEALTHCHECK_STATUS target that isn't 0–3, catching object-literal callers who bypass the builder.

Testing

21 gRPC unit + codegen tests green (all four labels → 0–3, .notEquals, raw-number incl. the falsy 0, codegen round-trip for EQUALS/NOT_EQUALS + object-literal fallback, validation positive/negative). tsc --build clean, lint clean.

Review

Reviewed via a tri-model daniel-review (Codex + Gemini + Claude) — no blockers; the confirmed should-fixes (codegen fallback must emit compilable TS; preserve invalid JS-caller value in the diagnostic) were fixed and re-verified before this PR.

Note

The backend counterpart (rejecting a non-numeric health-status target at the API edge) is monorepo #3044 (SIM-306). This PR fixes the CLI/construct side so the friendly label API works end-to-end.

🤖 Generated with Claude Code

…ckStatus() (SIM-307)

GrpcAssertionBuilder.healthCheckStatus() returned a GeneralAssertionBuilder,
so the CLI's own documented example .equals('SERVING') shipped target
"SERVING" to the API. The go-runner evaluates gRPC health status numerically
(strconv.Atoi), so the label could never pass ("Invalid. Target health status
is not a number") — the advertised example built a permanently-failing check.
Only the webapp normalized the label to a number.

- healthCheckStatus() now returns a dedicated HealthCheckStatusAssertionBuilder
  exposing only .equals()/.notEquals() (the only comparisons the runner
  supports), accepting a GrpcHealthStatus label or the raw 0|1|2|3 enum and
  emitting the numeric wire target. Mirrors the webapp's
  grpcHealthStatusTargetByLabel mapping (single source of truth).
- Codegen reverse-maps the number back to the label so an imported check
  round-trips to .equals('SERVING'); unmappable/legacy targets fall back to a
  raw assertion object literal so the generated code always type-checks.
- Validation flags a GRPC_HEALTHCHECK_STATUS target that isn't 0-3, catching
  object-literal callers who bypass the builder.

Reviewed via tri-model daniel-review (Codex + Gemini + Claude); all findings
fixed. Build clean, 21 gRPC unit/codegen tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013AYwkvoaANQTH5dGStbBj2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant