step 10.9: done

This commit is contained in:
bepis
2026-10-23 01:06:48 +11:00
parent bf0b3867bd
commit 28210ed56c
6 changed files with 464 additions and 15 deletions
+17 -12
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.8 — POST /api/character/allocate: stat point allocation endpoint with zod validation, service transaction, and 12 integration tests — TICKED in STATUS.md
- **Next step:** Phase 10.9 — Allocation UI: unspent points display with + buttons per stat on dashboard stats panel
- **Last completed step:** 10.9 — Allocation UI: unspent points display with + buttons per stat on dashboard stats panel — TICKED in STATUS.md
- **Next step:** Phase 10.10 — POST /api/character/rest endpoint + dashboard button
- **Updated:** 2026-10-23
- **Was the last session cut off mid-task?** No
@@ -14,18 +14,18 @@
|---|---|
| `npm install` | succeeds |
| `npm run migrate` | applies 001–006 / "nothing to do" |
| `npm test` | **214 passing, 0 failing** (85 unit + 129 integration incl. 12 allocate tests) |
| `npm test` | **222 passing, 0 failing** (85 unit + 137 integration incl. 8 allocation UI tests) |
| `npm run seed:dev` | creates demo user "demo"/"demo123", hero "Aldric" (warrior), starter gear |
| `npm start` + `curl localhost:3000/` | 200 HTML landing page |
| `curl -X POST localhost:3000/api/character/allocate -H 'Content-Type: application/json' -H 'Cookie: ...' -d '{"str":1}'` | 200 with updated stats (requires authenticated session) |
| Open `/game.html` logged in → check dashboard for allocation UI | Shows unspent points with + buttons when > 0, hidden when 0 |
## 3. What exists now (files that matter)
- `src/services/characterService.js` — New `allocatePoints(userId, allocation)` function: validates input, uses `allocatePoints` from `leveling.js`, computes `remainingPoints = character.unspent_points - total`, updates in transaction, returns `{character, derived}`.
- `src/routes/character.js` — New `handleAllocate` handler with zod `.strictObject` schema (optional stat fields + `.refine` requiring at least one).
- `src/game/leveling.js` — `allocatePoints` now accepts non-negative integers (including 0 for unallocated stats).
- `src/app.js` — Route `POST /api/character/allocate` mounted with `requireAuth`.
- `tests/integration/step-10.8.test.js` — 6 HTTP integration tests (spend partial, overspend, negative, float, unknown keys, cross-user).
- `tests/integration/allocate-service.test.js` — 6 direct service tests (same scenarios via service call).
- `public/game.html` — Added `#allocation-section` div (hidden by default) with unspent points display, alloc-rows container, alloc-total, alloc-apply-btn.
- `public/js/game.js` — Added 5 allocation functions: `buildAllocationRows`, `handleAllocIncrement`, `updateAllocState`, `handleAllocApply`, `initAllocationUI`. Calls `initAllocationUI` from `loadCharacter`. Apply button listener attached in init.
- `public/css/main.css` — Added allocation UI styles: `#allocation-section`, `.alloc-row`, `.alloc-btn`, `.btn-alloc-apply`.
- `tests/integration/step-10.9.test.js` — 8 tests (5 HTML/JS structure + 2 API flow + 1 full flow).
- `src/services/characterService.js` — `allocatePoints` function (from 10.8).
- `src/routes/character.js` — `handleAllocate` handler (from 10.8).
## 4. Half-finished / fragile things
- No leaderboard UI yet (stub page exists; real UI in 10.17).
@@ -36,7 +36,7 @@
- Starter gear documented but not auto-created on character creation.
- `GET /api/zones` documented in API.md but not implemented (Issue #2).
- Mobile nav uses emoji icons (⚔️ 🏕️ 🎒) — verify they render acceptably on all platforms.
- **10.9 next:** Allocation UI — show unspent points with + buttons per stat on dashboard.
- **10.10 next:** Rest endpoint — costs level*5 gold, heals to full max HP.
## 5. Decisions & deviations from the docs
- D-004..D-007 in `docs/DECISIONS.md` (combat rounds, equipment counted once, session store, clock).
@@ -47,6 +47,7 @@
- **D-018:** Link-checker test skips API endpoints (`/api/...`) since they're not static files.
- **D-019:** Rate limiters use `process.env.NODE_ENV === 'test' ? 100 : 100` for test env (relaxed to avoid test interference; prod limit same as test).
- **D-020:** `allocatePoints` in `leveling.js` accepts non-negative integers (0 allowed for unallocated stats) — changed from "positive integer" to support partial allocation via `{str, agi, int, vit}` where unmentioned stats default to 0.
- **D-021:** Allocation UI uses `container.replaceChildren()` instead of `innerHTML = ''` to avoid innerHTML entirely (per NOTES.md constraint).
## 6. Gotchas learned
- `npm test` must be `node --test` with NO path/glob; files must be named `*.test.js`.
@@ -91,6 +92,10 @@
- **10.8:** `leveling.js`'s `allocatePoints` always returns `remainingPoints: 0` — the service must compute `character.unspent_points - total` itself.
- **10.8:** zod `.strictObject` with optional fields needs `.refine()` to require at least one field present.
- **10.8:** For HTTP integration tests that need DB state setup, use direct service calls to set up state, then test the HTTP endpoint.
- **10.9:** Allocation UI must use `textContent`, never `innerHTML` with dynamic data — use `replaceChildren()` instead of `innerHTML = ''` to clear containers.
- **10.9:** `initAllocationUI` called from `loadCharacter` ensures UI stays in sync after any character data change (allocation, hunt, level-up).
## 7. Next-step briefing
- **Next step: 10.9** — Allocation UI: on the dashboard stats panel show unspent points and a `+` button per stat (only when points remain), with a confirm/apply button, loading state, and error toast. Use `textContent`, never `innerHTML` with dynamic data.
- **Next step: 10.10** — Rest endpoint: `POST /api/character/rest` costs `level * 5` gold, heals to full max HP. Errors: `NOTHING_TO_HEAL` (422) if HP is already full, `INSUFFICIENT_GOLD` (422). One transaction. Add a "Rest (N gold)" button to the dashboard.
- Read API.md §Rest and BALANCE.md §Rest for the spec.
- The endpoint is similar to allocate (auth, zod validation, transaction, returns updated character + derived).