Files
ObsiGate/docs/features/guide-coverage-105.md
bruno b8054665bc
CI / lint (push) Successful in 1m39s
CI / security (push) Successful in 1m5s
CI / test (push) Successful in 3m25s
CI / build (push) Successful in 1m18s
CI / e2e (push) Successful in 11m43s
fix: guide - bouton telechargement icone seule, diagramme Architecture rendu en image dans le PDF, emoji couleur (Noto) (#105)
2026-09-18 15:01:14 -04:00

140 lines
8.0 KiB
Markdown

# #105 — Guide d'utilisation : couverture, téléchargement MD/PDF, Architecture
> **Statut :** livré | **Version :** 2.13.0 | **Bugs liés :** BUG-067
> **Roadmap :** [docs/ROADMAP.md](../ROADMAP.md) · **Changelog :** [../../CHANGELOG.md](../../CHANGELOG.md)
## 1. Objectif
Après ~35 features livrées (#70→#104), le guide intégré (modale « Guide
d'utilisation », `#help-modal` de `frontend/index.html`) ne représentait plus
l'application : Mermaid, hors-ligne/PWA, collaboration Yjs, desktop Tauri,
exports HTML/ePub/ZIP, recherche sémantique, MFA/WebAuthn, push, split view,
API OpenAPI/MCP étaient absents. L'item couvre quatre livrables :
1. **Audit de couverture** — toutes les fonctionnalités visibles ET non visibles
(API, MCP, webhooks, endpoints de partage) sont documentées.
2. **Section Architecture** — diagramme Mermaid des grandes composantes.
3. **Téléchargement Markdown + PDF** du guide, dans la langue courante.
4. **Lecture desktop élargie** (mode Tauri + grands viewports web).
## 2. Source de vérité du contenu
Le contenu des nouvelles sections vit dans **`scripts/guide_content.py`** :
dictionnaire `CONTENT` (clé → FR, EN) + constructeurs HTML qui **ne peuvent
pas diverger** des locales (le FR inline est généré depuis `CONTENT`).
- `scripts/merge_guide_locales.py` → injecte les clés `guide105.*` dans
`frontend/locales/{fr,en}.json` (insertion textuelle, parité assertée).
- `scripts/insert_guide_sections.py` → insère sections/TOC/compléments dans
`index.html` (idempotent, préserve les fins de ligne, vérifie l'équilibre
`<section>` et l'absence d'ancre morte).
- **Règle :** ne jamais éditer les blocs `guide105.*` des JSON ni les sections
#105 de `index.html` à la main — modifier `guide_content.py` et relancer les
deux scripts (séquence figée, sinon HTML et locales divergent).
## 3. Rendu du guide dans l'app
Les textes portent `data-i18n="guide105.*"` ; `_applyDOM()` (i18n.js) les
remplit avec la locale courante. Les valeurs FR/EN contiennent du **HTML
minimal** (`<code>`, `<strong>`, `<a href="https://…">`) — sûre ici car ces
chaînes sont statiques dans le dépôt (jamais de contenu utilisateur ; même
convention que `help.desc_*` existant).
Le diagramme d'architecture est un bloc `<pre class="mermaid-code"><code
class="language-mermaid">` : à l'ouverture de la modale, `renderGuideMermaid()`
(config.js) appelle `renderMermaidBlocks()` (mermaid-viewer.js) sur la modale —
le viewer ne rend que les vues document, la modale est donc enrichie ici. Si le
CDN Mermaid n'est pas prêt, le bloc reste du code lisible et le rendu est
retenté à l'ouverture suivante (`data-mermaid-rendered` ne se pose qu'après
succès). Le MD exporté embarque le diagramme en fenced block ` ```mermaid `
(copiable, rendu par GitHub/VS Code/Obsidian) ; le PDF affiche le PNG pré-rendu
(section 4 — WeasyPrint n'exécute pas Mermaid).
## 4. Téléchargement (MD + PDF)
`backend/guide_export.py` : parseur stdlib (html.parser → arbre minimal) ;
extraction de `#help-modal`→`.help-content`, résolution i18n **identique à
_applyDOM** (un élément `data-i18n` est remplacé par la valeur locale, sinon le
FR inline sert de repli), conversion Markdown (titres, listes imbriquées,
tables, fenced code, gras/italique/code/kbd/links http) et HTML propre pour
WeasyPrint. PDF : pipeline d'export existant (`build_pdf_html` + `generate_pdf`),
repli `_render_reportlab_pdf` (markdown simplifié) quand GTK manque (Windows
nu) — même stratégie que le bouton « PDF » des documents (#92).
`get_guide_document(fmt, lang)` met en cache (octets+signature mtime/size de
`index.html` et `fr.json`) pour éviter de re-générer à chaque requête.
Endpoint `GET /api/guide/download?format=md|pdf&lang=fr|en`
(`require_auth`, tag OpenAPI « Guide »), `Content-Disposition: attachment`.
Côté UI : boutons **icônes seules** 📄/⬇ dans l'en-tête de la modale
(`#help-download-md`/`#help-download-pdf`, tooltip i18n), handler `downloadGuide()` dans
`frontend/js/config.js` — fetch avec `AuthManager.getAuthHeaders()` +
credentials (identique à `viewer.downloadExport()`), blob → lien
téléchargeable, toasts i18n réutilisés (`viewer.export_*`).
Diagramme d'architecture dans le PDF : WeasyPrint n'exécute pas Mermaid → le code
Mermaid est **pré-rendu en PNG** (`scripts/build_guide_diagrams.py` +
`scripts/render_guide_diagram.mjs`, Chromium + mermaid v11 CDN, scale 2) et le PNG
est **commité** dans `backend/assets/guide_diagrams/<sha1>.png` ; `diagram_png_for()`
(hash sha1[:16] du code normalisé, même algorithme des deux côtés) remplace le
bloc par `<img src="file:///…">` dans le HTML d'export. Après modification du
diagramme dans `guide_content.py` + réinsertion : relancer
`python scripts/build_guide_diagrams.py` et committer le nouveau PNG.
Emoji : l'image Docker installe `fonts-noto-color-emoji` et la pile de polices
PDF finit par `"Noto Color Emoji"` — sans cela les emoji pleine chasse des titres
de section s'affichent en rectangles (la TOC n'était pas touchée car elle passe
par DejaVu/Sans).
## 5. Guide desktop élargi
`frontend/js/desktop.js::initDesktopIntegration()` ajoute `body.desktop-mode`
(une fois, après le garde Tauri). CSS (section « Help Modal: desktop » de
`style.css`) : conteneur 1760 px / 96 vw, contenu 1440 px, modale 94 vh ; le
même layout est accordé aux viewports ≥1400 px web via media-query (contenu
1280 px). Le mobile reste inchangé (≤768 px plein écran).
## 6. Couverture fonctionnelle du guide (après #105)
| Domaine app | Section du guide |
|---|---|
| Vaults, arborescence, filtres, breadcrumb | Interface, Navigation |
| Onglets, popout, split view | Onglets, Personnalisation |
| Recherche TF-IDF, opérateurs, facettes, sémantique, recherches sauvegardées, signets | Recherche, Bibliothèque |
| Tags, frontmatter | Tags |
| Fichiers, types supportés, CodeMirror, PDF, export HTML/ePub/ZIP, anti-doublons upload | Fichiers |
| Mermaid | Diagrammes |
| Excalidraw | Excalidraw |
| Éditeur, AI toolbar, BooksLM, commandes @//, skills, images, outils, historique | Édition, IA |
| Édition mobile | Mobile (section dédiée, BUG-067) |
| Graphe, backlinks | Bibliothèque, Graphe |
| Palette de commandes, raccourcis | Palette, Raccourcis |
| Partage public, PDF du partage, webhooks HMAC | Partage, Webhooks |
| Backups, diff, purge, audit log, gestionnaire | Sauvegardes et Audits |
| JWT/Argon2id, rate limit, MFA TOTP/WebAuthn, admin dashboard, secrets, CSP | Sécurité |
| PWA hors-ligne, IndexedDB queue, watcher, conflits Syncthing | Hors-ligne, Bibliothèque |
| Collaboration Yjs/CRDT, awareness, push VAPID | Collaboration, Interface |
| Tauri desktop (updater signé, wizard, fenêtrage) | Desktop |
| API REST OpenAPI (/docs, /redoc, /api, /openapi.json), MCP /mcp, automatisation | API & Intégrations |
| i18n FR/EN, export du guide multilingue | Multilingue |
| Architecture technique (couches, flux, données, déploiement) | **Architecture** (nouveau) |
| Plugins sandboxés | Plugins |
## 7. Tests & vérifications
- `tests/test_guide.py` (13) : ancre TOC→sections (garde-fou BUG-067),
sections #105 présentes, parité/présence des clés `guide105.*` FR=EN,
Markdown FR/EN (titres, mermaid, absence de balises résiduelles), PDF
(`%PDF`, taille), **diagramme Architecture rendu en `<img>` PNG dans le HTML
d'export**, MD garde le fenced mermaid, metadata `get_guide_document`,
endpoint MD/PDF/400 via TestClient, OpenAPI (path + tag « Guide »).
- Suite backend pytest : 1218 passed · ruff/mypy 0 erreur ·
`validate-imports` 38 modules · `unit.test.mjs` 10/10 · E2E complet CI.
- SW cache busting : `SW_VERSION` v21→v23 (guides + boutons icônes).
## 8. Limites assumées
- Le PDF est généré côté serveur avec les polices système ; en l'absence de
GTK (Windows de dev) c'est le repli reportlab (sans tableaux) — la voie
WeasyPrint est celle des conteneurs Docker/prod.
- Le sommaire et les sections sont en dur dans `index.html` : tout ajout futur
de section passe par `guide_content.py` + les deux scripts (jamais à la main).