Fix two plan defects found in SDD pre-flight scan

1. inventory.service.ts (API production code) surfaces requiredLevel in
   its response DTO. Task 3 deletes the entity column, so this would
   fail to compile and keep shipping a dead field. No task covered it:
   Task 10 swept only test fixtures, Task 12 only the web model. Folded
   into Task 10 as a new Step 0.

2. No web-side sweep task existed. Task 12's model changes break
   CharacterResponse/InventoryItem fixtures in app.spec.ts,
   world.store.spec.ts, and inventory.store.spec.ts, none of which
   Tasks 13-16 touch. Added Task 17 mirroring Task 10's sweep rule.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Bastian Wagner
2026-08-21 08:39:43 +02:00
parent a376fb7128
commit e14f6dcbce

View File

@@ -3141,15 +3141,36 @@ git commit -m "feat(content): migrate ItemType, seed Räuberabzeichen/Grenzwacht
---
## Task 10: Sweep remaining API fixtures
## Task 10: Sweep remaining API fixtures + the inventory DTO
**Files:**
- Modify: `apps/api/src/inventory/inventory.service.ts` (production code — see Step 0, found in pre-flight)
- Modify: `apps/api/src/inventory/inventory.service.spec.ts`
- Modify: `apps/api/src/hunting/hunting.service.spec.ts`
- Modify: `apps/api/src/travel/travel.service.spec.ts`
- Modify: any other file the full suite still flags after Task 9 (see Step 1)
**Interfaces:**
- Consumes: nothing new.
- Produces: a fully green API suite with zero references to `Character.level`/`.experience`, `ItemDefinition.requiredLevel`, `MonsterDefinition.experienceReward`, `CombatReward.experienceGranted`, or the old `ItemType.WEAPON`/`.ARMOR`/`.MATERIAL` values anywhere in the test suite.
- Produces: `InventoryItemDto.item` without `requiredLevel` (Task 12's web `InventoryItem` model must match this exactly). A fully green API suite with zero references to `Character.level`/`.experience`, `ItemDefinition.requiredLevel`, `MonsterDefinition.experienceReward`, `CombatReward.experienceGranted`, or the old `ItemType.WEAPON`/`.ARMOR`/`.MATERIAL` values anywhere.
- [ ] **Step 0: Remove `requiredLevel` from the inventory API DTO (pre-flight finding — production code, not a fixture)**
`apps/api/src/inventory/inventory.service.ts` surfaces `requiredLevel` through its response DTO. Task 3 deletes the underlying entity column, so this both fails to compile and would keep shipping a dead field to the client.
In the `InventoryItemDto` interface (around line 18), delete the line:
```ts
requiredLevel: number;
```
In the `getInventory` mapping (around line 61), delete the line:
```ts
requiredLevel: characterItem.itemDefinition.requiredLevel,
```
Then in `apps/api/src/inventory/inventory.service.spec.ts`, remove the `requiredLevel: 1,` entries from its fixtures (around lines 25 and 69) and from any asserted expected-DTO object.
This is a sweep task: the exact file list cannot be fully enumerated in advance because Task 3's entity changes ripple through every fixture across the codebase that builds a `Character`/`ItemDefinition`/`MonsterDefinition`/`CombatReward` object literal with a full type annotation (not behind an `as X` cast — those, per design's empirical finding in the Slice 0.6 plan, are unaffected by TypeScript's structural widening through a type assertion). Follow the rule, not a fixed file list.
@@ -3915,6 +3936,58 @@ git commit -m "feat(reputation): add the reusable Regional Reputation display co
---
## Task 17: Sweep remaining web fixtures
**Files:**
- Modify: `apps/web/src/app/app.spec.ts`
- Modify: `apps/web/src/app/features/world/world.store.spec.ts`
- Modify: `apps/web/src/app/features/inventory/inventory.store.spec.ts`
- Modify: any other web file the full suite still flags (see Step 1)
**Interfaces:**
- Consumes: nothing new.
- Produces: a fully green web suite with zero references to `CharacterResponse.level`/`.experience`, `InventoryItem.item.requiredLevel`, or `CombatReward.experience`.
The web mirror of Task 10. Task 12's model changes ripple into every fixture that builds a `CharacterResponse`/`InventoryItem`/`CombatReward` object with a full type annotation. Tasks 1316 fix the four component-level consumers; this task sweeps everything else. Found in pre-flight: `app.spec.ts` (lines ~144-145, a `CharacterResponse` fixture with `level: 7, experience: 320`), `world.store.spec.ts` (lines ~17-18 fixture and ~358, which spreads `{ ...character, experience: 32, silver: 18 }`), and `inventory.store.spec.ts` (lines ~21 and ~38, `requiredLevel: 1` in item fixtures).
- [ ] **Step 1: Run the full web suite and collect every remaining failure**
Run: `npm run test --workspace=@ashen-realms/web`
Each failure falls into exactly one category:
1. **A `CharacterResponse`-typed fixture with `level`/`experience`**: remove both fields, add `renown: <plausible 1-15 value>`. For `app.spec.ts`'s `level: 7, experience: 320` use `renown: 7`; for `world.store.spec.ts`'s `level: 1, experience: 0` use `renown: 1`.
2. **A spread that overrides `experience`** (e.g. `{ ...character, experience: 32, silver: 18 }`): drop the `experience` key, keep the rest. If the test's *purpose* was to assert a character-refresh changed a value, use `silver` (still present) as the observed field rather than inventing a renown change — do not repurpose the test into a renown test, just keep it testing refresh via silver.
3. **An `InventoryItem`-typed fixture with `requiredLevel`**: remove the field.
4. **A `CombatReward`-typed fixture with `experience`**: remove the field.
Leave every `monster: { ..., level: N }` alone — monster level is unrelated and stays (spec §33).
- [ ] **Step 2: Fix every failure found in Step 1**
Apply the rule above to each flagged file. Do not guess ahead of the compiler — fix, re-run, repeat until clean.
- [ ] **Step 3: Run the full web suite until completely green**
Run: `npm run test --workspace=@ashen-realms/web`
Expected: PASS, zero failures.
- [ ] **Step 4: Grep-verify no residual references remain**
```bash
grep -rn "requiredLevel\|\.experience\b\|experience:" apps/web/src --include="*.ts" --include="*.html"
```
Expected: no output. Anything remaining is either a live bug or a monster-level false positive — inspect and resolve.
- [ ] **Step 5: Commit**
```bash
git add -A
git commit -m "fix(web): sweep every remaining fixture off level/experience/requiredLevel"
```
---
## Final Verification
- [ ] **Step 1: Run both full test suites**