Skip to content

Commit 56d03de

Browse files
committed
Define mock project ownership data and admin reset controls - PR_26155_041-044-project-workspace-ready-data
1 parent 221eac0 commit 56d03de

8 files changed

Lines changed: 334 additions & 0 deletions

docs_build/dev/PROJECT_INSTRUCTIONS.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,27 @@ Project Workspace is the next first real Toolbox rebuild target. Its contract ow
180180

181181
Do not implement Project Workspace runtime behavior, persistence, database behavior, authentication, or save/load flows before the rebuild PR explicitly scopes those capabilities.
182182

183+
## TARGETED MSJ VALIDATION GOVERNANCE
184+
185+
Every tool, page, or `src/` change must declare its impacted MSJ/test lane.
186+
187+
Run only the affected MSJ/test lane by default.
188+
189+
Do not run the full suite for small scoped changes unless one of these shared surfaces changes:
190+
- shared runtime behavior
191+
- shared parser behavior
192+
- shared DB behavior
193+
- shared Theme V2 behavior
194+
- cross-tool integration behavior
195+
196+
If a shared source file changes, name the affected dependent lanes and run only those targeted lanes unless the dependency impact proves broader validation is required.
197+
198+
Reports must state:
199+
- impacted lane
200+
- skipped lanes
201+
- why skipped lanes were safe to skip
202+
- when the full suite is required
203+
183204
## ARCHIVED V1/V2 REFERENCE MATERIAL
184205

