Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Branch Validation: PASS

PASS - Current branch: pr/26174-ALFA-008-alpha-stack-final-validation.
PASS - Stack base: pr/26174-ALFA-007-game-journey-count-ui-polish.
PASS - PR_008 contains final validation reports only.
PASS - No merge to main performed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ALFA Stack Final Report

## Branch

pr/26174-ALFA-008-alpha-stack-final-validation

## Stack Head Before PR_008 Reports

7ebadc46f25cec3ad52e3432f9c198d4ebab6516

## Covered PRs

- PR_26174_ALFA_001-idea-board-create-project-api-contract
- PR_26174_ALFA_002-game-hub-project-intake-display
- PR_26174_ALFA_003-game-hub-journey-bootstrap
- PR_26174_ALFA_004-game-hub-progress-count-model
- PR_26174_ALFA_005-idea-project-validation-polish
- PR_26174_ALFA_006-game-hub-empty-and-error-states
- PR_26174_ALFA_007-game-journey-count-ui-polish

## Targeted Validation

PASS - Idea Board: full targeted spec validated Ready-only project conversion, source idea project intake, Game Hub display, Journey bootstrap, guest redirect, and locked Project rows.
PASS - Game Hub: focused empty and unavailable states validated creator-safe messages without internal details.
PASS - Game Journey: progress dashboard lane validated count defaults, numeric inputs, bucket/target order, API persistence, and reload persistence.

## Stack Executable Changed Files

- toolbox/idea-board/index.js
- tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
- src/dev-runtime/persistence/mock-db-store.js
- src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js
- src/dev-runtime/server/local-api-router.mjs
- toolbox/game-hub/game-hub.js
- tests/playwright/tools/GameHubMockRepository.spec.mjs
- toolbox/game-journey/game-journey.js
- tests/playwright/tools/GameJourneyTool.spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Manual Validation Notes: PASS

PASS - Idea Board Create Project remains Ready-only, API-backed, locked/read-only after conversion, and guest-safe.
PASS - Game Hub displays Idea Board-created projects and source notes through Local API persistence.
PASS - Game Journey bootstrap creates starter buckets and source idea items through the service contract.
PASS - Game Journey count model remains numeric, ordered, and persisted through updateRecommendedTarget.
PASS - Game Hub empty and unavailable states use creator-safe copy and no silent fallback.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Requirement Checklist: PASS

PASS - Ran targeted validation for ALFA_001 through ALFA_007.
PASS - Produced final stack report.
PASS - Confirmed changed files.
PASS - Confirmed Playwright lane.
PASS - Confirmed manual validation notes.
PASS - Created required reports and repo-structured ZIP under tmp/.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Validation Lane: PASS

PASS - npx playwright test tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
PASS - npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs -g "Game Hub shows a creator-safe empty state|Game Hub shows a creator-safe unavailable state"
PASS - npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs -g "Game Journey progress dashboard summarizes completion metrics"

Notes:
- These targeted Playwright lanes cover the ALFA_001 through ALFA_007 stack.
- Full workspace smoke was not run.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# PR_26174_ALFA_008-alpha-stack-final-validation

## Purpose

Run final targeted validation for ALFA_001 through ALFA_007 and produce the final stack report.

## Summary

- Ran targeted validation lanes covering Idea Board project conversion, Game Hub intake/empty/error states, Game Journey bootstrap, and count UI polish.
- Confirmed stack changed files and manual validation notes.
- Created report-only PR_008 artifacts; no executable code changed in this PR.

## Validation

