step 10.15: done

This commit is contained in:
bepis
2026-10-23 06:16:38 +11:00
parent 2a79c4ea43
commit 81794c7dbd
7 changed files with 240 additions and 34 deletions
+9 -8
View File
@@ -4,8 +4,8 @@
> If this file disagrees with the code, trust the code and fix this file.
## 1. Where we are
- **Last completed step:** 10.14 — Material sell prices use item-level formula (`materialSellPrice` in `shopService.js`)
- **Next step:** Phase 10.15 — Non-stackable items must be one inventory row per unit
- **Last completed step:** 10.15 — Non-stackable items: one inventory row per unit (shared `grantItem` in `src/game/inventory.js`)
- **Next step:** Phase 10.16 — Make `GET /api/leaderboard` and `GET /api/heroes/:name` public (no login)
- **Updated:** 2026-10-23
- **Was the last session cut off mid-task?** No
@@ -14,15 +14,15 @@
|---|---|
| `npm install` | succeeds |
| `npm run migrate` | applies 001–007 / "nothing to do" |
| `npm test` | **260 passing, 0 failing** (97 unit + 163 integration incl. 7 material sell price tests) |
| `npm test` | **264 passing, 0 failing** (97 unit + 167 integration incl. 4 non-stackable buy tests) |
| `npm run seed:dev` | creates demo user "demo"/"demo123", hero "Aldric" (warrior), starter gear |
| `npm start` + `curl localhost:3000/` | 200 HTML landing page |
## 3. What exists now (files that matter)
- `src/game/rewards.js` — `materialSellPrice(rarity, level)` — item-level formula: `multiplier[rarity] * level`
- `src/services/shopService.js` — `getStock()` and `sellItem()` now use `materialSellPrice`; `deleteRowExact` added for CHECK constraint fix
- `tests/integration/step-10.14.test.js` — NEW: 7 integration tests (Rat Tail at 3 levels, Drake Scale at 2 levels, shop-listed = actual, multi-quantity sell)
- `docs/BALANCE.md` — Material sell prices corrected in table to match formula
- `src/game/inventory.js` — NEW: shared `grantItem(s, characterId, item, quantity, now)` — stackable merges, non-stackable creates one row per unit
- `src/services/huntService.js` — now imports `grantItem` from `src/game/inventory.js` (removed local copy)
- `src/services/shopService.js` — now imports `grantItem` from `src/game/inventory.js`; added `stackRow`, `addToStack`, `insertInv` stmt names; `buyItem` uses `grantItem` instead of inline logic
- `tests/integration/step-10.15.test.js` — NEW: 4 integration tests for non-stackable buy behavior
## 4. Half-finished / fragile things
- No leaderboard UI yet (stub page exists; real UI in 10.17).
@@ -86,6 +86,7 @@
- **10.10:** `setupHero` helper must use `.then()` chain.
- **10.12:** Warrior maxHp at level 1 = 135 (50 + 8*10 + 1*5).
- **10.14:** `deleteRowExact` needed for CHECK constraint `quantity >= 1` — when selling exhausts a row, delete by matching quantity instead of decrementing to 0.
- **10.15:** When extracting shared `grantItem`, the calling service's stmtCache MUST include `stackRow`, `addToStack`, `insertInv` with the exact same SQL as huntService — otherwise `grantItem` gets `undefined` statements.
## 7. Next-step briefing
- **Next step: 10.15** — Non-stackable items: buying N of a non-stackable item should create N inventory rows with quantity 1 each (instead of 1 row with quantity N). Stackable items keep merging. Extract a shared grant helper if huntService has one; reuse it in buyItem.
- **Next step: 10.16** — Make `GET /api/leaderboard` and `GET /api/heroes/:name` public (no login). Keep the `type` allowlist; reject bad `page` values with 400. Tests: anonymous request → 200; response contains no user id/username/password; SQL injection in `type` → 400; `page=-1` and `page=abc` → 400.