feat: publication IA (magazine/brief/essay) + fixes critique
Some checks failed
CI / Lint, Unit Tests & Build (push) Failing after 1m22s
CI / Deploy production (on server) (push) Has been skipped

Publication IA:
- 4 templates (magazine, brief, essay, simple) avec CSS riche
- Rewrite IA (article/exercises/tutorial/reference/mixed)
- Modération avec timeout 12s + fallback safe
- Quotas publish_enhance par tier (basic=2, pro=15, business=100)
- Détection contenu stale (hash)
- Migration DB publishedContent/publishedTemplate/publishedSourceHash

Fixes:
- cheerio v1.2: Element -> AnyNode (domhandler), decodeEntities cast
- _isShared ajouté au type Note (champ virtuel serveur)
- callout colors PDF export: extraction fonction pure testable
- admin/published: guard note.userId null
- Cmd+S fonctionne en mode dialog (pas seulement fullPage)

i18n:
- 23 clés publish* traduites dans les 15 locales
- Extension Web Clipper: 13 locales mise à jour

Tests:
- callout-colors.test.ts (6 tests)
- note-visible-in-view.test.ts (5 tests)
- entitlements.test.ts + byok-entitlements.test.ts: mock usageLog + unstubAllEnvs
- 199/199 tests passent

Tracker: user-stories.md sync avec sprint-status.yaml
This commit is contained in:
Antigravity
2026-06-28 07:32:57 +00:00
parent 902fe95a69
commit 96e7902f01
169 changed files with 5382 additions and 1527 deletions

View File

