Fixes 5 residual findings from the re-review of Playable Slice 0.6.6's
whole-branch review: two twice-hit spec files still carried invented
or seeded German fixture values (reputation-display faction name,
inventory-detail-panel item description and item name), a world store
fixture still used a German location description, and a dev comment
in reputation-content.ts referenced a faction name that no longer
exists in the code. All are literal string substitutions using
already-translated canon English text; no keys, ids, or logic changed.
- TRAVELLING spelling: fix TRAVELING -> TRAVELLING in travel-panel.component.html
to match UK spelling used everywhere else (world/hunting/combat stores + API
error messages)
- Grenzwacht -> Border Watch: fix stale German faction display name in
reputation-display, reputation.service/controller, turn-in.service specs,
and the vertical-slice seed spec test title
- Suedtor von Graufurt -> Graufurt South Gate: fix stale ASCII-transliterated
German location name in hunting.service.spec.ts
- Aschenfelder(n) -> Ashen Fields: fix stale German location name/description
in top-bar.component.spec.ts and context-panel.component.spec.ts (key
identifiers left untouched)
- Fix 7 test titles still describing translated error messages as "German"
across world/hunting/inventory/combat store specs
- README: update demo location names from German to their current English
names (Graufurt South Gate, Burned Road)
- item-rarity.enum.ts: fix now-false comment claiming rarity labels are
German; the frontend RARITY_LABELS map is English
Pure literal-string/comment substitutions; no keys, ids, or logic changed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACkMEDYiwtcfchqKkiUJNX
Task 10 review sweep found two German strings the closing sweep missed:
'Abgenutztes Kurzschwert' (8 occurrences across 5 spec files, the real
seeded worn-short-sword item) and 'Gepolsterter Helm' (1 occurrence, a
synthetic test-only bonus-hp-helm fixture). Translated both to their
English equivalents per the item-content.ts glossary and slice style.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACkMEDYiwtcfchqKkiUJNX
Repo-wide grep sweep (apps/web/src, apps/api/src) for leftover German
content strings missed by Tasks 1-9, mostly in spec fixtures/assertions
that mirror already-translated seed content (monster/item names, POI
titles and action labels, location names/descriptions) plus a few real
source-file gaps:
- inventory-detail-panel.component.ts: STAT_LABELS (Waffenschaden,
Angriff, Leben, Rüstung) were never translated by Task 6; now match
the identical English labels already used in inventory-page.component.html.
- app-shell.component.html: aria-label="Spielinhalt" -> "Game content"
(this file was outside every prior task's file list).
- location-interaction-panel.component.spec.ts: dead NPC-quote fixture
translated to match the real wounded-scout POI text.
Code comments referencing German source-spec section titles or
not-yet-seeded faction names, and inline calculation-documentation
comments, are left as-is per the source spec's scope (dev-facing
comments may stay German).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACkMEDYiwtcfchqKkiUJNX
Translates the five client-side error-message maps (world, hunting, combat,
inventory, local-location stores) that re-translate already-English API
error codes back to display text, per design doc §4. Also fixes four
component specs that hard-coded the same German strings when asserting
rendered error text (combat-page, hunt-page, location-interaction-panel,
location-page).
Translates the four static Angular label maps (SLOT_LABELS, RARITY_LABELS,
DANGER_LABELS, LOCATION_TYPE_LABELS) and the inventory detail panel's
hardcoded item-type fallback per the English Game Content Foundation
design doc glossary. Updates every spec assertion across the web app that
checks rendered text sourced from these maps, including specs owned by
later tasks (combat-page, encounter-card, inventory-page) where they
render one of these labels.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reconciles Slice 0.6.5 (Renown & Reputation Foundation) against master's
persistent-HP-and-regeneration slice, which landed independently and
touches several of the same files (Character entity, CombatService,
EquipmentService, the inventory detail panel).
Conflict resolutions:
- CharacterStatsService/EquipmentService constructor wiring: kept
master's CharacterVitalsService injection, which this branch's
version of the same files didn't have yet.
- CombatService.performAction: kept master's HP-guard logic
(characterTooWounded, vitals pause-on-enter) alongside this branch's
multi-line calculate() call style.
- Inventory detail panel (.html/.ts/.scss/.spec.ts): master had
redesigned the panel (wrapping section, rarity styling, flavour
text, a shared inventory.labels.ts) on top of the OLD level-gated
component, since this branch's removal of the level gate (R4, Task
8/14) hadn't reached master yet. Kept master's visual redesign in
full, but with the level-gate concept removed throughout: no
requiredLevel stat block, no meetsLevelRequirement() branch in the
equip button, no now-dead .detail__value--unmet SCSS rule. Kept both
branches' independent tests (non-equippable-item, flavour-text).
- inventory-page.component.ts: dropped master's dead characterLevel
computed (nothing in the template read it, and the level concept is
gone); kept its independent bagCells/bagUsed/bagCapacity grid
feature, which has nothing to do with renown or level.
Post-merge fixture repairs (three files failed the Angular bundle
compile because they predate master's hpRegenPerSecond/hpRegenSince
fields or master's item description field, neither conflict-marked
since git considered them non-overlapping edits):
- app.spec.ts: a 'renders loaded character values' test added on
master after this branch forked still used the abolished level/
experience fields on its decoy fixture -- retargeted to renown.
- inventory-detail-panel.component.spec.ts: the ashPelt fixture added
by this branch's final-review follow-up predates master's required
description field.
- top-bar.component.spec.ts: this branch's fixture predates master's
required hpRegenPerSecond/hpRegenSince fields.
No database migration touches the same column: master's
1792000000000-AddHpRegeneration only adds characters.hp_regen_since,
independent of this slice's 1791000000000-CreateRenownAndReputation.
Timestamp ordering between the two was already correct with no rename
needed.
Verified: API 288/288 (267 from this slice + 21 from master), API
build zero errors, web 237/237 (230 from this slice + 7 from master).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The branch review approved the slice with no blocking findings. These
are the substantive non-blocking ones.
N1, the one no per-task review could see: every seeded monster rolls
silverMin/silverMax = 0 (R7), so the victory screen showed "Silber +0"
after every fight in the shipped game. Three tasks were each correct in
isolation -- the mechanism stays, the values are zero, the field still
exists -- and the composite was wrong. Now conditional, with a test.
This does not contradict R16: R16 deleted the XP block because the
field ceased to exist, leaving nothing to hide. Silver still exists and
can be non-zero, so a conditional is the right tool.
N2: world.store.ts still said a combat "granted XP and silver". Same
false-fact-in-a-comment defect fixed in b5bcd50, one file over.
N4: resolveReputationRank threw a TypeError on negative input, since
findIndex returns -1 and REPUTATION_RANKS[-1] is undefined. Unreachable
today, but grantReputation is public and accepts any number.
N5/N6: grantReputation resolved factions without the enabled filter the
read path applies, so a disabled faction could accumulate invisible
reputation -- "disabled" was not actually a kill switch. The dense read
also had no ORDER BY, so the list could reorder between requests.
N8: design 13 requires silver stay 0 for every seeded monster; only two
of four were pinned. Re-adding silver to the others would have shipped
silently.
N9: spec 36's "a normal kill grants no Renown" had no test. It was
structurally guaranteed but unasserted -- now locked down against a
later slice wiring renown into combat.
N10: an impossible renown: 0 fixture, and RENOWN_MIN exported but never
used to clamp the floor.
API 268/268, web 230/230, API build zero errors.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The panel's three-way actions block had no test for its middle branch:
an item with equipmentSlot null should show "Nicht ausrüstbar" and no
equip button. The gap predates this slice -- Task 14's review found it
while confirming the removed level gate had not cost coverage.
Deferred until now on purpose: the web bundle could not compile for the
whole slice, so committing this earlier would have meant shipping a test
I had never executed.
Load-bearing: dropping the !isEquippable() guard would fall through to
the else branch and render the button, failing the assertion.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Add hpRegenPerSecond and hpRegenSince fields to CharacterResponse
- Update inventory-page.component.spec.ts fixture with new fields
- Add CHARACTER_TOO_WOUNDED error mapping to combat.store
- Add test for CHARACTER_TOO_WOUNDED error mapping
- Update app.spec.ts and world.store.spec.ts fixtures for compilation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The API can no longer emit ITEM_LEVEL_REQUIREMENT_NOT_MET (Task 8 removed
the level gate server-side) and InventoryItem.item no longer carries
requiredLevel (Task 12). Drop the characterLevel input, the
meetsLevelRequirement computed, the associated template branch and copy,
and the dead German error-message mapping. Update fixtures across the
inventory specs to the real InventoryItem/CharacterResponse shapes.
Fixes 4 Important findings from the final whole-branch review:
- /inventory never called WorldStore.load(), leaving the TopBar stuck on
"loading" and characterLevel() silently defaulting to 1 for any character
above level 1. Mirrors the same guard already used in HuntPageComponent.
- The combat/equipment snapshot-immutability integration test asserted only
status/round, never the actual playerState snapshot the whole test claims
to prove is untouched after a post-fight equip.
- Documented (comment only, no behavior change) that the demo character's
armor dropping from the old hardcoded 6 to 0 is an intentional,
spec-sanctioned tradeoff (Slice 0.5 spec Section19), not a bug.
- inventory.store.spec.ts's equip test used an identical inventory fixture
before and after equip(), so a regression dropping the post-equip
inventory re-fetch would still have passed. Now asserts the refetched
fixture is actually reflected.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The equippedItemInSelectedSlot computed is the riskiest logic this
component owns, but every existing test mocked selectedItem() as null,
so the slot-matching branch never ran and a regression to "any equipped
item" would have gone unnoticed. Adds a test with three items across two
slots that asserts the detail panel receives the same-slot equipped item,
not just any equipped item.