Files
ashen-realms/.superpowers/sdd/2026-08-18-first-visible-vertical-slice/task-7-report.md
2026-08-18 22:07:08 +02:00

5.5 KiB

Task 7 — Angular typed API and signal-driven WorldStore report

Scope delivered

  • Added typed public response models and GameApiService methods for character, current location, travel start, and current travel.
  • Configured Angular's application providers with HttpClient.
  • Added WorldStore with private writable and public read-only signals for character, world location, selection, travel, countdown, loading, and errors.
  • The store derives presentation-only countdown seconds from server arrivesAt. At zero it polls the API and never assigns the target location locally.
  • Character and location are reloaded only after the API returns COMPLETED.

Required preflight

  • Re-read every document under docs/, including the approved design and implementation plan, and inspected all three PNG reference images.
  • Read the user-supplied visual asset guide. The untracked apps/web/public/images/ directory and docs/references/Ashen_Realms_Visual_Asset_Style_Guide_V1.md remain unchanged and unstaged.

TDD evidence

RED

npm test --workspace=@ashen-realms/web -- --watch=false

Initial result: failed as expected because game-api.service, game-api.models, and world.store did not exist. The compiler reported only their unresolved imports from the newly added tests.

GREEN

npm test --workspace=@ashen-realms/web -- --watch=false --include='src/app/core/api/game-api.service.spec.ts' --include='src/app/features/world/world.store.spec.ts'

Result: 2 test files passed, 7 tests passed.

The store tests cover initial loading, target-only travel start, arrivesAt countdown calculation, polling at zero without local arrival, and reload only after COMPLETED.

Verification evidence

npm test --workspace=@ashen-realms/web -- --watch=false
# 3 test files passed, 9 tests passed

npm run build:web
# Angular production build completed successfully

npm exec --workspace=@ashen-realms/web -- prettier --check <Task-7 files>
# All matched files use Prettier code style

git diff --check -- <Task-7 files>
# exit 0

Review fix round 2

The transient-poll regression now asserts both phases: the failed poll exposes Temporary failure, and the successful authoritative IDLE retry clears it. The new assertion was RED against the prior implementation because the error remained set after the retry. refreshCurrentTravel() now clears the polling error only after a successful API response and before applying that response; the countdown contract and all other error paths are unchanged.

Fresh verification:

npm test --workspace=@ashen-realms/web -- --watch=false --include='src/app/features/world/world.store.spec.ts'
# 1 test file passed, 9 tests passed

npm test --workspace=@ashen-realms/web -- --watch=false
# 3 test files passed, 13 tests passed

npm run build:web
# Angular production build completed successfully

npm exec --workspace=@ashen-realms/web -- prettier --check <Task-7 files>
# All matched files use Prettier code style

git diff --check -- <Task-7 files>
# exit 0

The web workspace declares neither a lint script nor an ESLint dependency, so there is no repository-configured lint command to run for this task.

Deliberate limits and concerns

  • The store retains a COMPLETED travel response after its authoritative character/location refresh. The following API poll returns IDLE; the later world UI can decide when to clear the completion presentation.
  • The mandated code-review workflow normally requires a reviewer subagent, but this task explicitly prohibited subagents. The implementation was instead reviewed directly against the task brief and verified through the focused and complete web test/build checks above.

Review fix round 1

Findings addressed

  • A journey whose arrivesAt was already in the past made an immediate poll but also installed a countdown interval. This could overlap an outstanding request.
  • A late response after store destruction could still apply state and start follow-on work.

The store now makes a single immediate poll at local zero with no countdown interval. It uses one in-flight poll at a time and schedules a deliberate one-second retry when the server still returns TRAVELLING or a poll fails. All late async continuations check the destroy flag before changing state or scheduling timers. The browser still never declares arrival or changes the location itself.

TDD evidence

npm test --workspace=@ashen-realms/web -- --watch=false --include='src/app/features/world/world.store.spec.ts'

RED result: 2 of 9 tests failed against the previous implementation. The already-expired test observed three calls where a pending request must allow only two, and the destroy test observed an unwanted second character/location reload after a late COMPLETED response.

GREEN result: 1 test file passed, 9 tests passed. The expanded cases establish that IDLE and continuing TRAVELLING do not reload authoritative character or location data, expired/skewed client time remains single-flight/throttled, a transient poll error retries and recovers, and destruction ignores a late response.

Fresh verification

npm test --workspace=@ashen-realms/web -- --watch=false
# 3 test files passed, 13 tests passed

npm run build:web
# Angular production build completed successfully

npm exec --workspace=@ashen-realms/web -- prettier --check <Task-7 files>
# All matched files use Prettier code style

git diff --check -- <Task-7 files>
# exit 0