Skip to content

Commit ffa65b1

Browse files
committed
Enforce Toolbox DB service contract ownership - PR_26160_072-toolbox-db-contract-enforcement
1 parent 2ead081 commit ffa65b1

9 files changed

Lines changed: 229 additions & 102 deletions

admin/tool-votes.js

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
reorderToolboxVoteRows,
44
updateToolboxVoteMetadata,
55
} from "../src/engine/api/toolbox-votes-api-client.js";
6+
import { getToolboxContract } from "../toolbox/tool-registry-api-client.js";
67

78
const status = document.querySelector("[data-toolbox-votes-status]");
89
const dragStatus = document.querySelector("[data-toolbox-votes-drag-status]");
@@ -14,22 +15,15 @@ const sortButtonLabels = new Map(sortButtons.map((button) => [
1415
button.textContent.trim(),
1516
]));
1617

17-
const RELEASE_CHANNEL_OPTIONS = Object.freeze([
18-
["planned", "Planned"],
19-
["wireframe", "Wireframe"],
20-
["beta", "Beta"],
21-
["complete", "Complete"],
22-
]);
18+
const toolboxContract = getToolboxContract();
19+
const releaseChannelLabels = toolboxContract.releaseChannelLabels || {};
20+
const RELEASE_CHANNEL_OPTIONS = Object.freeze((toolboxContract.releaseChannels || []).map((channel) => [
21+
channel,
22+
releaseChannelLabels[channel] || channel,
23+
]));
2324
const RELEASE_CHANNEL_LABELS = new Map(RELEASE_CHANNEL_OPTIONS);
24-
const GROUP_OPTIONS = Object.freeze([
25-
"AI",
26-
"Audio",
27-
"Build/Create",
28-
"Design",
29-
"Marketplace",
30-
"Platform",
31-
"Play",
32-
]);
25+
const GROUP_OPTIONS = Object.freeze([...(toolboxContract.groups || [])]);
26+
const DEFAULT_RELEASE_CHANNEL = RELEASE_CHANNEL_OPTIONS[0]?.[0] || "planned";
3327

