# Battle and learning settlement `POST /player/adventure` uses the existing JWT user identity and existing `user_wallets` balance. It never imports the old client-local coin save. Actions: - `snapshot`: wallet, level, experience, health, enrollments and current battle. - `start`, `encounter`: create/resume one battle per account; response contains session ID and question without the answer. - `answer`, `session`, `turn`, `choice`: server grades the answer. Correct removes one of three hearts; wrong removes ten HP. Victory adds ten coins and no experience. Duplicate identical last-turn submission is idempotent. - `escape`, `session`: closes an active battle without a reward. - `rest`: restores health for free when not in battle. - `recover`: spends five coins for up to thirty HP, only when injured and out of battle. - `enroll`, `chapter`: spends twenty coins once for a published chapter. - `complete`, `chapter`, `answers`: validates option indexes against the server chapter catalog; grants twenty learning experience once. HP maximum is 10, 15, 20, 25, 30 for levels 1–5. Level requirements are 40, 60, 80, 100 experience. Only chapter completion grants experience. ## Deployment Run `npm run db:migrate` with the target database environment before deploying the new backend, then build/restart it and deploy the paired frontend. The migration adds a nullable JSON `adventure` column to `user_wallets` and can be run repeatedly. It does not change existing balances or grant old local coins. Do not run the new entity against a database without the migration. Database mode locks the wallet row and atomically saves progress, balance and transaction history. Existing spend/earn operations now lock the same wallet row so mall payments cannot overwrite adventure rewards. Memory mode supports development/tests only and is not durable across server restarts. `adventure_chapters.json` currently contains the two published chapter quizzes from hello-agents and happy-llm. Update it with the corresponding frontend book package when publishing a new chapter. Two chapters can reach level 2; levels 3–5 need additional published learning content. Completed chapters and defeated encounters persist per account. No client-provided coin, damage or XP amounts are accepted. Encounter proximity and movement are still client-authoritative; this is not a server-authoritative world simulation. ## Verification `npm run build`, `npm test`, and `npm run test:adventure`. The adventure suite covers replayed/concurrent victory and enrollment requests, wrong answers, insufficient funds, cross-account battle access, and chapter rewards. On macOS with the sibling frontend and Godot installed it also runs the real Godot API client against an isolated NestJS HTTP server using a test-only guard. Production JWT validation is unchanged. MySQL migration/locking must also be exercised in the target database environment before rollout.