# US-4 Redesign — Vue Structurée Inline dans l'Éditeur
> **Status :** DRAFT — En attente de validation fondateur
> **Remplace :** US-4 « Bloc de Base de Données Relationnelle Inline » (DEPRECATED)
> **Epic :** US-NEXTGEN-EDITOR
> **Dépend de :** US-STRUCTURED-VIEWS ✅ (livré), US-LIVING-BLOCKS ✅ (livré)
---
## 1. Problem Statement — Pourquoi l'ancienne US-4 est morte
L'implémentation actuelle (fichiers `tiptap-database-block-extension.tsx`, `database-block-editor.tsx`, `database-block-types.ts`) a été rejetée pour les raisons suivantes :
### 1.1 Copie de démo marketing, pas une feature produit
Le code source dans `createDefaultDatabaseBlockData()` insère **Jules Verne** et **Liu Cixin** avec leurs œuvres en données pré-remplies. C'est une copie directe du prototype `architectural-grid1/ModernBlockNoteEditor.tsx` qui était conçu pour une landing page, pas pour un produit de prise de notes réel.
### 1.2 Modèle de données parallèle et isolé
L'implémentation stocke `dbAuthorsJson` et `dbBooksJson` comme attributs HTML dans le nœud TipTap :
```html
```
Problèmes critiques :
- **Isolation totale** : ces données n'ont aucun lien avec le carnet, les notes, ni les propriétés Prisma.
- **Scalabilité zéro** : stocker des listes entières de rows dans les attributs d'un nœud TipTap = explostion de la taille du HTML à chaque sauvegarde.
- **Duplication du modèle** : `NotebookSchema` + `NotebookProperty` + `NoteProperty` existent déjà en BDD et fonctionnent.
### 1.3 Confusion utilisateur
Un utilisateur qui tape `/database` s'attend à voir ses propres données structurées — pas un jeu de rôle bibliothèque de SF. Cette confusion est documentée comme rejet non-négociable par le fondateur.
### 1.4 Audit du code à supprimer
| Fichier | Statut | Raison |
|---------|--------|--------|
| `memento-note/components/tiptap-database-block-extension.tsx` | **SUPPRIMER** | Extension TipTap avec modèle `dbAuthors`/`dbBooks` |
| `memento-note/components/database-block-editor.tsx` | **SUPPRIMER** | UI Auteurs & Œuvres, hardcodé |
| `memento-note/lib/editor/database-block-types.ts` | **SUPPRIMER** | Types + données Verne/Liu Cixin |
| `rich-text-editor.tsx` L28, L193-194, L395, L412-420, L1286, L1335-1338, L1397-1401 | **MODIFIER** | Retirer imports et références `/database` anciens |
| `block-action-menu.tsx` L15-17, L33, L39, L51, L134-135 | **MODIFIER** | Retirer option `database` du menu "Transformer en" |
| `locales/*.json` — clés `databaseBlock.*` | **SUPPRIMER** | ~15 clés obsolètes |
---
## 2. Personas & Jobs-to-be-Done
### Persona 1 — Chloé, chercheuse (carnet "Thèse Linguistique")
Chloé a configuré son carnet avec des propriétés : `Statut` (select), `Langue` (select), `Lu` (checkbox), `Source` (text). Elle a 47 notes dans ce carnet. Elle rédige un chapitre synthétique et veut **voir le tableau de ses sources directement sous son paragraphe d'introduction**, sans quitter l'éditeur.
**Job-to-be-done :** *"Quand je rédige, je veux voir le tableau de mes données structurées en contexte, sans naviguer vers le carnet."*
### Persona 2 — Mehdi, chef de projet (carnet "Sprint Q2 2026")
Carnet structuré avec propriétés `Statut` (Kanban), `Priorité`, `Assigné`. Il prend ses notes de réunion et veut **insérer une vue en lecture de son Kanban** pour partager l'état du sprint dans la note de compte-rendu.
**Job-to-be-done :** *"Dans ma note de réunion, je veux une vue rapide de l'état des tâches du sprint."*
### Persona 3 — Yasmin, étudiante (carnet "Lectures Persan")
Carnet avec propriétés `Lu` (checkbox), `Note` (number). Elle lit en persan (RTL). Elle veut **voir sa liste de lectures sous forme de tableau** inline dans ses notes de révision.
**Job-to-be-done :** *"Dans mes notes, je veux voir mon tableau de lectures avec les bonnes valeurs — en persan, dans le bon sens."*
---
## 3. Options Produit pour `/database` — Analyse & Recommandation
### Option A — Embed Structured View (Recommandée ✅)
**Description :** Le bloc inline affiche une vue filtrée (Table ou Galerie) du schéma du carnet courant. Données lues depuis l'API existante. Le bloc stocke seulement `notebookId`, `displayMode`, `filterJson` dans ses attributs TipTap.
**Avantages :**
- Réutilise `NotesStructuredTable` et `NotesGalleryView` existants (quasi plug-and-play).
- Données cohérentes avec `/home` (même source de vérité).
- Léger : 3 attributs string dans le nœud TipTap, pas de payload.
- Facile à migrer : si le schéma du carnet change, le bloc se met à jour automatiquement.
- Clair pour l'utilisateur : "c'est mon carnet, mes données."
**Risques :**
- Éditeur doit recevoir `notebookId` (actuellement absent — patch mineur dans `note-content-area.tsx`).
- Si le carnet n'a pas de schéma, le bloc doit le gérer gracieusement.
**Verdict :** Option principale retenue.
### Option B — Linked Database Block (style Notion)
**Description :** L'utilisateur choisit n'importe quel carnet structuré (pas forcément le carnet de la note courante), avec filtre et vue configurables dans le bloc.
**Avantages :** Plus puissant — permet de croiser des carnets.
**Risques :**
- UI de sélection de carnet complexe dans le NodeView.
- Scope plus large que ce que justifie une US-4 isolée.
- Cross-notebook = scope Living Blocks étendu → reporter à v2.
**Verdict :** Déféré à v2 après que l'Option A soit stabilisée.
### Option C — Mini-table locale (colonnes libres dans la note)
**Description :** Table simple dans la note, indépendante des carnets, avec colonnes définissables par l'utilisateur.
**Avantages :** Pas de dépendance à Structured Views.
**Risques :**
- Crée exactement le second système de données parallèle qu'on veut éviter.
- Ne répond pas aux personas (Chloé et Mehdi veulent leurs vraies données).
- Rejectée explicitement par le fondateur.
**Verdict :** Hors scope. Ne pas implémenter.
### Option D — Supprimer `/database`
**Description :** Retirer complètement la commande slash et l'option du menu.
**Avantages :** Simple, propre.
**Risques :**
- Perd une surface UX qui a du sens (une fois bien connectée).
- L'annonce "database inline" est une attente utilisateur légitime.
**Verdict :** Fallback si l'Option A prend trop de temps — mais l'Option A est faisable en taille M.
---
## 4. User Story & Critères d'Acceptation (Given/When/Then)
### US-4 (Nouvelle) : Vue Structurée de Carnet Inline dans l'Éditeur
**En tant que** rédacteur dans un carnet structuré,
**Je veux** insérer une vue en lecture de mon tableau de notes directement dans le corps de ma note,
**Afin de** voir mes données structurées en contexte, sans quitter l'éditeur ni naviguer vers le carnet.
---
#### Scénario 1 — Insertion dans un carnet structuré
**Given** que ma note est dans un carnet qui a un schéma (`NotebookSchema` défini)
**When** je tape `/database` dans l'éditeur
**Then** un bloc `structuredViewBlock` est inséré, affichant la vue Table du carnet (colonnes = propriétés du schéma, lignes = notes du carnet)
**And** aucune donnée de démo n'est insérée
**And** l'utilisateur peut modifier les valeurs simples directement dans le bloc (checkbox, select, texte) — les changements se sauvegardent via `PATCH /api/notes/:id/properties`
---
#### Scénario 2 — Carnet sans schéma
**Given** que ma note est dans un carnet sans `NotebookSchema`
**When** j'insère un bloc `/database`
**Then** le bloc affiche un message contextuel : *"Ce carnet n'a pas encore de vue structurée. Configurez-en une depuis l'en-tête du carnet."* avec un lien vers le wizard
**And** aucune donnée n'est chargée, aucun crash
---
#### Scénario 3 — Note sans carnet
**Given** que ma note n'appartient à aucun carnet (notebookId absent)
**When** j'insère un bloc `/database`
**Then** le bloc affiche : *"Ce bloc nécessite un carnet. Déplacez cette note dans un carnet pour l'utiliser."*
---
#### Scénario 4 — Migration des blocs legacy
**Given** qu'une note contient un ancien nœud `data-database-block="true"` (auteurs/œuvres)
**When** la note est ouverte
**Then** le bloc obsolète est silencieusement retiré (ou affiché comme placeholder "bloc obsolète")
**And** le reste du contenu de la note est intact
**And** aucun crash ne se produit
---
#### Scénario 5 — RTL / locale persane
**Given** que la langue de l'app est `fa` (persan, RTL)
**When** le bloc est affiché
**Then** le wrapper du bloc a `dir="auto"`, le tableau s'aligne correctement en RTL
**And** les libellés du bloc sont traduits en persan (via `useLanguage()`)
---
#### Scénario 6 — Bascule de vue (Table → Galerie)
**Given** que le bloc est inséré dans un carnet avec `illustrationSvg` ou couleur
**When** l'utilisateur clique sur le sélecteur de vue dans le bloc
**Then** il peut basculer entre `Table` et `Galerie`
**And** l'attribut `displayMode` du nœud TipTap est mis à jour
**And** la vue se met à jour sans re-insertion du bloc
---
## 5. Out of Scope Explicite
| Fonctionnalité | Raison |
|----------------|--------|
| Vue Kanban inline | Drag-and-drop dans un NodeView TipTap = mauvaise UX, reporté en v2 |
| Sélection d'un carnet différent de la note courante | Scope trop large → v2 |
| Formules / rollups calculés | Hors scope Structured Views v1 |
| Relations multi-carnets | Hors scope — nécessite migration Prisma dédiée |
| Filtre personnalisé via UI dans le bloc | v2 — le bloc affiche tout le carnet en v1 |
| Pagination dans le bloc | v2 si le carnet dépasse 50 notes |
| Export PDF/CSV depuis le bloc | Fonctionnalité séparée |
---
## 6. Composants Prototype à Référencer
| Composant prototype | Usage | Note |
|--------------------|-------|------|
| `architectural-grid/` — `NotesStructuredTable` pattern | Colonnes et cellules — **référence design** | Utiliser le composant prod `notes-structured-table.tsx` |
| `architectural-grid/` — `NotesGalleryView` pattern | Vue galerie — **référence design** | Utiliser le composant prod `notes-gallery-view.tsx` |
| `architectural-grid1/ModernBlockNoteEditor.tsx` L1704+ | **NE PAS COPIER** — démo marketing Verne/Liu Cixin | Audit uniquement |
> ⚠️ Le prototype `architectural-grid1` est la référence de ce qu'il **ne faut pas** shipper. Le prototype `architectural-grid` (sans `1`) est la référence de design courant.
---
## 7. Modèle de Données
### 7.1 Nœud TipTap — Attributs (référence légère uniquement)
```typescript
// Extension TipTap — tiptap-structured-view-block-extension.tsx
Node.create({
name: 'structuredViewBlock',
group: 'block',
atom: true,
draggable: true,
addAttributes() {
return {
notebookId: {
default: null,
parseHTML: (el) => el.getAttribute('data-sv-notebook-id'),
renderHTML: (attrs) => attrs.notebookId
? { 'data-sv-notebook-id': attrs.notebookId }
: {},
},
displayMode: {
default: 'table',
parseHTML: (el) => el.getAttribute('data-sv-mode') || 'table',
renderHTML: (attrs) => ({ 'data-sv-mode': attrs.displayMode }),
},
filterJson: {
default: '{}',
parseHTML: (el) => el.getAttribute('data-sv-filter') || '{}',
renderHTML: (attrs) => ({ 'data-sv-filter': attrs.filterJson }),
},
}
},
parseHTML: () => [{ tag: 'div[data-structured-view-block]' }],
renderHTML: ({ HTMLAttributes }) =>
['div', mergeAttributes(HTMLAttributes, { 'data-structured-view-block': 'true' })],
addNodeView: () => ReactNodeViewRenderer(StructuredViewBlockEmbed),
})
```
### 7.2 Aucune migration Prisma requise
Le bloc réutilise le schéma Prisma existant :
- `NotebookSchema` / `NotebookProperty` → définition des colonnes
- `NoteProperty` → valeurs par note
- `Note` → lignes du tableau
Aucune nouvelle table. Aucun risque BDD.
### 7.3 Diagramme de relations
```mermaid
graph TD
A["structuredViewBlock node
(TipTap attrs)"] -->|"notebookId"| B["GET /api/notebooks/:id/schema"]
B --> C["NotebookSchema
(Prisma)"]
C --> D["NotebookProperty[]
(colonnes)"]
A -->|"notebookId"| E["GET /api/notebooks/:id/notes
(avec properties)"]
E --> F["Note[]
(lignes)"]
F --> G["NoteProperty[]
(valeurs)"]
D & G --> H["NotesStructuredTable
(composant prod réutilisé)"]
H --> I["Rendu inline dans l'éditeur"]
```
---
## 8. Plan de Migration & Rollback du Code Actuel
### 8.1 Ordre de suppression (pour éviter les imports cassés)
1. **Supprimer** `memento-note/lib/editor/database-block-types.ts`
2. **Supprimer** `memento-note/components/database-block-editor.tsx`
3. **Supprimer** `memento-note/components/tiptap-database-block-extension.tsx`
4. **Modifier** `block-action-menu.tsx` — retirer import + option `database`
5. **Modifier** `rich-text-editor.tsx` — retirer import + slash entry + extension registration
6. **Créer** `tiptap-structured-view-block-extension.tsx` + `structured-view-block-embed.tsx`
7. **Modifier** `note-content-area.tsx` — passer `notebookId`
8. **Modifier** `locales/en.json` + `fr.json` — swap clés i18n
### 8.2 Gestion des notes existantes avec l'ancien bloc
Le nœud `databaseBlock` sera inconnu de TipTap après suppression de l'extension. Par défaut ProseMirror le drop silencieusement. Options :
- **Option simple (v1) :** Laisser ProseMirror supprimer le nœud inconnu au premier rendu — aucune action développeur.
- **Option propre (recommandée) :** Ajouter dans la nouvelle extension une règle `parseHTML` qui matche `div[data-database-block]` et le convertit en paragraphe `⚠️ Bloc base de données obsolète — ce contenu a été retiré.`
### 8.3 Rollback possible
Si le fondateur rejette l'Option A après implémentation :
- Les 3 fichiers supprimés sont dans git history — `git checkout HEAD~1 -- ` les restaure.
- La suppression de l'extension de `rich-text-editor.tsx` est une ligne — réversible en 2 minutes.
---
## 9. Risques Performance & Mitigations
| Risque | Probabilité | Impact | Mitigation |
|--------|-------------|--------|-----------|
| NodeView React lourd — re-render à chaque transaction TipTap | Haute | Haute | `shouldRerenderOnTransaction: false` sur l'éditeur (US-EDITOR-PERF) + `React.memo` sur le bloc embed + `trackNodeViewPosition: false` |
| SWR fetch bloque le rendu initial de la note | Moyenne | Moyenne | Suspense avec skeleton loader ; ne pas bloquer le rendu éditeur ; lazy-mount après 500ms |
| Note dans carnet avec 200+ notes — tableau trop long | Basse | Moyenne | Afficher les 20 premières notes avec `"Voir toutes les N notes dans le carnet"` CTA |
| RTL — cellules du tableau cassées | Basse | Haute | `dir="auto"` sur le wrapper ; tester avec locale `fa` avant merge |
---
## 10. i18n — Clés à Ajouter / Supprimer
### 10.1 Clés à ajouter (EN/FR minimum)
| Clé | EN | FR |
|-----|----|----|
| `structuredViewBlock.insertLabel` | Structured View | Vue structurée du carnet |
| `structuredViewBlock.insertDesc` | Embed your notebook's structured data | Intégrez les données structurées de votre carnet |
| `structuredViewBlock.noSchema` | This notebook has no structured view yet. Set one up from the notebook header. | Ce carnet n'a pas encore de vue structurée. Configurez-en une depuis l'en-tête du carnet. |
| `structuredViewBlock.noNotebook` | This block requires a notebook. Move this note to a notebook first. | Ce bloc nécessite un carnet. Déplacez cette note dans un carnet pour l'utiliser. |
| `structuredViewBlock.openInNotebook` | Open in notebook | Ouvrir dans le carnet |
| `structuredViewBlock.displayModeTable` | Table | Tableau |
| `structuredViewBlock.displayModeGallery` | Gallery | Galerie |
| `structuredViewBlock.loadError` | Failed to load structured data. | Impossible de charger les données structurées. |
| `structuredViewBlock.retry` | Retry | Réessayer |
| `structuredViewBlock.deprecatedBlock` | Outdated block removed. | Bloc obsolète retiré. |
> **Note :** Si l'utilisateur demande à compléter les 15 locales, ne remplir que les clés — laisser la traduction des 13 autres locales à l'outil de traduction externe (règle AGENTS.md).
### 10.2 Clés à supprimer (après vérification pas d'autre consommateur)
`databaseBlock.title`, `databaseBlock.viewTable`, `databaseBlock.viewCards`, `databaseBlock.hint`, `databaseBlock.colAuthor`, `databaseBlock.colWorks`, `databaseBlock.colRollup`, `databaseBlock.noLinkedWorks`, `databaseBlock.deleteShort`, `databaseBlock.addAuthor`, `databaseBlock.authorPlaceholder`, `databaseBlock.createAuthor`, `databaseBlock.worksBase`, `databaseBlock.storedCount`, `databaseBlock.addWork`, `databaseBlock.bookTitlePlaceholder`, `databaseBlock.selectAuthor`, `databaseBlock.tagPlaceholder`, `databaseBlock.coverPlaceholder`, `databaseBlock.insertWork`, `databaseBlock.deleteCard`, `databaseBlock.insertFailed`, `databaseBlock.defaultTag`
---
## 11. Checklist QA Manuelle
### 11.1 Français (LTR)
- [ ] Taper `/database` dans une note d'un carnet structuré → bloc s'insère avec les données réelles
- [ ] Taper `/database` → même résultat (rétrocompatibilité keyword)
- [ ] Taper `/database` dans une note sans carnet → message "nécessite un carnet"
- [ ] Taper `/database` dans une note d'un carnet sans schéma → callout wizard avec lien
- [ ] Ouvrir une note avec un ancien bloc `databaseBlock` → note s'ouvre, bloc absent ou placeholder, pas de crash
- [ ] Menu "Transformer en" → option "Vue structurée" présente, option "Base de données" (ancienne) absente
- [ ] Bascule Table ↔ Galerie dans le bloc → vue change, pas de réinsertion du bloc
- [ ] `npm run build` → 0 erreur, aucun import vers fichiers supprimés
### 11.2 Persan / RTL (fa)
- [ ] Changer la langue en `fa` → libellés du bloc en persan
- [ ] Le bloc wrapper est `dir="auto"` → tableau aligné à droite
- [ ] Cellules du tableau RTL lisibles (pas de texte coupé)
- [ ] Callout "no schema" en persan → texte lisible RTL
---
## 12. Estimation Effort
| Tâche | Taille |
|-------|--------|
| Supprimer 3 fichiers legacy | XS |
| Patcher `rich-text-editor.tsx` + `block-action-menu.tsx` | S |
| Patcher `note-content-area.tsx` (`notebookId` prop) | XS |
| Créer `tiptap-structured-view-block-extension.tsx` | S |
| Créer `structured-view-block-embed.tsx` (SWR + états + RTL) | M |
| i18n EN + FR | XS |
| QA manuelle FR + fa | S |
| **Total estimé** | **M** (~1–2 jours dev) |
---
## 13. Décisions Produit Actées
### Édition inline — ACTIVÉE en v1
L'utilisateur peut modifier les valeurs simples directement dans le bloc (checkbox, select, texte court). Les changements se sauvegardent via `PATCH /api/notes/:id/properties` avec mise à jour optimiste. C'est la meilleure expérience utilisateur — un bloc en lecture seule n'aurait aucun intérêt.
### Kanban inline — REPORTÉ en v2
Table + Galerie uniquement en v1. Le drag-and-drop dans un NodeView TipTap crée de mauvaises interactions. Le Kanban s'utilisera depuis le carnet comme aujourd'hui.
---
## Annexe — Diff Proposé pour `docs/story-nextgen-editor.md`
Remplacer la section `### US-4: Bloc de Base de Données Relationnelle Inline` (lignes 71–85) par :
```markdown
### US-4: Vue Structurée de Carnet Inline *(Redesign — voir `docs/story-nextgen-editor-us4-redesign.md`)*
> ⚠️ **DEPRECATED** — La spécification précédente (bloc "Auteurs & Œuvres") est rejetée.
> Voir [`docs/story-nextgen-editor-us4-redesign.md`](./story-nextgen-editor-us4-redesign.md) pour la nouvelle spec.
**En tant que** rédacteur dans un carnet structuré,
**Je veux** insérer une vue en lecture de mon tableau de notes directement dans le corps de ma note,
**Afin de** voir mes données structurées en contexte, sans quitter l'éditeur.
*(Critères d'acceptation détaillés dans le fichier redesign ci-dessus.)*
```
Et remplacer la section `### 1. Structure du Nœud de Base de Données Tiptap` + `### 2.` + `### 3.` dans les Spécifications Techniques (lignes 90–109) par :
```markdown
### 1. Structure du Nœud `structuredViewBlock` (TipTap)
Extension TipTap `StructuredViewBlockExtension` dans `tiptap-structured-view-block-extension.tsx` :
- Attributs : `notebookId` (string), `displayMode` ('table'|'gallery'), `filterJson` (string JSON)
- ReactNodeViewRenderer → `structured-view-block-embed.tsx`
### 2. Suppression du code legacy
- Supprimer : `tiptap-database-block-extension.tsx`, `database-block-editor.tsx`, `lib/editor/database-block-types.ts`
- Modifier : `rich-text-editor.tsx`, `block-action-menu.tsx`, `locales/*.json`
- Voir plan complet dans `docs/story-nextgen-editor-us4-redesign.md` §8.
```
---
## Annexe — Diff Proposé pour `docs/user-stories.md`
### Dans le tableau de bord (ligne 23)
```diff
-| **US-NEXTGEN-EDITOR** | Éditeur Next-Gen : Drag Handle + Menu Bloc + DB Inline + Smart Paste | 🚧 **PLANIFIÉ** | Voir `docs/story-nextgen-editor.md` |
+| **US-NEXTGEN-EDITOR** | Éditeur Next-Gen : Drag Handle + Menu Bloc + Vue Structurée Inline + Smart Paste | 🚧 **PLANIFIÉ** | Voir `docs/story-nextgen-editor.md` + `docs/story-nextgen-editor-us4-redesign.md` |
```
### Dans la section US-NEXTGEN-EDITOR (US-4, ligne 622–626)
```diff
-### US-4 : Bloc de Base de Données Relationnelle Inline
-- Slash `/database` → insère un React NodeView
-- Vues Tableau / Fiches avec Rollup dynamique
-- Modèle relationnel local (auteurs/livres par défaut, ou lié au carnet)
+### US-4 : Vue Structurée de Carnet Inline *(Redesign)*
+> Spec complète : [`docs/story-nextgen-editor-us4-redesign.md`](./story-nextgen-editor-us4-redesign.md)
+- Slash `/database` (+ keywords `db`, `tableau`, `structured`) → insère un `structuredViewBlock`
+- Affiche Table ou Galerie du carnet courant via l'API Structured Views existante
+- Bloc stocke uniquement `notebookId` + `displayMode` (pas de données en attrs)
+- Graceful fallback si carnet sans schéma ou note sans carnet
+- Supprime le code legacy `tiptap-database-block-extension.tsx` (Verne/Liu Cixin)
+- **Dépend de :** US-STRUCTURED-VIEWS ✅ (livré)
```
### Dans la liste de fichiers (ligne 627–631)
```diff
-### Fichiers
-- `[NEW]` `tiptap-drag-handle-plugin.ts` — Plugin ProseMirror pur
-- `[NEW]` `tiptap-database-block-extension.tsx` — NodeView React
-- `[MODIFY]` `rich-text-editor.tsx` — Intégration drag handle + DB + paste intercept
-- `[MODIFY]` `globals.css` — Gutter, poignée, glassmorphic dropdowns
+### Fichiers
+- `[NEW]` `tiptap-drag-handle-plugin.ts` — Plugin ProseMirror pur (US-1, inchangé)
+- `[NEW]` `tiptap-structured-view-block-extension.tsx` — NodeView Vue Structurée (remplace DB)
+- `[NEW]` `structured-view-block-embed.tsx` — Composant embed avec SWR + states
+- `[DELETE]` `tiptap-database-block-extension.tsx` — Bloc legacy auteurs/œuvres rejeté
+- `[DELETE]` `database-block-editor.tsx` — UI legacy rejetée
+- `[DELETE]` `lib/editor/database-block-types.ts` — Types legacy rejetés
+- `[MODIFY]` `rich-text-editor.tsx` — Intégration drag handle + Vue Structurée + paste intercept
+- `[MODIFY]` `note-content-area.tsx` — Passer `notebookId` à l'éditeur
+- `[MODIFY]` `block-action-menu.tsx` — Remplacer option "Database" par "Vue structurée"
+- `[MODIFY]` `globals.css` — Gutter, poignée, glassmorphic dropdowns
```