Skip to content

Commit 65becfe

Browse files
committed
Clean R2 stack reports and add Admin System Health with env-driven limits - PR_26168_226-through-228-system-health-stack
1 parent b2c04a1 commit 65becfe

20 files changed

Lines changed: 1806 additions & 2323 deletions

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,11 @@ GAMEFOUNDRY_STORAGE_ACCESS_KEY_ID=
2626
GAMEFOUNDRY_STORAGE_SECRET_ACCESS_KEY=
2727
GAMEFOUNDRY_STORAGE_BUCKET=
2828
GAMEFOUNDRY_STORAGE_PROJECTS_PREFIX=
29+
30+
# Environment-specific service limit placeholders.
31+
# Leave empty when live usage/limit reporting is not configured.
32+
GAMEFOUNDRY_STORAGE_LIMIT_BYTES=
33+
GAMEFOUNDRY_STORAGE_CLASS_A_LIMIT_MONTHLY=
34+
GAMEFOUNDRY_STORAGE_CLASS_B_LIMIT_MONTHLY=
35+
GAMEFOUNDRY_DB_SIZE_LIMIT_BYTES=
36+
GAMEFOUNDRY_DB_CONNECTION_LIMIT=

admin/infrastructure.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ <h2>Admin</h2>
3434
<nav class="accordion-body content-stack" aria-label="Admin tool pages" data-admin-tool-menu>
3535
<a class="btn btn--compact primary" aria-current="page" href="/admin/infrastructure.html">Infrastructure</a>
3636
<a class="btn btn--compact" href="/admin/platform-settings.html">Platform Settings</a>
37+
<a class="btn btn--compact" href="/admin/system-health.html">System Health</a>
3738
<a class="btn btn--compact" href="/admin/tool-votes.html">Tool Votes</a>
3839
<a class="btn btn--compact" href="/admin/users.html">Users</a>
3940
</nav>

admin/platform-settings.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ <h2>Admin</h2>
3434
<nav class="accordion-body content-stack" aria-label="Admin tool pages" data-admin-tool-menu>
3535
<a class="btn btn--compact" href="/admin/infrastructure.html">Infrastructure</a>
3636
<a class="btn btn--compact primary" aria-current="page" href="/admin/platform-settings.html">Platform Settings</a>
37+
<a class="btn btn--compact" href="/admin/system-health.html">System Health</a>
3738
<a class="btn btn--compact" href="/admin/tool-votes.html">Tool Votes</a>
3839
<a class="btn btn--compact" href="/admin/users.html">Users</a>
3940
</nav>

