docs
This commit is contained in:
@@ -1,50 +0,0 @@
|
||||
# Task 4: Health and demo-character API report
|
||||
|
||||
## RED
|
||||
|
||||
- Re-read every Markdown document below `docs/` and inspected `combat-screen.png`, `hunting-screen.png`, and `world-travel-screen.png` before implementation.
|
||||
- Added focused health and character-service tests, then ran:
|
||||
|
||||
```powershell
|
||||
npm test --workspace=@ashen-realms/api -- health.controller.spec.ts characters.service.spec.ts --runInBand
|
||||
```
|
||||
|
||||
- Observed the expected RED result: both suites failed because `HealthController` and `CharactersService` did not exist.
|
||||
|
||||
## GREEN
|
||||
|
||||
- Replaced the scaffold root controller/service with `HealthModule` and `CharactersModule`.
|
||||
- `GET /api/health` returns `{ status: 'ok' }` without a database query.
|
||||
- `GET /api/characters/me` obtains the fixed demo ID server-side, loads `currentLocation`, maps `baseHp` to `maxHp` and `baseAttack` to `attack`, and raises `NotFoundException` when the seed is absent.
|
||||
- Preserved the existing tested `configureApplication()` global-prefix seam and enabled Nest shutdown hooks in `main.ts` without repeating prefix configuration.
|
||||
- Updated the E2E assertion from the retired hello-world root route to `/api/health`; it replaces both database-dependent modules so the health test remains database independent.
|
||||
|
||||
## Verification
|
||||
|
||||
| Command | Result |
|
||||
| --- | --- |
|
||||
| `npm test --workspace=@ashen-realms/api -- health.controller.spec.ts characters.service.spec.ts --runInBand` | PASS: 2 suites, 3 tests |
|
||||
| `npm run test:e2e --workspace=@ashen-realms/api -- --runInBand` | PASS: 1 suite, 2 tests |
|
||||
| `npm test --workspace=@ashen-realms/api -- --runInBand` | PASS: 5 suites, 9 tests |
|
||||
| `npm run build:api` | PASS |
|
||||
| `apps/api/node_modules/.bin/prettier.cmd --check <task files>` | PASS |
|
||||
| `git diff --check` | PASS |
|
||||
|
||||
`npx prettier` did not resolve the workspace-local executable in this environment; the checked-in workspace binary at `apps/api/node_modules/.bin/prettier.cmd` was used for the formatting check.
|
||||
|
||||
## Files
|
||||
|
||||
- Added `apps/api/src/health/*` and character controller/service/module plus unit tests.
|
||||
- Updated `apps/api/src/app.module.ts`, `apps/api/src/main.ts`, and `apps/api/test/app.e2e-spec.ts`.
|
||||
- Removed `apps/api/src/app.controller.ts`, `app.controller.spec.ts`, and `app.service.ts`.
|
||||
|
||||
## Self-review and concerns
|
||||
|
||||
- Confirmed the repository query loads only the required current-location relation and response does not expose persistence-only base-stat names.
|
||||
- Confirmed the missing seed path is tested as a 404-producing Nest exception.
|
||||
- Confirmed `/` remains a 404 while `/api/health` is available through the existing global prefix.
|
||||
- No task-specific concerns remain. Pre-existing untracked `apps/web/public/images/` and `docs/references/Ashen_Realms_Visual_Asset_Style_Guide_V1.md` are intentionally excluded.
|
||||
|
||||
## Commit
|
||||
|
||||
- Pending: `feat: expose health and demo character APIs`
|
||||
@@ -1,105 +0,0 @@
|
||||
# Task 5 Report: Server-authoritative travel
|
||||
|
||||
## Outcome
|
||||
|
||||
Implemented the NestJS travel domain and public endpoints:
|
||||
|
||||
- `POST /api/travel`
|
||||
- `GET /api/travel/current`
|
||||
- injected deterministic/system clock abstraction
|
||||
- exact `StartTravelDto` input validation
|
||||
- stable idle, travelling, completed, and domain-error response shapes
|
||||
- `TravelModule` registration in the application
|
||||
|
||||
Travel start and completion use `DataSource.transaction`. Both operations acquire a pessimistic write lock on the character row followed by the active travel row. Relations are deliberately not joined into either locking query, which keeps the queries compatible with TypeORM/PostgreSQL `FOR UPDATE` behavior. Due completion changes the travel status and character location through repositories owned by the same transaction; a failed second save rolls back both mutations.
|
||||
|
||||
No ambush evaluation or other later-slice logic was added. Existing untracked frontend images and the visual asset guide were preserved and excluded from the commit.
|
||||
|
||||
## RED evidence
|
||||
|
||||
Command:
|
||||
|
||||
```powershell
|
||||
npm test --workspace=@ashen-realms/api -- travel.service.spec.ts travel.controller.spec.ts --runInBand
|
||||
```
|
||||
|
||||
Initial result: exit code 1. Both suites failed to resolve the missing production modules:
|
||||
|
||||
```text
|
||||
Cannot find module './travel.service' from 'travel/travel.service.spec.ts'
|
||||
Cannot find module './travel.controller' from 'travel/travel.controller.spec.ts'
|
||||
Test Suites: 2 failed, 2 total
|
||||
Tests: 0 total
|
||||
```
|
||||
|
||||
The active-travel regression test was also mutation-checked. Temporarily removing the `TRAVEL_ALREADY_ACTIVE` guard produced the expected focused failure (`Expected constructor: TravelDomainError; Received constructor: Object`); restoring the guard returned the test to green.
|
||||
|
||||
## GREEN evidence
|
||||
|
||||
Focused travel tests:
|
||||
|
||||
```powershell
|
||||
npm test --workspace=@ashen-realms/api -- travel.service.spec.ts travel.controller.spec.ts --runInBand
|
||||
```
|
||||
|
||||
```text
|
||||
Test Suites: 2 passed, 2 total
|
||||
Tests: 9 passed, 9 total
|
||||
Time: 10.973 s
|
||||
```
|
||||
|
||||
The service suite covers all five required behaviors plus active-travel rejection, public current-travel mapping, idempotent repeat completion, pessimistic-lock observation, and rollback when the second completion save fails. The controller suite drives a real Nest HTTP pipeline and verifies that server-owned timestamp/duration fields receive HTTP 400.
|
||||
|
||||
Full API suite:
|
||||
|
||||
```powershell
|
||||
npm test --workspace=@ashen-realms/api -- --runInBand
|
||||
```
|
||||
|
||||
```text
|
||||
Test Suites: 7 passed, 7 total
|
||||
Tests: 18 passed, 18 total
|
||||
Time: 15.87 s
|
||||
```
|
||||
|
||||
API E2E:
|
||||
|
||||
```powershell
|
||||
npm run test:e2e --workspace=@ashen-realms/api -- --runInBand
|
||||
```
|
||||
|
||||
```text
|
||||
Test Suites: 1 passed, 1 total
|
||||
Tests: 2 passed, 2 total
|
||||
Time: 9.406 s
|
||||
```
|
||||
|
||||
API build:
|
||||
|
||||
```powershell
|
||||
npm run build:api
|
||||
```
|
||||
|
||||
Result: exit code 0 (`nest build`).
|
||||
|
||||
Formatting and lint:
|
||||
|
||||
```powershell
|
||||
apps/api/node_modules/.bin/prettier.cmd --check <Task 5 files>
|
||||
node_modules/.bin/eslint.cmd <Task 5 files>
|
||||
```
|
||||
|
||||
Both commands exited 0. Prettier reported `All matched files use Prettier code style!`; ESLint reported no findings.
|
||||
|
||||
## Integration notes and self-review
|
||||
|
||||
- The first build exposed TypeScript `TS1272` for a decorated `Clock` parameter under `isolatedModules`; importing `Clock` as a type fixed the root cause, after which tests and build were rerun.
|
||||
- Registering the database-backed `TravelModule` exposed that the existing health E2E test replaced `DatabaseModule` and `CharactersModule` but not travel. The harness now replaces `TravelModule` as well, preserving the database-free health test.
|
||||
- Lock order is identical in start and completion, reducing deadlock risk.
|
||||
- The character row serializes concurrent starts even when no active travel row exists yet; the partial unique database index remains the final invariant.
|
||||
- The due comparison treats `arrivesAt === now` as due and never moves the character earlier.
|
||||
- Public responses contain only location summaries and travel timestamps/status, never entities, duration input, ambush probability, or persistence metadata.
|
||||
|
||||
## Remaining concern
|
||||
|
||||
No live-PostgreSQL travel integration test was added because the repository's current E2E harness intentionally runs without a database; clean migration/seed/API database smoke coverage belongs to Task 10. The transaction code uses supported real `EntityManager.getRepository`, `Repository.findOne` lock options, `findOneBy`, `create`, and `save` behavior, and the stateful fake verifies transaction commit/rollback semantics rather than mock call counts.
|
||||
@@ -1,83 +0,0 @@
|
||||
# Task 6 — Current-location World API report
|
||||
|
||||
## Scope delivered
|
||||
|
||||
- Added `WorldService.getCurrentLocation(characterId)`.
|
||||
- Added `GET /api/world/current-location` using the stable demo character.
|
||||
- Added `WorldModule`, including TypeORM repositories for `Character` and
|
||||
`LocationConnection`, and imported it through `AppModule`.
|
||||
- `WorldService` completes due travel before loading the character, returns the
|
||||
complete current-location DTO, returns only enabled outgoing connections, and
|
||||
exposes a target summary, duration, and textual danger rating only. The raw
|
||||
`ambushChance` is not part of the public DTO; `0.0500` maps to `LOW`.
|
||||
- Kept the existing database-free health E2E harness valid by overriding the
|
||||
newly imported `WorldModule`, just as it already overrides the database,
|
||||
character, and travel modules.
|
||||
|
||||
## Required preflight
|
||||
|
||||
- Read the complete Task-6 brief and the binding project documentation,
|
||||
including the visual asset style guide.
|
||||
- Inspected `world-travel-screen.png`, `combat-screen.png`, and
|
||||
`hunting-screen.png` in `docs/references/`.
|
||||
- Preserved the user-owned untracked `apps/web/public/images/` directory and
|
||||
`docs/references/Ashen_Realms_Visual_Asset_Style_Guide_V1.md` unchanged.
|
||||
|
||||
## TDD evidence
|
||||
|
||||
### RED
|
||||
|
||||
Command:
|
||||
|
||||
```powershell
|
||||
npm test --workspace=@ashen-realms/api -- world.service.spec.ts --runInBand
|
||||
```
|
||||
|
||||
Initial result: failed because `./world.service` did not exist. After the
|
||||
minimal initial implementation, the test exposed that a disabled connection
|
||||
could still be returned by an unexpected repository result. The service now
|
||||
defensively filters disabled connections in addition to querying with
|
||||
`enabled: true`.
|
||||
|
||||
### GREEN
|
||||
|
||||
```powershell
|
||||
npm test --workspace=@ashen-realms/api -- world.service.spec.ts --runInBand
|
||||
```
|
||||
|
||||
Result: 1 suite passed, 2 tests passed.
|
||||
|
||||
## Verification evidence
|
||||
|
||||
```powershell
|
||||
npm test --workspace=@ashen-realms/api -- --runInBand
|
||||
# 8 suites passed, 20 tests passed
|
||||
|
||||
npm run test:e2e --workspace=@ashen-realms/api -- --runInBand
|
||||
# 1 suite passed, 2 tests passed
|
||||
|
||||
npm run build:api
|
||||
# Nest build completed successfully
|
||||
|
||||
# From apps/api:
|
||||
.\node_modules\.bin\prettier.cmd --check <Task-6 TypeScript files>
|
||||
npx eslint <Task-6 TypeScript files>
|
||||
# Prettier: all matched files use Prettier code style; ESLint exit 0
|
||||
|
||||
git diff --check -- apps/api/src/app.module.ts apps/api/src/world apps/api/test/app.e2e-spec.ts
|
||||
# exit 0
|
||||
```
|
||||
|
||||
The initial E2E run was reproducibly red because the new `WorldModule` caused
|
||||
TypeORM repository construction after the test had intentionally replaced the
|
||||
database module. Adding its corresponding empty module override restored the
|
||||
existing database-free health test without changing product behavior.
|
||||
|
||||
## Deliberate limits and concerns
|
||||
|
||||
- The approved first slice only needs the seeded 5% route, so the public
|
||||
connection danger mapping currently distinguishes `LOW` (at or below 5%) and
|
||||
`HIGH` (above 5%). Future routes may require finer danger tiers when their
|
||||
product thresholds are specified.
|
||||
- This task adds no database-backed route E2E assertion; the dedicated
|
||||
migration/seed route smoke test is scheduled for Task 10.
|
||||
@@ -1,151 +0,0 @@
|
||||
# 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
|
||||
|
||||
```powershell
|
||||
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
|
||||
|
||||
```powershell
|
||||
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
|
||||
|
||||
```powershell
|
||||
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:
|
||||
|
||||
```powershell
|
||||
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
|
||||
|
||||
```powershell
|
||||
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
|
||||
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
@@ -1,74 +0,0 @@
|
||||
# Task 8 report: reusable Angular application shell
|
||||
|
||||
## Scope delivered
|
||||
|
||||
- Replaced the Angular scaffold with a route-hosting root component and a reusable dark-fantasy shell.
|
||||
- Added focused standalone components for the app shell, store-driven top bar, side navigation, footer, and context-panel frame.
|
||||
- Added requested design tokens, spacing, motion, elevation, global reset, responsive shell grid, and reduced-motion protection.
|
||||
- Configured `/` and fallback routing to `/world`; the route lazy-loads a deliberately scene-free `WorldPageComponent` placeholder so Task 9 can add the world composition without changing the route contract.
|
||||
- Made Karte the only enabled active navigation entry. Jagd, Quests, Inventar, and Charakter are disabled buttons with accessible explanatory labels. Shop is not rendered.
|
||||
- Top-bar character identity, level, and hit points are rendered only from `WorldStore.character`; it has no hardcoded character statistics.
|
||||
|
||||
## Preflight and asset evidence
|
||||
|
||||
- Re-read the Task 8 brief, visible-slice implementation plan, progress ledger, prior task reports, and the full user-provided visual asset style guide.
|
||||
- Visually inspected `combat-screen.png`, `hunting-screen.png`, and `world-travel-screen.png` before editing.
|
||||
- Visually inspected the relevant user HUD assets before use. The shell uses only:
|
||||
- `apps/web/public/images/hud/CharacterIcon.png`
|
||||
- `apps/web/public/images/hud/MapsIcon.png`
|
||||
- `apps/web/public/images/hud/HuntIcon.png`
|
||||
- `apps/web/public/images/hud/QuestsIcon.png`
|
||||
- `apps/web/public/images/hud/InventoryIcon.png`
|
||||
|
||||
## TDD evidence
|
||||
|
||||
### RED
|
||||
|
||||
`npm test --workspace=@ashen-realms/web -- --watch=false` failed as intended before production work: the new shell specification expected `app-top-bar`, but the scaffold only contained a router outlet. The existing two test files remained green (11 passing tests).
|
||||
|
||||
### GREEN
|
||||
|
||||
`npm test --workspace=@ashen-realms/web -- --watch=false` passed with 3 test files and 12 tests. The added shell test asserts top bar, side navigation, semantic main content, footer, enabled active Karte, disabled future destinations, and Shop absence.
|
||||
|
||||
## Final verification
|
||||
|
||||
- `npm test --workspace=@ashen-realms/web -- --watch=false`: 3 files and 12 tests passing.
|
||||
- `npm run build:web`: production Angular build passed and emits a lazy `world-page-component` chunk.
|
||||
- `npm exec --workspace=@ashen-realms/web -- prettier --check ...`: all Task 8 files formatted.
|
||||
- `git diff --check`: no whitespace errors.
|
||||
|
||||
## Visual QA limitation
|
||||
|
||||
The Browser plugin is not available in this session. The repository has no installed Playwright package, and a non-mutating `npm exec --workspace=@ashen-realms/web -- playwright --version` check could not resolve a local runner and timed out. No browser dependency was added outside task scope. Rendered browser verification remains for Task 11, which owns final browser workflow and fidelity captures.
|
||||
|
||||
## Intentional limits
|
||||
|
||||
- The world route placeholder contains no scene, nodes, API loading, or travel panel; Task 9 owns those surfaces.
|
||||
- The context panel is only a reusable framed shell until Task 9 supplies world data.
|
||||
|
||||
## Review fix round 1
|
||||
|
||||
### Accessibility and responsive behavior
|
||||
|
||||
- The active Karte button now has the explicit accessible name `Karte`, so its label remains available when the compact viewport hides visible navigation text.
|
||||
- At widths below 900px, the context panel now reflows into a full-width row below main content instead of being hidden. At widths below 620px it remains in DOM order after main content.
|
||||
|
||||
### Runtime HUD derivatives
|
||||
|
||||
The five original 1254 x 1254 user assets remain unmodified. The shell now loads deterministic 128 x 128 PNG derivatives from `images/hud/runtime/`; each was resized locally with high-quality bicubic interpolation and no creative image change.
|
||||
|
||||
| Asset | Original bytes | Runtime derivative bytes |
|
||||
| --- | ---: | ---: |
|
||||
| CharacterIcon | 2,283,892 | 26,670 |
|
||||
| MapsIcon | 2,144,772 | 27,774 |
|
||||
| HuntIcon | 2,313,949 | 29,486 |
|
||||
| QuestsIcon | 2,235,955 | 29,554 |
|
||||
| InventoryIcon | 2,060,169 | 26,142 |
|
||||
|
||||
The combined persistent-icon payload is reduced from 11,038,737 bytes to 139,626 bytes (about 98.7%). The resized Maps icon was visually inspected after generation.
|
||||
|
||||
### Regression evidence
|
||||
|
||||
RED: the added explicit accessible-name assertion failed before the fix because the active Karte control had no `aria-label`.
|
||||
|
||||
GREEN: `npm test --workspace=@ashen-realms/web -- --watch=false` passed with 3 test files and 14 tests. The added coverage verifies the explicit Karte name, non-null WorldStore character rendering, and root/wildcard `/world` route redirects.
|
||||
@@ -1,51 +0,0 @@
|
||||
# Task 9 Report: World UI
|
||||
|
||||
## Reference inventory
|
||||
|
||||
- `world-travel-screen.png`: persistent top bar and left navigation, a dominant central map, labelled current/reachable nodes with a dotted path, dense right context, and a bottom-centred travel decision panel.
|
||||
- `hunting-screen.png`: confirms the shared dark iron/bronze material treatment, restrained gold highlights, readable serif display hierarchy, and dense information without white cards or modern pills.
|
||||
- `combat-screen.png`: confirms the same persistent shell, dark desaturated palette, thin ornate borders, and blue only as a controlled active-state accent.
|
||||
|
||||
The reference screenshots were inspected but are not shipped or referenced by the application.
|
||||
|
||||
## Artwork and layout decision
|
||||
|
||||
- No ImageGen was used: the controller ruling makes the delivered user artwork final.
|
||||
- `/images/backgrounds/map_ashen_realm.png` is the dominant WorldPage scene. Its wide path, city, watchtower, and ash-field composition provides a clearer interactive map than either location image.
|
||||
- The server-delivered location paths are `/images/backgrounds/Suedtor.png` and `/images/backgrounds/Aschestrasse.png`; the ContextPanel renders the authoritative current-location image, so it changes only after server-confirmed arrival.
|
||||
- This deliberately supersedes the older brief wording that asked for generated assets and API artwork as the main scene background. It preserves the binding controller ruling while retaining the server-provided artwork as context.
|
||||
|
||||
## Delivered behavior
|
||||
|
||||
- `WorldPageComponent` loads `WorldStore` on init, renders a code-native SVG connection and two code-native location buttons, shows loading/error/retry states, and never advances location locally.
|
||||
- `LocationNodeComponent` exposes current, selected, reachable, disabled, hover, and focus states with textual labels.
|
||||
- `TravelPanelComponent` presents no-selection guidance, selected target/travel-time/danger with `Reise beginnen`, and an arrivesAt-derived travelling countdown with disabled action.
|
||||
- `ContextPanelComponent` renders the current/selected location, description, recommended level, safe status, hunting status, and server artwork.
|
||||
- Seed paths now match the delivered assets and are covered by the API seed test.
|
||||
|
||||
## Review-fix round
|
||||
|
||||
- Map-node geography is now anchored to the stable location keys (`south-gate` and `burned-road`). Current, reachable, and selected state only changes presentation; a regression test swaps the authoritative current location without moving either node.
|
||||
- On a server `COMPLETED` response, the selected connection is cleared and the store stays loading until the authoritative character/location/travel reload completes. All travel actions are disabled in that interval; no local arrival or location update is performed.
|
||||
- The moving countdown is a `<time role="timer">` without a broad live region. The selected and travelling mode headings remain labelled for assistive technology.
|
||||
- The decision panel now occupies normal document flow below the map scene, reserving a non-overlapping zone at desktop and narrow breakpoints.
|
||||
- The original delivered PNGs remain untouched. A deterministic local System.Drawing JPEG conversion (quality 86, high-quality bicubic) provides runtime derivatives: `map_ashen_realm-1440.jpg` (1440x810, 233,778 B), `Suedtor-960.jpg` (960x540, 94,286 B), and `Aschestrasse-960.jpg` (960x540, 93,277 B). The WorldPage and ContextPanel prefer these derivatives while retaining each server artwork path as the `<img>` fallback.
|
||||
- The load error is exposed as an alert and its retry control is covered by a store-load regression test.
|
||||
- The map no longer declares the runtime JPEG and original PNG as comma-separated background layers. It uses the original PNG as the classic CSS fallback and, where `image-set` with JPEG is supported, replaces it with one runtime JPEG candidate. The WorldPage regression test verifies there is no inline multi-layer binding or `mapBackground` source left to reintroduce the double load.
|
||||
|
||||
## Verification
|
||||
|
||||
- RED confirmed: four new WorldPage contracts failed against the empty placeholder; seed artwork-path assertion failed against the former WebP paths.
|
||||
- Focused WorldPage test: 4/4 pass.
|
||||
- Full web tests: 18/18 pass.
|
||||
- Affected API seed tests: 2/2 pass.
|
||||
- `npm run build:web` and `npm run build:api` pass.
|
||||
- Review focused World/Store/Context tests: 19 pass (4 files; 4 pre-existing skips).
|
||||
- Review full web suite: 23/23 pass.
|
||||
- Affected API seed test: 2/2 pass.
|
||||
- Both review builds (`npm run build:web`, `npm run build:api`) pass.
|
||||
- Review-fix round 2: focused WorldPage test 7/7 pass; full web suite and web build re-run after the fallback change.
|
||||
|
||||
## Remaining concern
|
||||
|
||||
Rendered browser fidelity QA is intentionally deferred to Task 11, as instructed. The Browser plugin is unavailable and no Playwright fallback was started for this task.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user