Skip to content

Commit 0d817a3

Browse files
committed
PR_26175_CHARLIE_013-service-health-dashboard
1 parent dc8a51d commit 0d817a3

14 files changed

Lines changed: 614 additions & 331 deletions

admin/system-health.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ <h2>Admin</h2>
4040
<div class="accordion-body content-stack">
4141
<p>Environment Identity</p>
4242
<p>Environment Map</p>
43+
<p>Service Health</p>
4344
<p>Local API Startup</p>
4445
<p>Database Health</p>
4546
<p>Storage Health</p>
@@ -100,6 +101,21 @@ <h2 id="admin-system-health-title">System Health Tables</h2>
100101
</tbody>
101102
</table>
102103
</div>
104+
<section class="content-stack" aria-label="Service health summary">
105+
<div>
106+
<div class="kicker">Current Deployment</div>
107+
<h3>Service Health</h3>
108+
</div>
109+
<div class="grid cols-3" data-admin-system-health-service-cards>
110+
<article class="card">
111+
<div class="card-body content-stack content-stack--compact">
112+
<h4>Loading</h4>
113+
<p data-health-status="PENDING" title="Reason: service health has not loaded yet." aria-label="PENDING: service health has not loaded yet.">PENDING</p>
114+
<p>Waiting for safe API status.</p>
115+
</div>
116+
</article>
117+
</div>
118+
</section>
103119
<div class="table-wrapper">
104120
<table class="data-table" aria-label="Local API startup diagnostics">
105121
<caption>Local API Startup Diagnostics</caption>

assets/theme-v2/js/admin-system-health.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class AdminSystemHealthController {
6161
node,
6262
]));
6363
this.historyRows = root.querySelector("[data-admin-system-health-history-rows]");
64+
this.serviceCards = root.querySelector("[data-admin-system-health-service-cards]");
6465
this.startupRows = root.querySelector("[data-admin-system-health-startup-rows]");
6566
this.runtimeRows = root.querySelector("[data-admin-system-health-runtime-rows]");
6667
}
@@ -134,6 +135,7 @@ class AdminSystemHealthController {
134135
this.renderStartupPending(reason);
135136
this.renderStoragePending(reason);
136137
this.renderRuntimeHealthPending(reason);
138+
this.renderServiceHealthPending(reason);
137139
this.renderHistoryPending(reason);
138140
}
139141

@@ -217,6 +219,65 @@ class AdminSystemHealthController {
217219
this.setRuntimeHealthStatus("lastChecked", runtimeHealth.lastChecked ? "PASS" : "WARN", reason);
218220
}
219221

