# Story 4.3: Data Portability & Export (GDPR) Status: done ## Story As a user, I want to securely export my workspace data and Brainstorm canvases, so that I have full portability of my knowledge and comply with GDPR data portability requirements. **Epic:** Epic 4 — Enterprise Compliance & Privacy (B2B Requirements) **FR coverage:** FR12 (export Brainstorm canvas), NFR-GDPR3 (data portability) **Out of scope for this story:** Story 4.5 (EU data residency), PDF-to-chat features, direct cloud backups (GDrive/Dropbox). --- ## Acceptance Criteria 1. [AC1] **ZIP Package Structure (NFR-GDPR3):** The export produces a single `.zip` file containing: - Notes organized as Markdown files (`.md`), placed in folders matching their parent Notebooks. - Trashed/archived notes placed in `trash/` and `archive/` folders respectively. - Notes exported as `.json` metadata sidecars or a single `metadata.json` mapping all note relations, tags, links, and custom properties. - A `canvases/` folder containing all user's Brainstorm sessions, exported as Markdown lists of ideas, nodes, and connections. - An `attachments/` folder containing all uploaded PDF/image attachments (reading actual files from `data/uploads/attachments/`). - A responsive, offline-friendly `index.html` at the root of the ZIP to browse notes and canvases locally. 2. [AC2] **GDPR Section in Settings → Data:** A new "GDPR — Data Portability" card appears in the Settings Data Management page. It displays a clear description of the export ZIP archive contents and has a primary "Export Workspace (ZIP)" download button. 3. [AC3] **Background ZIP Compilation:** To prevent server timeouts, the API compiles the ZIP file in memory using a streaming-friendly ZIP generator (`jszip`) and sends it with `Content-Type: application/zip`. 4. [AC4] **i18n & Design:** All UI labels, button states, toasts, and card headings are localized in all 15 JSON locale files under `memento-note/locales/*.json` (FR and EN references). 5. [AC5] **Regression:** Existing JSON import/export functions, database cascade actions, and note editors remain entirely unaffected. --- ## Tasks / Subtasks - [x] Task 1: Package setup & ZIP engine (AC: #1, #3) - [x] Subtask 1.1: Install `jszip` package in `package.json` dependencies and `@types/jszip` in `devDependencies`. - [x] Subtask 1.2: Create utility `memento-note/lib/export/zip-builder.ts` to convert TipTap HTML/JSON content into readable Markdown with YAML frontmatter (mapping title, tags, date, and notebook). - [x] Subtask 1.3: Implement Canvas-to-Markdown serialisation (serialising radial nodes, participants, and ideas into a nested list). - [x] Task 2: API Route — `GET /api/user/export` (AC: #1, #3) - [x] Subtask 2.1: Create GET handler in `memento-note/app/api/user/export/route.ts`. - [x] Subtask 2.2: Implement NextAuth check (return 401 if unauthenticated). - [x] Subtask 2.3: Query database for all active user notes (including content, notebook name, attachments, tags). - [x] Subtask 2.4: Query database for all user brainstorm sessions. - [x] Subtask 2.5: Compile the files: write notes `.md`, canvas `.md`, load note attachments via `fs.readFile`, and add all files to JSZip. - [x] Subtask 2.6: Generate an elegant, responsive `index.html` at the root using simple inline Tailwind/CSS that acts as a local browser. - [x] Subtask 2.7: Return the raw ZIP buffer with headers: - `Content-Type: application/zip` - `Content-Disposition: attachment; filename="memento-workspace-export-[date].zip"` - [x] Task 3: Settings UI Integration (AC: #2, #4) - [x] Subtask 3.1: Update `memento-note/app/(main)/settings/data/page.tsx` to insert the "GDPR — Data Portability" card next to the existing JSON export/import cards. - [x] Subtask 3.2: Wire state `isZipExporting`, showing a spinner and progress indicator. - [x] Subtask 3.3: Handle download dispatching on button click. - [x] Task 4: Internationalization (i18n) (AC: #4) - [x] Subtask 4.1: Add `dataManagement.zipExport.*` translations to all 15 JSON locale files: - `title`: "GDPR Workspace Export" / "Export Complet de l'Espace (RGPD)" - `description`: "Download all notes, attachments, and brainstorm canvases in standard Markdown and ZIP format." - `button`: "Export ZIP" / "Exporter en ZIP" - `exporting`: "Exporting..." / "Exportation en cours..." - `success`: "Workspace exported successfully" / "Espace de travail exporté avec succès" - `failed`: "Export failed" / "L'exportation a échoué" - [x] Task 5: Verification (AC: all) - [x] Subtask 5.1: Perform manual download and check archive integrity. - [x] Subtask 5.2: Open unzipped `index.html` locally in a browser to confirm note links and attachments resolve correctly. - [x] Subtask 5.3: Execute `npm run build` to verify compiling zero-errors. --- ## Dev Notes ### JSZip Installation Run the following inside `memento-note/`: ```bash npm install jszip npm install --save-dev @types/jszip ``` ### Note to Markdown Conversion Pattern Use a lightweight HTML-to-Markdown mapping or a basic converter to generate clean `.md` files: ```typescript function htmlToMarkdown(html: string): string { // Simple regex mapping for bold, italic, lists, and headings let md = html .replace(/
(.*?)<\/p>/gi, '$1\n\n') .replace(/