Skip to content

Commit b2f5ecb

Browse files
committed
Require authentication before Idea Board save actions
1 parent dd7a373 commit b2f5ecb

13 files changed

Lines changed: 927 additions & 154 deletions

assets/toolbox/idea-board/js/index.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ function ideaIdFromText(text) {
437437
}
438438

439439
function saveIdeaRow(root, row) {
440+
if (!requireAuthenticatedWrite(root)) return;
440441
const idea = row.querySelector("[data-idea-board-idea-input]")?.value.trim();
441442
const pitch = row.querySelector("[data-idea-board-pitch-input]")?.value.trim();
442443
const status = row.querySelector("[data-idea-board-idea-status-input]")?.value;
@@ -479,6 +480,7 @@ function saveIdeaRow(root, row) {
479480
}
480481

481482
function saveNoteRow(root, row) {
483+
if (!requireAuthenticatedWrite(root)) return;
482484
const ideaId = row.dataset.ideaId;
483485
const idea = ideaRecord(ideaId);
484486
if (idea && isLockedIdea(idea)) {
@@ -533,6 +535,7 @@ function toggleNotes(root, ideaId) {
533535
}
534536

535537
function deleteIdea(root, ideaId) {
538+
if (!requireAuthenticatedWrite(root)) return;
536539
const index = ideaTable.findIndex((record) => record.ideaId === ideaId);
537540
if (index < 0) {
538541
updateStatus(root, "Idea Board could not delete that idea.");
@@ -588,6 +591,20 @@ function currentSessionState() {
588591
}
589592
}
590593

594+
function requireAuthenticatedWrite(root) {
595+
const sessionState = currentSessionState();
596+
if (!sessionState.apiAvailable) {
597+
updateStatus(root, "API session status could not be verified. Try again shortly.");
598+
return false;
599+
}
600+
if (!sessionState.authenticated) {
601+
updateStatus(root, "Sign in before saving Idea Board changes.");
602+
window.location.href = signInUrl();
603+
return false;
604+
}
605+
return true;
606+
}
607+
591608
function createProject(root, ideaId) {
592609
const record = ideaRecord(ideaId);
593610
if (!record) {
@@ -598,16 +615,7 @@ function createProject(root, ideaId) {
598615
updateStatus(root, "Set this idea to Ready before creating a project.");
599616
return;
600617
}
601-
const sessionState = currentSessionState();
602-
if (!sessionState.apiAvailable) {
603-
updateStatus(root, "Sign-in status could not be verified. Try again shortly.");
604-
return;
605-
}
606-
if (!sessionState.authenticated) {
607-
updateStatus(root, "Sign in to create a Game Hub project.");
608-
window.location.href = signInUrl();
609-
return;
610-
}
618+
if (!requireAuthenticatedWrite(root)) return;
611619
const repository = gameHubProjectRepository();
612620
const project = repository.createGame({
613621
name: record.idea,
@@ -638,6 +646,7 @@ function archiveIdea(root, ideaId) {
638646
updateStatus(root, "Idea Board could not archive that idea.");
639647
return;
640648
}
649+
if (!requireAuthenticatedWrite(root)) return;
641650
if (record.status !== "Archived") record.previousStatus = record.status;
642651
record.status = "Archived";
643652
record.updated = today();
@@ -657,6 +666,7 @@ function restoreIdea(root, ideaId) {
657666
updateStatus(root, "Idea Board could not restore that idea.");
658667
return;
659668
}
669+
if (!requireAuthenticatedWrite(root)) return;
660670
record.status = previousStatusForRestore(record);
661671
record.previousStatus = record.status;
662672
record.updated = today();
@@ -742,6 +752,7 @@ function handleNoteAction(root, actionControl) {
742752
updateStatus(root, "Editing note.");
743753
render(root);
744754
} else if (action === "delete") {
755+
if (!requireAuthenticatedWrite(root)) return;
745756
const index = noteTable.findIndex((note) => note.noteId === noteId && note.ideaId === ideaId && !note.system);
746757
if (index >= 0) {
747758
noteTable.splice(index, 1);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# PR_26175_BRAVO_011 Branch Validation
2+
3+
Date: 2026-06-24
4+
5+
## Branch Gate
6+
7+
- PASS: Current branch was verified as `main` before planning and implementation.
8+
- PASS: Worktree was verified clean before the PR branch was created.
9+
- PASS: `origin/main` was pulled/rebased before the PR branch was created.
10+
- PASS: `HEAD`, `main`, and `origin/main` were synced at `dd7a3732e4225e42fe1033d37090abe179e6d5a5`.
11+
- PASS: Work moved to scoped branch `pr/26175-BRAVO-011-idea-board-guest-save-auth-redirect`.
12+
13+
## Current State Before Commit
14+
15+
- Branch: `pr/26175-BRAVO-011-idea-board-guest-save-auth-redirect`
16+
- Base commit: `dd7a3732e4225e42fe1033d37090abe179e6d5a5`
17+
- Origin/main sync before edits: `0/0`
18+
- Worktree: dirty with intended PR files and required reports.
19+
20+
## Result
21+
22+
PASS: Branch and clean-worktree gates passed before implementation. Current dirty state is expected PR output before commit.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# PR_26175_BRAVO_011 Instruction Compliance
2+
3+
Date: 2026-06-24
4+
5+
## Governance
6+
7+
- PASS: Read ProjectInstructions before implementation.
8+
- PASS: Initial branch was `main`; implementation did not begin until after the main-branch gate passed.
9+
- PASS: Initial worktree was clean before implementation.
10+
- PASS: Scope remained limited to Idea Board auth gating, impacted tests, and required reports.
11+
- PASS: No engine core files modified.
12+
- PASS: No `start_of_day` files modified.
13+
- PASS: No `imageDataUrl` contract usage introduced.
14+
- PASS: No runtime code outside the Idea Board save/auth path was changed.
15+
16+
## Frontend / Runtime Rules
17+
18+
- PASS: No inline runtime script/style/event handlers added.
19+
- PASS: No browser-owned product-data SSoT added.
20+
- PASS: No localStorage/sessionStorage product-data persistence added.
21+
- PASS: Existing API/session terminology and helpers were used.
22+
23+
## Reporting / Packaging
24+
25+
- PASS: Required PR reports created.
26+
- PASS: V8 coverage reports refreshed after Playwright route coverage.
27+
- PASS: `codex_review.diff`, `codex_changed_files.txt`, and repo-structured ZIP are generated for this run.
28+
29+
## ZIP
30+
31+
- `tmp/PR_26175_BRAVO_011-idea-board-guest-save-auth-redirect_delta.zip`
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# PR_26175_BRAVO_011 Manual Validation Notes
2+
3+
Date: 2026-06-24
4+
5+
## Reviewed Runtime Paths
6+
7+
- `toolbox/idea-board/index.html`
8+
- `assets/toolbox/idea-board/js/index.js`
9+
- `src/api/session-api-client.js`
10+
- `src/api/server-api-client.js`
11+
- Sign-in route usage: `account/sign-in.html`
12+
13+
## Persist Actions Verified
14+
15+
- Add idea save: guest redirects before save.
16+
- Edit idea save: guest redirects before update.
17+
- Delete idea: guest redirects before delete.
18+
- Add note save: guest redirects before save.
19+
- Edit note save: guest redirects before update.
20+
- Delete note: guest redirects before delete.
21+
- Create project: guest redirects before `createGame`.
22+
- Archive project idea: guest redirects before archive mutation.
23+
- Restore archived project idea: guest redirects before restore mutation.
24+
25+
## Browse Actions Verified
26+
27+
- Guest can load the Idea Board.
28+
- Guest can expand existing idea notes.
29+
- Guest remains on `toolbox/idea-board/index.html` while browsing.
30+
31+
## Data Safety Notes
32+
33+
- No production data was modified.
34+
- No migration or database write was executed outside Playwright local test servers.
35+
- No browser product-data SSoT was added.
36+
- No `localStorage` or `sessionStorage` product-data persistence was added.
37+
- No fake login or silent fallback was added.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# PR_26175_BRAVO_011 Idea Board Guest Save Auth Redirect
2+
3+
Date: 2026-06-24
4+
5+
## Scope
6+
7+
Require an authenticated API session before Idea Board save or persist actions. Guests may still browse the Idea Board, expand rows, and inspect notes. Guests are redirected to `account/sign-in.html` before any save/persist mutation.
8+
9+
## Review Findings
10+
11+
- PASS: ProjectInstructions and governance documents were reviewed before implementation.
12+
- PASS: Initial branch was `main`, worktree was clean, and `main`/`origin/main` were synced at `dd7a3732e4225e42fe1033d37090abe179e6d5a5` before the PR branch was created.
13+
- PASS: `toolbox/idea-board/index.html` delegates runtime behavior to `assets/toolbox/idea-board/js/index.js`.
14+
- PASS: Existing auth/session helper is `getSessionCurrent()` from `src/api/session-api-client.js`, backed by the API session contract.
15+
- PASS: Existing sign-in route pattern uses `account/sign-in.html`.
16+
- PASS: Persisting Idea Board actions identified: idea save, idea delete, note save, note delete, create project, archive, and restore.
17+
- PASS: Browse-only actions identified: loading the board, expanding/collapsing notes, filtering, starting/canceling edit rows, and opening existing project links.
18+
19+
## Implementation Summary
20+
21+
- Added one shared Idea Board write guard, `requireAuthenticatedWrite(root)`, using the existing API session helper.
22+
- Applied the guard before every Idea Board mutation/write path: idea save, note save, idea delete, note delete, create project, archive, and restore.
23+
- Preserved guest browsing by leaving load, filter, expand/collapse, and non-persist UI actions unauthenticated.
24+
- Expanded Playwright coverage so guest add/edit/delete idea, add/edit/delete note, create project, archive, and restore actions redirect to sign-in before writes.
25+
- Kept the implementation on the existing API contract; no browser product-data SSoT, fake login, localStorage/sessionStorage product data, or environment-specific branch was introduced.
26+
27+
## Affected Files
28+
29+
- `assets/toolbox/idea-board/js/index.js`
30+
- `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs`
31+
- `tests/playwright/tools/ToolboxRoutePages.spec.mjs`
32+
- `docs_build/dev/reports/playwright_v8_coverage_report.txt`
33+
- `docs_build/dev/reports/coverage_changed_js_guardrail.txt`
34+
35+
## Validation Summary
36+
37+
- PASS: Targeted node guardrail passed.
38+
- PASS: Runtime grep found no `localStorage` or `sessionStorage` use in Idea Board runtime HTML/JS.
39+
- PASS: Runtime grep found no inline script/style/event-handler additions in Idea Board runtime HTML/JS.
40+
- PASS: Focused Playwright guest redirect test passed.
41+
- PASS: Focused Playwright Toolbox-to-Idea-Board launch test passed after filtering unrelated selected-game status polling from the no-write assertion.
42+
- PASS: Playwright V8 coverage report includes `assets/toolbox/idea-board/js/index.js`.
43+
- WARN: Bundled Playwright Chromium was missing and `npx playwright install chromium` stalled with a partial install; focused browser validation used installed Google Chrome through a temporary config that was removed after validation.
44+
- WARN: Full legacy Playwright files still have unrelated expectation drift documented in the validation lane report.
45+
46+
## Recommended Next PR
47+
48+
Create a follow-up validation cleanup PR for existing Toolbox/Game Hub drift:
49+
50+
- Refresh `ToolboxRoutePages` expected tool counts, Game Hub route alias expectations, failed module-load assertions, and local dev port guard expectation.
51+
- Refresh or repair the Game Hub expanded child-row summary expectation in `IdeaBoardTableNotes`.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# PR_26175_BRAVO_011 Requirements Checklist
2+
3+
Date: 2026-06-24
4+
5+
| Requirement | Result | Evidence |
6+
| --- | --- | --- |
7+
| Guests may browse the Idea Board. | PASS | Playwright expands `top-thoughts` as a guest and remains on `toolbox/idea-board/index.html`. |
8+
| Guests may not save creator-owned data. | PASS | Guest save/persist controls redirect before mutation. |
9+
| Every save/persist action redirects unauthenticated users to `account/sign-in.html`. | PASS | Covered add/edit/delete idea, add/edit/delete note, create project, archive, and restore. |
10+
| Redirect before any API write. | PASS | Guest create/archive/restore assertions reset and inspect create-game requests; no write request is sent before redirect. |
11+
| All environments use the same API contract. | PASS | Uses existing `getSessionCurrent()` API session helper; no environment-specific branch added. |
12+
| Do not introduce browser-owned product data. | PASS | No new browser persistence or product-data SSoT added. |
13+
| Do not use localStorage/sessionStorage as product-data SSoT. | PASS | Runtime grep found no `localStorage` or `sessionStorage` in Idea Board runtime HTML/JS. |
14+
| Do not introduce fake login behavior. | PASS | Runtime uses existing API session helper only; tests use repo test session endpoint. |
15+
| No silent fallbacks. | PASS | API session verification failure blocks the write and reports status. |
16+
| Use API terminology only. | PASS | New unavailable status uses API session terminology. |
17+
| Keep PR limited to scope. | PASS | Runtime change is limited to Idea Board write gating; tests and reports cover the same scope. |
18+
| Create required reports. | PASS | PR report, branch validation, requirement checklist, validation lane, manual notes, instruction compliance, review diff, changed files, and V8 coverage reports are included. |
19+
| Create repo-structured ZIP under `tmp/`. | PASS | `tmp/PR_26175_BRAVO_011-idea-board-guest-save-auth-redirect_delta.zip`. |
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# PR_26175_BRAVO_011 Validation Lane
2+
3+
Date: 2026-06-24
4+
5+
## Commands
6+
7+
| Command | Result | Notes |
8+
| --- | --- | --- |
9+
| `git diff --check` | PASS | CRLF warnings only for touched Playwright specs. |
10+
| `rg -n "localStorage|sessionStorage" assets/toolbox/idea-board/js/index.js toolbox/idea-board/index.html` | PASS | No runtime matches. |
11+
| `rg -n "<script>|<style|style=|onclick=|onchange=|oninput=|onsubmit=" toolbox/idea-board/index.html assets/toolbox/idea-board/js/index.js` | PASS | No matches. |
12+
| `node scripts/run-node-test-files.mjs tests/regression/CanonicalRepositoryStructureGuardrail.test.mjs` | PASS | 1 file, 2 tests passed. |
13+
| `npx playwright test tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --config=tmp/playwright-system-chrome.config.cjs --workers=1 --reporter=list -g "Idea Board guest write actions redirect to sign in before saving data"` | PASS | Guest redirects verified for all scoped write actions. |
14+
| `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs --config=tmp/playwright-system-chrome.config.cjs --workers=1 --reporter=list -g "Idea Board launches from Toolbox with accordion table notes model"` | PASS | Idea Board route and V8 coverage path exercised. |
15+
| `npx playwright test tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --config=tmp/playwright-system-chrome.config.cjs --workers=1 --reporter=list` | WARN | 3 passed, 1 failed in downstream Game Hub expanded-row expectation: expected 3 child rows, received 2 (`source-idea`, `readiness-output`). This is unrelated legacy drift. |
16+
| `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs --config=tmp/playwright-system-chrome.config.cjs --workers=1 --reporter=list` | WARN | 6 passed, 5 failed in unrelated toolbox metadata/route/local-port expectations. The Idea Board launch test passed. |
17+
18+
## Browser Setup Note
19+
20+
- WARN: Default Playwright Chromium was missing at `C:\Users\davidq\AppData\Local\ms-playwright\chromium-1217\chrome-win64\chrome.exe`.
21+
- WARN: `npx playwright install chromium` stalled with only partial placeholder files and was stopped.
22+
- PASS: Focused browser validation was rerun with installed Google Chrome through a temporary `tmp/playwright-system-chrome.config.cjs`, then the temp config and `tmp/test-results` were removed.
23+
24+
## Full-Suite Residual Failures
25+
26+
- `ToolboxRoutePages`: expected `Game Hub` route `/toolbox/game-workspace/index.html` not visible.
27+
- `ToolboxRoutePages`: expected toolbox status counts `Planned (28)` and `Beta (6)`; actual `Planned (27)` and `Beta (8)`.
28+
- `ToolboxRoutePages`: Game Crew route run recorded failed requests for shared toolbox metadata modules.
29+
- `ToolboxRoutePages`: local dev port guard expected redirect to port `5501`; page remained on the ephemeral test server port.
30+
- `IdeaBoardTableNotes`: Game Hub row expansion expected `summary`, `source-idea`, and `readiness-output`; rendered `source-idea` and `readiness-output`.
31+
32+
## Result
33+
34+
PASS: BRAVO_011 validation lane passed for scoped guest-save auth redirect behavior.
35+
36+
WARN: Broad legacy Playwright files are not fully green due to unrelated existing drift listed above.
Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
1-
assets/toolbox/idea-board/js/index.js
2-
docs_build/dev/reports/PR_26175_ALFA_018-alfa-idea-board-polish-consolidation.md
3-
docs_build/dev/reports/codex_changed_files.txt
4-
docs_build/dev/reports/codex_review.diff
5-
tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
1+
# git diff --cached --name-status origin/main
2+
M assets/toolbox/idea-board/js/index.js
3+
A docs_build/dev/reports/PR_26175_BRAVO_011-idea-board-guest-save-auth-redirect_branch-validation.md
4+
A docs_build/dev/reports/PR_26175_BRAVO_011-idea-board-guest-save-auth-redirect_instruction-compliance.md
5+
A docs_build/dev/reports/PR_26175_BRAVO_011-idea-board-guest-save-auth-redirect_manual-validation-notes.md
6+
A docs_build/dev/reports/PR_26175_BRAVO_011-idea-board-guest-save-auth-redirect_report.md
7+
A docs_build/dev/reports/PR_26175_BRAVO_011-idea-board-guest-save-auth-redirect_requirements-checklist.md
8+
A docs_build/dev/reports/PR_26175_BRAVO_011-idea-board-guest-save-auth-redirect_validation-lane.md
9+
M docs_build/dev/reports/codex_changed_files.txt
10+
M docs_build/dev/reports/codex_review.diff
11+
M docs_build/dev/reports/coverage_changed_js_guardrail.txt
12+
M docs_build/dev/reports/playwright_v8_coverage_report.txt
13+
M tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
14+
M tests/playwright/tools/ToolboxRoutePages.spec.mjs
15+
16+
# git diff --cached --stat origin/main
17+
assets/toolbox/idea-board/js/index.js | 31 +-
18+
...d-guest-save-auth-redirect_branch-validation.md | 22 +
19+
...st-save-auth-redirect_instruction-compliance.md | 31 +
20+
...t-save-auth-redirect_manual-validation-notes.md | 37 +
21+
...1-idea-board-guest-save-auth-redirect_report.md | 51 +
22+
...st-save-auth-redirect_requirements-checklist.md | 19 +
23+
...ard-guest-save-auth-redirect_validation-lane.md | 36 +
24+
docs_build/dev/reports/codex_changed_files.txt | 38 +-
25+
docs_build/dev/reports/codex_review.diff | 1350 ++++++++++++++++++--
26+
.../dev/reports/coverage_changed_js_guardrail.txt | 10 +-
27+
.../dev/reports/playwright_v8_coverage_report.txt | 39 +-
28+
.../playwright/tools/IdeaBoardTableNotes.spec.mjs | 118 +-
29+
tests/playwright/tools/ToolboxRoutePages.spec.mjs | 5 +-
30+
13 files changed, 1640 insertions(+), 147 deletions(-)

0 commit comments

Comments
 (0)