222+
renderServiceHealthPending(reason) {
223+
if (!this.serviceCards) {
224+
return;
225+
}
226+
const card = this.createServiceHealthCard({
227+
healthStatus: "PENDING",
228+
label: "Service Health",
229+
status: "Not Configured",
230+
summary: reason,
231+
});
232+
this.serviceCards.replaceChildren(card);
233+
}
234+
235+
createServiceHealthCard(service = {}) {
236+
const card = document.createElement("article");
237+
card.className = "card";
238+
card.dataset.adminSystemHealthServiceCard = service.id || "";
239+
const body = document.createElement("div");
240+
body.className = "card-body content-stack content-stack--compact";
241+
const title = document.createElement("h4");
242+
title.textContent = asText(service.label, "Service");
243+
const status = document.createElement("p");
244+
const healthStatus = normalizeStatusValue(service.healthStatus);
245+
status.dataset.healthStatus = healthStatus;
246+
status.textContent = asText(service.status, "Not Configured");
247+
if (healthStatus !== "PASS") {
248+
const reason = asText(service.summary, "Safe server diagnostics did not provide a reason.");
249+
status.setAttribute("title", `Reason: ${reason}`);
250+
status.setAttribute("aria-label", `${status.textContent}: ${reason}`);
251+
}
252+
const summary = document.createElement("p");
253+
summary.textContent = asText(service.summary, "Status unavailable.");
254+
const checkedAt = document.createElement("p");
255+
checkedAt.textContent = `Last checked: ${asText(service.lastChecked, "not available")}`;
256+
body.append(title, status, summary, checkedAt);
257+
card.append(body);
258+
return card;
259+
}
260+
261+
renderServiceHealth(serviceHealth = {}) {
262+
if (!this.serviceCards) {
263+
return;
264+
}
265+
if (serviceHealth?.secretsExposed === true || serviceHealth?.secretEditingAllowed === true) {
266+
this.renderServiceHealthPending("Safe service health response was blocked because it exposed secret controls.");
267+
return;
268+
}
269+
const services = Array.isArray(serviceHealth.services) ? serviceHealth.services : [];
270+
if (!services.length) {
271+
this.renderServiceHealthPending("Safe Admin System Health API returned no service health cards.");
272+
return;
273+
}
274+
const fragment = document.createDocumentFragment();
275+
services.forEach((service) => {
276+
fragment.append(this.createServiceHealthCard(service));
277+
});
278+
this.serviceCards.replaceChildren(fragment);
279+
}
280+
220281
renderStartupPending(reason) {
221282
if (!this.startupRows) {
222283
return;
@@ -399,6 +460,7 @@ class AdminSystemHealthController {
399460
this.renderStorageStatus(data?.storageStatus || {});
400461
this.runStorageDiagnostics();
401462
this.renderRuntimeHealth(data?.runtimeHealth || {});
463+
this.renderServiceHealth(data?.serviceHealth || {});
402464
this.renderHealthCheckHistory(data?.healthCheckHistory || []);
403465
this.renderRuntimeEnvironment(data?.runtimeEnvironment || {});
404466
} catch (error) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# PR_26175_CHARLIE_013 Branch Validation
2+
3+
## Branch Rules
4+
5+
- PASS: Continued on `pr/26175-CHARLIE-010-system-health-history-and-closeout`.
6+
- PASS: Stacked on PR_26175_CHARLIE_012.
7+
- PASS: No merge was performed.
8+
- PASS: No rebase was performed.
9+
- PASS: No new root branch was created.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# PR_26175_CHARLIE_013 Manual Validation Notes
2+
3+
- Verified Service Health cards render on `admin/system-health.html`.
4+
- Verified all seven requested service labels are present.
5+
- Verified visible card statuses are limited to Healthy, Warning, Failed, and Not Configured.
6+
- Verified Email and Background Jobs remain Not Configured placeholders.
7+
- Verified no peer environment health checks were introduced.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# PR_26175_CHARLIE_013 Requirement Checklist
2+
3+
- PASS: Added Service Health summary cards.
4+
- PASS: Added Runtime card.
5+
- PASS: Added API card.
6+
- PASS: Added Database card.
7+
- PASS: Added Storage card.
8+
- PASS: Added Authentication placeholder/status.
9+
- PASS: Added Email placeholder/status.
10+
- PASS: Added Background Jobs placeholder/status.
11+
- PASS: Used statuses Healthy, Warning, Failed, and Not Configured.
12+
- PASS: Current environment only.
13+
- PASS: Browser does not own service health state.
14+
- PASS: Tests were updated.
15+
- PASS: Required reports were generated.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# PR_26175_CHARLIE_013 Validation Report
2+
3+
## Commands
4+
5+
- PASS: `node --check src/dev-runtime/server/local-api-router.mjs`
6+
- PASS: `node --check assets/theme-v2/js/admin-system-health.js`
7+
- PASS: `git diff --check`
8+
- Result: no whitespace errors; CRLF conversion warnings only.
9+
- PASS: `node --test tests/dev-runtime/AdminHealthOperations.test.mjs`
10+
- Result: 4 passed.
11+
- PASS: `npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs --workers=1 --reporter=line`
12+
- Result: 3 passed.
13+
14+
## Validation Lane
15+
16+
- Targeted System Health API/unit lane: PASS.
17+
- Targeted System Health Playwright lane: PASS.
18+
- Full samples smoke: not run; not required for this System Health-only slice.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# PR_26175_CHARLIE_013 Service Health Dashboard
2+
3+
## Scope
4+
5+
Team: Charlie
6+
7+
Purpose: Add current-environment Service Health summary cards to Admin System Health Phase 2.
8+
9+
## Changes
10+
11+
- Added server-owned `serviceHealth` payload to the Admin System Health status API.
12+
- Added compact Service Health cards for Runtime, API, Database, Storage, Authentication, Email, and Background Jobs.
13+
- Used the requested visible statuses: Healthy, Warning, Failed, and Not Configured.
14+
- Kept Email and Background Jobs as production-safe Not Configured placeholders.
15+
- Updated API and Playwright System Health tests.
16+
17+
## Architecture Notes
18+
19+
- PASS: Current deployment only.
20+
- PASS: No cross-environment health checks were added.
21+
- PASS: Browser renders API/service contract state only.
22+
- PASS: Placeholder services do not fake successful health.
23+
24+
## Artifact
25+
26+
- `tmp/PR_26175_CHARLIE_013-service-health-dashboard_delta.zip`

docs_build/dev/reports/codex_changed_files.txt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@ M admin/system-health.html
66
M src/dev-runtime/server/local-api-router.mjs
77
M tests/dev-runtime/AdminHealthOperations.test.mjs
88
M tests/playwright/tools/AdminHealthOperationsPage.spec.mjs
9-
?? docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health-branch-validation.md
10-
?? docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health-manual-validation-notes.md
11-
?? docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health-requirement-checklist.md
12-
?? docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health-validation.md
13-
?? docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health.md
9+
?? docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard-branch-validation.md
10+
?? docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard-manual-validation-notes.md
11+
?? docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard-requirement-checklist.md
12+
?? docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard-validation.md
13+
?? docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard.md
1414

1515
# git ls-files --others --exclude-standard
16-
docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health-branch-validation.md
17-
docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health-manual-validation-notes.md
18-
docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health-requirement-checklist.md
19-
docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health-validation.md
20-
docs_build/dev/reports/PR_26175_CHARLIE_012-runtime-health.md
16+
docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard-branch-validation.md
17+
docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard-manual-validation-notes.md
18+
docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard-requirement-checklist.md
19+
docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard-validation.md
20+
docs_build/dev/reports/PR_26175_CHARLIE_013-service-health-dashboard.md
2121

2222
# git diff --stat
23-
admin/system-health.html | 22 +++++++++
24-
assets/theme-v2/js/admin-system-health.js | 56 ++++++++++++++++++++++
25-
.../dev/reports/coverage_changed_js_guardrail.txt | 5 +-
26-
.../dev/reports/playwright_v8_coverage_report.txt | 30 +++++-------
27-
src/dev-runtime/server/local-api-router.mjs | 43 ++++++++++++++++-
28-
tests/dev-runtime/AdminHealthOperations.test.mjs | 7 +++
29-
.../tools/AdminHealthOperationsPage.spec.mjs | 9 ++++
30-
7 files changed, 150 insertions(+), 22 deletions(-)
23+
admin/system-health.html | 16 +++
24+
assets/theme-v2/js/admin-system-health.js | 62 +++++++++++
25+
.../dev/reports/coverage_changed_js_guardrail.txt | 3 +-
26+
.../dev/reports/playwright_v8_coverage_report.txt | 12 +--
27+
src/dev-runtime/server/local-api-router.mjs | 115 +++++++++++++++++++++
28+
tests/dev-runtime/AdminHealthOperations.test.mjs | 10 ++
29+
.../tools/AdminHealthOperationsPage.spec.mjs | 9 ++
30+
7 files changed, 216 insertions(+), 11 deletions(-)

0 commit comments

Comments
 (0)