# Quickstart: JSON Import/Export **Feature**: 007-json-import-export **Date**: 2026-03-27 ## Overview Export and import the full application state (encounter, undo/redo history, player characters) as a JSON file. Enables backup/restore and sharing encounters between DMs. ## Key Concepts - **ExportBundle**: A JSON object containing `version`, `exportedAt`, `encounter`, `undoStack`, `redoStack`, and `playerCharacters`. This is the file format. - **Full replacement**: Import replaces all existing state — encounter, undo/redo, and player characters. It's not a merge. - **Validation reuse**: Import validation uses the same `rehydrateEncounter()` and player character validation functions that localStorage loading uses. ## Implementation Layers ### Domain Layer No new domain functions are needed. The existing types (`Encounter`, `PlayerCharacter`, `UndoRedoState`) and validation functions are reused as-is. A new `ExportBundle` type is defined in the domain layer as a pure data structure. ### Application Layer A new use case for import validation and bundle assembly: - `validateImportBundle(data: unknown)` — validates and rehydrates an export bundle, returning the validated bundle or an error. Export assembly is straightforward enough to live in the adapter layer (it's just reading and packaging existing state). ### Adapter Layer (Web) - **Export**: Read state from contexts, assemble bundle, trigger browser download via `URL.createObjectURL()` + anchor element. - **Import**: File picker input, parse JSON, delegate to application-layer validation, show confirmation dialog if encounter is non-empty, replace state via context setters. - **UI**: Two new overflow menu items in the action bar — "Export Encounter" and "Import Encounter". ## File Locations | Artifact | Path | |----------|------| | ExportBundle type | `packages/domain/src/types.ts` or new file | | Import validation use case | `packages/application/src/` | | Export/import adapter functions | `apps/web/src/persistence/` | | UI integration | `apps/web/src/components/action-bar.tsx` | | Confirmation dialog | `apps/web/src/components/` (new or reuse existing confirm pattern) | ## Testing Strategy - **Domain**: No new domain tests needed (existing types unchanged). - **Application**: Test `validateImportBundle()` with valid bundles, invalid bundles, missing fields, wrong types, and edge cases (empty encounter, empty stacks). - **Adapter**: Test export bundle assembly and import file handling. - **Integration**: Round-trip test — export then import should produce identical state.