185206
Deprecated V1/V2 reference material lives under:
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# PR_26155_042 Admin Project Data Banner
2+
3+
## Summary
4+
5+
Added an admin-only Project Data wireframe menu to the existing Toolbox role banner row.
6+
7+
Admin row text now includes:
8+
9+
`ADMIN VIEW • Planned tools visible • Switch to Creator View • Project Data ▾`
10+
11+
## Behavior
12+
13+
Supported role modes remain:
14+
- `?role=guest`
15+
- `?role=user`
16+
- `?role=admin`
17+
18+
Visibility:
19+
- Guest view hides Project Data controls.
20+
- Creator view hides Project Data controls.
21+
- Admin view shows Project Data controls.
22+
23+
Project Data submenu actions:
24+
- Reset Project Data
25+
- Seed Demo Project
26+
- Clear Test Data
27+
28+
The actions are native button controls with no destructive behavior wired in this PR.
29+
30+
## Theme V2 Use
31+
32+
Existing Theme V2 classes only:
33+
- role row container: `container callout`
34+
- role banner and Project Data menu: `status`
35+
- submenu action stack: `content-stack content-stack--compact`
36+
- buttons: `btn`
37+
38+
No CSS, page-local CSS, inline styles, style blocks, DB, auth, cloud, persistence, or new tools were added.
39+
40+
## Manual Test Notes
41+
42+
- `?role=guest` shows the guest banner and no visible Project Data controls.
43+
- `?role=user` shows the creator banner and no visible Project Data controls.
44+
- `?role=admin` shows the admin banner and Project Data submenu.
45+
- Project Data submenu contains Reset Project Data, Seed Demo Project, and Clear Test Data.
46+
- Clicking the buttons does not mutate `localStorage` or `sessionStorage`.
47+
- No duplicate Admin appears under Toolbox.
48+
- No console errors were observed by the Playwright lane.
49+
50+
## Validation Notes
51+
52+
Impacted lane: `workspace-contract` through `npm run test:workspace-v2`.
53+
54+
Validation run:
55+
- `npm run test:workspace-v2` passed with 4 Playwright tests.
56+
- `git diff --check` passed.
57+
58+
Skipped lanes:
59+
- runtime
60+
- integration
61+
- engine
62+
- samples
63+
- recovery/UAT
64+
65+
Skipped-lane rationale: this is an inert Toolbox page/header wireframe control and docs contract bundle. No shared runtime, real persistence, parser, engine, sample, or cross-tool behavior changed.
66+
67+
Theme V2 gap findings: none.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# PR_26155_041 Mock DB User Project Contract
2+
3+
## Purpose
4+
5+
Define the mock SQL-shaped user/project ownership contract needed before the Project Workspace rebuild starts.
6+
7+
This PR is contract-only. It does not implement a real database, auth, cloud sync, persistence, save/load, or Project Workspace runtime behavior.
8+
9+
## Mock SQL-Shaped Tables
10+
11+
### `users`
12+
13+
| column | type | notes |
14+
| --- | --- | --- |
15+
| `id` | text primary key | Stable mock user id. |
16+
| `displayName` | text | User-facing name. |
17+
| `email` | text | Mock email address. |
18+
| `role` | text | Guest, Creator, or Admin. |
19+
20+
### `projects`
21+
22+
| column | type | notes |
23+
| --- | --- | --- |
24+
| `id` | text primary key | Stable mock project id. |
25+
| `ownerUserId` | text foreign key to `users.id` | Owner for single-user implementation and future multi-user support. |
26+
| `name` | text | Project name. |
27+
| `status` | text | Wireframe project status. |
28+
29+
### `project_members`
30+
31+
| column | type | notes |
32+
| --- | --- | --- |
33+
| `projectId` | text foreign key to `projects.id` | Project membership link. |
34+
| `userId` | text foreign key to `users.id` | User membership link. |
35+
| `permission` | text | Owner, Editor, Viewer, or Admin. |
36+
37+
## Permissions
38+
39+
Allowed mock permissions:
40+
- Owner
41+
- Editor
42+
- Viewer
43+
- Admin
44+
45+
## Seed Records
46+
47+
### Users
48+
49+
| id | displayName | email | role |
50+
| --- | --- | --- | --- |
51+
| `admin-user` | Admin User | `admin@example.test` | Admin |
52+
| `creator-user` | Creator User | `creator@example.test` | Creator |
53+
| `guest-preview-user` | Guest Preview User | `guest@example.test` | Guest |
54+
55+
### Projects
56+
57+
| id | ownerUserId | name | status |
58+
| --- | --- | --- | --- |
59+
| `demo-project` | `creator-user` | Demo Project | Wireframe |
60+
61+
### Project Members
62+
63+
| projectId | userId | permission |
64+
| --- | --- | --- |
65+
| `demo-project` | `creator-user` | Owner |
66+
| `demo-project` | `admin-user` | Admin |
67+
| `demo-project` | `guest-preview-user` | Viewer |
68+
69+
## Mock Data Actions
70+
71+
Wireframe/dev-mode actions:
72+
- Reset Project Data
73+
- Seed Demo Project
74+
- Clear Test Data
75+
76+
These actions are declared for upcoming Project Workspace rebuild planning only. They must not perform destructive behavior until a later implementation PR explicitly scopes the mock repository behavior.
77+
78+
## Implementation Guidance
79+
80+
Design for multi-user ownership now, but implement single-user behavior first in a later Project Workspace implementation PR.
81+
82+
The first implementation PR should use a mock SQL-shaped repository interface so the data shape can later map cleanly to a real SQL database.
83+
84+
## Validation Notes
85+
86+
Impacted lane: `workspace-contract` through `npm run test:workspace-v2`.
87+
88+
Skipped lanes:
89+
- runtime
90+
- integration
91+
- engine
92+
- samples
93+
- recovery/UAT
94+
95+
Skipped-lane rationale: this bundle adds a docs contract and inert Toolbox header controls only. It does not change engine runtime, parsers, real DB behavior, samples, or cross-tool integrations.
96+
97+
Full suite is required when shared runtime, shared parser, shared DB, shared Theme V2, or cross-tool integration behavior changes.
98+
99+
Theme V2 gap findings: none.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# PR_26155_044 Project Workspace Ready Gate
2+
3+
## Summary
4+
5+
Project Workspace implementation can start after this bundle because the required planning gates now exist:
6+
- mock SQL-shaped DB/user/project ownership contract
7+
- admin Project Data wireframe controls
8+
- targeted MSJ validation rule
9+
10+
## First Implementation PR Requirement
11+
12+
The first Project Workspace implementation PR must build against the mock SQL-shaped repository contract defined in `docs_build/dev/reports/mock-db-user-project-contract.md`.
13+
14+
The first implementation should support single-user behavior over multi-user-ready tables:
15+
- `users`
16+
- `projects`
17+
- `project_members`
18+
19+
The table design must preserve future multi-user ownership and membership behavior even while the first implementation behaves as a single-user Project Workspace.
20+
21+
## Out Of Scope For This Bundle
22+
23+
- No Project Workspace runtime implementation.
24+
- No real database.
25+
- No auth.
26+
- No cloud sync.
27+
- No persistence implementation.
28+
- No save/load behavior.
29+
- No new tools.
30+
- No CSS changes.
31+
32+
## Validation Notes
33+
34+
Impacted lane: `workspace-contract`.
35+
36+
Validation run:
37+
- `npm run test:workspace-v2` passed with 4 Playwright tests.
38+
- `git diff --check` passed.
39+
40+
Skipped lanes:
41+
- runtime
42+
- integration
43+
- engine
44+
- samples
45+
- recovery/UAT
46+
47+
Skipped-lane rationale: this bundle creates a contract, an inert admin-only wireframe control, governance, and tests. It does not change shared runtime, shared parser, real DB implementation, engine, samples, or cross-tool integration behavior.
48+
49+
Theme V2 gap findings: none.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# PR_26155_043 Targeted MSJ Validation Rule
2+
3+
## Summary
4+
5+
Added targeted MSJ validation governance to `docs_build/dev/PROJECT_INSTRUCTIONS.md`.
6+
7+
Every tool, page, or `src/` change must declare its impacted MSJ/test lane.
8+
9+
## Rule
10+
11+
Run only the affected MSJ/test lane by default.
12+
13+
Do not run the full suite for small scoped changes unless one of these shared surfaces changes:
14+
- shared runtime behavior
15+
- shared parser behavior
16+
- shared DB behavior
17+
- shared Theme V2 behavior
18+
- cross-tool integration behavior
19+
20+
If a shared source file changes, name affected dependent lanes and run only those targeted lanes unless the dependency impact proves broader validation is required.
21+
22+
Reports must state:
23+
- impacted lane
24+
- skipped lanes
25+
- why skipped lanes were safe to skip
26+
- when the full suite is required
27+
28+
## This Bundle
29+
30+
Impacted lane: `workspace-contract`.
31+
32+
Command run:
33+
- `npm run test:workspace-v2`
34+
35+
Skipped lanes:
36+
- runtime
37+
- integration
38+
- engine
39+
- samples
40+
- recovery/UAT
41+
42+
Skipped-lane rationale: the bundle updates Toolbox role-banner wireframe markup, its existing page script visibility wiring, governance docs, and Playwright coverage. It does not alter shared runtime, shared parser, shared DB implementation, shared Theme V2 CSS, engine behavior, samples, or cross-tool integration.
43+
44+
Full suite is required when shared runtime, shared parser, shared DB, shared Theme V2, or cross-tool integration behavior changes.
45+
46+
## Validation Notes
47+
48+
- `npm run test:workspace-v2` passed with 4 Playwright tests.
49+
- `git diff --check` passed.
50+
51+
Theme V2 gap findings: none.

