Skip to content

Commit 0c06a66

Browse files
committed
Add DB SSoT governance and consolidate tool metadata - PR_26160_068-db-ssot-governance-and-tool-audit
1 parent dc420e8 commit 0c06a66

15 files changed

Lines changed: 493 additions & 171 deletions

admin/tool-votes.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ function percentCell(value) {
7272
function toolNameCell(voteRow) {
7373
const cell = document.createElement("td");
7474
const link = document.createElement("a");
75-
link.href = voteRow.path || "#";
75+
const path = String(voteRow.path || "").trim().replace(/^\/+/, "");
76+
link.href = path ? `/${path}` : "#";
7677
link.textContent = voteRow.toolName;
7778
link.setAttribute("aria-label", `Open ${voteRow.toolName}`);
7879
cell.append(link);
@@ -92,10 +93,15 @@ function releaseChannelLabel(value) {
9293
return RELEASE_CHANNEL_LABELS.get(value) || RELEASE_CHANNEL_LABELS.get("planned");
9394
}
9495

96+
function rowReleaseChannel(voteRow) {
97+
const value = String(voteRow.status || voteRow.releaseChannel || "").trim().toLowerCase();
98+
return RELEASE_CHANNEL_LABELS.has(value) ? value : "planned";
99+
}
100+
95101
function stateCell(voteRow) {
96102
const cell = document.createElement("td");
97103
const select = document.createElement("select");
98-
const currentState = RELEASE_CHANNEL_LABELS.has(voteRow.releaseChannel) ? voteRow.releaseChannel : "planned";
104+
const currentState = rowReleaseChannel(voteRow);
99105
select.dataset.toolboxVotesState = voteRow.toolId;
100106
select.setAttribute("aria-label", `State for ${voteRow.toolName}`);
101107
RELEASE_CHANNEL_OPTIONS.forEach(([value, label]) => {
@@ -117,19 +123,20 @@ function stateCell(voteRow) {
117123

118124
function handleStateChange(voteRow, select) {
119125
const nextState = select.value;
120-
if (nextState === voteRow.releaseChannel) {
126+
if (nextState === rowReleaseChannel(voteRow)) {
121127
return;
122128
}
123129
try {
124130
const snapshot = updateToolboxVoteMetadata(voteRow.toolId, {
125131
group: voteRow.group,
126132
path: voteRow.path,
133+
status: nextState,
127134
releaseChannel: nextState,
128135
});
129136
renderSnapshot(snapshot, `${voteRow.toolName} state updated to ${releaseChannelLabel(nextState)}. Toolbox Build Path uses the same metadata.`);
130137
selectRow(voteRow.toolId);
131138
} catch (error) {
132-
select.value = RELEASE_CHANNEL_LABELS.has(voteRow.releaseChannel) ? voteRow.releaseChannel : "planned";
139+
select.value = rowReleaseChannel(voteRow);
133140
const message = error instanceof Error ? error.message : String(error || "Toolbox state update unavailable.");
134141
setStatus(`${voteRow.toolName} state could not be updated. ${message}`);
135142
}

docs_build/dev/PROJECT_INSTRUCTIONS.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,29 @@ The Mock DB viewer must render live adapter state and table schemas, including e
288288

289289
Audit ownership is users-only: every shared table record uses `key`, `createdAt`, `updatedAt`, `createdBy`, and `updatedBy`; the ownership fields reference `users.key`. Roles are modeled with `roles` and `user_roles`.
290290

291+
## DB-BACKED PRODUCT DATA SSOT GOVERNANCE
292+
293+
Web UI must access product data only through API or service contracts backed by DB adapters.
294+
295+
Allowed production flow:
296+
- Web UI -> API/Service Contract -> Server DB
297+
298+
Allowed dev/UAT/test flow:
299+
- Web UI -> API/Service Contract -> DB Adapter
300+
- The DB Adapter may be MEM DB, Local DB, Test DB, or Server DB.
301+
302+
Prohibited product-data ownership:
303+
- page-local product data arrays
304+
- page-local metadata registries
305+
- hardcoded product counts
306+
- duplicated status, group, path, or order data
307+
- duplicated lookup maps that compete with DB-backed metadata
308+
- browser storage as the product source of truth
309+
- UI-only vote, order, or status state
310+
- direct DB-shaped product data embedded in HTML or browser JavaScript pages
311+
312+
Toolbox and Admin tool metadata must use a shared DB-backed tool metadata source for `toolKey`, `toolName`, `group`, `path`, `order`, and `status`. Browser pages may render metadata returned by the API/service contract, but they must not own a separate runtime copy of that metadata.
313+
291314
## DEV RUNTIME BOUNDARY
292315

293316
All mock/dev-only runtime implementation must live under `src/dev-runtime/`.

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ 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/guest-seeds/tool-state-samples.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
10+
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
911
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
10-
(96%) toolbox/tools-page-accordions.js - executed lines 1048/1048; executed functions 109/114
11-
(100%) admin/tool-votes.js - executed lines 294/294; executed functions 37/37
12+
(0%) toolbox/toolRegistry.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
13+
(74%) admin/tool-votes.js - executed lines 320/320; executed functions 29/39
14+
(84%) toolbox/tools-page-accordions.js - executed lines 997/997; executed functions 90/107
1215

1316
Guardrail warnings:
17+
(0%) src/dev-runtime/guest-seeds/tool-state-samples.js - WARNING: changed runtime JS file missing from coverage; advisory only
18+
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file missing from coverage; advisory only
1419
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file missing from coverage; advisory only
20+
(0%) toolbox/toolRegistry.js - WARNING: changed runtime JS file missing from coverage; advisory only
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# PR_26160_068 DB SSoT Governance And Tool Audit
2+
3+
Date: 2026-06-09
4+
5+
## Branch Validation
6+
7+
| Check | Status | Evidence |
8+
| --- | --- | --- |
9+
| Current branch is `main` | PASS | `git branch --show-current` returned `main`. |
10+
11+
## Governance Location
12+
13+
| Requirement | Status | Evidence |
14+
| --- | --- | --- |
15+
| Add DB-backed product data SSoT governance | PASS | `docs_build/dev/PROJECT_INSTRUCTIONS.md` now contains `## DB-BACKED PRODUCT DATA SSOT GOVERNANCE`. |
16+
| Production flow is Web UI -> API/Service Contract -> Server DB | PASS | Governance section lists the allowed production flow. |
17+
| Dev/UAT/test flow is Web UI -> API/Service Contract -> DB Adapter | PASS | Governance section lists DB Adapter options: MEM DB, Local DB, Test DB, Server DB. |
18+
| Prohibited browser/page-local ownership is documented | PASS | Governance section prohibits page-local product arrays, metadata registries, hardcoded counts, duplicated status/group/path/order data, duplicated lookup maps, browser storage as product SSoT, UI-only vote/order/status state, and direct DB-shaped product data in HTML/browser JS. |
19+
20+
## Requirement Checklist
21+
22+
| Requirement | Status | Evidence |
23+
| --- | --- | --- |
24+
| Audit Toolbox/Admin tool metadata sources | PASS | Audit findings below identify fixed and deferred sources. |
25+
| Move scoped Toolbox/Admin metadata into shared DB-backed source | PASS | `toolbox_tool_metadata` schema/seed/API now own `toolKey`, `toolName`, `group`, `path`, `order`, and `status`. |
26+
| Seed DB-backed metadata from 43-tool inventory | PASS | API contract probe and Playwright verified 43 rows, including original inventory plus AI Assistant and restored Creator Learning. |
27+
| Toolbox Build Path and Admin Tool Votes read same metadata | PASS | `ToolboxAdminMetadataSsot.spec.mjs` verifies Admin rows and Toolbox Build Path rows match the same API snapshot. |
28+
| Admin edits affect Toolbox after reload | PASS | Playwright changes Creator Learning state in Admin Tool Votes and verifies Toolbox Build Path shows Beta after reload. |
29+
| Environments, Users, Game Migration, Platform Settings included under Admin | PASS | Existing Admin menu source keeps all four in `ADMIN_MAIN_ITEMS`; `AdminPlatformToolsWireframes.spec.mjs` passed. |
30+
| Game Migration not under My Stuff | PASS | `gamefoundry-partials.js` has Game Migration in main Admin items; My Stuff remains DB Viewer, Design System, Grouping Colors, Notes. |
31+
| Do not migrate unrelated game/sample data | PASS | Changes are scoped to Toolbox/Admin metadata, docs, and tests. |
32+
| Do not use inline script/style/event handlers | PASS | `rg --pcre2 "onclick=|onchange=|oninput=|<script(?![^>]+src)|<style[\\s>]" toolbox/index.html admin/tool-votes.html` returned no matches. |
33+
34+
## Metadata Inventory
35+
36+
| Item | Status | Evidence |
37+
| --- | --- | --- |
38+
| Total active tool metadata rows | PASS | API probe returned `count: 43`. |
39+
| Status counts | PASS | API probe returned planned 33, wireframe 4, beta 5, complete 1. |
40+
| Required restored/current tools | PASS | API/Playwright verified AI Assistant, Creator Learning, Users, Environments, Game Migration, and Platform Settings are present. |
41+
| Key fields present | PASS | Playwright asserts every row has `toolKey`, `toolName`, `group`, `path`, whole-number `order`, and allowed `status`. |
42+
43+
## Audit Findings
44+
45+
| Finding | Status | Files |
46+
| --- | --- | --- |
47+
| Missing governance for DB-backed product data SSoT | FIXED | `docs_build/dev/PROJECT_INSTRUCTIONS.md` |
48+
| `toolbox_tool_metadata` schema did not expose `toolKey` and `status` as first-class metadata fields | FIXED | `src/dev-runtime/persistence/mock-db-store.js` |
49+
| Tool metadata seed covered only `visibleInToolsList` tools, omitting Admin tools | FIXED | `src/dev-runtime/guest-seeds/tool-state-samples.js` |
50+
| Server Toolbox vote snapshot and metadata updates only considered visible public tools | FIXED | `src/dev-runtime/server/mock-api-router.mjs` |
51+
| Toolbox Build Path counts/rows used public-visible registry rows only, not the Admin 43-tool metadata inventory | FIXED | `toolbox/tools-page-accordions.js` |
52+
| Toolbox page contained an unused page-local `buildPathGroups` metadata array | FIXED | Removed from `toolbox/tools-page-accordions.js`. |
53+
| Toolbox page had hardcoded `Tool Count: 0/0` placeholder | FIXED | `toolbox/index.html` now uses `Tool Count: loading`. |
54+
| Admin Tool Votes read/write path only looked at `releaseChannel` | FIXED | `admin/tool-votes.js` now reads `status` first and submits `status` with compatibility `releaseChannel`. |
55+
| Admin-only registry bucket was not included in Toolbox Admin card inventory | FIXED | `toolbox/tools-page-accordions.js` includes the `Admin` toolbox group for Admin sessions. |
56+
| Previous tests encoded old public counts | FIXED | Targeted Toolbox Playwright expectations updated to 39 public / 43 admin inventory. |
57+
| Static `toolbox/toolRegistry.js` remains as bootstrap route/image/default seed registry | DEFERRED | Runtime metadata now comes from DB-backed API rows, but full removal of the bootstrap registry is a larger server registry/data-source migration. Browser code consumes it through the `/api/toolbox/registry/snapshot` service client rather than direct static import. |
58+
| Compatibility aliases `toolId` and `releaseChannel` remain in API rows | DEFERRED | Kept to avoid breaking existing vote rows and clients while `toolKey` and `status` become first-class metadata fields. |
59+
60+
## Validation
61+
62+
| Lane | Status | Command | Evidence |
63+
| --- | --- | --- | --- |
64+
| Branch guard | PASS | `git branch --show-current` | Returned `main`. |
65+
| Changed JS syntax | PASS | `node --check` on changed JS/test files | All parsed successfully. |
66+
| API contract probe | PASS | Inline Node mock API probe | Snapshot returned 43 rows and required tools; counts planned 33, wireframe 4, beta 5, complete 1. |
67+
| Toolbox/Admin SSoT Playwright | PASS | `npx playwright test tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs` | 3 passed. |
68+
| 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. |
69+
| Static 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 matches. |
70+
| Inline handler/style scan | PASS | `rg --pcre2 "onclick=|onchange=|oninput=|<script(?![^>]+src)|<style[\\s>]" toolbox/index.html admin/tool-votes.html` | No matches. |
71+
| Whitespace/static diff | PASS | `git diff --check` | No whitespace errors; Git printed line-ending warnings only. |
72+
73+
## Impacted Lane
74+
75+
Toolbox Build Path, Admin Tool Votes, shared dev mock API metadata, Toolbox registry seed data, governance docs, and targeted Playwright coverage.
76+
77+
## Skipped Lanes
78+
79+
| Lane | Reason |
80+
| --- | --- |
81+
| Full samples validation | This PR does not touch samples, sample loaders, playable game runtime, or shared sample framework code. |
82+
| Broad all-Playwright suite | Targeted Toolbox/Admin lanes cover the changed UI/API behavior. |
83+
| Unrelated game/sample DB migrations | Explicitly out of scope for this PR. |
84+
85+
## Manual Test Notes
86+
87+
No separate manual browser walkthrough was required beyond Playwright. The API probe and Playwright assertions verify the 43-row inventory, counts, Admin edit propagation, Admin menu placement, no page-local count usage, and no inline script/style/event handlers.

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,43 @@ 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-
(69%) Toolbox Index - exercised 9 runtime JS files
15+
(80%) Toolbox Index - exercised 3 runtime JS files
1616
(0%) Tool Template V2 - not exercised by this Playwright run
1717
(74%) Theme V2 Shared JS - exercised 2 runtime JS files
1818

1919
Changed runtime JS files covered:
20+
(0%) src/dev-runtime/guest-seeds/tool-state-samples.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
21+
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
2022
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
21-
(96%) toolbox/tools-page-accordions.js - executed lines 1048/1048; executed functions 109/114
22-
(100%) admin/tool-votes.js - executed lines 294/294; executed functions 37/37
23+
(0%) toolbox/toolRegistry.js - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
24+
(74%) admin/tool-votes.js - executed lines 320/320; executed functions 29/39
25+
(84%) toolbox/tools-page-accordions.js - executed lines 997/997; executed functions 90/107
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
26-
(55%) toolbox/project-journey/project-journey.js - executed lines 1003/1003; executed functions 54/99
27-
(57%) toolbox/colors/colors.js - executed lines 2289/2289; executed functions 123/216
28-
(58%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 11/19
29+
(50%) src/engine/api/toolbox-votes-api-client.js - executed lines 46/46; executed functions 3/6
30+
(53%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 10/19
31+
(63%) toolbox/tool-registry-api-client.js - executed lines 148/148; executed functions 15/24
2932
(64%) assets/theme-v2/js/tool-display-mode.js - executed lines 209/209; executed functions 9/14
30-
(71%) toolbox/assets/assets.js - executed lines 519/519; executed functions 42/59
31-
(77%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 547/547; executed functions 37/48
32-
(80%) src/engine/api/toolbox-votes-api-client.js - executed lines 37/37; executed functions 4/5
33-
(85%) toolbox/tool-registry-api-client.js - executed lines 148/148; executed functions 23/27
34-
(96%) toolbox/tools-page-accordions.js - executed lines 1048/1048; executed functions 109/114
35-
(100%) admin/tool-votes.js - executed lines 294/294; executed functions 37/37
36-
(100%) toolbox/assets/assets-api-client.js - executed lines 17/17; executed functions 3/3
37-
(100%) toolbox/colors/palette-api-client.js - executed lines 19/19; executed functions 4/4
38-
(100%) toolbox/project-journey/project-journey-api-client.js - executed lines 12/12; executed functions 2/2
33+
(74%) admin/tool-votes.js - executed lines 320/320; executed functions 29/39
34+
(77%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 548/548; executed functions 37/48
35+
(84%) toolbox/tools-page-accordions.js - executed lines 997/997; executed functions 90/107
3936
(100%) toolbox/project-workspace/project-workspace-api-client.js - executed lines 12/12; executed functions 2/2
4037

4138
Uncovered or low-coverage changed JS files:
39+
(0%) src/dev-runtime/guest-seeds/tool-state-samples.js - WARNING: uncovered changed runtime JS file; advisory only
40+
(0%) src/dev-runtime/persistence/mock-db-store.js - WARNING: uncovered changed runtime JS file; advisory only
4241
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: uncovered changed runtime JS file; advisory only
42+
(0%) toolbox/toolRegistry.js - WARNING: uncovered changed runtime JS file; advisory only
4343

4444
Changed JS files considered:
45+
(0%) src/dev-runtime/guest-seeds/tool-state-samples.js - changed JS file not collected as browser runtime coverage
46+
(0%) src/dev-runtime/persistence/mock-db-store.js - changed JS file not collected as browser runtime coverage
4547
(0%) src/dev-runtime/server/mock-api-router.mjs - changed JS file not collected as browser runtime coverage
48+
(0%) tests/playwright/tools/AdminPlatformToolsWireframes.spec.mjs - changed JS file not collected as browser runtime coverage
49+
(0%) tests/playwright/tools/BuildPathProgressSimplification.spec.mjs - changed JS file not collected as browser runtime coverage
50+
(0%) tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs - changed JS file not collected as browser runtime coverage
4651
(0%) tests/playwright/tools/ToolboxRoutePages.spec.mjs - changed JS file not collected as browser runtime coverage
47-
(96%) toolbox/tools-page-accordions.js - changed JS file with browser V8 coverage
48-
(100%) admin/tool-votes.js - changed JS file with browser V8 coverage
52+
(0%) toolbox/toolRegistry.js - changed JS file not collected as browser runtime coverage
53+
(74%) admin/tool-votes.js - changed JS file with browser V8 coverage
54+
(84%) toolbox/tools-page-accordions.js - changed JS file with browser V8 coverage

0 commit comments

Comments
 (0)