Skip to content

Commit d39cc8c

Browse files
committed
Merge Team Charlie system health and R2 storage closeout
2 parents 8ac1bb1 + a46c39f commit d39cc8c

25 files changed

Lines changed: 2482 additions & 273 deletions

.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ GAMEFOUNDRY_DB_BACKUP_DIR=
5050

5151
# Server-only project asset storage configuration.
5252
# Browser uploads must go through the server API and must not receive these secrets.
53+
# Approved GAMEFOUNDRY_STORAGE_PROJECTS_PREFIX values:
54+
# DEV /dev/projects/
55+
# IST /ist/projects/
56+
# UAT /uat/projects/
57+
# PRD /prod/projects/
5358
GAMEFOUNDRY_STORAGE_ENDPOINT=
5459
GAMEFOUNDRY_STORAGE_ACCESS_KEY_ID=
5560

admin/infrastructure.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ <h2>Admin</h2>
4141
<p>/dev/projects/</p>
4242
<p>/ist/projects/</p>
4343
<p>/uat/projects/</p>
44-
<p>/prd/projects/</p>
44+
<p>/prod/projects/</p>
4545
</div>
4646
</details>
4747
</div>
@@ -81,7 +81,7 @@ <h3 id="admin-infrastructure-image-zoom-title">Game Foundry Infrastructure</h3>
8181
<tr><td>DEV</td><td>/dev/projects/</td><td>Loading</td></tr>
8282
<tr><td>IST</td><td>/ist/projects/</td><td>Loading</td></tr>
8383
<tr><td>UAT</td><td>/uat/projects/</td><td>Loading</td></tr>
84-
<tr><td>PRD</td><td>/prd/projects/</td><td>Loading</td></tr>
84+
<tr><td>PRD</td><td>/prod/projects/</td><td>Loading</td></tr>
8585
</tbody>
8686
</table>
8787
</div>

admin/system-health.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ <h2>Admin</h2>
3939
<summary>Health Sections</summary>
4040
<div class="accordion-body content-stack">
4141
<p>Environment Summary</p>
42+
<p>Local API Startup</p>
4243
<p>Database Health</p>
4344
<p>Storage Health</p>
4445
<p>Runtime Environment</p>
@@ -74,6 +75,21 @@ <h2 id="admin-system-health-title">System Health Tables</h2>
7475
</tbody>
7576
</table>
7677
</div>
78+
<div class="table-wrapper">
79+
<table class="data-table" aria-label="Local API startup diagnostics">
80+
<caption>Local API Startup Diagnostics</caption>
81+
<thead>
82+
<tr>
83+
<th scope="col">Field</th>
84+
<th scope="col">Safe Value</th>
85+
<th scope="col">Status</th>
86+
</tr>
87+
</thead>
88+
<tbody data-admin-system-health-startup-rows>
89+
<tr><td>Startup diagnostics</td><td>Waiting for safe API status</td><td data-health-status="PENDING" title="Reason: safe Local API startup diagnostics have not loaded yet." aria-label="PENDING: safe Local API startup diagnostics have not loaded yet.">PENDING</td></tr>
90+
</tbody>
91+
</table>
92+
</div>
7793
<div class="table-wrapper">
7894
<table class="data-table" aria-label="Database health">
7995
<caption>Database Health - Postgres Only</caption>

assets/theme-v2/js/admin-infrastructure.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const STORAGE_PATH_LANES = Object.freeze([
66
Object.freeze({ lane: "DEV", path: "/dev/projects/" }),
77
Object.freeze({ lane: "IST", path: "/ist/projects/" }),
88
Object.freeze({ lane: "UAT", path: "/uat/projects/" }),
9-
Object.freeze({ lane: "PRD", path: "/prd/projects/" }),
9+
Object.freeze({ lane: "PRD", path: "/prod/projects/" }),
1010
]);
1111

