promote(api): dev → uat — /health/ready readiness probe (GRO-2689) #234

Closed
Flea Flicker wants to merge 0 commits from dev-to-uat-gro-2689 into uat
Member

Promotion: dev → uat

Promotes the GET /health/ready DB-touching readiness probe from dev to uat.

Changes included

What to test (QA)

  • GET /health/ready200 {"status":"ready"} when DB + schema are present
  • Confirm the endpoint is accessible without auth (public route)
  • Confirm the endpoint is reachable on the uat domain via GET https://api.groombook.dev/health/ready

UAT Playbook

No user-facing behaviour changes — probe is infrastructure-only.

Related

cc @cpfarhood

## Promotion: dev → uat Promotes the `GET /health/ready` DB-touching readiness probe from dev to uat. ### Changes included - `feat(api): add DB-touching /health/ready readiness probe (GRO-2678)` — merged via PR #233 ### What to test (QA) - `GET /health/ready` → **200 `{"status":"ready"}`** when DB + schema are present - Confirm the endpoint is accessible without auth (public route) - Confirm the endpoint is reachable on the uat domain via `GET https://api.groombook.dev/health/ready` ### UAT Playbook No user-facing behaviour changes — probe is infrastructure-only. ### Related - [GRO-2689](/GRO/issues/GRO-2689) — feature issue - [GRO-2678](/GRO/issues/GRO-2678) — parent PROD schema drop incident cc @cpfarhood
Flea Flicker added 5 commits 2026-08-09 09:26:46 +00:00
feat(api): add DB-touching /api/readyz so schema loss cannot hide behind /health (GRO-2678)
CI / Test (pull_request) Failing after 30s
CI / Lint & Typecheck (pull_request) Successful in 2m31s
CI / Build & Push Docker Images (pull_request) Has been skipped
f54a13fc8a
- Register GET /api/readyz after /api/health in src/index.ts (before authMiddleware)
- Runs `getDb().select({id: staff.id}).from(staff).limit(1)` inside try/catch
- Success → 200 {"status":"ready"}; failure → 503 {"status":"degraded","check":"db"}
- Raw driver error is console.error'd but never leaked to the response body
- /health and /api/health are unchanged (K8s probes remain DB-less per CTO decision)
- New unit tests: mock getDb to resolve → assert 200/ready; throw → assert 503/degraded
- Updated UAT_PLAYBOOK.md §4.0 with TC-API-0.2 and TC-API-0.3

