step 10.8: done

This commit is contained in:
bepis
2026-10-23 00:47:40 +11:00
parent 46663d892e
commit bf0b3867bd
2 changed files with 7 additions and 6 deletions
+6 -5
View File
@@ -8,9 +8,9 @@
## Current Focus
- **Phase:** 10
- **Step:** 10.8 — POST /api/character/allocate (stat point allocation)
- **Step:** 10.9 — Allocation UI: unspent points display with + buttons per stat on dashboard stats panel
- **Blocked?** No
- **Last verified working command:** `npm test` — 214/214 passing (85 unit + 124 integration incl. 6 allocate HTTP + 6 allocate service), 2026-10-23 step 10.8
- **Last verified working command:** `npm test` — 214/214 passing (85 unit + 129 integration incl. 12 allocate tests), 2026-10-23 step 10.8
## Project Health
| Item | State |
@@ -162,8 +162,9 @@
*Acceptance:* tests for each of the three responses (exact status + `error.code`); a test that forces `regenerate` to fail and asserts a 500 JSON response and that the server stays up.
*Verified:* 5 integration tests (malformed JSON → 400 INVALID_JSON on /api/auth/login, malformed JSON → 400 on /api/character, body over 10kb → 413 PAYLOAD_TOO_LARGE, unknown /api/* → 404 JSON NOT_FOUND, session regenerate error → 500 JSON with server staying up). Catch-all for /api/* paths now always returns JSON regardless of Accept header. Error handler catches SyntaxError (400) and PayloadTooLargeError (413) from body-parser. Session regenerate callbacks use next(err) instead of throw. 202/202 tests pass.
### D. Progression: stat points, HP, equipment
- [ ] **10.8** Add `POST /api/character/allocate` (API.md): body `{str,agi,int,vit}` as points to add (zod `.strict()`, non-negative integers). Use the existing, tested `allocatePoints` from `src/game/leveling.js`. One transaction; reject if the total exceeds `unspent_points` (422 `NOT_ENOUGH_POINTS`); return `{character, derived}`.
- [x] **10.8** Add `POST /api/character/allocate` (API.md): body `{str,agi,int,vit}` as points to add (zod `.strict()`, non-negative integers). Use the existing, tested `allocatePoints` from `src/game/leveling.js`. One transaction; reject if the total exceeds `unspent_points` (422 `NOT_ENOUGH_POINTS`); return `{character, derived}`.
*Acceptance:* tests: spend 2 of 3 points on STR → `str` +2, `unspent_points` 1, derived attack increased by the exact expected amount; spending 4 of 3 → 422 and nothing changed; negative / float / unknown keys → 400; another user's character cannot be affected.
*Verified:* 12 integration tests (6 HTTP + 6 direct service) covering partial allocation, overspend rejection, negative/float/unknown validation, cross-user isolation; `allocatePoints` in `characterService.js` uses `allocatePoints` from `leveling.js`, computes `remainingPoints` itself, updates in transaction; 214/214 tests pass.
- [ ] **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.
*Acceptance:* in the frontend, applying points calls the endpoint and refreshes stats without a page reload. Add a link-checker/DOM-free test only if feasible; otherwise list manual verification steps in HANDOFF.md.
- [ ] **10.10** Add `POST /api/character/rest` (API.md, BALANCE.md §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.
@@ -229,8 +230,8 @@ Severity: `blocker` / `major` / `minor` / `cosmetic`. Status: `open` / `fixing`
## Test Summary
| Suite | Passing | Failing | Last run |
|---|---|---|---|
| unit | 85 | 0 | 2026-10-21 step 9.5 |
| integration | 91 | 0 | 2026-10-21 step 9.5 (1 e2e + 90 existing) |
| unit | 85 | 0 | 2026-10-23 step 10.8 |
| integration | 129 | 0 | 2026-10-23 step 10.8 (12 allocate tests) |
## Session Log
_Format:_ `YYYY-MM-DD | step | what changed | result`