-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodex_review.diff
More file actions
1 lines (1 loc) · 16.9 KB
/
Copy pathcodex_review.diff
File metadata and controls
1 lines (1 loc) · 16.9 KB
1
diff --git a/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints.md b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints.md new file mode 100644 index 000000000..7f1f8d884 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints.md @@ -0,0 +1,30 @@ +# PR_26177_CHARLIE_032-runtime-health-json-endpoints + +Team: Charlie +Branch: pr/26177-CHARLIE-032-runtime-health-json-endpoints +Base: pr/26177-CHARLIE-031-environment-health-comparison +Lifecycle: Build / Validation +Repair: Rebased onto repaired PR_26177_CHARLIE_031 branch on 2026-06-25. + +## Scope +- Added GET /api/runtime/health as a structured Local API JSON health endpoint. +- Endpoint includes environment, API status, database status, storage status, and timestamp. +- Endpoint is server-owned, does not expose secrets, and does not give the browser direct database ownership. + +## Changed Files +- src/dev-runtime/server/local-api-router.mjs +- tests/api/admin-system-health/contract.test.mjs +- tests/dev-runtime/AdminHealthOperations.test.mjs +- tests/playwright/tools/AdminHealthOperationsPage.spec.mjs +- docs_build/dev/reports/coverage_changed_js_guardrail.txt +- docs_build/dev/reports/playwright_v8_coverage_report.txt + +## Validation +- PASS: node --check src/dev-runtime/server/local-api-router.mjs +- PASS: node --test tests/api/admin-system-health/contract.test.mjs +- PASS: node --test tests/dev-runtime/AdminHealthOperations.test.mjs +- PASS: npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --workers=1 --reporter=line +- PASS: git diff --check + +## ZIP +- Generated after repair: C:\Users\DavidQ\Documents\GitHub\HTML-JavaScript-Gaming\tmp\PR_26177_CHARLIE_032-runtime-health-json-endpoints_delta.zip diff --git a/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_branch-validation.md b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_branch-validation.md new file mode 100644 index 000000000..ffee36713 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_branch-validation.md @@ -0,0 +1,17 @@ +# PR_26177_CHARLIE_032-runtime-health-json-endpoints Branch Validation + +Branch: pr/26177-CHARLIE-032-runtime-health-json-endpoints +Expected stack base: pr/26177-CHARLIE-031-environment-health-comparison +Current status at validation: +## pr/26177-CHARLIE-032-runtime-health-json-endpoints +Updated onto repaired PR_26177_CHARLIE_031 stack base. + +Result: PASS + +Checks: +- PASS: Branch created from PR 031 branch for the approved stacked chain. +- PASS: Active branch matches PR identity. +- PASS: Worktree contained only scoped PR changes and generated validation reports. +- PASS: Branch is based on repaired PR 031 branch. +- PASS: Rebase conflict scope was generated report artifacts only. +- PASS: No start_of_day files modified. diff --git a/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_manual-validation-notes.md b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_manual-validation-notes.md new file mode 100644 index 000000000..ed6174f57 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_manual-validation-notes.md @@ -0,0 +1,8 @@ +# PR_26177_CHARLIE_032-runtime-health-json-endpoints Manual Validation Notes + +- Confirmed GET /api/runtime/health returns JSON through the Local API router. +- Confirmed payload includes environment, API, database, storage, and timestamp fields. +- Confirmed payload excludes configured API/site credentials and secret values. +- Confirmed System Health API Contract/Admin API Registry list the runtime health endpoint. +- Confirmed branch repair conflict was limited to generated report artifacts. +- Confirmed no start_of_day files changed. diff --git a/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_requirements-checklist.md b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_requirements-checklist.md new file mode 100644 index 000000000..6a3f730a9 --- /dev/null +++ b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_requirements-checklist.md @@ -0,0 +1,13 @@ +# PR_26177_CHARLIE_032-runtime-health-json-endpoints Requirement Checklist + +- PASS: Added structured Local API JSON health endpoint. +- PASS: Includes environment details. +- PASS: Includes API status. +- PASS: Includes DB status when available. +- PASS: Includes storage status when available. +- PASS: Includes timestamp. +- PASS: Does not expose secrets or URL credentials. +- PASS: Browser UI remains API/service-contract based. +- PASS: No direct browser database access added. +- PASS: No unrelated files or start_of_day files modified. +- PASS: Rebased onto repaired PR_26177_CHARLIE_031 branch. diff --git a/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_validation-lane.md b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_validation-lane.md new file mode 100644 index 000000000..0aa4db67f --- /dev/null +++ b/docs_build/dev/reports/PR_26177_CHARLIE_032-runtime-health-json-endpoints_validation-lane.md @@ -0,0 +1,20 @@ +# PR_26177_CHARLIE_032-runtime-health-json-endpoints Validation Lane Report + +Impacted lanes: +- runtime: Local API route contract. +- contract: Admin System Health API contract tests. +- UI-adjacent: Admin System Health API registry display. +- Playwright: targeted Admin System Health page spec. + +Commands: +- PASS: node --check src/dev-runtime/server/local-api-router.mjs +- PASS: node --test tests/api/admin-system-health/contract.test.mjs +- PASS: node --test tests/dev-runtime/AdminHealthOperations.test.mjs +- PASS: npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --workers=1 --reporter=line +- PASS: git diff --check + +Skipped lanes: +- Full samples smoke skipped; no samples/runtime game code changed. +- Full Project Workspace suite skipped; endpoint and Admin registry were covered by targeted tests. + +Result: PASS diff --git a/docs_build/dev/reports/coverage_changed_js_guardrail.txt b/docs_build/dev/reports/coverage_changed_js_guardrail.txt index fe02b5ecf..74a29674c 100644 --- a/docs_build/dev/reports/coverage_changed_js_guardrail.txt +++ b/docs_build/dev/reports/coverage_changed_js_guardrail.txt @@ -7,7 +7,6 @@ Source: Playwright/Chromium built-in V8 coverage from the active Playwright run. Changed runtime JS files considered: (0%) src/dev-runtime/server/local-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only -(80%) assets/theme-v2/js/admin-system-health.js - executed lines 920/920; executed functions 74/92 Guardrail warnings: (0%) src/dev-runtime/server/local-api-router.mjs - WARNING: changed runtime JS file missing from coverage; advisory only diff --git a/docs_build/dev/reports/playwright_v8_coverage_report.txt b/docs_build/dev/reports/playwright_v8_coverage_report.txt index c6e25e167..e539a3bb1 100644 --- a/docs_build/dev/reports/playwright_v8_coverage_report.txt +++ b/docs_build/dev/reports/playwright_v8_coverage_report.txt @@ -18,7 +18,6 @@ Exercised tool entry points detected: Changed runtime JS files covered: (0%) src/dev-runtime/server/local-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only -(80%) assets/theme-v2/js/admin-system-health.js - executed lines 920/920; executed functions 74/92 Files with executed line/function counts where available: (36%) src/api/server-api-client.js - executed lines 168/168; executed functions 5/14 @@ -41,4 +40,3 @@ Changed JS files considered: (0%) tests/api/admin-system-health/contract.test.mjs - changed JS file not collected as browser runtime coverage (0%) tests/dev-runtime/AdminHealthOperations.test.mjs - changed JS file not collected as browser runtime coverage (0%) tests/playwright/tools/AdminHealthOperationsPage.spec.mjs - changed JS file not collected as browser runtime coverage -(80%) assets/theme-v2/js/admin-system-health.js - changed JS file with browser V8 coverage diff --git a/src/dev-runtime/server/local-api-router.mjs b/src/dev-runtime/server/local-api-router.mjs index 01702c505..9ffc20905 100644 --- a/src/dev-runtime/server/local-api-router.mjs +++ b/src/dev-runtime/server/local-api-router.mjs @@ -365,11 +365,13 @@ const SYSTEM_HEALTH_MANUAL_ACTION_LABELS = Object.freeze({ "storage-check": "Run Storage Check", }); const SYSTEM_HEALTH_API_ENDPOINTS = Object.freeze([ + Object.freeze({ method: "GET", path: "/api/runtime/health", purpose: "Read public-safe Local API runtime health JSON." }), Object.freeze({ method: "GET", path: "/api/admin/system-health/status", purpose: "Read current deployment System Health status." }), Object.freeze({ method: "POST", path: "/api/admin/system-health/action", purpose: "Run current deployment manual health actions." }), Object.freeze({ method: "POST", path: "/api/admin/system-health/storage-connectivity-action", purpose: "Run current deployment R2 folder diagnostics." }), ]); const ADMIN_API_REGISTRY_ENTRIES = Object.freeze([ + Object.freeze({ method: "GET", owner: "Team Charlie", path: "/api/runtime/health", purpose: "Runtime health JSON contract" }), Object.freeze({ method: "GET", owner: "Team Charlie", path: "/api/admin/system-health/status", purpose: "System Health status contract" }), Object.freeze({ method: "POST", owner: "Team Charlie", path: "/api/admin/system-health/action", purpose: "System Health manual actions" }), 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, }; } + async runtimeHealthJsonStatus() { + const checkedAt = new Date().toISOString(); + const environmentIdentity = systemHealthEnvironmentIdentity(process.env, checkedAt); + const runtimeHealth = systemHealthRuntimeHealth(environmentIdentity, checkedAt); + const databaseStatus = await this.ownerDatabaseStatus(environmentIdentity); + const storageStatus = this.ownerStorageStatus(); + return { + api: { + status: runtimeHealth.status || "WARN", + version: runtimeHealth.apiVersion || "not available", + }, + database: { + connectivity: databaseStatus.connectivity || "not configured", + databaseType: databaseStatus.databaseType || environmentIdentity.databaseModel || "PostgreSQL", + lastChecked: databaseStatus.lastChecked || checkedAt, + responseTimeMs: Number.isFinite(databaseStatus.responseTimeMs) ? databaseStatus.responseTimeMs : null, + status: databaseStatus.connectivityStatus || databaseStatus.status || "WARN", + version: databaseStatus.version || "not available", + }, + environment: { + hostingModel: environmentIdentity.hostingModel || "not configured", + name: environmentIdentity.name || "Unknown", + storageFolder: environmentIdentity.storageFolder || "not configured", + }, + message: "Runtime health JSON is server-owned and safe for Local API status consumers.", + secretEditingAllowed: false, + secretsExposed: false, + status: overallHealthStatus([ + { status: runtimeHealth.status || "WARN" }, + { status: databaseStatus.connectivityStatus || databaseStatus.status || "WARN" }, + { status: storageStatus.status || "WARN" }, + ]), + storage: { + configured: storageStatus.configured === true, + environmentFolder: storageStatus.environmentFolder || environmentIdentity.storageFolder || "not configured", + lastChecked: storageStatus.lastChecked || checkedAt, + status: storageStatus.status || "WARN", + }, + timestamp: checkedAt, + }; + } + projectWorkspaceProjectsForRoute() { const activeProject = this.gameWorkspaceRepository.getActiveGame(); const records = gameWorkspaceProjectRecords(this.gameWorkspaceRepository); @@ -6725,6 +6769,10 @@ export function createLocalApiRouter({ if (request.method === "GET" && await handleAdminNotesDirectoryApiRequest(requestUrl, response, { repoRoot })) { return true; } + if (parts[1] === "runtime" && request.method === "GET" && parts[2] === "health") { + ok(response, await dataSource.runtimeHealthJsonStatus()); + return true; + } if (parts[1] === "session") { if (request.method === "HEAD" && ["current", "modes", "users"].includes(parts[2])) { sendNoContent(response, 200); diff --git a/tests/api/admin-system-health/contract.test.mjs b/tests/api/admin-system-health/contract.test.mjs index 9d54111f2..c82496a7b 100644 --- a/tests/api/admin-system-health/contract.test.mjs +++ b/tests/api/admin-system-health/contract.test.mjs @@ -93,6 +93,15 @@ test("Admin System Health completion contract remains server-owned and current-e }, async () => { const server = await startApiServer(); try { + const runtimeJson = await apiJson(server.baseUrl, "/api/runtime/health"); + assert.equal(runtimeJson.environment.name, "DEV"); + assert.equal(runtimeJson.environment.storageFolder, "/dev"); + assert.equal(runtimeJson.api.status, "PASS"); + assert.equal(Object.hasOwn(runtimeJson, "timestamp"), true); + assert.equal(runtimeJson.secretEditingAllowed, false); + assert.equal(runtimeJson.secretsExposed, false); + assert.equal(JSON.stringify(runtimeJson).includes("api-secret"), false); + assert.equal(JSON.stringify(runtimeJson).includes("site-secret"), false); await apiJson(server.baseUrl, "/api/session/user", { body: { userKey: SEED_DB_KEYS.users.admin }, method: "POST", diff --git a/tests/dev-runtime/AdminHealthOperations.test.mjs b/tests/dev-runtime/AdminHealthOperations.test.mjs index 0c413cfda..8d37ad5c3 100644 --- a/tests/dev-runtime/AdminHealthOperations.test.mjs +++ b/tests/dev-runtime/AdminHealthOperations.test.mjs @@ -242,6 +242,7 @@ test("Admin can view operational health while Creator sessions are blocked", asy assert.deepEqual( health.apiContract.endpoints.map((endpoint) => `${endpoint.method} ${endpoint.path}`), [ + "GET /api/runtime/health", "GET /api/admin/system-health/status", "POST /api/admin/system-health/action", "POST /api/admin/system-health/storage-connectivity-action", @@ -250,6 +251,7 @@ test("Admin can view operational health while Creator sessions are blocked", asy assert.deepEqual( health.adminApiRegistry.rows.map((row) => `${row.method} ${row.path}`), [ + "GET /api/runtime/health", "GET /api/admin/system-health/status", "POST /api/admin/system-health/action", "POST /api/admin/system-health/storage-connectivity-action", @@ -260,6 +262,16 @@ test("Admin can view operational health while Creator sessions are blocked", asy "GET /api/navigation/admin-menu", ], ); + const runtimeJson = await apiJson(server.baseUrl, "/api/runtime/health"); + assert.equal(runtimeJson.environment.name, "Local"); + assert.equal(runtimeJson.api.status, "PASS"); + assert.ok(["PASS", "WARN", "FAIL"].includes(runtimeJson.database.status)); + assert.ok(["PASS", "WARN", "FAIL"].includes(runtimeJson.storage.status)); + assert.equal(typeof runtimeJson.timestamp, "string"); + assert.equal(runtimeJson.secretEditingAllowed, false); + assert.equal(runtimeJson.secretsExposed, false); + assert.equal(JSON.stringify(runtimeJson).includes("api-secret"), false); + assert.equal(JSON.stringify(runtimeJson).includes("site-secret"), false); assert.deepEqual( health.runtimeFeatureFlags.rows.map((row) => `${row.flag}:${row.value}`), [ diff --git a/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs b/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs index f7f2cb66c..45d704c3e 100644 --- a/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs +++ b/tests/playwright/tools/AdminHealthOperationsPage.spec.mjs @@ -166,8 +166,10 @@ test("Admin System Health renders Postgres diagnostics through the safe status A await expect(apiContractTable).toContainText("2026-06-24.system-health.v1"); await expect(apiContractTable).toContainText("Current deployment only"); await expect(apiContractTable).toContainText("Reference only"); + await expect(apiContractTable).toContainText("GET /api/runtime/health"); await expect(apiContractTable).toContainText("GET /api/admin/system-health/status"); const apiRegistryTable = page.getByRole("table", { name: "Admin API registry" }); + await expect(apiRegistryTable).toContainText("/api/runtime/health"); await expect(apiRegistryTable).toContainText("/api/admin/system-health/status"); await expect(apiRegistryTable).toContainText("/api/admin/system-health/action"); await expect(apiRegistryTable).toContainText("/api/admin/infrastructure/storage-path-status");