3428
const SORT_TYPES = Object.freeze({
3529
down: "number",
@@ -125,7 +119,7 @@ function groupCell(voteRow) {
125119
const select = document.createElement("select");
126120
const currentGroup = String(voteRow.group || "").trim();
127121
const options = GROUP_OPTIONS.includes(currentGroup) || !currentGroup
128-
? GROUP_OPTIONS
122+
? [...GROUP_OPTIONS]
129123
: [...GROUP_OPTIONS, currentGroup];
130124
select.dataset.toolboxVotesGroup = voteRow.toolId;
131125
select.setAttribute("aria-label", `Group for ${voteRow.toolName}`);
@@ -135,7 +129,7 @@ function groupCell(voteRow) {
135129
option.textContent = group;
136130
select.append(option);
137131
});
138-
select.value = currentGroup || GROUP_OPTIONS[0];
132+
select.value = currentGroup || GROUP_OPTIONS[0] || "";
139133
select.addEventListener("click", (event) => {
140134
event.stopPropagation();
141135
});
@@ -169,12 +163,12 @@ function pathCell(voteRow) {
169163
}
170164

171165
function releaseChannelLabel(value) {
172-
return RELEASE_CHANNEL_LABELS.get(value) || RELEASE_CHANNEL_LABELS.get("planned");
166+
return RELEASE_CHANNEL_LABELS.get(value) || RELEASE_CHANNEL_LABELS.get(DEFAULT_RELEASE_CHANNEL) || value || DEFAULT_RELEASE_CHANNEL;
173167
}
174168

175169
function rowReleaseChannel(voteRow) {
176170
const value = String(voteRow.status || voteRow.releaseChannel || "").trim().toLowerCase();
177-
return RELEASE_CHANNEL_LABELS.has(value) ? value : "planned";
171+
return RELEASE_CHANNEL_LABELS.has(value) ? value : DEFAULT_RELEASE_CHANNEL;
178172
}
179173

180174
function stateCell(voteRow) {
@@ -183,7 +177,8 @@ function stateCell(voteRow) {
183177
const currentState = rowReleaseChannel(voteRow);
184178
select.dataset.toolboxVotesState = voteRow.toolId;
185179
select.setAttribute("aria-label", `State for ${voteRow.toolName}`);
186-
RELEASE_CHANNEL_OPTIONS.forEach(([value, label]) => {
180+
const options = RELEASE_CHANNEL_OPTIONS.length ? RELEASE_CHANNEL_OPTIONS : [[currentState, currentState]];
181+
options.forEach(([value, label]) => {
187182
const option = document.createElement("option");
188183
option.value = value;
189184
option.textContent = label;

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Changed runtime JS files considered:
99
(0%) src/dev-runtime/guest-seeds/tool-state-samples.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
1010
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
1111
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
12+
(89%) toolbox/tool-registry-api-client.js - executed lines 152/152; executed functions 25/28
13+
(92%) admin/tool-votes.js - executed lines 378/378; executed functions 47/51
14+
(96%) toolbox/tools-page-accordions.js - executed lines 954/954; executed functions 109/113
1215

1316
Guardrail warnings:
1417
(0%) src/dev-runtime/guest-seeds/tool-state-samples.js - WARNING: changed runtime JS file missing from coverage; advisory only

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Changed runtime JS files covered:
2020
(0%) src/dev-runtime/guest-seeds/tool-state-samples.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
2121
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
2222
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
23+
(89%) toolbox/tool-registry-api-client.js - executed lines 152/152; executed functions 25/28
24+
(92%) admin/tool-votes.js - executed lines 378/378; executed functions 47/51
25+
(96%) toolbox/tools-page-accordions.js - executed lines 954/954; executed functions 109/113
2326

2427
Files with executed line/function counts where available:
2528
(38%) src/engine/api/session-api-client.js - executed lines 34/34; executed functions 3/8
@@ -30,9 +33,9 @@ Files with executed line/function counts where available:
3033
(71%) toolbox/assets/assets.js - executed lines 519/519; executed functions 42/59
3134
(77%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 548/548; executed functions 37/48
3235
(83%) src/engine/api/toolbox-votes-api-client.js - executed lines 46/46; executed functions 5/6
33-
(89%) toolbox/tool-registry-api-client.js - executed lines 148/148; executed functions 24/27
34-
(92%) admin/tool-votes.js - executed lines 383/383; executed functions 46/50
35-
(96%) toolbox/tools-page-accordions.js - executed lines 997/997; executed functions 108/112
36+
(89%) toolbox/tool-registry-api-client.js - executed lines 152/152; executed functions 25/28
37+
(92%) admin/tool-votes.js - executed lines 378/378; executed functions 47/51
38+
(96%) toolbox/tools-page-accordions.js - executed lines 954/954; executed functions 109/113
3639
(100%) toolbox/assets/assets-api-client.js - executed lines 17/17; executed functions 3/3
3740
(100%) toolbox/colors/palette-api-client.js - executed lines 19/19; executed functions 4/4
3841
(100%) toolbox/project-journey/project-journey-api-client.js - executed lines 12/12; executed functions 2/2
@@ -48,3 +51,6 @@ Changed JS files considered:
4851
(0%) src/dev-runtime/persistence/mock-db-store.js - changed JS file not collected as browser runtime coverage
4952
(0%) src/dev-runtime/server/mock-api-router.mjs - changed JS file not collected as browser runtime coverage
5053
(0%) tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs - changed JS file not collected as browser runtime coverage
54+
(89%) toolbox/tool-registry-api-client.js - changed JS file with browser V8 coverage
55+
(92%) admin/tool-votes.js - changed JS file with browser V8 coverage
56+
(96%) toolbox/tools-page-accordions.js - changed JS file with browser V8 coverage
Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Testing Lane Execution Report
22

3-
PR: PR_26160_068-db-ssot-governance-and-tool-audit
3+
PR: PR_26160_072-toolbox-db-contract-enforcement
44
Generated: 2026-06-09
55
Full samples validation: SKIPPED
66

77
## Summary
88

9-
PASS: 9
9+
PASS: 8
1010
WARN: 1
1111
FAIL: 0
1212
SKIP: 3
@@ -16,24 +16,23 @@ SKIP: 3
1616
| Lane | Status | Command | Evidence |
1717
| --- | --- | --- | --- |
1818
| Branch guard | PASS | `git branch --show-current` | Returned `main`. |
19-
| Changed JS syntax | PASS | `node --check admin/tool-votes.js src/dev-runtime/guest-seeds/tool-state-samples.js src/dev-runtime/persistence/mock-db-store.js src/dev-runtime/server/mock-api-router.mjs tests/playwright/tools/BuildPathProgressSimplification.spec.mjs tests/playwright/tools/ToolboxRoutePages.spec.mjs tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs toolbox/toolRegistry.js toolbox/tools-page-accordions.js` | All changed JS/test files parsed. |
20-
| Governance/static placement | PASS | `Select-String` for `DB-BACKED PRODUCT DATA SSOT GOVERNANCE` | Governance section exists in `docs_build/dev/PROJECT_INSTRUCTIONS.md`. |
21-
| API contract probe | PASS | Inline Node mock API probe against `/api/toolbox/votes/snapshot` | Snapshot returned 43 rows; counts planned 33, wireframe 4, beta 5, complete 1; required tools present. |
22-
| Toolbox/Admin SSoT Playwright | PASS | `npx playwright test tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs` | 3 passed. Verifies 43-tool metadata, Admin edit propagation, and no hardcoded Toolbox count text. |
23-
| Adjacent Toolbox/Admin Playwright | PASS | `npx playwright test tests/playwright/tools/BuildPathProgressSimplification.spec.mjs tests/playwright/tools/ToolboxRoutePages.spec.mjs tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs` | 17 passed. Verifies Build Path filters/counts, Admin Tool Votes, group matching, Admin wireframes/menu items. |
24-
| Hardcoded count/local metadata scan | PASS | `rg "Tool Count: [0-9]|Planned \\([0-9]+\\)|Wireframe \\([0-9]+\\)|Beta \\([0-9]+\\)|Complete \\([0-9]+\\)|buildPathGroups|sourceToolByTitle" toolbox admin src/dev-runtime` | No active source matches. |
25-
| Inline script/style/event scan | PASS | `rg --pcre2 "onclick=|onchange=|oninput=|<script(?![^>]+src)|<style[\\s>]" toolbox/index.html admin/tool-votes.html` | No matches. |
19+
| Changed JS syntax | PASS | `node --check admin/tool-votes.js`; `node --check toolbox/tool-registry-api-client.js`; `node --check toolbox/tools-page-accordions.js`; `node --check src/dev-runtime/server/mock-api-router.mjs`; `node --check tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs` | All changed JS/test files parsed. |
20+
| DB/API contract probe | PASS | Inline Node probe against `/api/toolbox/registry/snapshot`, `/api/toolbox/votes/snapshot`, and `/api/mock-db/snapshot` | Registry active tools 43; vote rows 43; metadata rows 43; planning rows 43; contract channels `planned,wireframe,beta,complete`. |
21+
| Toolbox/Admin SSoT Playwright | PASS | `npx playwright test tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs --reporter=line` | 4 passed. Verifies 43-tool DB-backed metadata/planning, Admin edit propagation, Toolbox reload behavior, no hardcoded count text, and no retired browser registry request. |
22+
| Toolbox route/display Playwright | PASS | `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs --reporter=line` | 8 passed. Verifies Toolbox filters, voting controls, group colors/assignments, Build Path status rows, Colors route behavior, wireframe pages, and port guard. |
23+
| UI-owned product data audit | PASS | Static `rg` scans for old local arrays, hardcoded counts, storage SSoT, and contract endpoints | Active Toolbox/Admin local status/group arrays were replaced by API contract reads; no browser storage product SSoT found. |
24+
| Inline event/style constraint | PASS | Changed-file review plus static scan | No changed file adds inline script, inline style, or inline event handlers. |
2625
| Static whitespace validation | PASS | `git diff --check` | No whitespace errors; Git printed line-ending warnings only. |
27-
| V8 coverage artifact refresh | WARN | Playwright coverage reporter after targeted lanes | `docs_build/dev/reports/playwright_v8_coverage_report.txt` and `coverage_changed_js_guardrail.txt` were refreshed. Server/dev-runtime files are listed as advisory 0% browser coverage because they are not browser runtime files. |
26+
| V8 coverage artifact refresh | WARN | Playwright coverage reporter after targeted lanes | `playwright_v8_coverage_report.txt` and `coverage_changed_js_guardrail.txt` were refreshed. Server/dev-runtime files remain advisory 0% browser coverage because they are not browser runtime files. |
2827

2928
## Skipped Lanes
3029

3130
| Lane | Status | Reason |
3231
| --- | --- | --- |
33-
| Full samples validation | SKIP | This PR does not touch sample loaders, sample assets, playable game runtime, or shared sample framework behavior. |
34-
| Broad all-Playwright suite | SKIP | Targeted Toolbox/Admin lanes cover the impacted UI/API contracts. |
35-
| Unrelated game/sample DB migration validation | SKIP | The request explicitly scoped migration to Toolbox/Admin tool metadata only. |
32+
| Full samples validation | SKIP | This PR does not touch samples, sample loaders, sample assets, playable runtime, or sample framework behavior. |
33+
| Broad all-Playwright suite | SKIP | Targeted Toolbox/Admin lanes cover the impacted API contract and UI surfaces. |
34+
| Unrelated game/sample DB migration validation | SKIP | The request explicitly scoped migration to Toolbox/Admin tool metadata, planning, voting, and order. |
3635

3736
## Manual Test Notes
3837

39-
No additional manual browser walkthrough was needed. The targeted Playwright lanes directly exercise Toolbox Build Path, Admin Tool Votes, Admin menu/wireframes, 43-tool inventory parity, Admin metadata edits reflected in Toolbox after reload, and source scans for hardcoded counts/inline behavior.
38+
No additional manual walkthrough was needed. The targeted Playwright lanes exercised Toolbox Build Path, Admin Tool Votes, 43-tool inventory parity, tool planning load, votes, order/status/group metadata, Admin edits reflected in Toolbox after reload, and active-page guardrails against retired browser registry use.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# PR_26160_072 Toolbox DB Contract Enforcement Report
2+
3+
Generated: 2026-06-09
4+
5+
## Branch Validation
6+
7+
| Check | Status | Evidence |
8+
| --- | --- | --- |
9+
| Current branch | PASS | `git branch --show-current` returned `main`. |
10+
| Expected branch | PASS | Required branch is `main`. |
11+
| Local branches found | PASS | `git branch --list` returned `* main`. |
12+
13+
## Requirement Checklist
14+
15+
| Requirement | Status | Evidence |
16+
| --- | --- | --- |
17+
| Audit active Toolbox/Admin pages for UI-owned product arrays, counts, maps, status/group/path/order duplication, and browser-storage SSoT use. | PASS | Static scans covered `toolbox/`, `admin/`, `src/engine/api`, and `src/dev-runtime/server/mock-api-router.mjs`. Active local status/group arrays were found in `toolbox/tools-page-accordions.js` and `admin/tool-votes.js`; no active `localStorage`/`sessionStorage` product SSoT matches were found. |
18+
| Move remaining Toolbox/Admin product data reads/writes behind API/service contract backed by DB adapter. | PASS | `src/dev-runtime/server/mock-api-router.mjs` now returns `toolboxContract` from `/api/toolbox/registry/snapshot`; `toolbox/tool-registry-api-client.js` exposes `getToolboxContract()`; `toolbox/tools-page-accordions.js` and `admin/tool-votes.js` consume that contract. |
19+
| Ensure Tool Metadata flows through Web UI -> API/Service Contract -> DB Adapter. | PASS | `/api/toolbox/registry/snapshot` and `/api/toolbox/votes/snapshot` read `toolbox_tool_metadata`; Playwright verified 43 metadata rows and Admin edits reflected in Toolbox after reload. |
20+
| Ensure Tool Planning flows through Web UI -> API/Service Contract -> DB Adapter. | PASS | `ToolboxAdminMetadataSsot.spec.mjs` verifies planning fields are absent from `toolbox_tool_metadata`, present in `toolbox_tool_planning`, and merged into registry tools as `planningSource: toolbox_tool_planning`. |
21+
| Ensure Tool Voting flows through Web UI -> API/Service Contract -> DB Adapter. | PASS | `admin/tool-votes.js` continues to call `readToolboxVoteSnapshot`, `updateToolboxVoteMetadata`, and `reorderToolboxVoteRows`; Playwright verified vote rows and Admin/Toolbox parity. |
22+
| Ensure Tool Order flows through Web UI -> API/Service Contract -> DB Adapter. | PASS | Admin reorder API remains `/api/toolbox/votes/order-list`; Playwright verified order changes propagate to Toolbox Build Path after reload. |
23+
| Keep Toolbox and Admin Tool Votes behavior unchanged. | PASS | `ToolboxAdminMetadataSsot.spec.mjs` passed 4/4; `ToolboxRoutePages.spec.mjs` passed 8/8. |
24+
| Do not migrate unrelated game/sample data. | PASS | Changes are limited to Toolbox/Admin contract wiring, one targeted Playwright spec, and generated reports. |
25+
| Do not use inline script/style/event handlers. | PASS | No changed file adds inline script, inline style, or inline event handlers. |
26+
27+
## Remaining UI-Owned Data Audit
28+
29+
| Area | Finding | Status | Action |
30+
| --- | --- | --- | --- |
31+
| Toolbox status/default filters | Page-local arrays previously owned release channels and defaults. | PASS | Moved to `toolboxContract.releaseChannels` and `toolboxContract.defaultReleaseChannels`. |
32+
| Toolbox status labels/help/swatches | Page-local maps previously duplicated release labels/help and state swatches. | PASS | Moved to `toolboxContract.releaseChannelLabels`, `releaseChannelHelpText`, and `releaseChannelSwatches`. |
33+
| Toolbox group order/swatches | Page-local group order and group swatch maps duplicated DB-backed metadata. | PASS | `toolboxContract.toolboxGroupOrder`, `groups`, and `groupSwatches` are derived from active registry tools. |
34+
| Toolbox role focus lists | Page-local role focus lists were UI-owned product display data. | PASS | Moved behind the registry API contract as `toolboxContract.roleFocusTools`. |
35+
| Admin Tool Votes state/group editors | Page-local status and group option arrays duplicated registry metadata. | PASS | Admin now uses `getToolboxContract()` for status labels and group options. |
36+
| Hardcoded counts | No active source hardcoded visible Toolbox counts. Test constants remain validation expectations only. | PASS | `Tool Count` is computed at runtime; Playwright verifies DB-backed counts. |
37+
| Browser storage SSoT | No active Toolbox/Admin product SSoT use of `localStorage` or `sessionStorage` found. | PASS | Session/storage test helpers are validation-only. |
38+
| `toolbox/toolRegistry.js` compatibility shell | Not loaded by active Toolbox/Admin pages; retained as a compatibility stub for older tests/scripts. | PASS | Existing Playwright test asserts active pages do not request `/toolbox/toolRegistry.js`. |
39+
40+
## Validation
41+
42+
| Lane | Status | Command | Evidence |
43+
| --- | --- | --- | --- |
44+
| Branch guard | PASS | `git branch --show-current` | Returned `main`. |
45+
| Changed JS syntax | PASS | `node --check` for changed JS/spec files | `admin/tool-votes.js`, `toolbox/tool-registry-api-client.js`, `toolbox/tools-page-accordions.js`, `src/dev-runtime/server/mock-api-router.mjs`, and `ToolboxAdminMetadataSsot.spec.mjs` all parsed. |
46+
| DB/API contract probe | PASS | Inline Node server probe | Registry returned 43 active tools, votes returned 43 rows, metadata/planning returned 43 rows each, and contract defaults were present. |
47+
| Toolbox/Admin Tool Votes Playwright | PASS | `npx playwright test tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs --reporter=line` | 4 passed. |
48+
| Toolbox route/UI Playwright | PASS | `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs --reporter=line` | 8 passed. |
49+
| Static whitespace | PASS | `git diff --check` | No whitespace errors; Git printed line-ending warnings only. |
50+
| V8 coverage | PASS | Playwright reporter output | `playwright_v8_coverage_report.txt` updated; changed browser files covered at 89%, 92%, and 96%. |
51+
52+
## Impacted Lane
53+
54+
- Toolbox/Admin Tool Votes DB contract and UI behavior.
55+
56+
## Skipped Lanes
57+
58+
| Lane | Reason |
59+
| --- | --- |
60+
| Full samples validation | This PR does not touch sample loaders, game runtime, or shared sample framework behavior. |
61+
| Unrelated game/sample DB migration lanes | Request is scoped to Toolbox/Admin tool metadata, planning, voting, and order contracts. |
62+
| Broad all-Playwright suite | Targeted Toolbox/Admin lanes cover the changed service contract and active UI surfaces. |
63+
64+
## Manual Test Notes
65+
66+
No extra manual browser walkthrough was required. Targeted Playwright covered 43-tool inventory, planning load, votes, order, status/group metadata, filters, admin edits, and reload behavior.

0 commit comments

Comments
 (0)