--- sessionId: session-260929-233614-1hed --- # Requirements ### Overview & Goals Add a "Download JSON" button to the interactive Galaxy Map in `ZeroSpace.Web` that exports all data powering the galaxy map into a structured, downloadable JSON file (`galaxy-map-data.json`). The exported data will include all planetary systems with their full metadata and Markdown bodies, system masteries with their bonuses and notes, and planetary mastery items. ### Scope - **In Scope**: - A client-side browser file download utility via Blazor `IJSRuntime`. - Aggregation and serialization of `StarSystems.All` (including all markdown notes in `Body`), `SystemMasteries.All`, and `PlanetaryMasteryItems.All`. - A "Download JSON" button styled with the project's Sci-Fi theme in `ZeroSpace.Web/Pages/Galaxy.razor`. - **Out of Scope**: - Backend API changes (the export is generated client-side from the static/in-memory data models already present in Blazor WebAssembly). - Editing or mutating star system data. ### User Stories - **As a player / community developer**, I want to download all galaxy map data (including star systems, hyperlane connections, occupation buffs, masteries, and markdown notes) in JSON format from the Galaxy Map page so that I can analyze the data offline, create custom tooling, or reference game lore. ### Functional Requirements 1. **Download Action**: Clicking the "Download JSON" button generates and initiates a browser download of `galaxy-map-data.json`. 2. **Star System Data & Markdown**: The JSON output must contain all star systems from `StarSystems.All` including ID, name, category, owner, yield flags, occupation buff, system mastery, connected systems, coordinates, and full markdown text (`Body`). 3. **Mastery Data**: The JSON output must contain all system masteries from `SystemMasteries.All` (levels, available systems, stats, and markdown body) and planetary mastery items from `PlanetaryMasteryItems.All`. 4. **JSON Formatting**: The output JSON must be well-formatted (indented, camelCase property naming, string representations for enums). 5. **UI Integration**: The button must be positioned intuitively in the Galaxy header / control bar matching the existing glassmorphic Sci-Fi styling. ### Non-Functional Requirements - **Performance**: Export generation and download initiation should take < 50ms without blocking UI interactions. - **Offline / WebAssembly Compatibility**: The export must function entirely within the client-side Blazor WebAssembly runtime without requiring server endpoints. # Technical Design ### Current Implementation - `ZeroSpace.Web/Pages/Galaxy.razor`: The interactive galaxy map page displaying star systems, hyperlanes, and faction occupation details using `StarSystems.All` and `SystemMasteries.All`. - `ZeroSpace.Model/StarSystemData.cs` & `StarSystems.g.cs`: Contains `StarSystemData` records where `Body` contains the planetary system Markdown notes. - `ZeroSpace.Model/SystemMasteryData.cs` & `SystemMasteries.g.cs`: Contains `SystemMasteryData` records with mastery levels, system associations, stats, and markdown `Body`. - `ZeroSpace.Model/PlanetaryMasteryItemData.cs` & `PlanetaryMasteryItems.g.cs`: Contains `PlanetaryMasteryItemData` records for mastery items. ### Key Decisions 1. **Client-Side Export**: Use Blazor WebAssembly's `IJSRuntime` with a lightweight browser Blob URL helper to trigger file download instantly in memory without backend roundtrips. 2. **Unified Data Structure**: Group data under top-level properties (`systems`, `masteries`, `planetaryMasteryItems`, `exportedAt`) for easy consumption by external tools. 3. **Formatting**: Use `System.Text.Json` with `JsonSerializerOptions` configured for `WriteIndented = true`, `PropertyNamingPolicy = JsonNamingPolicy.CamelCase`, and `JsonStringEnumConverter`. ### Proposed Changes 1. **File Download Helper**: - Add `ZeroSpace.Web/wwwroot/js/fileDownload.js` containing `downloadFileFromText(fileName, contentType, textContent)`. - Include script reference in `ZeroSpace.Web/wwwroot/index.html`. 2. **Export Model**: - Define `GalaxyMapExportData` record containing `IReadOnlyList Systems`, `IReadOnlyList Masteries`, `IReadOnlyList PlanetaryMasteryItems`, and `DateTimeOffset ExportedAt`. 3. **Galaxy Page Update**: - Add a "Download JSON" button to the header action bar in `Galaxy.razor`. - Add `DownloadJsonAsync()` method in `@code` section that builds `GalaxyMapExportData`, serializes to JSON, and calls the JS helper. ### Data Models / Contracts ```csharp public sealed record GalaxyMapExportData( DateTimeOffset ExportedAt, int TotalSystems, int TotalMasteries, IReadOnlyList Systems, IReadOnlyList Masteries, IReadOnlyList PlanetaryMasteryItems); ``` ### Architecture Diagram ```mermaid graph LR User[User clicks Download JSON] --> Razor[Galaxy.razor] Razor --> Aggregator[Aggregate StarSystems, Masteries, Items] Aggregator --> Serializer[System.Text.Json Serializer] Serializer --> JSInterop[IJSRuntime downloadFileFromText] JSInterop --> Browser[Browser saves galaxy-map-data.json] ``` ### File Structure - `ZeroSpace.Web/wwwroot/js/fileDownload.js` *(new)* - `ZeroSpace.Web/wwwroot/index.html` *(modified to include script tag)* - `ZeroSpace.Web/Models/GalaxyMapExportData.cs` *(new)* - `ZeroSpace.Web/Pages/Galaxy.razor` *(modified to add download button and handler)* - `ZeroSpace.Web/Pages/Galaxy.razor.css` *(optional style tweaks for button layout)* ### Risks - **Large Payload / Memory**: The total size of all systems and markdown is < 500 KB, which fits easily in browser memory for Blob generation. # Testing ### Validation Approach - Verify solution builds with 0 errors via `build_solution_start` and `build_solution_state`. - Verify the serialized JSON structure against required fields (star system metadata, markdown `Body`, masteries, levels, stats). - Verify the button UI placement, styling, and JSInterop invocation logic. ### Key Scenarios 1. **Download Button Interaction**: User clicks the "Download JSON" button on `/galaxy`. - Expected: `downloadFileFromText` JSInterop is called with `galaxy-map-data.json`, `application/json`, and the formatted JSON string. 2. **JSON Content Completeness**: - Every star system from `StarSystems.All` is present in the `systems` array. - The markdown `body` field of each star system is included. - Every mastery from `SystemMasteries.All` is present in the `masteries` array with levels and stats. - Planetary mastery items from `PlanetaryMasteryItems.All` are included. ### Edge Cases - Systems with empty vs populated markdown `Body` serialize properly as strings (`""` or markdown text). - Enum values (`StarSystemCategory`) serialize cleanly as strings (e.g. `"homeworldSystem"`, `"coreSystem"`, `"sideSystem"` or PascalCase). # Delivery Steps ### ✓ Step 1: Implement file download JSInterop helper and export serialization model Create the file download JSInterop utility and the galaxy map data export serialization contract. - Add a JavaScript file download helper (`ZeroSpace.Web/wwwroot/js/fileDownload.js` or equivalent) that accepts filename, content type, and content/bytes, creating an object URL blob and triggering a download anchor click. - Reference the script in `ZeroSpace.Web/wwwroot/index.html`. - Define an export container record (e.g., `GalaxyMapExportData`) in `ZeroSpace.Web` / `ZeroSpace.Model` that aggregates star systems (with full metadata and markdown `Body`), system masteries (with levels, stats, available systems, and `Body`), and planetary mastery items. - Implement a JSON serialization helper/service configured with `JsonSerializerOptions` (`WriteIndented = true`, camelCase naming, `JsonStringEnumConverter`) for clean formatting. ### ✓ Step 2: Integrate Download JSON button and handler into the Galaxy Map page Add the Download JSON button to the Galaxy Map page and wire up the export trigger. - Add the "Download JSON" button in the top action bar of `ZeroSpace.Web/Pages/Galaxy.razor` next to the map legend/stats controls. - Apply consistent Sci-Fi design system styling (`btn-scifi-outline` with appropriate icon/label) in `Galaxy.razor` and `Galaxy.razor.css`. - Inject `IJSRuntime` in `Galaxy.razor` and implement the `DownloadGalaxyJsonAsync` event handler to generate the export payload and trigger the client-side download named `galaxy-map-data.json`. - Build the solution and verify clean compilation without errors or warnings.