PASS - `npx playwright test tests/playwright/tools/IdeaBoardTableNotes.spec.mjs`
PASS - `npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs -g "Game Hub shows a creator-safe empty state|Game Hub shows a creator-safe unavailable state"`
PASS - `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs -g "Game Journey progress dashboard summarizes completion metrics"`
13 changes: 6 additions & 7 deletions docs_build/dev/reports/codex_changed_files.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
toolbox/game-journey/game-journey.js
tests/playwright/tools/GameJourneyTool.spec.mjs
docs_build/dev/reports/codex_review.diff
docs_build/dev/reports/codex_changed_files.txt
docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish.md
docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish-branch-validation.txt
docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish-requirement-checklist.txt
docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish-validation-lane.txt
docs_build/dev/reports/PR_26174_ALFA_007-game-journey-count-ui-polish-manual-validation-notes.txt
docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation.md
docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-final-stack-report.md
docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-branch-validation.txt
docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-requirement-checklist.txt
docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-validation-lane.txt
docs_build/dev/reports/PR_26174_ALFA_008-alpha-stack-final-validation-manual-validation-notes.txt
133 changes: 1 addition & 132 deletions docs_build/dev/reports/codex_review.diff
Original file line number Diff line number Diff line change
@@ -1,132 +1 @@
diff --git a/tests/playwright/tools/GameJourneyTool.spec.mjs b/tests/playwright/tools/GameJourneyTool.spec.mjs
index e9005f08b..586e7521f 100644
--- a/tests/playwright/tools/GameJourneyTool.spec.mjs
+++ b/tests/playwright/tools/GameJourneyTool.spec.mjs
@@ -69,7 +69,6 @@ async function openRepoPage(page, pathName, options = {}) {
page.on("requestfailed", (request) => {
failedRequests.push(`FAILED ${request.url()}`);
});
-
if (collectCoverage) {
await workspaceV2CoverageReporter.start(page);
}
@@ -258,6 +257,7 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p
const failedRequests = [];
const pageErrors = [];
const consoleErrors = [];
+ const recommendedTargetRequests = [];

page.on("pageerror", (error) => {
pageErrors.push(error.message);
@@ -275,6 +275,12 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p
page.on("requestfailed", (request) => {
failedRequests.push(`FAILED ${request.url()}`);
});
+ page.on("request", (request) => {
+ const requestUrl = request.url();
+ if (requestUrl.includes("/api/toolbox/game-journey/repositories/") && requestUrl.includes("/methods/updateRecommendedTarget")) {
+ recommendedTargetRequests.push(request.postDataJSON());
+ }
+ });

try {
await workspaceV2CoverageReporter.start(page);
@@ -332,12 +338,23 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p
"Next action: mark one finished section item complete so overall progress can rise above 0%.",
]);
await expect(page.locator("[data-journey-recommended-target]")).toHaveCount(5);
+ const recommendedTargetOrder = await page.locator("[data-journey-recommended-target]").evaluateAll((rows) => (
+ rows.map((row) => row.dataset.journeyRecommendedTarget)
+ ));
+ expect(recommendedTargetOrder).toEqual([
+ "hero",
+ "enemy",
+ "boss",
+ "background",
+ "music",
+ ]);
+ await expect(page.locator("[data-journey-recommended-targets] th")).toHaveText(["Target", "Section", "Count"]);
await expect(page.locator("[data-journey-recommended-target] td:first-child")).toHaveText([
- "Hero",
- "Enemy",
- "Boss",
- "Background",
- "Music",
+ "Hero [1]",
+ "Enemy [4]",
+ "Boss [1]",
+ "Background [3]",
+ "Music [5]",
]);
await expect(page.locator("[data-journey-recommended-target='hero'] td").nth(1)).toHaveText("Objects");
await expect(page.locator("[data-journey-recommended-target='enemy'] td").nth(1)).toHaveText("Objects");
@@ -349,11 +366,19 @@ test("Game Journey progress dashboard summarizes completion metrics", async ({ p
await expect(page.locator("[data-journey-target-input='boss']")).toHaveValue("1");
await expect(page.locator("[data-journey-target-input='background']")).toHaveValue("3");
await expect(page.locator("[data-journey-target-input='music']")).toHaveValue("5");
+ await expect(page.locator("[data-journey-recommended-target] input[type='checkbox']")).toHaveCount(0);
+ await expect(page.locator("[data-journey-target-input='hero']")).toHaveAttribute("type", "number");
+ await expect(page.locator("[data-journey-target-input='hero']")).toHaveAttribute("inputmode", "numeric");
+ await expect(page.locator("[data-journey-target-input='hero']")).toHaveAttribute("aria-label", "Hero count");
await page.locator("[data-journey-target-input='hero']").fill("2");
await expect(page.locator("[data-journey-target-status]")).toHaveText("Saved Hero target at 2.");
await expect(page.locator("[data-journey-target-input='hero']")).toHaveValue("2");
+ await expect(page.locator("[data-journey-target-count-preview='hero']")).toHaveText(" [2]");
+ expect(recommendedTargetRequests).toHaveLength(1);
+ expect(recommendedTargetRequests[0].args).toEqual(["hero", 2]);
await page.reload({ waitUntil: "networkidle" });
await expect(page.locator("[data-journey-target-input='hero']")).toHaveValue("2");
+ await expect(page.locator("[data-journey-target-count-preview='hero']")).toHaveText(" [2]");
const repositoryData = await fetchApiData(server, "/api/toolbox/game-journey/repositories", {
body: JSON.stringify({ options: {} }),
method: "POST",
diff --git a/toolbox/game-journey/game-journey.js b/toolbox/game-journey/game-journey.js
index c2b2f876c..332274910 100644
--- a/toolbox/game-journey/game-journey.js
+++ b/toolbox/game-journey/game-journey.js
@@ -1161,7 +1161,7 @@ function renderRecommendedTargets() {
table.setAttribute("aria-label", "Game Journey recommended planning targets");
const head = createElement("thead");
const headRow = createElement("tr");
- ["Target", "Section", "Suggested"].forEach((heading) => {
+ ["Target", "Section", "Count"].forEach((heading) => {
const cell = createElement("th", { text: heading });
cell.scope = "col";
headRow.append(cell);
@@ -1169,16 +1169,22 @@ function renderRecommendedTargets() {
head.append(headRow);
const body = createElement("tbody");
targets.forEach((target) => {
+ const targetCount = recommendedTargetValues.get(target.key) ?? target.suggestedCount;
const row = createElement("tr");
row.dataset.journeyRecommendedTarget = target.key;
- const labelCell = createElement("td", { text: target.label });
+ const labelCell = createElement("td");
+ const label = createElement("span", { text: target.label });
+ const countPreview = createElement("span", { text: ` [${targetCount}]` });
+ countPreview.dataset.journeyTargetCountPreview = target.key;
+ labelCell.append(label, countPreview);
const sectionCell = createElement("td", { text: target.sectionName });
const input = document.createElement("input");
input.type = "number";
+ input.inputMode = "numeric";
input.min = "0";
input.step = "1";
- input.value = String(recommendedTargetValues.get(target.key) ?? target.suggestedCount);
- input.setAttribute("aria-label", `${target.label} suggested target`);
+ input.value = String(targetCount);
+ input.setAttribute("aria-label", `${target.label} count`);
input.dataset.journeyTargetInput = target.key;
const inputCell = createElement("td");
inputCell.append(input);
@@ -1773,6 +1779,10 @@ recommendedTargets?.addEventListener("input", (event) => {
const savedValue = normalizeTargetCount(updated.suggestedCount);
recommendedTargetValues.set(target.key, savedValue);
input.value = String(savedValue);
+ const preview = recommendedTargets.querySelector(`[data-journey-target-count-preview='${target.key}']`);
+ if (preview) {
+ preview.textContent = ` [${savedValue}]`;
+ }
if (recommendedTargetStatus) {
recommendedTargetStatus.textContent = `Saved ${target.label} target at ${savedValue}.`;
}
No executable code changes in PR_26174_ALFA_008; final validation and reporting only.
Loading