Skip to content

Commit 83c19bc

Browse files
committed
Add runtime health JSON endpoint
1 parent 1a63c19 commit 83c19bc

13 files changed

Lines changed: 182 additions & 37 deletions
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# PR_26177_CHARLIE_032-runtime-health-json-endpoints
2+
3+
Team: Charlie
4+
Branch: pr/26177-CHARLIE-032-runtime-health-json-endpoints
5+
Base: pr/26177-CHARLIE-031-environment-health-comparison
6+
Lifecycle: Build / Validation
7+
Repair: Rebased onto repaired PR_26177_CHARLIE_031 branch on 2026-06-25.
8+
9+
## Scope
10+
- Added GET /api/runtime/health as a structured Local API JSON health endpoint.
11+
- Endpoint includes environment, API status, database status, storage status, and timestamp.
12+
- Endpoint is server-owned, does not expose secrets, and does not give the browser direct database ownership.
13+
14+
## Changed Files
15+
- src/dev-runtime/server/local-api-router.mjs
16+
- tests/api/admin-system-health/contract.test.mjs
17+
- tests/dev-runtime/AdminHealthOperations.test.mjs
18+
- tests/playwright/tools/AdminHealthOperationsPage.spec.mjs
19+
- docs_build/dev/reports/coverage_changed_js_guardrail.txt
20+
- docs_build/dev/reports/playwright_v8_coverage_report.txt
21+
22+
## Validation
23+
- PASS: node --check src/dev-runtime/server/local-api-router.mjs
24+
- PASS: node --test tests/api/admin-system-health/contract.test.mjs
25+
- PASS: node --test tests/dev-runtime/AdminHealthOperations.test.mjs
26+
- PASS: npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --workers=1 --reporter=line
27+
- PASS: git diff --check
28+
29+
## ZIP
30+
- Generated after repair: C:\Users\DavidQ\Documents\GitHub\HTML-JavaScript-Gaming\tmp\PR_26177_CHARLIE_032-runtime-health-json-endpoints_delta.zip
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# PR_26177_CHARLIE_032-runtime-health-json-endpoints Branch Validation
2+
3+
Branch: pr/26177-CHARLIE-032-runtime-health-json-endpoints
4+
Expected stack base: pr/26177-CHARLIE-031-environment-health-comparison
5+
Current status at validation:
6+
## pr/26177-CHARLIE-032-runtime-health-json-endpoints
7+
Updated onto repaired PR_26177_CHARLIE_031 stack base.
8+
9+
Result: PASS
10+
11+
Checks:
12+
- PASS: Branch created from PR 031 branch for the approved stacked chain.
13+
- PASS: Active branch matches PR identity.
14+
- PASS: Worktree contained only scoped PR changes and generated validation reports.
15+
- PASS: Branch is based on repaired PR 031 branch.
16+
- PASS: Rebase conflict scope was generated report artifacts only.
17+
- PASS: No start_of_day files modified.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# PR_26177_CHARLIE_032-runtime-health-json-endpoints Manual Validation Notes
2+
3+
- Confirmed GET /api/runtime/health returns JSON through the Local API router.
4+
- Confirmed payload includes environment, API, database, storage, and timestamp fields.
5+
- Confirmed payload excludes configured API/site credentials and secret values.
6+
- Confirmed System Health API Contract/Admin API Registry list the runtime health endpoint.
7+
- Confirmed branch repair conflict was limited to generated report artifacts.
8+
- Confirmed no start_of_day files changed.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# PR_26177_CHARLIE_032-runtime-health-json-endpoints Requirement Checklist
2+
3+
- PASS: Added structured Local API JSON health endpoint.
4+
- PASS: Includes environment details.
5+
- PASS: Includes API status.
6+
- PASS: Includes DB status when available.
7+
- PASS: Includes storage status when available.
8+
- PASS: Includes timestamp.
9+
- PASS: Does not expose secrets or URL credentials.
10+
- PASS: Browser UI remains API/service-contract based.
11+
- PASS: No direct browser database access added.
12+
- PASS: No unrelated files or start_of_day files modified.
13+
- PASS: Rebased onto repaired PR_26177_CHARLIE_031 branch.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# PR_26177_CHARLIE_032-runtime-health-json-endpoints Validation Lane Report
2+
3+
Impacted lanes:
4+
- runtime: Local API route contract.
5+
- contract: Admin System Health API contract tests.
6+
- UI-adjacent: Admin System Health API registry display.
7+
- Playwright: targeted Admin System Health page spec.
8+
9+
Commands:
10+
- PASS: node --check src/dev-runtime/server/local-api-router.mjs
11+
- PASS: node --test tests/api/admin-system-health/contract.test.mjs
12+
- PASS: node --test tests/dev-runtime/AdminHealthOperations.test.mjs
13+
- PASS: npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --workers=1 --reporter=line
14+
- PASS: git diff --check
15+
16+
Skipped lanes:
17+
- Full samples smoke skipped; no samples/runtime game code changed.
18+
- Full Project Workspace suite skipped; endpoint and Admin registry were covered by targeted tests.
19+
20+
Result: PASS
Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
# git diff --name-only pr/26177-CHARLIE-030-r2-storage-health-expanded-validation --
2-
admin/system-health.html
3-
assets/theme-v2/js/admin-system-health.js
4-
docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison.md
5-
docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison_branch-validation.md
6-
docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison_manual-validation-notes.md
7-
docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison_requirements-checklist.md
8-
docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison_validation-lane.md
1+
# git diff --name-only pr/26177-CHARLIE-031-environment-health-comparison --
2+
docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints.md
3+
docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_branch-validation.md
4+
docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_manual-validation-notes.md
5+
docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_requirements-checklist.md
6+
docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_validation-lane.md
97
docs_build/dev/reports/codex_changed_files.txt
108
docs_build/dev/reports/codex_review.diff
119
docs_build/dev/reports/coverage_changed_js_guardrail.txt
@@ -16,29 +14,20 @@ tests/dev-runtime/AdminHealthOperations.test.mjs
1614
tests/playwright/tools/AdminHealthOperationsPage.spec.mjs
1715