admin/system-health.html

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<!doctype html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<base href="/">
7+
<meta name="viewport" content="width=device-width, initial-scale=1">
8+
<title>System Health - Game Foundry Studio LLC</title>
9+
<meta name="description" content="Admin read-only system health status for account, product data, storage, environment, migrations, packages, and promotion safety.">
10+
<link rel="icon" href="/favicon.svg">
11+
<link rel="stylesheet" href="assets/theme-v2/css/theme.css">
12+
</head>
13+
14+
<body class="meaning-molten-orange">
15+
<div data-partial="header-nav"></div>
16+
<main data-admin-only="true" data-admin-system-health data-admin-wireframe="system-health">
17+
<section class="page-title">
18+
<div class="container">
19+
<div class="kicker">Admin</div>
20+
<h1>System Health</h1>
21+
<p class="lede">Review safe runtime readiness across account, Local DB, R2 storage, migrations, package planning, and promotion safety.</p>
22+
</div>
23+
</section>
24+
<section class="section">
25+
<div class="container container--tool-wide">
26+
<div class="tool-workspace tool-workspace--wide">
27+
<aside class="tool-column tool-group-platform">
28+
<div class="tool-column-header">
29+
<h2>Admin</h2>
30+
</div>
31+
<div class="accordion-stack">
32+
<details class="vertical-accordion" open>
33+
<summary>Admin Tools</summary>
34+
<nav class="accordion-body content-stack" aria-label="Admin tool pages" data-admin-tool-menu>
35+
<a class="btn btn--compact" href="/admin/infrastructure.html">Infrastructure</a>
36+
<a class="btn btn--compact" href="/admin/platform-settings.html">Platform Settings</a>
37+
<a class="btn btn--compact primary" aria-current="page" href="/admin/system-health.html">System Health</a>
38+
<a class="btn btn--compact" href="/admin/tool-votes.html">Tool Votes</a>
39+
<a class="btn btn--compact" href="/admin/users.html">Users</a>
40+
</nav>
41+
</details>
42+
<details class="vertical-accordion" open>
43+
<summary>Status Sources</summary>
44+
<div class="accordion-body content-stack">
45+
<p>Account/session readiness</p>
46+
<p>Product Data / Local DB</p>
47+
<p>Project Asset Storage / R2</p>
48+
<p>Project package readiness</p>
49+
</div>
50+
</details>
51+
</div>
52+
</aside>
53+
<div data-tool-display-mode data-asset-root="assets/theme-v2/images" data-tool-slug="admin-system-health" data-tool-icon-src="assets/theme-v2/images/image-missing.svg" data-tool-character-src="assets/theme-v2/images/image-missing.svg"></div>
54+
<section class="tool-center-panel content-stack" aria-labelledby="admin-system-health-title">
55+
<div>
56+
<div class="kicker">Read-only Status</div>
57+
<h2 id="admin-system-health-title">System Health Overview</h2>
58+
</div>
59+
<div class="table-wrapper">
60+
<table class="data-table" aria-label="System health overview">
61+
<caption>System Health Overview</caption>
62+
<thead>
63+
<tr>
64+
<th scope="col">Area</th>
65+
<th scope="col">Status</th>
66+
<th scope="col">Summary</th>
67+
</tr>
68+
</thead>
69+
<tbody data-admin-system-health-overview-rows>
70+
<tr><td>System Health</td><td>Loading</td><td>Loading safe status.</td></tr>
71+
</tbody>
72+
</table>
73+
</div>
74+
<div class="table-wrapper">
75+
<table class="data-table" aria-label="System health details">
76+
<caption>System Health Details</caption>
77+
<thead>
78+
<tr>
79+
<th scope="col">Area</th>
80+
<th scope="col">Field</th>
81+
<th scope="col">Status</th>
82+
<th scope="col">Value</th>
83+
</tr>
84+
</thead>
85+
<tbody data-admin-system-health-detail-rows>
86+
<tr><td>System Health</td><td>Status</td><td>Loading</td><td>Loading safe details.</td></tr>
87+
</tbody>
88+
</table>
89+
</div>
90+
<div class="table-wrapper">
91+
<table class="data-table" aria-label="System health environment limits">
92+
<caption>Environment Limits from current .env; values may differ by DEV/IST/UAT/PRD</caption>
93+
<thead>
94+
<tr>
95+
<th scope="col">Variable</th>
96+
<th scope="col">Limit</th>
97+
<th scope="col">Usage</th>
98+
<th scope="col">Pressure</th>
99+
<th scope="col">Next Step</th>
100+
</tr>
101+
</thead>
102+
<tbody data-admin-system-health-limit-rows>
103+
<tr><td>System Health</td><td>Loading</td><td>Loading</td><td>Loading</td><td>Loading limit diagnostics.</td></tr>
104+
</tbody>
105+
</table>
106+
</div>
107+
</section>
108+
<aside class="tool-column tool-group-platform">
109+
<div class="tool-column-header">
110+
<h2>Inspector</h2>
111+
</div>
112+
<div class="accordion-stack">
113+
<details class="vertical-accordion" open>
114+
<summary>Status</summary>
115+
<div class="accordion-body content-stack">
116+
<p class="status" role="status" data-admin-system-health-status>Loading Admin System Health.</p>
117+
</div>
118+
</details>
119+
<details class="vertical-accordion" open>
120+
<summary>Related Pages</summary>
121+
<div class="accordion-body content-stack">
122+
<a class="btn btn--compact" href="/admin/infrastructure.html">Infrastructure Reference</a>
123+
<a class="btn btn--compact" href="/owner/operations.html">Owner Operations Actions</a>
124+
</div>
125+
</details>
126+
<details class="vertical-accordion" open>
127+
<summary>Guardrails</summary>
128+
<div class="accordion-body content-stack">
129+
<p>System Health is read-only and does not expose secrets.</p>
130+
<p>Infrastructure remains the architecture reference page.</p>
131+
<p>Owner Operations remains the action page.</p>
132+
</div>
133+
</details>
134+
</div>
135+
</aside>
136+
</div>
137+
</div>
138+
</section>
139+
</main>
140+
<div data-partial="footer"></div>
141+
<script src="assets/theme-v2/js/gamefoundry-partials.js" defer></script>
142+
<script src="assets/theme-v2/js/tool-display-mode.js" defer></script>
143+
<script type="module" src="assets/theme-v2/js/admin-system-health.js"></script>
144+
</body>
145+
146+
</html>

admin/tool-votes.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ <h2>Admin</h2>
3434
<nav class="accordion-body content-stack" aria-label="Admin tool pages" data-admin-tool-menu>
3535
<a class="btn btn--compact" href="/admin/infrastructure.html">Infrastructure</a>
3636
<a class="btn btn--compact" href="/admin/platform-settings.html">Platform Settings</a>
37+
<a class="btn btn--compact" href="/admin/system-health.html">System Health</a>
3738
<a class="btn btn--compact primary" aria-current="page" href="/admin/tool-votes.html">Tool Votes</a>
3839
<a class="btn btn--compact" href="/admin/users.html">Users</a>
3940
</nav>