@@ -1,7 +1,7 @@
# User Stories — Momento Next Phase
# User Stories — Memento Next Phase
> Basé sur l'analyse du prototype `architectural-grid/` et du code production `memento-note/`.
> Dernière mise à jour : 2026-05-29 (Epic 6 Croissance & Activation ajouté — analyse stratégique Mary/BMad)
> Dernière mise à jour : 2026-06-28 (Epic 6 terminé — sync avec sprint-status.yaml)
---
@@ -24,10 +24,12 @@
| **US-EDITOR-PERF** | Performance de frappe TipTap (quick wins) | ✅ **LIVRÉ** | `rich-text-editor.tsx` (useEditorState), `note-editor-context.tsx` (debounced setContent) |
| **US-EDITOR-UX** | Micro-interactions saisie (slash menu, sélection multi-blocs, paste étendu, placeholders) | ✅ **LIVRÉ** | Sélection globale, redesign Slash Menu (favoris/preview), placeholders contextuels, smart paste étendu, Turn Into & Undo/Redo |
| **US-EDITOR-MOBILE** | Expérience tactile & toolbar mobile adaptée | ✅ **LIVRÉ** | Toolbar fixe premium 44px, Bottom Sheet tactile (actions de bloc + IA), sélection facilitée de bloc |
| **US-EDITOR-MARKDOWN** | Rendu WYSIWYG Markdown fidèle (round-trip byte-for-byte) | **À FAIRE** | Brief : `docs/brief-markdown-roundtrip.md` |
| **US-ONBOARDING** | Wizard Activation — Effet "Aha!" Recherche Sémantique | 🆕 **À FAIRE** | Story : `docs/story-onboarding-activation.md` |
| **US-BRAINSTORM-FINALIZE** | Brainstorm Canvas D3 — Finalisation (export PPTX, gaps UX) | 🆕 **À FAIRE** | ~75% code existant (`brainstorm-page.tsx`, 14 routes API) |
| **US-CHAT-PDF** | Chat with PDF — RAG documentaire | 🆕 **À FAIRE** | |
| **US-EDITOR-MARKDOWN** | Rendu WYSIWYG Markdown fidèle (round-trip byte-for-byte) | **LIVRÉ** | Brief : `docs/brief-markdown-roundtrip.md` |
| **US-ONBOARDING** | Wizard Activation — Effet "Aha!" Recherche Sémantique | **LIVRÉ** | Story : `docs/story-onboarding-activation.md` |
| **US-BRAINSTORM-FINALIZE** | Brainstorm Canvas D3 — Finalisation (export PPTX, gaps UX) | **LIVRÉ** | `brainstorm-page.tsx`, 14 routes API |
| **US-CHAT-PDF** | Chat with PDF — RAG documentaire | **LIVRÉ** | `document-qa-overlay.tsx`, `document-ingestion`, `document-search` tool |
| **US-PPTX-EXPORT** | Export PPTX + Watermark | ✅ **LIVRÉ** | `lib/brainstorm/export-pptx.ts`, `lib/ai/tools/pptx.tool.ts` |
| **US-PUBLISH-IA** | Publication IA (templates magazine/brief/essay + rewrite) | ✅ **LIVRÉ** | `lib/publish/`, `publish-enhance.service.ts`, 4 templates CSS, quota `publish_enhance` |
---
@@ -119,7 +121,7 @@ Le prototype `SearchModal.tsx` est une refonte complète avec dual-panel, regex,
**Contexte :**
Le prototype contient `ClipperSimulator.tsx` (618 lignes) qui simule le clipping avec données mock. Il n'existe rien d'équivalent dans `memento-note`. La feature doit être réalisée en deux parties : une **extension Chrome/Firefox** et un **modal de réception** côté app.
**En tant qu'utilisateur**, je veux capturer n'importe quelle page web depuis mon navigateur et l'enregistrer dans Momento avec résumé IA, tags suggérés et choix du carnet — sans quitter le navigateur.
**En tant qu'utilisateur**, je veux capturer n'importe quelle page web depuis mon navigateur et l'enregistrer dans Memento avec résumé IA, tags suggérés et choix du carnet — sans quitter le navigateur.
**Critères d'acceptation :**
@@ -129,7 +131,7 @@ Le prototype contient `ClipperSimulator.tsx` (618 lignes) qui simule le clipping
- Bouton "Analyser avec IA" → appel `POST /api/clip/analyze` (URL + HTML content) → retourne `{ title, summary, tags[], readingTime }`
- Champ de sélection du carnet (dropdown hiérarchique, dernier carnet mémorisé)
- Aperçu du contenu clipé (150px scrollable)
- Bouton "Sauvegarder dans Momento" → appel `POST /api/clip/save` avec `{ url, title, content, summary, tags, notebookId }`
- Bouton "Sauvegarder dans Memento" → appel `POST /api/clip/save` avec `{ url, title, content, summary, tags, notebookId }`
- Feedback visuel : spinner → "Sauvegardé ✓" avec lien direct vers la note
### Route API `app/api/clip/analyze/route.ts` (nouvelle)
@@ -653,7 +655,7 @@ L'éditeur actuel est un document linéaire classique. Pour rivaliser avec Notio
> **Source recherche :** TipTap 2.5 (mai 2026), TipTap docs performance, PR #7828
**Contexte :**
Actuellement `rich-text-editor.tsx` utilise `immediatelyRender: false` mais pas `shouldRerenderOnTransaction` ni `useEditorState`. TipTap re-render le composant React à chaque transaction (frappe, déplacement curseur, sélection) — ce qui ajoute de la latence. Obsidian atteint <16ms de latence (local-first), Notion 50-150ms (cloud). Momento est local mais se comporte comme Notion à cause de ces re-renders inutiles.
Actuellement `rich-text-editor.tsx` utilise `immediatelyRender: false` mais pas `shouldRerenderOnTransaction` ni `useEditorState`. TipTap re-render le composant React à chaque transaction (frappe, déplacement curseur, sélection) — ce qui ajoute de la latence. Obsidian atteint <16ms de latence (local-first), Notion 50-150ms (cloud). Memento est local mais se comporte comme Notion à cause de ces re-renders inutiles.
**En tant qu'utilisateur**, je veux que la frappe dans l'éditeur soit instantanée, sans aucun décalage perceptible, même sur des notes longues avec de nombreux blocs.
@@ -711,7 +713,7 @@ const { isBold, isItalic, isHeading } = useEditorState({
> **Source recherche :** Mintlify "22 UX improvements" (mai 2026), BlockNote v0.50, BlockNote v0.49
**Contexte :**
Après les quick wins performance (US-EDITOR-PERF) et le drag handle (US-NEXTGEN-EDITOR), il reste des micro-interactions qui font la différence entre un éditeur "correct" et un éditeur "agréable". Mintlify a listé 22 améliorations UX en mai 2026 — voici les plus pertinentes pour Momento.
Après les quick wins performance (US-EDITOR-PERF) et le drag handle (US-NEXTGEN-EDITOR), il reste des micro-interactions qui font la différence entre un éditeur "correct" et un éditeur "agréable". Mintlify a listé 22 améliorations UX en mai 2026 — voici les plus pertinentes pour Memento.
**En tant qu'utilisateur**, je veux que chaque interaction courante (insérer un bloc, déplacer du contenu, transformer un format) soit fluide et intuitive, sans recourir à des raccourcis clavier obscurs.
@@ -802,7 +804,7 @@ L'éditeur fonctionne sur mobile mais l'expérience est dégradée : la bubble m
> **Source recherche :** Milkdown v7.20, "Human Markdown" extension VSCode, round-trip byte-for-byte
**Contexte :**
Momento stocke les notes en HTML (TipTap). Mais les notes de type `markdown` existent aussi. Le problème classique : éditer en riche et voir le Markdown reformatté intégralement (indentations changées, lignes vides supprimées, `##` convertis en soulignements). Milkdown (11k+ stars, ProseMirror + remark) résout ce problème avec un round-trip byte-for-byte.
Memento stocke les notes en HTML (TipTap). Mais les notes de type `markdown` existent aussi. Le problème classique : éditer en riche et voir le Markdown reformatté intégralement (indentations changées, lignes vides supprimées, `##` convertis en soulignements). Milkdown (11k+ stars, ProseMirror + remark) résout ce problème avec un round-trip byte-for-byte.
**En tant qu'utilisateur**, je veux que mes fichiers Markdown restent intacts quand je les édite en mode visuel — pas de diff parasite sur chaque modification.