1212
class AdminInfrastructureStoragePathStatus {

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class AdminSystemHealthController {
3838
node.dataset.adminSystemHealthStorageStatus,
3939
node,
4040
]));
41+
this.startupRows = root.querySelector("[data-admin-system-health-startup-rows]");
4142
this.runtimeRows = root.querySelector("[data-admin-system-health-runtime-rows]");
4243
}
4344

@@ -80,6 +81,7 @@ class AdminSystemHealthController {
8081
["host", "database", "migration", "connection"].forEach((key) => {
8182
this.setStatus(key, "PENDING", reason);
8283
});
84+
this.renderStartupPending(reason);
8385
this.renderStoragePending(reason);
8486
}
8587

@@ -118,6 +120,45 @@ class AdminSystemHealthController {
118120
this.setStorageStatus("bucket", storageStatus.bucketStatus || storageStatus.status, reason);
119121
}
120122

123+
renderStartupPending(reason) {
124+
if (!this.startupRows) {
125+
return;
126+
}
127+
const row = document.createElement("tr");
128+
row.append(
129+
this.createCell("Local API startup diagnostics"),
130+
this.createCell("not available"),
131+
this.createStatusCell("PENDING", reason),
132+
);
133+
this.startupRows.replaceChildren(row);
134+
}
135+
136+
renderStartupDiagnostics(localApiStartup = {}) {
137+
if (!this.startupRows) {
138+
return;
139+
}
140+
if (localApiStartup?.secretsExposed === true || localApiStartup?.secretEditingAllowed === true) {
141+
this.renderStartupPending("Safe Local API startup diagnostics were blocked because the response exposed secret controls.");
142+
return;
143+
}
144+
const rows = Array.isArray(localApiStartup.rows) ? localApiStartup.rows : [];
145+
if (!rows.length) {
146+
this.renderStartupPending("Safe Local API startup diagnostics returned no rows.");
147+
return;
148+
}
149+
const fragment = document.createDocumentFragment();
150+
rows.forEach((startupRow) => {
151+
const row = document.createElement("tr");
152+
row.append(
153+
this.createCell(startupRow.field),
154+
this.createCell(startupRow.value),
155+
this.createStatusCell(startupRow.status, startupRow.reason || localApiStartup.message),
156+
);
157+
fragment.append(row);
158+
});
159+
this.startupRows.replaceChildren(fragment);
160+
}
161+
121162
storageResultTarget(result = {}) {
122163
if (typeof result.keysListed === "number" && result.actionId === "storage-list") {
123164
return `${result.keysListed} object(s) under ${asText(result.projectsPrefix, "configured prefix")}`;
@@ -210,6 +251,7 @@ class AdminSystemHealthController {
210251
return;
211252
}
212253
this.renderPostgresStatus(data?.databaseStatus || {});
254+
this.renderStartupDiagnostics(data?.localApiStartup || {});
213255
this.renderStorageStatus(data?.storageStatus || {});
214256
this.runStorageDiagnostics();
215257
this.renderRuntimeEnvironment(data?.runtimeEnvironment || {});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# PR_26175_CHARLIE_002 Instruction Compliance Checklist
2+
3+
| Requirement | Status | Evidence |
4+
|---|---:|---|
5+
| Read active ProjectInstructions | PASS | Reviewed README, root Project Instructions, team ownership, and PLAN report. |
6+
| Active branch remains Charlie stack branch | PASS | Branch is `PR_26172_CHARLIE_repository-compliance-stack`. |
7+
| Worktree clean before implementation | PASS | Start gate showed clean worktree. |
8+
| Implement only approved System Health dashboard scope | PASS | Changes are limited to System Health page/controller/API status payload and targeted tests. |
9+
| Preserve existing Postgres behavior | PASS | Database Health rendering and payload remain in place. |
10+
| Preserve existing R2 behavior | PASS | Storage Health and connectivity action behavior remain in place. |
11+
| Preserve Runtime Environment behavior | PASS | Runtime environment rows continue to mask secret-like values. |
12+
| Preserve Limits behavior | PASS | Limits/capacity table and payload remain in place. |
13+
| Preserve Diagnostics Plan and Diagnostics Log behavior | PASS | Existing tables remain in the page. |
14+
| Use PASS/WARN/FAIL/PENDING correctly | PASS | Deferred configurable multiple runtime ports are `PENDING`; real status rows use `PASS`/`WARN`. |
15+
| Every non-PASS status has reason text | PASS | Startup rendering uses existing `applyStatusNode()` helper with reason text. |
16+
| Do not expose secrets | PASS | URL credentials are redacted; tests assert raw credentials are absent. |
17+
| Do not implement telemetry | PASS | No telemetry code or route added. |
18+
| Do not implement configurable runtime ports | PASS | Multiple runtime ports are only marked deferred/cancelled. |
19+
| Required reports created | PASS | PR report, manual notes, checklist, Codex diff, and changed-files report created. |
20+
| Repo-structured ZIP under `tmp/` | PASS | `tmp/PR_26175_CHARLIE_002-system-health-dashboard_delta.zip`. |
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# PR_26175_CHARLIE_002 Manual Validation Notes
2+
3+
## Manual Review
4+
5+
- Confirmed active branch was `PR_26172_CHARLIE_repository-compliance-stack`.
6+
- Confirmed implementation stayed within Admin System Health dashboard and Local API status payload.
7+
- Confirmed no Team Bravo branch changes were made.
8+
- Confirmed no telemetry implementation was added.
9+
- Confirmed configurable multiple runtime ports are reported as `PENDING` / `deferred/cancelled` only.
10+
- Confirmed Postgres, R2, Runtime Environment, Limits, Diagnostics Plan, and Diagnostics Log sections remain present.
11+
12+
## Secret Exposure Review
13+
14+
- Local API startup diagnostic URL display removes username/password credentials.
15+
- Runtime secret masking behavior remains unchanged.
16+
- Targeted API test checks raw API URL and site URL credentials are not serialized in the `localApiStartup` payload.
17+
- Targeted Playwright test checks System Health page does not expose test secret values.
18+
19+
## Validation Results
20+
21+
- `git diff --check`: PASS.
22+
- `node --test tests/dev-runtime/LocalApiStartupLogging.test.mjs`: PASS.
23+
- `node --test tests/dev-runtime/AdminHealthOperations.test.mjs`: PASS.
24+
- `npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs`: PASS.
25+
26+
## Notes
27+
28+
- Playwright refreshed coverage report artifacts during validation; those generated changes were restored because they are outside this PR's required report set.
29+
- No samples were run.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# PR_26175_CHARLIE_002-system-health-dashboard
2+
3+
## Summary
4+
5+
Implemented the approved System Health dashboard increment for safe Local API startup diagnostics.
6+
7+
The dashboard now surfaces a server-owned Local API Startup Diagnostics table that reports:
8+
9+
- approved startup diagnostics format availability
10+
- Environment Variables section masking/redaction behavior
11+
- configured startup bind target
12+
- configured site URL status
13+
- configured or derived API URL
14+
- configured API URL port
15+
- configurable multiple runtime ports as `PENDING` and `deferred/cancelled`
16+
17+
The implementation preserves existing Postgres, R2, Runtime Environment, Limits, Diagnostics Plan, and Diagnostics Log behavior.
18+
19+
## Scope Controls
20+
21+
| Requirement | Result | Notes |
22+
|---|---:|---|
23+
| Active branch remains `PR_26172_CHARLIE_repository-compliance-stack` | PASS | Work stayed on the Charlie stack branch. |
24+
| Implement only approved System Health dashboard scope | PASS | Changes are limited to Admin System Health dashboard/API status and targeted tests. |
25+
| Preserve existing Postgres behavior | PASS | Existing database status rendering and server payload remain intact. |
26+
| Preserve existing R2 behavior | PASS | Existing storage status and connectivity action behavior remain intact. |
27+
| Preserve Runtime Environment behavior | PASS | Existing runtime environment masking/rendering remains intact. |
28+
| Preserve Limits behavior | PASS | Existing limits/capacity rows and usage placeholders remain intact. |
29+
| Preserve Diagnostics Plan and Diagnostics Log behavior | PASS | Existing tables remain; only Local API startup diagnostics table was added. |
30+
| Use PASS/WARN/FAIL/PENDING correctly | PASS | Real known-good checks are `PASS`; missing configured site URL is `WARN`; deferred multiple runtime ports is `PENDING`. |
31+
| Do not expose secrets | PASS | URL credentials are redacted, secret values are not returned, and tests assert no raw credentials appear. |
32+
| Do not implement telemetry | PASS | No telemetry collection, storage, route, or metric implementation was added. |
33+
| Do not implement configurable runtime ports | PASS | Multiple runtime ports are explicitly reported as `PENDING` / `deferred/cancelled`. |
34+
35+
## Files Changed
36+
37+
- `admin/system-health.html`
38+
- `assets/theme-v2/js/admin-system-health.js`
39+
- `src/dev-runtime/server/local-api-router.mjs`
40+
- `tests/dev-runtime/AdminHealthOperations.test.mjs`
41+
- `tests/playwright/tools/AdminHealthOperationsPage.spec.mjs`
42+
- `docs_build/dev/reports/PR_26175_CHARLIE_002-system-health-dashboard.md`
43+
- `docs_build/dev/reports/PR_26175_CHARLIE_002-system-health-dashboard-manual-validation-notes.md`
44+
- `docs_build/dev/reports/PR_26175_CHARLIE_002-system-health-dashboard-instruction-compliance-checklist.md`
45+
- `docs_build/dev/reports/codex_review.diff`
46+
- `docs_build/dev/reports/codex_changed_files.txt`
47+
48+
## Implementation Notes
49+
50+
- Added `systemHealthLocalApiStartupDiagnostics()` in the Local API router so the browser receives structured, sanitized diagnostics instead of parsing startup console output.
51+
- Added a `localApiStartup` payload to `/api/admin/system-health/status`.
52+
- Added Local API Startup Diagnostics table markup to `admin/system-health.html`.
53+
- Extended `assets/theme-v2/js/admin-system-health.js` to render startup diagnostic rows using the existing shared status helpers.
54+
- Added API-level tests for local startup diagnostics rows, deferred runtime ports, and URL credential redaction.
55+
- Added Playwright coverage for the new dashboard table and static markup.
56+
57+
## Validation Lane Report
58+
59+
| Command | Result |
60+
|---|---:|
61+
| `git diff --check` | PASS |
62+
| `node --test tests/dev-runtime/LocalApiStartupLogging.test.mjs` | PASS, 2 tests |
63+
| `node --test tests/dev-runtime/AdminHealthOperations.test.mjs` | PASS, 4 tests |
64+
| `npx playwright test tests/playwright/tools/AdminHealthOperationsPage.spec.mjs` | PASS, 3 tests |
65+
66+
## Skipped Lanes
67+
68+
- Full samples smoke: skipped; the scope is Admin System Health dashboard diagnostics only.
69+
- Broad Playwright suite: skipped; targeted System Health coverage passed.
70+
- Telemetry validation: skipped; telemetry was explicitly out of scope and not implemented.
71+
- Configurable runtime port validation: skipped; configurable multiple runtime ports were explicitly deferred/cancelled and not implemented.
72+
73+
## Dependency Notes
74+
75+
The current branch already contains the approved Local API startup diagnostics formatter shape:
76+
77+
- deterministic `Environment Variables` section
78+
- deterministic `All Runtime Ports being used by Service` section
79+
- secret-like value masking
80+
- URL credential redaction
81+
82+
Validation confirmed the startup formatter remains intact through `tests/dev-runtime/LocalApiStartupLogging.test.mjs`.
83+
84+
## ZIP Artifact
85+
86+
Repo-structured delta ZIP:
87+
88+
- `tmp/PR_26175_CHARLIE_002-system-health-dashboard_delta.zip`

0 commit comments

Comments
 (0)