1816
# git status --short
19-
M docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison.md
20-
M docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison_branch-validation.md
21-
M docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison_manual-validation-notes.md
22-
M docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison_requirements-checklist.md
23-
M docs_build/dev/reports/PR_26177_CHARLIE_031-environment-health-comparison_validation-lane.md
24-
M docs_build/dev/reports/codex_review.diff
25-
M docs_build/dev/reports/coverage_changed_js_guardrail.txt
26-
M docs_build/dev/reports/playwright_v8_coverage_report.txt
17+
(no output)
2718

28-
# git diff --stat pr/26177-CHARLIE-030-r2-storage-health-expanded-validation --
29-
admin/system-health.html | 20 +
30-
assets/theme-v2/js/admin-system-health.js | 50 ++
31-
...77_CHARLIE_031-environment-health-comparison.md | 33 +
32-
...ironment-health-comparison_branch-validation.md | 17 +
33-
...nt-health-comparison_manual-validation-notes.md | 9 +
34-
...ent-health-comparison_requirements-checklist.md | 12 +
35-
...nvironment-health-comparison_validation-lane.md | 21 +
36-
docs_build/dev/reports/codex_changed_files.txt | 71 +--
37-
docs_build/dev/reports/codex_review.diff | 663 +--------------------
38-
.../dev/reports/coverage_changed_js_guardrail.txt | 3 +-
39-
.../dev/reports/playwright_v8_coverage_report.txt | 8 +-
40-
src/dev-runtime/server/local-api-router.mjs | 76 +++
41-
tests/api/admin-system-health/contract.test.mjs | 13 +
42-
tests/dev-runtime/AdminHealthOperations.test.mjs | 9 +
43-
.../tools/AdminHealthOperationsPage.spec.mjs | 11 +
44-
15 files changed, 305 insertions(+), 711 deletions(-)
19+
# git diff --stat pr/26177-CHARLIE-031-environment-health-comparison --
20+
...77_CHARLIE_032-runtime-health-json-endpoints.md | 30 ++++++++++
21+
...time-health-json-endpoints_branch-validation.md | 17 ++++++
22+
...ealth-json-endpoints_manual-validation-notes.md | 8 +++
23+
...health-json-endpoints_requirements-checklist.md | 13 +++++
24+
...untime-health-json-endpoints_validation-lane.md | 20 +++++++
25+
docs_build/dev/reports/codex_changed_files.txt | 66 ++++++++--------------
26+
docs_build/dev/reports/codex_review.diff | 2 +-
27+
.../dev/reports/coverage_changed_js_guardrail.txt | 1 -
28+
.../dev/reports/playwright_v8_coverage_report.txt | 2 -
29+
src/dev-runtime/server/local-api-router.mjs | 48 ++++++++++++++++
30+
tests/api/admin-system-health/contract.test.mjs | 9 +++
31+
tests/dev-runtime/AdminHealthOperations.test.mjs | 12 ++++
32+
.../tools/AdminHealthOperationsPage.spec.mjs | 2 +
33+
13 files changed, 185 insertions(+), 45 deletions(-)

