Sync New Content now updates baseCost, class, combatPower, essencePerSecond,
goldPerSecond, level, and name for all existing adventurer entries to match
the current defaults, while preserving count and unlocked state.
Closes#126
## Summary
- Fix `NaN` displayed in Sync New Content / Force Unlock notifications by guarding against undefined counts
- Poll server for exploration claimability before showing Collect button to prevent client/server desync
- Return authoritative materials list from craft API to prevent client desync causing false affordability
- Add test coverage for `sync-new-content` and `explore/claimable` endpoints
Closes#125Closes#127Closes#128
## Test plan
- [ ] Trigger a sync with new content and verify the notification shows a real count instead of `NaN`
- [ ] Start an exploration, wait for it to complete, and verify the Collect button only appears after the server confirms claimable
- [ ] Attempt to craft a recipe and verify the material counts in the UI update to match the server's authoritative values
✨ This issue was created with help from Hikari~ 🌸
Reviewed-on: #129
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
The force-unlock debug route now scans completed quests for adventurer rewards and ensures those tiers are marked as unlocked in game state.
The UI and API response type both surface the new `adventurersUnlocked` count alongside the existing zone/quest/boss/exploration counts.
Closes#88✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #93
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
- Adds a new **Debug** tab to the game UI with two self-service tools for players with broken save state
- **Force Unlocks**: scans the player's save and grants any zones, quests, bosses, and exploration areas they've earned but that are still locked — shows a breakdown of what was unlocked (or reports nothing needed fixing)
- **Hard Reset**: wipes progress back to a fresh save (preserving lifetime stats), guarded behind a confirmation modal to prevent accidental clicks
## Files added
- `apps/api/src/routes/debug.ts` — two POST endpoints (`/force-unlocks`, `/hard-reset`)
- `apps/web/src/components/game/debugPanel.tsx` — the Debug tab UI
- `apps/web/src/components/ui/confirmationModal.tsx` — reusable confirmation modal
## Files modified
- `apps/api/src/index.ts` — registers the debug router
- `packages/types/src/interfaces/api.ts` — adds `ForceUnlocksResponse` type
- `packages/types/src/index.ts` — exports the new type
- `apps/web/src/api/client.ts` — adds `forceUnlocks()` and `debugHardReset()` API calls
- `apps/web/src/context/gameContext.tsx` — wires both functions into game context
- `apps/web/src/components/game/gameLayout.tsx` — adds the Debug tab
- `apps/web/src/styles.css` — styles for action buttons, cards, result messages, and confirmation modal
✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #65
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>