admin/users.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ <h2>Admin</h2>
3434
<nav class="accordion-body content-stack" aria-label="Admin tool pages" data-admin-tool-menu>
3535
<a class="btn btn--compact" href="/admin/infrastructure.html">Infrastructure</a>
3636
<a class="btn btn--compact" href="/admin/platform-settings.html">Platform Settings</a>
37+
<a class="btn btn--compact" href="/admin/system-health.html">System Health</a>
3738
<a class="btn btn--compact" href="/admin/tool-votes.html">Tool Votes</a>
3839
<a class="btn btn--compact primary" aria-current="page" href="/admin/users.html">Users</a>
3940
</nav>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import {
2+
readAdminSystemHealthStatus
3+
} from "../../../src/engine/api/admin-system-health-api-client.js";
4+
5+
class AdminSystemHealthController {
6+
constructor(root) {
7+
this.root = root;
8+
this.details = root.querySelector("[data-admin-system-health-detail-rows]");
9+
this.limits = root.querySelector("[data-admin-system-health-limit-rows]");
10+
this.overview = root.querySelector("[data-admin-system-health-overview-rows]");
11+
this.status = root.querySelector("[data-admin-system-health-status]");
12+
}
13+
14+
init() {
15+
if (!this.details || !this.limits || !this.overview || !this.status) {
16+
return;
17+
}
18+
this.load();
19+
}
20+
21+
setStatus(status, message) {
22+
this.status.textContent = `${status}: ${message}`;
23+
}
24+
25+
createRow(values) {
26+
const row = document.createElement("tr");
27+
values.forEach((value) => {
28+
const cell = document.createElement("td");
29+
cell.textContent = value;
30+
row.append(cell);
31+
});
32+
return row;
33+
}
34+
35+
renderOverview(rows) {
36+
this.overview.replaceChildren();
37+
rows.forEach((row) => {
38+
this.overview.append(this.createRow([
39+
row.area || "Unknown",
40+
row.status || "WARN",
41+
row.summary || "Status unavailable.",
42+
]));
43+
});
44+
}
45+
46+
renderDetails(rows) {
47+
this.details.replaceChildren();
48+
rows.forEach((row) => {
49+
this.details.append(this.createRow([
50+
row.area || "Unknown",
51+
row.field || "Status",
52+
row.status || "WARN",
53+
row.value || "not available",
54+
]));
55+
});
56+
}
57+
58+
renderLimits(rows) {
59+
this.limits.replaceChildren();
60+
rows.forEach((row) => {
61+
this.limits.append(this.createRow([
62+
row.variableName || "Unknown",
63+
row.limit || "not configured",
64+
row.usage || "NOT AVAILABLE",
65+
row.pressure || "NOT AVAILABLE",
66+
row.nextStep || "Add safe service usage reporting through the Local API.",
67+
]));
68+
});
69+
}
70+
71+
load() {
72+
try {
73+
const payload = readAdminSystemHealthStatus();
74+
this.renderOverview(Array.isArray(payload.overview) ? payload.overview : []);
75+
this.renderDetails(Array.isArray(payload.details) ? payload.details : []);
76+
this.renderLimits(Array.isArray(payload.limits) ? payload.limits : []);
77+
this.setStatus(payload.status || "WARN", payload.message || "Admin System Health loaded.");
78+
} catch (error) {
79+
this.renderOverview([
80+
{
81+
area: "System Health",
82+
status: "FAIL",
83+
summary: error instanceof Error ? error.message : "Admin System Health unavailable.",
84+
},
85+
]);
86+
this.renderDetails([]);
87+
this.renderLimits([]);
88+
this.setStatus("FAIL", error instanceof Error ? error.message : "Admin System Health unavailable.");
89+
}
90+
}
91+
}
92+
93+
document.addEventListener("DOMContentLoaded", () => {
94+
const root = document.querySelector("[data-admin-system-health]");
95+
if (!root) {
96+
return;
97+
}
98+
new AdminSystemHealthController(root).init();
99+
});

assets/theme-v2/js/gamefoundry-partials.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
"admin-ratings": "admin/ratings.html",
8989
"admin-users": "admin/users.html",
9090
"admin-roles": "admin/roles.html",
91+
"admin-system-health": "admin/system-health.html",
9192
"admin-tool-votes": "admin/tool-votes.html",
9293
"admin-moderation": "admin/moderation.html",
9394
"admin-analytics": "admin/analytics.html",

0 commit comments

Comments
 (0)