docs_build/dev/reports/codex_review.diff

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ Source: Playwright/Chromium built-in V8 coverage from the active Playwright run.
77

88
Changed runtime JS files considered:
99
(0%) src/dev-runtime/server/local-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
10-
(80%) assets/theme-v2/js/admin-system-health.js - executed lines 920/920; executed functions 74/92
1110

1211
Guardrail warnings:
1312
(0%) src/dev-runtime/server/local-api-router.mjs - WARNING: changed runtime JS file missing from coverage; advisory only

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ Exercised tool entry points detected:
1818

1919
Changed runtime JS files covered:
2020
(0%) src/dev-runtime/server/local-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
21-
(80%) assets/theme-v2/js/admin-system-health.js - executed lines 920/920; executed functions 74/92
2221

2322
Files with executed line/function counts where available:
2423
(36%) src/api/server-api-client.js - executed lines 168/168; executed functions 5/14
@@ -41,4 +40,3 @@ Changed JS files considered:
4140
(0%) tests/api/admin-system-health/contract.test.mjs - changed JS file not collected as browser runtime coverage
4241
(0%) tests/dev-runtime/AdminHealthOperations.test.mjs - changed JS file not collected as browser runtime coverage
4342
(0%) tests/playwright/tools/AdminHealthOperationsPage.spec.mjs - changed JS file not collected as browser runtime coverage
44-
(80%) assets/theme-v2/js/admin-system-health.js - changed JS file with browser V8 coverage

src/dev-runtime/server/local-api-router.mjs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,13 @@ const SYSTEM_HEALTH_MANUAL_ACTION_LABELS = Object.freeze({
365365
"storage-check": "Run Storage Check",
366366
});
367367
const SYSTEM_HEALTH_API_ENDPOINTS = Object.freeze([
368+
Object.freeze({ method: "GET", path: "/api/runtime/health", purpose: "Read public-safe Local API runtime health JSON." }),
368369
Object.freeze({ method: "GET", path: "/api/admin/system-health/status", purpose: "Read current deployment System Health status." }),
369370
Object.freeze({ method: "POST", path: "/api/admin/system-health/action", purpose: "Run current deployment manual health actions." }),
370371
Object.freeze({ method: "POST", path: "/api/admin/system-health/storage-connectivity-action", purpose: "Run current deployment R2 folder diagnostics." }),
371372
]);
372373
const ADMIN_API_REGISTRY_ENTRIES = Object.freeze([
374+
Object.freeze({ method: "GET", owner: "Team Charlie", path: "/api/runtime/health", purpose: "Runtime health JSON contract" }),
373375
Object.freeze({ method: "GET", owner: "Team Charlie", path: "/api/admin/system-health/status", purpose: "System Health status contract" }),
374376
Object.freeze({ method: "POST", owner: "Team Charlie", path: "/api/admin/system-health/action", purpose: "System Health manual actions" }),
375377
Object.freeze({ method: "POST", owner: "Team Charlie", path: "/api/admin/system-health/storage-connectivity-action", purpose: "System Health R2 diagnostics" }),
@@ -4865,6 +4867,48 @@ SELECT pg_database_size(current_database()) AS database_size_bytes,
48654867
};
48664868
}
48674869

