Skip to content

Commit 8a6ea6d

Browse files
committed
Recover local API routes and missing tool script dependency - PR_26158_029-api-static-route-recovery
1 parent cca34ba commit 8a6ea6d

12 files changed

Lines changed: 239 additions & 39 deletions

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@
138138
return rootPrefix() + (routeMap[routeName] || routeName || "index.html");
139139
}
140140

141+
function localRouteUnavailableDiagnostic(method, url, status) {
142+
return "Local server API route unavailable for " + method + " " + url + " (" + status + "). Start the API-backed local server route instead of a static-only server.";
143+
}
144+
141145
function rewriteRootedPaths(root) {
142146
root.querySelectorAll("[data-route]").forEach(function (link) {
143147
link.setAttribute("href", routeHref(link.dataset.route));
@@ -156,6 +160,9 @@
156160
request.send(null);
157161
const payload = request.responseText ? JSON.parse(request.responseText) : null;
158162
if (request.status < 200 || request.status >= 300 || payload?.ok === false) {
163+
if (request.status === 404 || request.status === 405) {
164+
throw new Error(localRouteUnavailableDiagnostic("GET", "/api/session/current", request.status));
165+
}
159166
throw new Error(payload?.error || "Session API did not return a valid current session.");
160167
}
161168
const session = payload?.data || {};
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# PR_26158_029 API Static Route Recovery Report
2+
3+
## Summary
4+
5+
Recovered login/session API route probes, made 404/405 diagnostics actionable, and filtered named browser-extension noise without adding UAT/Prod adapters or changing `start_of_day`.
6+
7+
## Artifact
8+
9+
- Delta ZIP: `tmp/PR_26158_029-api-static-route-recovery_delta.zip`
10+
11+
## Requirement Checklist
12+
13+
| Requirement | Status | Evidence |
14+
| --- | --- | --- |
15+
| Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` first. | PASS | Read before edits. |
16+
| Fix `ShowOneChild.js` failing because `ActionableCoachmark` is not defined before use. | PASS | No active repo runtime file contains `ShowOneChild` or `ActionableCoachmark`; extension script failures are filtered by `tests/helpers/browserExtensionNoise.mjs` without defining globals or masking bare repo `ActionableCoachmark` errors. |
17+
| Fix `localDevLoginState` 404 from `gamefoundry-partials.js`. | PASS | `assets/theme-v2/js/gamefoundry-partials.js` now reports actionable local API route diagnostics for 404/405 instead of the generic session failure. |
18+
| Fix `server-api-client.js` 404/405 for local server API calls used by login/session mode. | PASS | `src/engine/api/server-api-client.js` reports actionable 404/405 diagnostics, and `src/dev-runtime/server/mock-api-router.mjs` supports session `HEAD` probes and API `OPTIONS` probes. `ApiStaticRouteRecovery.spec.mjs` verifies no 404/405 for login/session route calls. |
19+
| Ignore browser extension errors from `ch-content-script-dend.js` and `content-script-idle.js` unless repo code is causing global pollution. | PASS | `tests/helpers/browserExtensionNoise.mjs` ignores only named extension script files. Bare repo errors without those script names still fail the lanes. |
20+
| Preserve Local Mem and Local DB clickability. | PASS | `LoginSessionMode.spec.mjs` and `ApiStaticRouteRecovery.spec.mjs` assert both controls are enabled. |
21+
| Preserve SQLite-backed Local DB behind API boundary. | PASS | LoginSessionMode and AdminDbViewer Local DB tests passed. Browser code still calls API clients/server routes only. |
22+
| Do not add UAT/Prod API adapter behavior. | PASS | No adapter behavior added; only session route probe handling and diagnostics changed. |
23+
| Do not expose UAT or Prod as local login choices. | PASS | LoginSessionMode and ApiStaticRouteRecovery assert UAT/Prod buttons are absent. |
24+
| Do not modify `start_of_day` folders. | PASS | Changed-file list contains no `start_of_day` paths. |
25+
| Run changed-file syntax checks. | PASS | All changed JS/spec files passed `node --check`. |
26+
| Run LoginSessionMode Playwright. | PASS | `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs` passed 5/5. |
27+
| Run targeted local API route validation for login/session endpoints. | PASS | `npx playwright test tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs` passed 1/1. |
28+
| Run ToolboxRoutePages Playwright. | PASS | `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` passed 1/1. |
29+
| Run AdminDbViewer Playwright if DB route behavior is touched. | PASS | `npx playwright test tests/playwright/tools/AdminDbViewer.spec.mjs` passed 7/7 because the API router was touched. |
30+
| Do not run full samples smoke unless directly impacted. | PASS | Full samples smoke skipped because no samples or shared sample loader/framework changed. |
31+
32+
## Files Changed
33+
34+
- `assets/theme-v2/js/gamefoundry-partials.js`
35+
- `src/engine/api/server-api-client.js`
36+
- `src/dev-runtime/server/mock-api-router.mjs`
37+
- `tests/helpers/browserExtensionNoise.mjs`
38+
- `tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs`
39+
- `tests/playwright/tools/LoginSessionMode.spec.mjs`
40+
- `tests/playwright/tools/ToolboxRoutePages.spec.mjs`
41+
- `tests/playwright/tools/AdminDbViewer.spec.mjs`
42+
- `docs_build/dev/reports/testing_lane_execution_report.md`
43+
- `docs_build/dev/reports/api-static-route-recovery-report.md`
44+
- `docs_build/dev/reports/playwright_v8_coverage_report.txt`
45+
- `docs_build/dev/reports/coverage_changed_js_guardrail.txt`
46+
- `docs_build/dev/reports/codex_review.diff`
47+
- `docs_build/dev/reports/codex_changed_files.txt`
48+
49+
## Validation Commands
50+
51+
| Command | Result |
52+
| --- | --- |
53+
| `node --check assets/theme-v2/js/gamefoundry-partials.js` | PASS |
54+
| `node --check src/engine/api/server-api-client.js` | PASS |
55+
| `node --check src/dev-runtime/server/mock-api-router.mjs` | PASS |
56+
| `node --check tests/helpers/browserExtensionNoise.mjs` | PASS |
57+
| `node --check tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs` | PASS |
58+
| `node --check tests/playwright/tools/LoginSessionMode.spec.mjs` | PASS |
59+
| `node --check tests/playwright/tools/ToolboxRoutePages.spec.mjs` | PASS |
60+
| `node --check tests/playwright/tools/AdminDbViewer.spec.mjs` | PASS |
61+
| `npx playwright test tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs` | PASS, 1/1 |
62+
| `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs` | PASS, 5/5 |
63+
| `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` | PASS, 1/1 |
64+
| `npx playwright test tests/playwright/tools/AdminDbViewer.spec.mjs` | PASS, 7/7 |
65+
| `git diff --check` | PASS, with Git line-ending warnings only |
66+
67+
## Notes
68+
69+
- `ShowOneChild.js`, `ch-content-script-dend.js`, and `content-script-idle.js` are not repo-owned active runtime files. The recovery is intentionally limited to test noise filtering for those named extension scripts plus evidence that repo code is not defining or depending on `ActionableCoachmark`.
70+
- Node emitted the standard experimental warning for `node:sqlite` during Playwright lanes; validation passed.

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ Missing changed runtime JS files are WARN, not FAIL.
66
Source: Playwright/Chromium built-in V8 coverage from the active Playwright run.
77

88
Changed runtime JS files considered:
9-
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
109
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
11-
(60%) src/engine/api/mock-db-api-client.js - executed lines 19/19; executed functions 3/5
12-
(85%) src/engine/api/mock-db-viewer-ui.js - executed lines 510/510; executed functions 82/96
10+
(63%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 12/19
1311

1412
Guardrail warnings:
15-
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file missing from coverage; advisory only
1613
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file missing from coverage; advisory only

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,40 @@ Note: entry percentages use function coverage when available, otherwise line cov
1212
Note: coverage entries are aggregated across every page/tool where coverageReporter.start(page) and coverageReporter.stop(page) ran.
1313

1414
Exercised tool entry points detected:
15-
(61%) Toolbox Index - exercised 3 runtime JS files
15+
(77%) Toolbox Index - exercised 7 runtime JS files
1616
(0%) Tool Template V2 - not exercised by this Playwright run
17-
(84%) Theme V2 Shared JS - exercised 3 runtime JS files
17+
(73%) Theme V2 Shared JS - exercised 2 runtime JS files
1818

1919
Changed runtime JS files covered:
20-
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
2120
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
22-
(60%) src/engine/api/mock-db-api-client.js - executed lines 19/19; executed functions 3/5
23-
(85%) src/engine/api/mock-db-viewer-ui.js - executed lines 510/510; executed functions 82/96
21+
(63%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 12/19
2422

2523
Files with executed line/function counts where available:
26-
(55%) toolbox/project-journey/project-journey.js - executed lines 1003/1003; executed functions 54/99
27-
(56%) src/engine/api/server-api-client.js - executed lines 154/154; executed functions 10/18
28-
(60%) src/engine/api/mock-db-api-client.js - executed lines 19/19; executed functions 3/5
24+
(63%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 12/19
2925
(64%) assets/theme-v2/js/tool-display-mode.js - executed lines 201/201; executed functions 9/14
3026
(67%) admin/db-viewer.js - executed lines 53/53; executed functions 4/6
27+
(69%) toolbox/colors/colors.js - executed lines 877/877; executed functions 62/90
28+
(75%) toolbox/project-journey/project-journey.js - executed lines 1003/1003; executed functions 74/99
29+
(76%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 421/421; executed functions 29/38
3130
(81%) toolbox/tool-registry-api-client.js - executed lines 148/148; executed functions 22/27
32-
(85%) src/engine/api/mock-db-viewer-ui.js - executed lines 510/510; executed functions 82/96
33-
(86%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 415/415; executed functions 32/37
34-
(88%) src/engine/api/session-api-client.js - executed lines 34/34; executed functions 7/8
35-
(94%) assets/theme-v2/js/login-session.js - executed lines 163/163; executed functions 15/16
31+
(88%) toolbox/assets/assets.js - executed lines 519/519; executed functions 53/60
32+
(96%) src/engine/api/mock-db-viewer-ui.js - executed lines 510/510; executed functions 92/96
33+
(100%) src/engine/api/mock-db-api-client.js - executed lines 19/19; executed functions 5/5
34+
(100%) toolbox/assets/assets-api-client.js - executed lines 17/17; executed functions 3/3
35+
(100%) toolbox/colors/palette-api-client.js - executed lines 19/19; executed functions 4/4
3636
(100%) toolbox/project-journey/project-journey-api-client.js - executed lines 12/12; executed functions 2/2
3737

3838
Uncovered or low-coverage changed JS files:
39-
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: uncovered changed runtime JS file; advisory only
4039
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: uncovered changed runtime JS file; advisory only
4140

4241
Changed JS files considered:
43-
(0%) src/dev-runtime/persistence/mock-db-store.js - changed JS file not collected as browser runtime coverage
42+
(0%) assets/theme-v2/js/login-session.js - changed JS file not collected as browser runtime coverage
4443
(0%) src/dev-runtime/server/mock-api-router.mjs - changed JS file not collected as browser runtime coverage
44+
(0%) tests/helpers/browserExtensionNoise.mjs - changed JS file not collected as browser runtime coverage
45+
(0%) tests/helpers/playwrightRepoServer.mjs - changed JS file not collected as browser runtime coverage
4546
(0%) tests/playwright/tools/AdminDbViewer.spec.mjs - changed JS file not collected as browser runtime coverage
47+
(0%) tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs - changed JS file not collected as browser runtime coverage
4648
(0%) tests/playwright/tools/LoginSessionMode.spec.mjs - changed JS file not collected as browser runtime coverage
47-
(60%) src/engine/api/mock-db-api-client.js - changed JS file with browser V8 coverage
48-
(67%) admin/db-viewer.js - changed JS file with browser V8 coverage
49-
(85%) src/engine/api/mock-db-viewer-ui.js - changed JS file with browser V8 coverage
49+
(0%) tests/playwright/tools/ToolboxRoutePages.spec.mjs - changed JS file not collected as browser runtime coverage
50+
(63%) src/engine/api/server-api-client.js - changed JS file with browser V8 coverage
51+
(76%) assets/theme-v2/js/gamefoundry-partials.js - changed JS file with browser V8 coverage
Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
1-
# PR_26158_028 Testing Lane Execution Report
1+
# PR_26158_029 Testing Lane Execution Report
22

33
## Lanes Run
44

55
| Lane | Command | Result |
66
| --- | --- | --- |
7-
| Changed-file syntax | `node --check assets/theme-v2/js/login-session.js`; `node --check tests/helpers/playwrightRepoServer.mjs`; `node --check tests/playwright/tools/LoginSessionMode.spec.mjs`; `node --check tests/playwright/tools/ToolboxRoutePages.spec.mjs` | PASS |
7+
| Changed-file syntax | `node --check assets/theme-v2/js/gamefoundry-partials.js`; `node --check src/engine/api/server-api-client.js`; `node --check src/dev-runtime/server/mock-api-router.mjs`; `node --check tests/helpers/browserExtensionNoise.mjs`; `node --check tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs`; `node --check tests/playwright/tools/LoginSessionMode.spec.mjs`; `node --check tests/playwright/tools/ToolboxRoutePages.spec.mjs`; `node --check tests/playwright/tools/AdminDbViewer.spec.mjs` | PASS |
8+
| Local API route validation | `npx playwright test tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs` | PASS, 1/1 |
89
| LoginSessionMode Playwright | `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs` | PASS, 5/5 |
9-
| Toolbox route/page smoke | `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` | PASS, 1/1 after correcting a stale expected H1 in the new smoke spec |
10+
| ToolboxRoutePages Playwright | `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` | PASS, 1/1 |
1011
| AdminDbViewer Playwright | `npx playwright test tests/playwright/tools/AdminDbViewer.spec.mjs` | PASS, 7/7 |
1112
| Changed-file/static validation | `git diff --check` | PASS, with Git line-ending warnings only |
13+
| Runtime JS V8 coverage | Playwright coverage generated by targeted runs | PASS/WARN; `docs_build/dev/reports/playwright_v8_coverage_report.txt` lists changed runtime JS coverage. `src/dev-runtime/server/mock-api-router.mjs` is server-side and reported as advisory WARN. |
1214

1315
## Validation Notes
1416

1517
| Check | Evidence | Result |
1618
| --- | --- | --- |
17-
| Local Mem and Local DB mode controls are enabled on the login page. | `LoginSessionMode.spec.mjs` asserts both `[data-login-mode='local-mem']` and `[data-login-mode='local-db']` are enabled before and after selecting Local DB. | PASS |
18-
| Local DB remains selected when choosing a local user. | `LoginSessionMode.spec.mjs` asserts session mode remains `local-db` and persistence remains `Local DB` after selecting User 2. | PASS |
19-
| `/tools/.../index.html` route aliases render toolbox pages. | `ToolboxRoutePages.spec.mjs` opens `/tools/project-journey/index.html`, `/tools/colors/index.html`, and `/tools/assets/index.html` and verifies visible H1/main content with no failed requests. | PASS |
20-
| Local Mem behavior is preserved. | LoginSessionMode and AdminDbViewer Local Mem coverage passed. | PASS |
21-
| SQLite-backed Local DB behavior is preserved behind the server API boundary. | LoginSessionMode Local DB assertions and AdminDbViewer Local DB readonly/diagnostic tests passed. | PASS |
22-
| UAT/Prod are not exposed as local login choices. | LoginSessionMode asserts DEV, UAT, and Prod buttons are absent. | PASS |
19+
| Login/session local API routes avoid 404/405 on supported local server calls. | `ApiStaticRouteRecovery.spec.mjs` validates `HEAD /api/session/current`, `OPTIONS /api/session/mode`, GET current/modes/users, and POST mode/user/logout. | PASS |
20+
| Local Mem and Local DB remain enabled/clickable. | LoginSessionMode and ApiStaticRouteRecovery assert Local Mem/Local DB controls are enabled. | PASS |
21+
| SQLite-backed Local DB remains behind the API boundary. | LoginSessionMode Local DB flow and AdminDbViewer Local DB readonly/diagnostic tests passed. | PASS |
22+
| `/tools/.../index.html` route pages still render content. | ToolboxRoutePages opens Project Journey, Colors, and Assets aliases with no failed requests. | PASS |
23+
| Extension script noise is ignored without masking repo global pollution. | Active runtime search found no `ShowOneChild` or `ActionableCoachmark`; Playwright filters only known extension script names and does not ignore bare `ActionableCoachmark` repo errors. | PASS |
24+
| UAT/Prod remain absent from local login choices. | LoginSessionMode and ApiStaticRouteRecovery assert UAT/Prod buttons are absent. | PASS |
2325

2426
## Skipped Lanes
2527

2628
| Lane | Decision | Reason |
2729
| --- | --- | --- |
2830
| Full samples smoke | SKIP | No samples, shared sample loader, or sample framework files changed. |
29-
| Full Playwright suite | SKIP | The targeted LoginSessionMode, route smoke, AdminDbViewer, syntax, and static checks cover the changed surfaces. |
31+
| Full Playwright suite | SKIP | Targeted API route, login/session, toolbox route, AdminDbViewer, syntax, and static checks cover the changed surfaces. |

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ function sendJson(response, statusCode, payload) {
170170
response.end(JSON.stringify(payload));
171171
}
172172

173+
function sendNoContent(response, statusCode = 204) {
174+
response.statusCode = statusCode;
175+
response.setHeader("Allow", "GET, POST, HEAD, OPTIONS");
176+
response.setHeader("Content-Type", "application/json; charset=utf-8");
177+
response.end();
178+
}
179+
173180
function ok(response, data) {
174181
sendJson(response, 200, {
175182
data,
@@ -904,7 +911,15 @@ export function createMockApiRouter() {
904911

905912
try {
906913
const parts = requestUrl.pathname.split("/").filter(Boolean);
914+
if (request.method === "OPTIONS") {
915+
sendNoContent(response);
916+
return true;
917+
}
907918
if (parts[1] === "session") {
919+
if (request.method === "HEAD" && ["current", "modes", "users"].includes(parts[2])) {
920+
sendNoContent(response, 200);
921+
return true;
922+
}
908923
if (request.method === "GET" && parts[2] === "current") {
909924
ok(response, dataSource.currentSession());
910925
return true;

src/engine/api/server-api-client.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ function hasBrowserRequest() {
1212
return typeof XMLHttpRequest !== "undefined";
1313
}
1414

15+
function localRouteUnavailableDiagnostic(method, url, status) {
16+
return `Local server API route unavailable for ${method} ${url} (${status}). Start the API-backed local server route instead of a static-only server.`;
17+
}
18+
1519
export function getServerApiDiagnostics() {
1620
return diagnostics.slice();
1721
}
@@ -26,7 +30,7 @@ export function requestServerApi(path, options = {}) {
2630
}
2731

2832
const xhr = new XMLHttpRequest();
29-
const method = options.method || "GET";
33+
const method = (options.method || "GET").toUpperCase();
3034
const url = path.startsWith(API_ROOT) ? path : `${API_ROOT}${path.startsWith("/") ? "" : "/"}${path}`;
3135
xhr.open(method, url, false);
3236
xhr.setRequestHeader("Accept", "application/json");
@@ -43,7 +47,9 @@ export function requestServerApi(path, options = {}) {
4347
}
4448

4549
if (xhr.status < 200 || xhr.status >= 300 || payload?.ok === false) {
46-
const message = payload?.error || payload?.message || `Server API request failed: ${method} ${url} (${xhr.status}).`;
50+
const message = xhr.status === 404 || xhr.status === 405
51+
? localRouteUnavailableDiagnostic(method, url, xhr.status)
52+
: payload?.error || payload?.message || `Server API request failed: ${method} ${url} (${xhr.status}).`;
4753
throw new Error(recordDiagnostic(message));
4854
}
4955

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const EXTENSION_SCRIPT_NAMES = [
2+
"ch-content-script-dend.js",
3+
"content-script-idle.js",
4+
"ShowOneChild.js",
5+
];
6+
7+
export function isBrowserExtensionNoise(value) {
8+
const text = String(value || "");
9+
const hasKnownScriptName = EXTENSION_SCRIPT_NAMES.some((scriptName) => text.includes(scriptName));
10+
if (!hasKnownScriptName) {
11+
return false;
12+
}
13+
return text.includes("chrome-extension://") ||
14+
text.includes("moz-extension://") ||
15+
text.includes("extension://") ||
16+
hasKnownScriptName;
17+
}

0 commit comments

Comments
 (0)