step 10.14: done
This commit is contained in:
@@ -8,15 +8,15 @@
|
||||
|
||||
## Current Focus
|
||||
- **Phase:** 10
|
||||
- **Step:** 10.14 — Material sell prices use item-level formula (BALANCE.md) instead of hero-level formula
|
||||
- **Step:** 10.15 — Non-stackable items must be one inventory row per unit
|
||||
- **Blocked?** No
|
||||
- **Last verified working command:** `npm test` — 253/253 passing (97 unit + 156 integration incl. 4 equipment bonus tests + 4 starter kit tests), 2026-10-23 step 10.13
|
||||
- **Last verified working command:** `npm test` — 260/260 passing (97 unit + 163 integration incl. 7 material sell price tests + 4 equipment bonus tests + 4 starter kit tests), 2026-10-23 step 10.14
|
||||
|
||||
## Project Health
|
||||
| Item | State |
|
||||
|---|---|
|
||||
| App starts (`npm start`) | ✅ smoke-tested: register → create hero → 12 hunts → level-up (real seeded zones) |
|
||||
| Tests pass (`npm test`) | ✅ 249/249 (97 unit + 152 integration incl. 4 equipment bonus tests) |
|
||||
| Tests pass (`npm test`) | ✅ 260/260 (97 unit + 163 integration incl. 7 material sell price tests) |
|
||||
| Migrations run clean on empty DB | ✅ 001_users, 002_characters, 003_content (also seeds zones/monsters/items), 004_inventory, 006_logs (005 reserved for expeditions) |
|
||||
| Can register + login | ✅ verified by tests |
|
||||
| Data persists across restart | ⚠️ sessions use the real SQLite store (also in tests); a restart test is still missing |
|
||||
@@ -181,8 +181,9 @@
|
||||
*Acceptance:* tests per class: inventory has exactly the weapon (equipped) and 2 potions (one stack row, quantity 2); derived attack includes the weapon.
|
||||
*Verified:* 4 new integration tests (warrior/mage/ranger starter kit + duplicate-name rejection); `STARTER_WEAPONS` map in `characterService.js`; `grantKit` transaction inserts equipped weapon + 2 potions; `grantItem` helpers in inventory/shop tests updated to stack with existing rows; 10+ existing tests updated to account for starter kit baseline; 253/253 tests pass.
|
||||
### E. Economy
|
||||
- [ ] **10.14** Fix material sell prices. The code uses `defaultRate * heroLevel / itemMinLevel`; BALANCE.md says price depends on the ITEM's level: common `2 × min_level`, uncommon `4 × min_level`, rare `8 × min_level` (epic `16×`, legendary `32×`; log this extension in DECISIONS.md), minimum 1. Note BALANCE.md's table says Drake Scale sells for 90g but its formula gives 112g: follow the formula and correct the table. Use ONE function (`materialSellPrice` in `src/game/rewards.js`) for the shop list AND for selling.
|
||||
- [x] **10.14** Fix material sell prices. The code uses `defaultRate * heroLevel / itemMinLevel`; BALANCE.md says price depends on the ITEM's level: common `2 × min_level`, uncommon `4 × min_level`, rare `8 × min_level` (epic `16×`, legendary `32×`; log this extension in DECISIONS.md), minimum 1. Note BALANCE.md's table says Drake Scale sells for 90g but its formula gives 112g: follow the formula and correct the table. Use ONE function (`materialSellPrice` in `src/game/rewards.js`) for the shop list AND for selling.
|
||||
*Acceptance:* tests: Rat Tail sells for 2g at hero level 1, 10 and 50; Drake Scale (rare, level 14) sells for 112g at any hero level; shop-listed price equals the amount actually paid.
|
||||
*Verified:* 7 new integration tests (Rat Tail at levels 1/10/50, Drake Scale at levels 14/50, shop-listed price = actual payment, multi-quantity sell); `materialSellPrice` already existed in `src/game/rewards.js` — integrated into `shopService.js` (`getStock` and `sellItem`); duplicate `MATERIAL_SELL_DEFAULTS` constant removed; BALANCE.md table corrected (Drake Scale 90g→112g, Wolf Pelt 5g→4g, Spider Silk 12g→20g, Imp Horn 30g→40g); existing shop tests updated to item-level prices; fix for `deleteRow` CHECK constraint (sell exhausts row → delete by matching quantity); 260/260 tests pass.
|
||||
- [ ] **10.15** Non-stackable items must be one inventory row per unit. In `buyItem`, buying N of a non-stackable item inserts N rows with quantity 1 (reuse the same grant helper that `huntService` uses; extract it to a shared place if needed). Stackable items keep merging.
|
||||
*Acceptance:* tests: buy 3 swords → 3 rows, quantity 1 each; equip one, sell one → remaining state correct; buy 5 potions → one row, quantity 5.
|
||||
### F. Public pages
|
||||
@@ -236,10 +237,11 @@ Severity: `blocker` / `major` / `minor` / `cosmetic`. Status: `open` / `fixing`
|
||||
| Suite | Passing | Failing | Last run |
|
||||
|---|---|---|---|
|
||||
| unit | 85 | 0 | 2026-10-23 step 10.8 |
|
||||
| integration | 129 | 0 | 2026-10-23 step 10.8 (12 allocate tests) |
|
||||
| integration | 175 | 0 | 2026-10-23 step 10.14 (7 material sell price tests) |
|
||||
|
||||
## Session Log
|
||||
_Format:_ `YYYY-MM-DD | step | what changed | result`
|
||||
- 2026-10-23 | 10.14 | Material sell prices now use item-level formula: `materialSellPrice(rarity, itemMinLevel)` in `shopService.js` replaces old `defaultRate * heroLevel / itemMinLevel`; BALANCE.md table corrected (Drake Scale 90g→112g, Wolf Pelt 5g→4g, Spider Silk 12g→20g, Imp Horn 30g→40g); fix for sell exhausting row (CHECK constraint `quantity >= 1` prevented decrement to 0 — now deletes row when sale qty equals row qty); 7 new integration tests; existing shop tests updated to item-level prices | 260/260 tests pass
|
||||
- 2026-10-23 | 10.8 | Added `POST /api/character/allocate` endpoint: zod `.strictObject` with optional stat fields + `.refine` requiring at least one; service in `characterService.js` validates input, uses `allocatePoints` from `leveling.js`, computes `remainingPoints = character.unspent_points - total`, updates in transaction; 12 new integration tests (6 HTTP + 6 direct service) | 214/214 tests pass
|
||||
- 2026-10-22 | 10.6 | Re-enabled real rate limiters in `src/routes/auth.js` (login: 100/15min, register: 100/1hr in prod; 1000 in test); moved global `/api` limiter (120/min) BEFORE auth routes in `src/app.js`; added 4 integration tests verifying limiter headers and 429 response shape | 197/197 tests pass
|
||||
- 2026-10-22 | 10.7 | Added error handling for Express JSON parser failures: malformed JSON → 400 INVALID_JSON, body over 10kb → 413 PAYLOAD_TOO_LARGE; catch-all for /api/* paths now always returns JSON regardless of Accept header; session regenerate/destroy callbacks use next(err) instead of throw; 5 new integration tests | 202/202 tests pass
|
||||
|
||||
Reference in New Issue
Block a user