Implement the 008-persist-encounter feature that saves encounter state to localStorage so it survives page reloads

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-05 16:24:00 +01:00
parent c4a90c9982
commit a9c280a6d6
12 changed files with 818 additions and 4 deletions

View File

@@ -0,0 +1,39 @@
# Quickstart: Persist Encounter
## What This Feature Does
Saves the current encounter to browser localStorage so it survives page reloads. No user action required -- saving and restoring happens automatically.
## Key Files
| File | Purpose |
|------|---------|
| `apps/web/src/persistence/encounter-storage.ts` | New: read/write/validate encounter in localStorage |
| `apps/web/src/hooks/use-encounter.ts` | Modified: load from storage on init, persist on change |
## How It Works
1. **On app load**: The `useEncounter` hook calls `loadEncounter()` from the storage module. If valid data exists, it initializes state from it. Otherwise, the demo encounter is used.
2. **On every state change**: A `useEffect` watches the encounter state and calls `saveEncounter()` to write it to localStorage.
3. **On error**: All storage operations are wrapped in try/catch. Failures are silent -- the app continues working in memory-only mode.
## Testing
```bash
pnpm vitest run apps/web/src/persistence/__tests__/encounter-storage.test.ts
```
Tests cover:
- Round-trip serialization (save then load returns same encounter)
- Invalid/corrupt data returns null
- Missing fields return null
- Non-JSON data returns null
## Manual Verification
1. Run `pnpm --filter web dev`
2. Add/remove combatants, set initiative, advance turns
3. Refresh the page -- encounter state should be preserved
4. Open DevTools > Application > localStorage to inspect the stored data
5. Delete the storage key and refresh -- demo encounter should appear
6. Set the storage value to `"garbage"` and refresh -- demo encounter should appear