tests/playwright/tools/RootToolsFutureState.spec.mjs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ async function primaryNavigationLabels(page) {
5858
))).map(normalizeMenuText);
5959
}
6060

61+
async function storageSnapshot(page) {
62+
return page.evaluate(() => ({
63+
local: { ...localStorage },
64+
session: { ...sessionStorage }
65+
}));
66+
}
67+
6168
test("root tools surface links current tool pages without old_* routes", async ({ page }) => {
6269
const { failedRequests, pageErrors, server } = await openRepoPage(page, "/toolbox/index.html");
6370

@@ -72,6 +79,9 @@ test("root tools surface links current tool pages without old_* routes", async (
7279
await expect(page.locator("[data-tools-count]")).toHaveText("Tool Count: 30/37");
7380
await expect(page.locator("[data-toolbox-role-banner]")).toHaveText("GUEST VIEW • Preview only • Sign in to create");
7481
await expect(page.locator("[data-toolbox-role-banner]")).toHaveAttribute("href", /role=user/);
82+
await expect(page.locator("[data-project-data-menu]")).toBeHidden();
83+
await expect(page.locator("[data-project-data-action]")).toHaveCount(3);
84+
await expect(page.locator("[data-project-data-action]:visible")).toHaveCount(0);
7585
await expect(page.locator("[aria-label='Toolbox role simulation']")).toHaveClass(/callout/);
7686
await expect(page.locator("[aria-label='Toolbox role simulation']")).not.toHaveCSS("background-color", "rgba(0, 0, 0, 0)");
7787
await expect(page.locator("[data-toolbox-role-banner]")).toHaveClass(/status/);
@@ -247,13 +257,31 @@ test("root tools surface links current tool pages without old_* routes", async (
247257
await page.locator("[data-toolbox-role-banner]").click();
248258
await page.waitForURL(/role=user/);
249259
await expect(page.locator("[data-toolbox-role-banner]")).toHaveText("CREATOR VIEW • Project tools enabled • Switch to Admin View");
260+
await expect(page.locator("[data-project-data-menu]")).toBeHidden();
261+
await expect(page.locator("[data-project-data-action]:visible")).toHaveCount(0);
250262
await expect(page.locator("[aria-label='Toolbox role simulation']")).not.toHaveCSS("background-color", "rgba(0, 0, 0, 0)");
251263
await expect(page.locator("[data-tools-count]")).toHaveText("Tool Count: 30/37");
252264
await expect(page.locator("main").getByText("Users", { exact: true })).toHaveCount(0);
253265
await expect(page.locator("[data-toolbox-admin-nav-group]")).toHaveCount(0);
254266
await page.locator("[data-toolbox-role-banner]").click();
255267
await page.waitForURL(/role=admin/);
256268
await expect(page.locator("[data-toolbox-role-banner]")).toHaveText("ADMIN VIEW • Planned tools visible • Switch to Creator View");
269+
await expect(page.locator("[aria-label='Toolbox role simulation']")).toContainText("ADMIN VIEW • Planned tools visible • Switch to Creator View");
270+
await expect(page.locator("[aria-label='Toolbox role simulation']")).toContainText("Project Data ▾");
271+
await expect(page.locator("[data-project-data-menu]")).toBeVisible();
272+
await expect(page.locator("[data-project-data-menu] > summary")).toHaveText("Project Data ▾");
273+
await page.locator("[data-project-data-menu] > summary").click();
274+
await expect(page.locator("[data-project-data-menu]")).toHaveAttribute("open", "");
275+
await expect(page.locator("[data-project-data-action]")).toHaveText([
276+
"Reset Project Data",
277+
"Seed Demo Project",
278+
"Clear Test Data"
279+
]);
280+
const beforeProjectDataActions = await storageSnapshot(page);
281+
await page.getByRole("button", { name: "Reset Project Data" }).click();
282+
await page.getByRole("button", { name: "Seed Demo Project" }).click();
283+
await page.getByRole("button", { name: "Clear Test Data" }).click();
284+
expect(await storageSnapshot(page)).toEqual(beforeProjectDataActions);
257285
await expect(page.locator("[aria-label='Toolbox role simulation']")).not.toHaveCSS("background-color", "rgba(0, 0, 0, 0)");
258286
await expect(page.locator("[data-tools-count]")).toHaveText("Tool Count: 37/37");
259287
await expect(page.locator("[data-toolbox-admin-nav-group]")).toHaveCount(0);
@@ -280,10 +308,14 @@ test("root tools surface links current tool pages without old_* routes", async (
280308
await page.locator("[data-toolbox-role-banner]").click();
281309
await page.waitForURL(/role=user/);
282310
await expect(page.locator("[data-toolbox-role-banner]")).toHaveText("CREATOR VIEW • Project tools enabled • Switch to Admin View");
311+
await expect(page.locator("[data-project-data-menu]")).toBeHidden();
312+
await expect(page.locator("[data-project-data-action]:visible")).toHaveCount(0);
283313
await expect(page.locator("main").getByText("Users", { exact: true })).toHaveCount(0);
284314
await expect(page.locator("[data-toolbox-admin-nav-group]")).toHaveCount(0);
285315
await page.goto(`${server.baseUrl}/toolbox/index.html?role=guest`, { waitUntil: "networkidle" });
286316
await expect(page.locator("[data-toolbox-role-banner]")).toHaveText("GUEST VIEW • Preview only • Sign in to create");
317+
await expect(page.locator("[data-project-data-menu]")).toBeHidden();
318+
await expect(page.locator("[data-project-data-action]:visible")).toHaveCount(0);
287319
await expect(page.locator("[aria-label='Toolbox role simulation']")).not.toHaveCSS("background-color", "rgba(0, 0, 0, 0)");
288320
await expect(page.locator("[data-tools-count]")).toHaveText("Tool Count: 30/37");
289321
await expect(page.locator("main").getByText("Users", { exact: true })).toHaveCount(0);

toolbox/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
<div data-partial="header-nav"></div>
1515
<div class="container callout" aria-label="Toolbox role simulation">
1616
<a class="status" href="toolbox/index.html?role=user" data-toolbox-role-banner>GUEST VIEW • Preview only • Sign in to create</a>
17+
<details class="status" data-project-data-menu hidden>
18+
<summary>Project Data ▾</summary>
19+
<div class="content-stack content-stack--compact" aria-label="Project Data actions">
20+
<button class="btn" type="button" data-project-data-action="reset">Reset Project Data</button>
21+
<button class="btn" type="button" data-project-data-action="seed">Seed Demo Project</button>
22+
<button class="btn" type="button" data-project-data-action="clear">Clear Test Data</button>
23+
</div>
24+
</details>
1725
</div>
1826
<main>
1927
<section class="page-title">

0 commit comments

Comments
 (0)