# Story: Brainstorm Canvas — Finalisation (PPTX export + UX Canvas) > **Epic:** Epic 6 — Croissance & Activation (PLG) > **ID:** 6-3-brainstorm-canvas-finalize > **Priority:** High > **Status:** review > **Depends on:** `pptxgenjs@^4.0.1` (already in `package.json` ✅), `lib/ai/tools/pptx.tool.ts` (patterns) --- ## Contexte Le brainstorm canvas est quasi-complet (WaveCanvas D3, collaboration temps réel, export en note Markdown, finalize session). Il manque deux choses pour un produit fini : 1. **Export PPTX** (FR12) : génère une présentation branded depuis la session brainstorm — route API serveur `/api/brainstorm/[sessionId]/export-pptx` + bouton dans le modal "Export/Résumé" existant. 2. **UX Canvas** : légende des vagues (couleurs Wave 1/2/3) + bouton "Fit to screen" (re-center). `pptxgenjs@^4.0.1` est déjà installé. `lib/ai/tools/pptx.tool.ts` fournit les patterns d'utilisation (lazy import, helpers, thèmes). --- ## User Stories ### US-BRAINSTORM-PPTX : Export PPTX **En tant qu'** utilisateur, **Je veux** télécharger ma session brainstorm en fichier `.pptx`, **Afin de** la présenter ou la partager en dehors de l'application. #### Critères d'acceptation : - [x] **AC-1** : Un bouton "Télécharger en PPTX" est visible dans le modal "Résumé/Export" du brainstorm - [x] **AC-2** : Au clic, un fichier `brainstorm-{seedIdea-slug}.pptx` est téléchargé via le navigateur - [x] **AC-3** : Le PPTX contient : slide couverture (titre, seedIdea, date, stats), une slide par vague active (Wave 1/2/3 avec idées), slide "Top idées" (starred + converted), slide bilan - [x] **AC-4** : Les idées dismissées ne sont pas incluses - [x] **AC-5** : Le thème utilise les couleurs de l'app (brand-accent `#A47148`, fond clair) - [x] **AC-6** : La route est protégée (auth + participant check) ### US-BRAINSTORM-CANVAS-UX : UX Canvas **En tant qu'** utilisateur, **Je veux** comprendre les codes couleurs du canvas et recentrer la vue, **Afin de** naviguer efficacement dans la session. #### Critères d'acceptation : - [x] **AC-7** : Une légende compacte est visible en bas-gauche du canvas (Wave 1 🟠, Wave 2 🔵, Wave 3 🟣, ✓ Converti, ✦ IA, initiale Humain) - [x] **AC-8** : Un bouton "Recentrer" (⊙) est visible sur le canvas et recentre la vue sur le nœud racine --- ## Tasks / Subtasks ### T1 — Route API export PPTX - [x] T1.1 — Créer `app/api/brainstorm/[sessionId]/export-pptx/route.ts` - Auth + participant check (réutiliser `verifyParticipant`) - Charger la session avec les idées (non-dismissed) - Générer le PPTX via `pptxgenjs` (lazy import pattern de `pptx.tool.ts`) - Retourner le buffer en `application/vnd.openxmlformats-officedocument.presentationml.presentation` - Headers: `Content-Disposition: attachment; filename="brainstorm-{slug}.pptx"` ### T2 — Lib helper `lib/brainstorm/export-pptx.ts` - [x] T2.1 — Créer `lib/brainstorm/export-pptx.ts` avec `generateBrainstormPptx(session): Promise` - Thème "architectural_mono" (`bg: F2F0E9, primary: 1C1C1C, accent: A47148`) — cohérent avec l'app - Slide 0 : Cover — titre "Brainstorm", seedIdea en sous-titre, date, stats (N idées, M converties) - Slide 1-3 : Une slide par vague active — titre "Wave N — {label}", liste des idées (titre + description courte) - Slide finale : "Top idées" — starred ⭐ et converties ✓ — max 6 items - Idées dismissed : exclues ### T3 — Bouton PPTX dans le modal export - [x] T3.1 — Dans `brainstorm-page.tsx`, ajouter un bouton "Télécharger PPTX" dans le modal de résumé (`summaryOpen`) - Fetch `POST /api/brainstorm/{sessionId}/export-pptx` → blob download - Loading state + toast succès/erreur - i18n key `brainstorm.downloadPptx` ### T4 — UX Canvas : légende + recentrer - [x] T4.1 — Dans `wave-canvas.tsx`, ajouter une légende compacte (overlay bas-droit, au-dessus du hint double-click) - 4 entrées : Wave 1 🟠, Wave 2 🔵, Wave 3 🟣 + ✓ Converti - Style minimaliste, fond semi-transparent - [x] T4.2 — Exposer une ref/méthode `fitToScreen()` ou callback `onFitToScreen` depuis `WaveCanvas` - Re-applique `zoom.transform` vers `d3.zoomIdentity.translate(centerX, centerY).scale(0.8)` - [x] T4.3 — Dans `brainstorm-page.tsx`, ajouter un bouton ⊙ "Recentrer" dans les contrôles canvas - Appelle `fitToScreen()` - i18n key `brainstorm.fitToScreen` ### T5 — i18n (15 locales) - [x] T5.1 — Ajouter dans `locales/en.json` et `locales/fr.json` : - `brainstorm.downloadPptx`, `brainstorm.downloadPptxDesc`, `brainstorm.pptxSuccess`, `brainstorm.pptxError`, `brainstorm.fitToScreen` - [x] T5.2 — Propager dans les 13 autres locales (valeur EN par défaut) --- ## Dev Notes ### Architecture **Route API (`'use server'` implicite via Next.js route handler) :** ```typescript // app/api/brainstorm/[sessionId]/export-pptx/route.ts export async function POST(req, { params }) { // auth + verifyParticipant // load session + ideas (status !== 'dismissed') // generateBrainstormPptx(session) → Buffer // return new Response(buffer, { headers: { 'Content-Type': 'application/vnd.openxmlformats...', 'Content-Disposition': 'attachment; filename=...' } }) } ``` **Lazy import pptxgenjs (pattern depuis `pptx.tool.ts`) :** ```typescript let _PptxGenJS: (new () => PptxGenJSModule) | null = null async function getPptxGenClass() { if (!_PptxGenJS) { const mod = await import('pptxgenjs') _PptxGenJS = (mod.default ?? mod) as unknown as new () => PptxGenJSModule } return _PptxGenJS } ``` **Client download depuis brainstorm-page.tsx :** ```typescript const res = await fetch(`/api/brainstorm/${sessionId}/export-pptx`, { method: 'POST' }) const blob = await res.blob() const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `brainstorm-${slug}.pptx` a.click() URL.revokeObjectURL(url) ``` **WaveCanvas fit-to-screen :** - Exposer via `useImperativeHandle` + `forwardRef` un objet `{ fitToScreen: () => void }` - Ou plus simple : passer une prop `fitTrigger: number` (increment → re-zoom) ### Thème PPTX Cohérent avec l'identité visuelle Memento : - `bg: F2F0E9` — fond papier - `primary: 1C1C1C` — noir ardoise - `accent: A47148` — brand-accent Memento - `secondary: D4A373` — ocre clair ### Fichiers clés existants - `memento-note/lib/ai/tools/pptx.tool.ts` — référence pour patterns pptxgenjs - `memento-note/components/brainstorm/wave-canvas.tsx` — canvas D3 - `memento-note/components/brainstorm/brainstorm-page.tsx` — page principale - `memento-note/app/api/brainstorm/[sessionId]/export/route.ts` — export Markdown (référence) - `memento-note/lib/brainstorm-collab.ts` — `verifyParticipant` --- ## Dev Agent Record ### Implementation Plan _À compléter par l'agent dev_ ### Debug Log _À compléter_ ### Completion Notes _À compléter_ --- ## File List _À compléter_ --- ## Change Log | Date | Description | |------|-------------| | 2026-05-29 | Story créée — 6-3 brainstorm canvas finalize |