4870+
async runtimeHealthJsonStatus() {
4871+
const checkedAt = new Date().toISOString();
4872+
const environmentIdentity = systemHealthEnvironmentIdentity(process.env, checkedAt);
4873+
const runtimeHealth = systemHealthRuntimeHealth(environmentIdentity, checkedAt);
4874+
const databaseStatus = await this.ownerDatabaseStatus(environmentIdentity);
4875+
const storageStatus = this.ownerStorageStatus();
4876+
return {
4877+
api: {
4878+
status: runtimeHealth.status || "WARN",
4879+
version: runtimeHealth.apiVersion || "not available",
4880+
},
4881+
database: {
4882+
connectivity: databaseStatus.connectivity || "not configured",
4883+
databaseType: databaseStatus.databaseType || environmentIdentity.databaseModel || "PostgreSQL",
4884+
lastChecked: databaseStatus.lastChecked || checkedAt,
4885+
responseTimeMs: Number.isFinite(databaseStatus.responseTimeMs) ? databaseStatus.responseTimeMs : null,
4886+
status: databaseStatus.connectivityStatus || databaseStatus.status || "WARN",
4887+
version: databaseStatus.version || "not available",
4888+
},
4889+
environment: {
4890+
hostingModel: environmentIdentity.hostingModel || "not configured",
4891+
name: environmentIdentity.name || "Unknown",
4892+
storageFolder: environmentIdentity.storageFolder || "not configured",
4893+
},
4894+
message: "Runtime health JSON is server-owned and safe for Local API status consumers.",
4895+
secretEditingAllowed: false,
4896+
secretsExposed: false,
4897+
status: overallHealthStatus([
4898+
{ status: runtimeHealth.status || "WARN" },
4899+
{ status: databaseStatus.connectivityStatus || databaseStatus.status || "WARN" },
4900+
{ status: storageStatus.status || "WARN" },
4901+
]),
4902+
storage: {
4903+
configured: storageStatus.configured === true,
4904+
environmentFolder: storageStatus.environmentFolder || environmentIdentity.storageFolder || "not configured",
4905+
lastChecked: storageStatus.lastChecked || checkedAt,
4906+
status: storageStatus.status || "WARN",
4907+
},
4908+
timestamp: checkedAt,
4909+
};
4910+
}
4911+
48684912
projectWorkspaceProjectsForRoute() {
48694913
const activeProject = this.gameWorkspaceRepository.getActiveGame();
48704914
const records = gameWorkspaceProjectRecords(this.gameWorkspaceRepository);
@@ -6725,6 +6769,10 @@ export function createLocalApiRouter({
67256769
if (request.method === "GET" && await handleAdminNotesDirectoryApiRequest(requestUrl, response, { repoRoot })) {
67266770
return true;
67276771
}
6772+
if (parts[1] === "runtime" && request.method === "GET" && parts[2] === "health") {
6773+
ok(response, await dataSource.runtimeHealthJsonStatus());
6774+
return true;
6775+
}
67286776
if (parts[1] === "session") {
67296777
if (request.method === "HEAD" && ["current", "modes", "users"].includes(parts[2])) {
67306778
sendNoContent(response, 200);

0 commit comments

Comments
 (0)