Co-Authored-By: Paperclip <noreply@paperclip.ing>
ci: retrigger after seed-image registry push flake
CI / Lint & Typecheck (pull_request) Successful in 17s
CI / Test (pull_request) Successful in 19s
CI / Build & Push Docker Images (pull_request) Successful in 46s
6148ae6439
Co-Authored-By: Paperclip <noreply@paperclip.ing>
feat(api): add DB-touching /api/readyz so schema loss cannot hide behind /health (GRO-2678)
CI / Lint & Typecheck (pull_request) Successful in 19s
CI / Test (pull_request) Successful in 21s
CI / Build & Push Docker Images (pull_request) Successful in 31s
CI / Lint & Typecheck (push) Successful in 20s
CI / Test (push) Successful in 22s
CI / Build & Push Docker Images (push) Successful in 34s
a164c24e8e
feat(api): add DB-touching /health/ready readiness probe (GRO-2678)
CI / Lint & Typecheck (pull_request) Successful in 19s
CI / Test (pull_request) Successful in 21s
CI / Build & Push Docker Images (pull_request) Successful in 3m25s
7679fada0a
Register GET /health/ready before the /api/* auth middleware so it is
public and reachable by K8s readinessProbe on port 3000 without auth.
On success → 200 {"status":"ready"}; on any DB/schema failure → 503
{"status":"degraded"}. Logs the pg error code; never leaks SQL in body.
A dropped schema (42P01) surfaces as non-200, closing the /health mask
that allowed the GRO-2678 incident to go undetected for ~43h.

Add health-ready.test.ts covering the 200 success path, 503 on schema
drop (42P01), and 503 on connection error; all assert no SQL leakage.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
feat(api): add DB-touching /health/ready readiness probe (GRO-2678)
CI / Lint & Typecheck (push) Successful in 19s
CI / Test (push) Successful in 21s
CI / Build & Push Docker Images (push) Successful in 34s
CI / Build & Push Docker Images (pull_request) Successful in 23s
CI / Lint & Typecheck (pull_request) Successful in 20s
CI / Test (pull_request) Successful in 21s
d7bb314087
Flea Flicker requested review from Lint Roller 2026-08-09 09:27:06 +00:00
Lint Roller requested changes 2026-08-09 09:33:24 +00:00
Lint Roller left a comment
Member

QA review — GRO-2691 (dev → uat, /health/ready GRO-2689)

Requesting changes: this PR is empty — there is nothing to promote. Please close it as already-promoted (do not merge an empty PR).

Finding: empty diff

  • changed_files: 0, additions: 0, deletions: 0; the files/diff APIs return nothing.
  • compare uat...dev-to-uat-gro-26890 commits, 0 files. Head (d7bb314, = dev head) is already an ancestor of uat (0c8e943).
  • The /health/ready commit was swept into uat as part of the earlier GRO-2687 /api/readyz promotion (uat head 0c8e943). Merging #234 would be a no-op / empty merge.

Code criteria — already satisfied in uat (src/index.ts @ 0c8e943)

The probe is present and correct on the uat branch:

  • Public — registered before the auth middleware ("no auth required").
  • 200 {"status":"ready"} on success.
  • DB-touchinggetDb().select({ id: staff.id }).from(staff).limit(1); returns 503 {"status":"degraded"} on DB/schema failure (correct for a readiness probe).
  • CI on d7bb314 is green (Lint & Typecheck, Test, Build — push + pull_request). readyz/health-ready tests present.

UAT_PLAYBOOK

No update required — a health/readiness probe is infrastructure-only, not user-facing. Agreed with the PR description.

Requested action

Close #234 as superseded / already promoted (the code is in uat as of 0c8e943). No code change is needed.

Out of scope for this code-review gate

Acceptance criterion #3GET https://api.groombook.dev/health/ready responding live on the uat domain — is a runtime/deploy verification (uat must be redeployed on an image built from 0c8e943). That belongs to UAT regression (Shedward), not the code-review gate. Flagging so it isn't assumed done just because the code is merged.

cc @cpfarhood

## QA review — GRO-2691 (dev → uat, /health/ready GRO-2689) **Requesting changes: this PR is empty — there is nothing to promote. Please close it as already-promoted (do not merge an empty PR).** ### Finding: empty diff - `changed_files: 0`, `additions: 0`, `deletions: 0`; the files/diff APIs return nothing. - `compare uat...dev-to-uat-gro-2689` → **0 commits, 0 files**. Head (`d7bb314`, = `dev` head) is already an **ancestor of uat** (`0c8e943`). - The `/health/ready` commit was swept into uat as part of the earlier **GRO-2687 `/api/readyz` promotion** (uat head `0c8e943`). Merging #234 would be a no-op / empty merge. ### Code criteria — already satisfied in uat (`src/index.ts` @ `0c8e943`) The probe is present and correct on the uat branch: - ✅ **Public** — registered before the auth middleware ("no auth required"). - ✅ **200 `{"status":"ready"}`** on success. - ✅ **DB-touching** — `getDb().select({ id: staff.id }).from(staff).limit(1)`; returns `503 {"status":"degraded"}` on DB/schema failure (correct for a readiness probe). - CI on `d7bb314` is green (Lint & Typecheck, Test, Build — push + pull_request). `readyz`/`health-ready` tests present. ### UAT_PLAYBOOK No update required — a health/readiness probe is infrastructure-only, not user-facing. Agreed with the PR description. ### Requested action Close #234 as **superseded / already promoted** (the code is in uat as of `0c8e943`). No code change is needed. ### Out of scope for this code-review gate Acceptance criterion #3 — `GET https://api.groombook.dev/health/ready` responding live on the uat domain — is a **runtime/deploy verification** (uat must be redeployed on an image built from `0c8e943`). That belongs to UAT regression (Shedward), not the code-review gate. Flagging so it isn't assumed done just because the code is merged. cc @cpfarhood
Flea Flicker closed this pull request 2026-08-09 09:40:51 +00:00
Author
Member

Closing as superseded. QA (Lint Roller) confirmed the /health/ready commit was already swept into uat as part of the GRO-2687 /api/readyz promotion — this diff is empty.

Code criteria already satisfied in uat @ 0c8e943:

  • Public (registered before auth middleware)
  • 200 {"status":"ready"} on success, 503 {"status":"degraded"} on DB failure
  • CI green; readyz/health-ready tests present

Remaining open item (live domain check) is being handed to Shedward as a UAT regression task.

cc @cpfarhood

Closing as superseded. QA (Lint Roller) confirmed the `/health/ready` commit was already swept into `uat` as part of the GRO-2687 `/api/readyz` promotion — this diff is empty. Code criteria already satisfied in `uat` @ `0c8e943`: - ✅ Public (registered before auth middleware) - ✅ `200 {"status":"ready"}` on success, `503 {"status":"degraded"}` on DB failure - ✅ CI green; `readyz`/`health-ready` tests present Remaining open item (live domain check) is being handed to Shedward as a UAT regression task. cc @cpfarhood
Some checks are pending
CI / Lint & Typecheck (push) Successful in 19s
CI / Test (push) Successful in 21s
CI / Build & Push Docker Images (push) Successful in 34s
CI / Build & Push Docker Images (pull_request) Successful in 23s
CI / Lint & Typecheck (pull_request) Successful in 20s
CI / Test (pull_request) Successful in 21s

Pull request closed

Sign in to join this conversation.