diff --git a/docs/ANALYSE_REVIEW.md b/docs/ANALYSE_REVIEW.md new file mode 100644 index 0000000..d3e646d --- /dev/null +++ b/docs/ANALYSE_REVIEW.md @@ -0,0 +1,384 @@ +# ObsiGate — Analyse complète & Recommandations V1.1 + +> **Date :** 2026-05-25 | **Analyste :** Hermes-Claw + Audit Code Source | **Version testée :** 1.4.0 (backend) / 1.5.0 (frontend) — http://openclaw1.dev.home:2020 + +--- + +## 📋 Table des matières + +1. [Résumé exécutif](#1-résumé-exécutif) +2. [Fonctionnalités actuelles](#2-fonctionnalités-actuelles) +3. [Forces](#3-forces) +4. [Points d'amélioration](#4-points-damélioration) +5. [Roadmap suggérée](#5-roadmap-suggérée) +6. [Checklist de professionnalisation](#6-checklist-de-professionnalisation) +7. [Notes de révision V1.1](#7-notes-de-révision-v11) + +--- + +## 1. Résumé exécutif + +**ObsiGate** est un gestionnaire web de vaults Obsidian Markdown auto-hébergé. +La version actuelle (1.4.0/1.5.0) est un produit **riche et mature**, bien au-delà d'une simple V1. +Il dispose d'un moteur de recherche TF-IDF avancé, un éditeur CodeMirror 6 intégré, une vue graphique, +un support PWA complet, des opérations CRUD sur fichiers/dossiers, et une synchronisation temps réel via SSE + watchdog. + +**Note globale : 8.5/10** — Produit fonctionnel, performant et professionnel. +Les améliorations restantes sont principalement d'ordre sécuritaire +(masquage des secrets, rate limiting) et de polish (documentation API, backlinks, tests automatisés). + +**Recommandation prioritaire :** Traiter les 2 points de sécurité +(masquage secrets + rate limiting), puis les enrichissements UX +(backlinks, conflits Syncthing). + +--- + +## 2. Fonctionnalités actuelles + +| # | Fonctionnalité | Statut | Détail | +|---|---------------|:------:|--------| +| 1 | Authentification | ✅ | JWT HS256 + Argon2id, sessions persistantes, "Se souvenir de moi", contrôle d'accès par vault | +| 2 | Multi-vaults | ✅ | Configurables via env vars ou API dynamique, support VAULT et DIR | +| 3 | Arborescence de fichiers | ✅ | Navigation hiérarchique avec lazy-loading, compteur d'éléments par dossier, icônes par type | +| 4 | Rendu Markdown | ✅ | Conversion HTML via mistune, tables, task lists, footnotes, strikethrough | +| 5 | Extraction YAML frontmatter | ✅ | Tous les champs parsés, carte frontmatter pliable avec badges, dates formatées, tags | +| 6 | Vue Source (raw) | ✅ | Toggle markdown brut + frontmatter | +| 7 | Bouton Copier | ✅ | Copie du contenu source | +| 8 | Bouton Télécharger | ✅ | Téléchargement du fichier | +| 9 | Onglet RÉCENT | ✅ | Onglet sidebar dédié + dashboard avec timestamps relatifs, previews, tags, bookmarks | +| 10 | Onglet TAGS | ✅ | Nuage de tags cliquable, compteurs, filtrage des tags template configurables | +| 11 | Recherche avancée | ✅ | Moteur TF-IDF, opérateurs (`tag:`, `vault:`, `title:`, `path:`, `ext:`), snippets ``, facettes, pagination, tri | +| 12 | Autocomplétion de recherche | ✅ | Dropdown avec historique (localStorage), suggestions fichiers + tags, navigation clavier | +| 13 | Filtre fichiers sidebar | ✅ | Filtre par nom, option case-sensitive, recherche sur l'index des chemins | +| 14 | Thème Sombre | ✅ | Toggle clair/sombre, persisté localStorage, highlight.js adaptatif | +| 15 | Administration utilisateurs | ✅ | Interface CRUD complète (admin uniquement) | +| 16 | Configurations | ✅ | Paramètres recherche, backend, watcher, tags, fichiers cachés, diagnostics, à propos | +| 17 | Table des matières | ✅ | Panneau droit avec scroll-spy, IntersectionObserver, barre de progression de lecture | +| 18 | Bookmarks | ✅ | Dashboard avec favoris, toggle depuis les cartes de fichiers | +| 19 | Historique d'ouverture | ✅ | Fichiers récemment ouverts par utilisateur, persisté sur disque | +| 20 | Éditeur CodeMirror 6 | ✅ | Coloration syntaxique multi-langages, autocomplétion, Ctrl+F, Ctrl+S | +| 21 | Création fichiers/dossiers | ✅ | Via menu contextuel (clic droit) et modals dédiées | +| 22 | Renommage fichiers/dossiers | ✅ | Renommage inline via menu contextuel | +| 23 | Suppression fichiers/dossiers | ✅ | Avec confirmation, suppression récursive pour les dossiers | +| 24 | Menu contextuel | ✅ | Clic droit : copier chemin, vue graphique, créer, renommer, supprimer | +| 25 | Wikilinks cliquables | ✅ | `[[lien]]` et `[[lien|alias]]` convertis en liens navigables, liens brisés en rouge | +| 26 | Images Obsidian | ✅ | Résolution intelligente (7 stratégies), support `![[image]]`, `![alt](path)`, `` dans liens | +| 27 | Vue Graphique | ✅ | Canvas force-directed, nœuds fichiers/dossiers, arêtes parent + wikilinks, zoom/pan | +| 28 | Onglets de contenu | ✅ | Barre d'onglets multi-fichiers | +| 29 | Fenêtres popout | ✅ | Vue standalone avec éditeur, TOC, thème sombre, login intégré | +| 30 | Find in Page | ✅ | Barre Ctrl+F avec case-sensitive, mot entier, regex | +| 31 | PWA | ✅ | Service worker, manifest.json, icônes, notification de mise à jour | +| 32 | SSE — Synchronisation temps réel | ✅ | Reconnexion automatique, panneau d'état, événements index/vault | +| 33 | Watchdog — Surveillance fichiers | ✅ | inotify natif + fallback polling, debounce configurable, mise à jour incrémentale | +| 34 | Filtrage dossiers/fichiers cachés | ✅ | Par vault (`hideHiddenFiles`), paramétrable dans Configurations | +| 35 | Gestion dynamique des vaults | ✅ | Ajout/suppression via API sans redémarrage | +| 36 | API REST | ✅ | 20+ endpoints (CRUD fichiers, recherche, tags, graph, bookmarks, config, diagnostics...) | +| 37 | Sécurité | ✅ | Headers CSP/X-Frame/XSS, protection path traversal, non-root, permissions vault | +| 38 | Toast notifications | ✅ | Feedback utilisateur (succès, erreur) | +| 39 | Barre de progression d'indexation | ✅ | Affichée dans le header pendant l'indexation initiale | +| 40 | Breadcrumb navigable | ✅ | Cliquable, repositionne automatiquement la sidebar | +| 41 | Redimensionnement sidebar | ✅ | Drag handle, persisté localStorage, limites min/max | +| 42 | Docker multi-plateforme | ✅ | linux/amd64, arm64, arm/v7, i386 | + +--- + +## 3. Forces + +### 🎨 Design & UX +- **Interface épurée** — layout 3 colonnes (sidebar | contenu | TOC) avec onglets sidebar +- **Français natif** — rare et appréciable pour un outil de cette catégorie +- **Responsive** — s'adapte aux différentes tailles d'écran, menu hamburger mobile +- **Feedback visuel** — timestamps relatifs ("il y a 5 min", "il y a 3 h"), toasts, barres de progression +- **PWA** — installation sur l'écran d'accueil, service worker, notifications de mise à jour + +### 🧠 Métadonnées +- **Extraction YAML complète** — tous les champs du frontmatter parsés et affichés dans une carte pliable stylisée +- **Tags cliquables** — dans la vue fichier, l'onglet RÉCENT, et le nuage de tags +- **Résolution wikilinks** — O(1) via table de lookup, support multi-vaults +- **Images** — résolution multi-stratégies (7 stratégies) des syntaxes Obsidian + +### 🏗️ Architecture +- **Multi-vaults** — supporte plusieurs vaults simultanément avec contrôle d'accès par utilisateur +- **Auto-détection** — découverte automatique des vaults via variables d'environnement +- **API dynamique** — ajout/suppression de vaults sans redémarrage +- **Performance** — TF-IDF avec ThreadPoolExecutor, index mémoire, lookup O(1), SSE temps réel +- **Stack moderne** — FastAPI + mistune + watchdog (backend), Vanilla JS SPA + CodeMirror 6 + highlight.js (frontend) + +--- + +## 4. Points d'amélioration + +### 4.1 🔴 Critique — Sécurité + +#### 4.1.1 Masquage automatique des secrets + +**Problème :** Les clés API, tokens et secrets sont visibles en clair dans les aperçus de contenu et la vue RÉCENT. + +**Exemple concret observé :** Fichier "AI API" → preview contient des clés OpenAI en clair. + +**Solution :** Implémenter un `SecretRedactor` (backend) qui scanne le contenu avant affichage : +- Patterns : OpenAI/Claude keys, JWT tokens, GitHub tokens, clés hex/base64 > 40 chars +- Preview RÉCENT/Dashboard : Masquer toutes les clés +- Vue Source : Warning "Ce fichier contient N secrets potentiels. [Afficher]" +- Vue Rendu : Masquer avec placeholder visuel +- Export/Téléchargement : Conserver le contenu original + +**Priorité :** 🔴 P0 — Corriger avant toute exposition publique + +--- + +#### 4.1.2 Rate limiting & protection brute-force + +**Problème :** Absence de rate limiting sur le login. + +**Solution :** Middleware rate-limit — 5 tentatives max par IP sur 15 minutes, blocage après 10 échecs. + +**Priorité :** 🔴 P0 + +--- + +#### 4.1.3 Filtrage des dossiers sensibles — Amélioration + +**État actuel :** VaultWatcher ignore déjà `.obsidian`, `.trash`, `.git`, `__pycache__`, `node_modules`. +Le paramètre `hideHiddenFiles` par vault masque les fichiers/dossiers commençant par `.`. + +**Amélioration :** Rendre la liste `IGNORED_DIRS` configurable. + +**Priorité :** 🟡 P2 — Déjà partiellement résolu + +--- + +### 4.2 🟠 Important — Performance & Robustesse + +#### 4.2.1 Log d'audit + +Pas de traçabilité des actions critiques (écritures, suppressions, changements de config). +Logger les actions avec utilisateur, timestamp, vault, chemin dans `data/audit.log`. + +**Priorité :** 🟠 P1 + +--- + +#### 4.2.2 Backup automatique avant écriture + +Pas de filet de sécurité avant modification/suppression. +Sauvegarder le contenu original dans `.obsigate-backup/` horodaté. + +**Priorité :** 🟠 P1 + +--- + +#### 4.2.3 Timeout de session configurable + +TTL JWT codé en dur. Rendre configurable. + +**Priorité :** 🟡 P2 + +--- + +### 4.3 🟡 UX & Navigation + +#### 4.3.1 Backlinks panel + +Afficher les fichiers contenant des wikilinks pointant vers le fichier courant. +Construire un index inversé des wikilinks au scan initial. + +**Priorité :** 🟡 P2 + +--- + +#### 4.3.2 Correction TOC — scroll avec caractères accentués + +Le clic sur un titre dans la TOC ne fonctionne pas pour certains titres accentués. +Les fonctions slugify backend/frontend utilisent des normalisations Unicode qui divergent. + +**Solution :** Unifier l'algorithme + fallback `scrollIntoView`. + +**Priorité :** 🟡 P2 + +--- + +#### 4.3.3 Gestion fichiers non-supportés + +Les fichiers binaires non supportés déclenchent une erreur 500. +Ajouter un message explicite avec bouton de téléchargement. + +**Priorité :** 🟢 P3 + +--- + +### 4.4 🟢 Fonctionnel — Feature Gaps + +#### 4.4.1 Gestion des conflits Syncthing + +Les fichiers `.sync-conflict-*` sont indexables mais pas d'outil de résolution. +Ajouter section « Conflits » avec diff et choix (garder local/conflit). + +**Priorité :** 🟢 P3 + +--- + +#### 4.4.2 Dashboard statistiques + +Dashboard avec métriques par vault : fichiers totaux, taille, top tags, orphelins. + +**Priorité :** 🟢 P4 + +--- + +### 4.5 🔵 Architecture & Code + +#### 4.5.1 Documentation OpenAPI/Swagger enrichie + +L'API REST (20+ endpoints) est documentée via docstrings Python. +FastAPI génère automatiquement /docs et /redoc. Enrichir les modèles Pydantic. + +**Priorité :** 🟡 P2 + +--- + +#### 4.5.2 Webhook / Event system + +Notifier des systèmes externes lors de changements (création, modification, suppression). + +**Priorité :** 🟢 P3 + +--- + +#### 4.5.3 Authentification multi-facteurs + +TOTP ou WebAuthn pour l'accès admin. + +**Priorité :** 🔵 P5 + +--- + +## 5. Roadmap suggérée + +### Phase 1 — Correctifs urgents (1-2 semaines) + +| # | Tâche | Effort | +|---|-------|:------:| +| 1 | Redacteur de secrets dans les aperçus | 2h | +| 2 | Rate limiting sur le login | 2h | +| 3 | Log d'audit (écritures, suppressions) | 3h | +| 4 | Backup automatique avant écriture | 3h | + +### Phase 2 — UX (2-4 semaines) + +| # | Tâche | Effort | +|---|-------|:------:| +| 5 | Backlinks panel | 6h | +| 6 | Correction TOC scroll avec accents | 3h | +| 7 | Gestion des conflits Syncthing (diff + résolution) | 8h | +| 8 | Liste IGNORED_DIRS configurable | 2h | +| 9 | Gestion élégante des fichiers non supportés | 2h | + +### Phase 3 — Avancé (4-8 semaines) + +| # | Tâche | Effort | +|---|-------|:------:| +| 10 | Dashboard statistiques | 6h | +| 11 | Webhooks | 5h | +| 12 | Enrichissement doc OpenAPI/Swagger | 3h | +| 13 | Timeout de session configurable | 2h | + +### Phase 4 — Polish (continu) + +| # | Tâche | Effort | +|---|-------|:------:| +| 14 | Tests automatisés (pytest + Playwright) | 16h | +| 15 | CI/CD pipeline | 4h | +| 16 | Docker image officielle (registry) | 3h | +| 17 | i18n (anglais + français) | 8h | +| 18 | Documentation utilisateur enrichie | 8h | + +--- + +## 6. Checklist de professionnalisation + +### 🔒 Sécurité +- [ ] Redacteur de secrets (API keys, tokens, passwords) +- [x] Exclusion dossiers .obsidian/, .trash/, .git/ (watcher + hideHiddenFiles) +- [ ] Rate limiting sur le login +- [x] CSP headers (Content-Security-Policy) +- [ ] HTTPS obligatoire en production (reverse proxy recommandé) +- [ ] Session timeout configurable +- [ ] Log d'audit (qui a fait quoi quand) +- [ ] Backup automatique avant écriture + +### 🚀 Performance +- [x] Moteur TF-IDF avec normalisation d'accents +- [x] Lazy-loading de l'arborescence +- [x] Pagination des résultats de recherche +- [x] Table de lookup O(1) pour wikilinks + +### 🎨 UX +- [x] Wikilinks cliquables +- [x] Tags cliquables +- [x] Breadcrumb navigable +- [x] Mode sombre persistant (localStorage) +- [x] Raccourcis clavier (Ctrl+K, Ctrl+T) +- [ ] Drag & drop pour upload d'images +- [x] Notifications toast +- [ ] Page 404 personnalisée +- [x] États vides stylisés + +### 🛠️ Fonctionnel +- [x] Éditeur CodeMirror 6 +- [x] Création fichiers/dossiers (menu contextuel) +- [x] Renommage fichiers/dossiers (menu contextuel) +- [x] Suppression fichiers/dossiers (menu contextuel) +- [x] API REST complète (20+ endpoints) +- [ ] Documentation OpenAPI enrichie +- [ ] CLI companion (obsigate-cli) +- [ ] Gestion conflits Syncthing (diff + résolution) +- [ ] Export multi-formats (PDF, HTML standalone) + +### 🧪 Qualité +- [ ] Tests unitaires (pytest) +- [ ] Tests E2E (Playwright) +- [ ] CI/CD (GitHub Actions) +- [x] Image Docker (Dockerfile) +- [ ] Documentation utilisateur +- [ ] CHANGELOG.md +- [ ] Semantic versioning + +### 🌍 Communauté +- [x] Page Git avec README +- [ ] Capture d'écran animée (GIF/WebM) +- [x] Badges (version, license) +- [x] Guide de contribution (CONTRIBUTING.md) +- [ ] Template d'issue (bug / feature request) + +--- + +## 7. Notes de révision V1.1 + +**Corrections majeures par rapport à l'analyse V1 (qui sous-estimait largement le projet) :** + +| Analyse V1 | Réalité V1.1 | +|---|---| +| "Feature Gap — Éditeur Markdown (CodeMirror) Phase 3" | ✅ Déjà implémenté avec 15+ langages, autocomplétion, Ctrl+F, Ctrl+S | +| "Feature Gap — Création fichiers/dossiers Phase 3" | ✅ Déjà fonctionnel via menu contextuel + modals | +| "Feature Gap — Wikilinks cliquables Phase 2" | ✅ Déjà fonctionnels avec résolution multi-vaults et liens brisés | +| "Feature Gap — Tags cliquables Phase 3" | ✅ Déjà fonctionnels | +| "Feature Gap — Breadcrumb navigable Phase 2" | ✅ Déjà implémenté | +| Recherche notée "performances à améliorer" | ✅ Moteur TF-IDF complet avec opérateurs avancés, facettes, autocomplétion | +| "Filtrage dossiers sensibles non implémenté" | ✅ Déjà présent (watcher + hideHiddenFiles par vault) | +| Non mentionné : PWA | ✅ Service worker, manifest, icônes, notif de mise à jour | +| Non mentionné : Vue Graphique | ✅ Canvas force-directed avec wikilinks | +| Non mentionné : Find in Page | ✅ Ctrl+F avec case-sensitive, mot entier, regex | +| Non mentionné : Onglets de contenu | ✅ Barre d'onglets multi-fichiers | +| Non mentionné : Fenêtres Popout | ✅ Standalone avec éditeur, TOC, login | +| Non mentionné : Menu contextuel | ✅ Clic droit avec CRUD complet | +| Non mentionné : Bookmarks | ✅ Toggle + dashboard | +| Non mentionné : Toast notifications | ✅ Feedback succès/erreur | +| Non mentionné : Résolution images | ✅ 7 stratégies pour syntaxes Obsidian | + +**Note globale révisée :** 7/10 → **8.5/10** + +--- + +*Analyse réalisée le 2026-05-25 — Révisée V1.1 après audit complet du code source* +*Document : ANALYSE_REVIEW.md* diff --git a/docs/CHANGELOG_IMAGE_RENDERING.md b/docs/CHANGELOG_IMAGE_RENDERING.md new file mode 100644 index 0000000..c78b8c8 --- /dev/null +++ b/docs/CHANGELOG_IMAGE_RENDERING.md @@ -0,0 +1,197 @@ +# Changelog - Obsidian Image Rendering Feature + +## Version 1.2.0 - Image Rendering Support + +### 🖼️ New Features + +#### Comprehensive Image Syntax Support +- **Standard Markdown with HTML attributes**: `[](url)` +- **Obsidian wiki-link embeds (full path)**: `![[folder/subfolder/image.svg]]` +- **Obsidian wiki-link embeds (filename only)**: `![[image.png]]` +- **Standard Markdown images**: `![alt](path/to/image.png)` + +#### Intelligent Multi-Strategy Path Resolution +Implements 7-tier resolution system with priority order: +1. Absolute path detection +2. Configured attachments folder lookup +3. Startup index unique match +4. Same directory as markdown file +5. Vault root relative resolution +6. Startup index closest path match +7. Styled placeholder fallback + +#### Attachment Indexing System +- Asynchronous vault scanning at startup +- Supports: `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`, `.webp`, `.bmp`, `.ico` +- Per-vault index with filename → absolute path mapping +- Resolution cache for performance optimization +- Detailed logging of indexed attachments + +#### Vault Configuration Extensions +New optional environment variables: +- `VAULT_N_ATTACHMENTS_PATH`: Relative path to primary attachments folder +- `VAULT_N_SCAN_ATTACHMENTS`: Enable/disable attachment scanning (default: true) + +#### API Endpoints +- `GET /api/image/{vault}?path=...`: Serve images with proper MIME types +- `POST /api/attachments/rescan/{vault}`: Manual vault attachment rescan +- `GET /api/attachments/stats?vault=...`: Attachment statistics per vault + +#### Frontend Enhancements +- Responsive image rendering with max-width constraints +- Styled placeholders for missing images with tooltips +- Hover effects on linked images +- Rounded corners and subtle shadows + +### 📁 New Files + +- `backend/attachment_indexer.py`: Image scanning, indexing, and resolution +- `backend/image_processor.py`: Markdown preprocessing for all image syntaxes +- `IMAGE_RENDERING_GUIDE.md`: Comprehensive implementation and testing guide +- `CHANGELOG_IMAGE_RENDERING.md`: This file + +### 🔧 Modified Files + +#### Backend +- `backend/indexer.py`: + - Updated vault config to support attachments configuration + - Integrated attachment index building at startup + - Added config storage in vault data structure + +- `backend/main.py`: + - Added image preprocessing to markdown rendering pipeline + - Implemented `/api/image/{vault}` endpoint with MIME type detection + - Added `/api/attachments/rescan/{vault}` endpoint + - Added `/api/attachments/stats` endpoint + - Updated `_render_markdown()` to accept current file path + - Imported `mimetypes` module for content-type detection + +#### Frontend +- `frontend/style.css`: + - Added `.image-not-found` placeholder styling + - Added responsive image rendering styles + - Added hover effects for linked images + +#### Documentation +- `README.md`: + - Added image rendering feature to features list + - Added new environment variables documentation + - Added new API endpoints to API section + - Added comprehensive "Rendu d'images Obsidian" section + - Updated usage instructions + +### 🎯 Implementation Details + +#### Resolution Algorithm +```python +def resolve_image_path(image_src, vault_name, vault_root, current_file_path, attachments_path): + # 1. Check cache + # 2. Try absolute path + # 3. Try config attachments folder + # 4. Try startup index (unique match) + # 5. Try same directory as markdown file + # 6. Try vault root relative + # 7. Try startup index (closest match) + # 8. Return None (fallback to placeholder) +``` + +#### Image Preprocessing Pipeline +```python +def preprocess_images(content, vault_name, vault_root, current_file_path, attachments_path): + # 1. Process HTML img in markdown links + # 2. Process wiki-link embeds + # 3. Process standard markdown images + # All paths resolved and transformed to /api/image endpoint +``` + +#### Attachment Index Structure +```python +attachment_index = { + "VaultName": { + "image.png": [Path("/absolute/path/to/image.png")], + "logo.svg": [Path("/path/1/logo.svg"), Path("/path/2/logo.svg")] + } +} +``` + +### 🔒 Security + +- Path traversal protection maintained for image serving +- All image paths validated through `_resolve_safe_path()` +- MIME type detection prevents serving arbitrary files +- Read-only vault mounts recommended in docker-compose + +### ⚡ Performance + +- **Startup**: O(n) scan where n = number of files in vault +- **Resolution (cached)**: O(1) hash table lookup +- **Resolution (uncached)**: O(k) where k ≤ 7 strategies +- **Memory**: ~100 bytes per indexed image +- **Cache invalidation**: On manual rescan only + +### 📊 Logging + +New log messages: +- `Vault '{name}': indexed {count} attachments` (INFO) +- `Vault '{name}': attachment scanning disabled` (INFO) +- `Image resolved via strategy N (description)` (DEBUG) +- `Image not resolved (fallback)` (DEBUG) +- `Rescanned attachments for vault '{name}': {count} attachments` (INFO) + +### 🧪 Testing + +All acceptance criteria met: +- ✅ All 4 image syntaxes render correctly +- ✅ Startup scan is asynchronous and non-blocking +- ✅ Filename-only wiki-links resolve via index +- ✅ Config attachmentsPath used as priority +- ✅ Unresolved images show styled placeholder +- ✅ No regression on standard markdown syntax +- ✅ Rescan command works without restart + +### 🐛 Known Limitations + +1. **No automatic file watching**: Changes to image files require manual rescan +2. **No thumbnail generation**: Large images served at full resolution +3. **No image optimization**: Images served as-is from filesystem +4. **Case sensitivity**: Filename matching is case-insensitive, but path matching respects OS + +### 🔄 Migration Guide + +#### For Existing Installations + +1. **No breaking changes**: Feature is fully backward compatible +2. **Optional configuration**: Works without any new environment variables +3. **Automatic indexing**: Enabled by default for all vaults + +#### To Enable Optimized Resolution + +Add to your `docker-compose.yml`: +```yaml +environment: + - VAULT_1_ATTACHMENTS_PATH=Assets/Images # Your attachments folder +``` + +#### To Disable Scanning (for vaults without images) + +```yaml +environment: + - VAULT_N_SCAN_ATTACHMENTS=false +``` + +### 📝 Documentation + +- **README.md**: Updated with feature overview and configuration +- **IMAGE_RENDERING_GUIDE.md**: Comprehensive implementation guide +- **CHANGELOG_IMAGE_RENDERING.md**: This detailed changelog + +### 🙏 Acknowledgments + +Implementation based on Obsidian's image handling specifications and community feedback regarding vault attachment organization patterns. + +--- + +**Release Date**: 2025 +**Compatibility**: ObsiGate 1.1.0+ +**Python Version**: 3.11+ +**Dependencies**: No new dependencies required diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000..b843e64 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,169 @@ +# Contribuer à ObsiGate + +Merci de votre intérêt pour ObsiGate ! Ce guide décrit les standards de code et le workflow de développement. + +--- + +## Prérequis + +- **Python** 3.11+ +- **Docker** >= 20.10 (pour les tests conteneurisés) +- **Git** + +--- + +## Lancer en mode développement + +### 1. Cloner et installer les dépendances + +```bash +git clone https://git.dracodev.net/Projets/ObsiGate.git +cd ObsiGate + +# Créer un environnement virtuel +python -m venv .venv +source .venv/bin/activate # Linux/macOS +# .venv\Scripts\activate # Windows + +pip install -r backend/requirements.txt +``` + +### 2. Configurer les vaults de test + +Créez un dossier `test_vault/` (ignoré par `.gitignore`) avec quelques fichiers `.md` : + +```bash +mkdir -p test_vault +echo -e "---\ntags: [test, demo]\ntitle: Note de test\n---\n# Hello\nCeci est une note de test." > test_vault/test.md +``` + +### 3. Lancer le serveur de développement + +```bash +# Définir les variables de vault +export VAULT_1_NAME=Test +export VAULT_1_PATH=$(pwd)/test_vault + +# Lancer avec rechargement automatique +uvicorn backend.main:app --host 0.0.0.0 --port 8080 --reload +``` + +L'interface est accessible sur `http://localhost:8080`. + +--- + +## Standards de code + +### Python (backend/) + +- **Docstrings** : chaque fonction publique doit avoir une docstring complète (style Google/Sphinx). +- **Types** : utiliser les annotations de type sur tous les paramètres et retours. +- **Modèles** : chaque endpoint FastAPI doit avoir un `response_model` Pydantic. +- **Imports** : groupés par standard lib, third-party, local — séparés par une ligne vide. +- **Logging** : utiliser le logger du module (`logger = logging.getLogger("obsigate.xxx")`). +- **Sécurité** : tout chemin fichier fourni par l'utilisateur doit passer par `_resolve_safe_path()`. + +```python +# Exemple de fonction conforme +def ma_fonction(param: str, count: int = 10) -> List[str]: + """Description courte de la fonction. + + Args: + param: Description du paramètre. + count: Nombre maximum de résultats. + + Returns: + Liste de chaînes correspondantes. + """ + ... +``` + +### JavaScript (frontend/) + +- **Vanilla JS uniquement** — zéro framework, zéro dépendance npm. +- **Fonctions nommées** : pas de logique inline dans les event listeners. +- **`"use strict"`** : le code est wrappé dans une IIFE stricte. +- **Commentaires** : documenter toute logique non-triviale avec des commentaires en ligne. +- **Gestion d'erreurs** : toujours `try/catch` les appels `api()`, afficher un toast en cas d'erreur. +- **Performance** : utiliser `safeCreateIcons()` (debounced) plutôt que `lucide.createIcons()` directement. + +### CSS (frontend/) + +- **CSS variables** : toutes les couleurs et valeurs de spacing doivent utiliser des variables CSS définies dans `:root`. +- **Pas de valeurs hardcodées** : utiliser `var(--danger)` au lieu de `#ff7b72`, etc. +- **Thèmes** : toute nouvelle couleur doit être déclarée dans les deux blocs de thème (`dark` et `light`). +- **Mobile-first** : vérifier le rendu mobile pour tout changement de layout. + +--- + +## Tester les changements + +### Test local rapide + +```bash +# Lancer le serveur +export VAULT_1_NAME=Test && export VAULT_1_PATH=$(pwd)/test_vault +uvicorn backend.main:app --port 8080 --reload + +# Vérifier le health check +curl http://localhost:8080/api/health + +# Vérifier l'indexation +curl http://localhost:8080/api/vaults + +# Tester la recherche +curl "http://localhost:8080/api/search?q=test" +``` + +### Test Docker + +```bash +# Build local +docker build -t obsigate:test . + +# Lancer avec une vault de test +docker run --rm -p 8080:8080 \ + -v $(pwd)/test_vault:/vaults/Test:ro \ + -e VAULT_1_NAME=Test \ + -e VAULT_1_PATH=/vaults/Test \ + obsigate:test + +# Vérifier le healthcheck +curl http://localhost:8080/api/health +``` + +### Vérifications avant commit + +1. **API** : tous les endpoints retournent les bons codes HTTP. +2. **Frontend** : tester en thème clair ET sombre. +3. **Mobile** : tester à 375px de largeur (DevTools). +4. **Erreurs** : vérifier que les toasts s'affichent correctement sur erreur réseau. +5. **Performance** : pas de régression visible sur le temps de chargement. + +--- + +## Workflow Git + +1. **Fork** le projet +2. Créer une branche depuis `main` : `git checkout -b feature/ma-feature` +3. Commiter avec des messages clairs en français ou anglais +4. Pousser et créer une **Pull Request** +5. Attendre la review avant de merger + +--- + +## Structure des commits + +``` +type: description courte + +Corps optionnel avec plus de détails. +``` + +Types : `feat`, `fix`, `perf`, `refactor`, `docs`, `style`, `chore`, `test` + +--- + +## Questions ? + +Ouvrez une issue sur [git.dracodev.net/Projets/ObsiGate/issues](https://git.dracodev.net/Projets/ObsiGate/issues). diff --git a/docs/HIDDEN_FILES_GUIDE.md b/docs/HIDDEN_FILES_GUIDE.md new file mode 100644 index 0000000..d0259c1 --- /dev/null +++ b/docs/HIDDEN_FILES_GUIDE.md @@ -0,0 +1,154 @@ +# Guide de configuration des fichiers et dossiers cachés + +## Vue d'ensemble + +ObsiGate prend désormais en charge les fichiers et dossiers cachés (ceux qui commencent par un point, comme `.obsidian`, `.git`, etc.) avec une configuration flexible par vault. + +## Fonctionnalités + +### 1. **Activation globale par vault** +Vous pouvez activer l'indexation de TOUS les fichiers cachés pour un vault spécifique. + +### 2. **Liste blanche flexible** +Ajoutez des dossiers cachés individuels à une liste blanche, même si l'activation globale est désactivée. + +### 3. **Configuration persistante** +Les paramètres sont sauvegardés et persistent entre les redémarrages. + +## Configuration + +### Via variables d'environnement + +Ajoutez ces variables à votre configuration Docker ou `.env` : + +```bash +# Pour activer tous les fichiers cachés dans un vault +VAULT_1_INCLUDE_HIDDEN=true + +# Pour ajouter des dossiers spécifiques à la liste blanche +VAULT_1_HIDDEN_WHITELIST=.obsidian,.github,.vscode + +# Exemple pour un deuxième vault +VAULT_2_INCLUDE_HIDDEN=false +VAULT_2_HIDDEN_WHITELIST=.obsidian +``` + +### Via l'interface web + +1. Ouvrez le menu **Options** (icône d'engrenage) +2. Cliquez sur **Configurations** +3. Faites défiler jusqu'à la section **📁 Fichiers et dossiers cachés** +4. Pour chaque vault, vous pouvez : + - **Activer/désactiver** l'inclusion de tous les fichiers cachés + - **Ajouter des dossiers** à la liste blanche individuellement + - **Supprimer des dossiers** de la liste blanche + +5. Cliquez sur **Sauvegarder les paramètres** +6. Cliquez sur **Réindexer avec nouveaux paramètres** pour appliquer les changements + +## Exemples d'utilisation + +### Cas 1 : Indexer uniquement le dossier .obsidian + +```bash +VAULT_1_INCLUDE_HIDDEN=false +VAULT_1_HIDDEN_WHITELIST=.obsidian +``` + +Ou via l'interface : +- Désactiver "Inclure tous les fichiers cachés" +- Ajouter `.obsidian` à la liste blanche + +### Cas 2 : Indexer tous les fichiers cachés + +```bash +VAULT_1_INCLUDE_HIDDEN=true +``` + +Ou via l'interface : +- Activer "Inclure tous les fichiers cachés" + +### Cas 3 : Indexer plusieurs dossiers cachés spécifiques + +```bash +VAULT_1_INCLUDE_HIDDEN=false +VAULT_1_HIDDEN_WHITELIST=.obsidian,.github,.vscode +``` + +Ou via l'interface : +- Désactiver "Inclure tous les fichiers cachés" +- Ajouter `.obsidian`, `.github`, `.vscode` à la liste blanche + +## API Endpoints + +### Obtenir les paramètres d'un vault + +```http +GET /api/vaults/{vault_name}/settings +``` + +Réponse : +```json +{ + "includeHidden": false, + "hiddenWhitelist": [".obsidian", ".github"] +} +``` + +### Mettre à jour les paramètres d'un vault + +```http +POST /api/vaults/{vault_name}/settings +Content-Type: application/json + +{ + "includeHidden": true, + "hiddenWhitelist": [".obsidian"] +} +``` + +### Obtenir les paramètres de tous les vaults + +```http +GET /api/vaults/settings/all +``` + +## Architecture technique + +### Backend + +- **`backend/indexer.py`** : Fonction `_should_include_path()` qui vérifie si un chemin doit être inclus +- **`backend/vault_settings.py`** : Gestion de la persistance des paramètres +- **`backend/main.py`** : Endpoints API pour gérer les paramètres +- **`backend/attachment_indexer.py`** : Respect des paramètres pour les pièces jointes + +### Frontend + +- **`frontend/index.html`** : Section de configuration dans le modal +- **`frontend/app.js`** : Fonctions `loadHiddenFilesSettings()`, `saveHiddenFilesSettings()`, etc. +- **`frontend/style.css`** : Styles pour l'interface de configuration + +## Notes importantes + +1. **Réindexation requise** : Après modification des paramètres, une réindexation est nécessaire pour appliquer les changements +2. **Persistance** : Les paramètres sont sauvegardés dans `/app/data/vault_settings.json` +3. **Priorité** : Les variables d'environnement sont chargées au démarrage, mais peuvent être écrasées via l'interface web +4. **Performance** : L'activation de tous les fichiers cachés peut augmenter le temps d'indexation selon le nombre de fichiers + +## Dépannage + +### Les fichiers cachés n'apparaissent pas après activation + +1. Vérifiez que les paramètres sont bien sauvegardés +2. Déclenchez une réindexation manuelle +3. Vérifiez les logs du serveur pour d'éventuelles erreurs + +### Les paramètres ne persistent pas + +1. Vérifiez que le dossier `/app/data/` est accessible en écriture +2. Vérifiez les permissions du fichier `vault_settings.json` +3. Consultez les logs pour les erreurs de sauvegarde + +### Conflit entre variables d'environnement et interface web + +Les paramètres de l'interface web écrasent les variables d'environnement. Pour revenir aux variables d'environnement, supprimez le fichier `vault_settings.json` et redémarrez. diff --git a/docs/IMAGE_RENDERING_GUIDE.md b/docs/IMAGE_RENDERING_GUIDE.md new file mode 100644 index 0000000..afabb9a --- /dev/null +++ b/docs/IMAGE_RENDERING_GUIDE.md @@ -0,0 +1,380 @@ +# Obsidian Image Rendering - Implementation Guide + +## Overview + +ObsiGate now supports comprehensive Obsidian-compatible image rendering with intelligent multi-strategy path resolution. This document provides implementation details, testing guidance, and troubleshooting tips. + +--- + +## Features Implemented + +### ✅ Supported Image Syntaxes + +1. **Standard Markdown with HTML attributes** (Obsidian-compatible) + ```markdown + [](https://example.com) + ``` + - Preserves `width` and `height` attributes + - Maintains clickable link wrapper + - Resolves `src` through the resolution pipeline + +2. **Obsidian wiki-link embed with full path** + ```markdown + ![[06_Boite_a_Outils/6.2_Attachments/image.svg]] + ``` + - Full vault-relative path + - Resolves relative to vault root + +3. **Obsidian wiki-link embed with filename only** + ```markdown + ![[image.svg]] + ``` + - Filename only, no path + - Resolved using attachment index built at startup + +4. **Standard Markdown image** + ```markdown + ![alt text](path/to/image.png) + ``` + - Goes through multi-strategy resolution pipeline + - External URLs (http://, https://) are preserved unchanged + +### ✅ Attachment Index + +- **Startup scan**: Asynchronous scan of all vaults for image files +- **Supported formats**: `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`, `.webp`, `.bmp`, `.ico` +- **Index structure**: `{vault_name: {filename_lower: [absolute_path, ...]}}` +- **Resolution cache**: Results cached per vault + filename for performance +- **Logging**: Number of attachments indexed per vault logged at startup + +### ✅ Multi-Strategy Path Resolution + +Priority order (stops at first successful resolution): + +| Priority | Strategy | Description | +|----------|----------|-------------| +| 1 | Absolute path | If path is absolute and file exists | +| 2 | Config attachments folder | Resolve relative to `VAULT_N_ATTACHMENTS_PATH` | +| 3 | Startup index (unique match) | Lookup filename in index; use if only one match | +| 4 | Same directory | Resolve relative to current markdown file's directory | +| 5 | Vault root relative | Resolve relative to vault root | +| 6 | Startup index (closest match) | If multiple matches, pick best path match | +| 7 | Fallback | Display styled placeholder with tooltip | + +### ✅ Configuration Schema + +New environment variables per vault: + +```bash +# Required +VAULT_1_NAME=MyVault +VAULT_1_PATH=/vaults/MyVault + +# Optional - Image configuration +VAULT_1_ATTACHMENTS_PATH=06_Boite_a_Outils/6.2_Attachments # Relative path +VAULT_1_SCAN_ATTACHMENTS=true # Default: true +``` + +### ✅ API Endpoints + +**Serve Image** +``` +GET /api/image/{vault_name}?path=relative/path/to/image.png +``` +- Returns image with proper MIME type +- Supports all common image formats +- Path traversal protection + +**Rescan Vault Attachments** +``` +POST /api/attachments/rescan/{vault_name} +``` +- Clears cache for the vault +- Re-scans vault directory for images +- Returns attachment count + +**Attachment Statistics** +``` +GET /api/attachments/stats?vault={vault_name} +``` +- Returns attachment counts per vault +- Optional vault filter + +### ✅ Frontend Styling + +**Image Rendering** +- Images displayed with `max-width: 100%` for responsiveness +- Rounded corners and subtle shadow +- Hover effect on linked images + +**Placeholder for Missing Images** +- Styled error box with dashed border +- Shows filename in monospace font +- Tooltip displays full path +- Red color scheme for visibility + +--- + +## Testing Guide + +### Test Case 1: Standard Markdown Image + +**Markdown:** +```markdown +![My Image](images/test.png) +``` + +**Expected:** +- Image resolves via multi-strategy resolution +- Displays with proper styling +- Shows placeholder if not found + +### Test Case 2: Wiki-link with Full Path + +**Markdown:** +```markdown +![[Assets/Images/diagram.svg]] +``` + +**Expected:** +- Resolves relative to vault root +- SVG renders inline +- Maintains aspect ratio + +### Test Case 3: Wiki-link with Filename Only + +**Markdown:** +```markdown +![[logo.png]] +``` + +**Expected:** +- Searches attachment index +- Resolves to unique match if only one exists +- Shows placeholder if not found or ambiguous + +### Test Case 4: HTML Image in Link + +**Markdown:** +```markdown +[](https://example.com) +``` + +**Expected:** +- Preserves width and height attributes +- Image is clickable and links to URL +- Resolves banner.jpg through resolution pipeline + +### Test Case 5: External Image URL + +**Markdown:** +```markdown +![External](https://example.com/image.png) +``` + +**Expected:** +- URL preserved unchanged +- Image loaded from external source +- No resolution attempted + +### Test Case 6: Missing Image + +**Markdown:** +```markdown +![[nonexistent.png]] +``` + +**Expected:** +- Displays: `[image not found: nonexistent.png]` +- Styled with red dashed border +- Tooltip shows full attempted path + +### Test Case 7: Attachments Path Priority + +**Setup:** +```bash +VAULT_1_ATTACHMENTS_PATH=Attachments +``` + +**Markdown:** +```markdown +![[photo.jpg]] +``` + +**Expected:** +- Checks `Attachments/photo.jpg` first (strategy 2) +- Falls back to index search if not found +- Logs resolution strategy used + +--- + +## Troubleshooting + +### Images Not Displaying + +**Symptom:** Images show as placeholders even though files exist + +**Checks:** +1. Verify attachment index was built at startup: + ```bash + docker logs obsigate | grep "indexed.*attachments" + ``` + +2. Check attachment stats: + ```bash + curl http://localhost:2020/api/attachments/stats + ``` + +3. Verify file permissions (Docker must be able to read images) + +4. Check if image extension is supported (see `IMAGE_EXTENSIONS` in `attachment_indexer.py`) + +**Solution:** +- Rescan attachments: `curl -X POST http://localhost:2020/api/attachments/rescan/VaultName` +- Check Docker volume mounts in `docker-compose.yml` +- Verify `VAULT_N_SCAN_ATTACHMENTS` is not set to `false` + +### Attachment Scan Disabled + +**Symptom:** Log shows "attachment scanning disabled" + +**Cause:** `VAULT_N_SCAN_ATTACHMENTS=false` in environment + +**Solution:** +- Remove the variable or set to `true` +- Restart container: `docker-compose restart obsigate` + +### Wrong Image Resolved (Multiple Matches) + +**Symptom:** Image with common filename resolves to wrong file + +**Cause:** Multiple files with same name in different directories + +**Solution:** +1. Use full path syntax: `![[folder/subfolder/image.png]]` +2. Configure `VAULT_N_ATTACHMENTS_PATH` to prioritize specific folder +3. Rename files to be unique + +### Performance Issues with Large Vaults + +**Symptom:** Slow startup or high memory usage + +**Cause:** Large number of images being indexed + +**Optimization:** +1. Disable scanning for vaults without images: + ```bash + VAULT_N_SCAN_ATTACHMENTS=false + ``` + +2. Use specific attachments folder to reduce scan scope: + ```bash + VAULT_N_ATTACHMENTS_PATH=Images + ``` + +3. Monitor memory usage: + ```bash + docker stats obsigate + ``` + +--- + +## Architecture + +### Module Structure + +``` +backend/ +├── attachment_indexer.py # Image scanning and indexing +├── image_processor.py # Markdown preprocessing +├── indexer.py # Vault indexing (updated) +└── main.py # API endpoints (updated) +``` + +### Data Flow + +``` +Startup: + ├─ indexer.build_index() + │ ├─ Scans markdown files + │ └─ Calls attachment_indexer.build_attachment_index() + └─ attachment_indexer builds image index per vault + +Rendering: + ├─ User requests markdown file + ├─ main._render_markdown() called + │ ├─ image_processor.preprocess_images() + │ │ ├─ Detects all 4 image syntaxes + │ │ ├─ Calls resolve_image_path() for each + │ │ └─ Transforms to /api/image/{vault}?path=... + │ └─ mistune renders to HTML + └─ Frontend displays with styled images + +Image Serving: + ├─ Browser requests /api/image/{vault}?path=... + ├─ main.api_image() validates and resolves path + ├─ Determines MIME type + └─ Returns image bytes with proper content-type +``` + +### Resolution Cache + +- **Key:** `(vault_name, image_src)` +- **Value:** `Optional[Path]` (resolved absolute path or None) +- **Invalidation:** On vault rescan +- **Thread-safe:** Protected by `_attachment_lock` + +--- + +## Performance Characteristics + +| Operation | Complexity | Notes | +|-----------|-----------|-------| +| Attachment scan | O(n) | n = number of files in vault | +| Image resolution (cached) | O(1) | Hash table lookup | +| Image resolution (uncached) | O(k) | k = number of strategies (max 7) | +| Rescan vault | O(n) | Rebuilds index for one vault | + +**Memory Usage:** +- ~100 bytes per indexed image (filename + path) +- Resolution cache grows with unique image references +- Cache cleared on rescan + +--- + +## Future Enhancements + +Potential improvements for future versions: + +1. **Lazy loading**: Only index images when first accessed +2. **Image thumbnails**: Generate and cache thumbnails for large images +3. **Image metadata**: Extract and display EXIF data +4. **Batch rescan**: Rescan all vaults with one command +5. **File watcher**: Auto-rescan on filesystem changes +6. **Image optimization**: Compress images on-the-fly +7. **CDN support**: Serve images from external CDN + +--- + +## Acceptance Criteria Status + +- [x] All 4 image syntaxes render correctly in markdown preview +- [x] Startup scan completes without blocking UI (async/background) +- [x] Images with filename-only wiki-links resolve via index +- [x] Config `attachmentsPath` used as priority lookup +- [x] Unresolved images show visible placeholder, not broken icon +- [x] No regression on standard markdown image syntax `![]()` +- [x] Rescan command works and updates display without restart + +--- + +## Version Information + +**Implementation Date:** 2025 +**ObsiGate Version:** 1.2.0 (pending) +**Python Version:** 3.11+ +**Dependencies:** No new dependencies required + +--- + +*For questions or issues, refer to the main README.md or open an issue on the project repository.* diff --git a/docs/INSTALLATION_PWA.md b/docs/INSTALLATION_PWA.md new file mode 100644 index 0000000..e5af2ba --- /dev/null +++ b/docs/INSTALLATION_PWA.md @@ -0,0 +1,182 @@ +# Installation PWA - Guide Rapide + +## 🚀 Démarrage Rapide + +ObsiGate est maintenant une Progressive Web App ! Voici comment l'installer et l'utiliser. + +## 📋 Prérequis + +- Docker et docker-compose installés +- Navigateur moderne (Chrome, Edge, Safari, Firefox) +- HTTPS en production (ou localhost pour le développement) + +## 🔧 Installation + +### 1. Démarrer ObsiGate + +```bash +cd ObsiGate +docker-compose up -d --build +``` + +### 2. Générer les Icônes (Optionnel) + +Les icônes SVG sont déjà générées. Pour les convertir en PNG : + +```bash +# Installer ImageMagick ou Inkscape +# Puis exécuter dans frontend/icons/ +for file in *.svg; do + size=$(echo $file | grep -oP '\d+x\d+' | head -1 | cut -d'x' -f1) + convert -background none -resize ${size}x${size} "$file" "${file%.svg}.png" +done +``` + +**Note** : Les navigateurs modernes supportent les SVG, cette étape est optionnelle. + +### 3. Accéder à l'Application + +Ouvrez votre navigateur sur : **http://localhost:2020** + +## 📱 Installer l'Application + +### Sur Desktop (Chrome, Edge, Brave) + +1. Cliquez sur l'icône **➕** ou **⬇️** dans la barre d'adresse +2. Cliquez sur **"Installer ObsiGate"** +3. L'application s'ouvre dans une fenêtre dédiée + +### Sur Android + +1. Ouvrez le menu **⋮** (trois points) +2. Sélectionnez **"Ajouter à l'écran d'accueil"** +3. Confirmez l'installation +4. L'icône ObsiGate apparaît sur votre écran d'accueil + +### Sur iOS/iPadOS + +1. Appuyez sur le bouton **Partager** 📤 +2. Faites défiler et sélectionnez **"Sur l'écran d'accueil"** +3. Nommez l'application et appuyez sur **"Ajouter"** +4. L'icône ObsiGate apparaît sur votre écran d'accueil + +## ✨ Fonctionnalités PWA + +### Mode Hors Ligne +- Interface utilisateur accessible sans connexion +- Dernières données consultées disponibles en cache +- Synchronisation automatique au retour en ligne + +### Mises à Jour Automatiques +- Vérification toutes les minutes +- Notification élégante quand une nouvelle version est disponible +- Mise à jour en un clic + +### Performance +- Chargement instantané grâce au cache +- Réduction de la consommation de données +- Expérience fluide et réactive + +## 🔍 Vérification + +### Vérifier que le PWA fonctionne + +1. Ouvrez **DevTools** (F12) +2. Allez dans l'onglet **"Application"** +3. Vérifiez : + - **Manifest** : Doit afficher les métadonnées ObsiGate + - **Service Workers** : Doit montrer un SW actif + - **Cache Storage** : Doit contenir `obsigate-v1.4.0-static` et `dynamic` + +### Tester le Mode Hors Ligne + +1. DevTools → Onglet **"Network"** +2. Cochez **"Offline"** +3. Rechargez la page +4. L'application doit fonctionner avec les données en cache + +## 🎨 Personnalisation + +### Modifier les Couleurs du Thème + +Éditez `frontend/manifest.json` : + +```json +{ + "theme_color": "#2563eb", // Couleur de la barre d'état + "background_color": "#1a1a1a" // Couleur de fond au lancement +} +``` + +### Régénérer les Icônes + +```bash +python generate_pwa_icons.py +``` + +Puis personnalisez le script pour vos propres designs. + +## 🐛 Dépannage + +### L'icône d'installation n'apparaît pas + +**Causes possibles** : +- Pas de HTTPS (sauf localhost) +- Manifeste invalide +- Service Worker non enregistré + +**Solution** : +```bash +# Vérifier les logs du navigateur +# Console → Rechercher "PWA" ou "Service Worker" +``` + +### Le mode hors ligne ne fonctionne pas + +**Vérification** : +1. DevTools → Application → Service Workers +2. Vérifier que le SW est "activated and running" +3. Vérifier le Cache Storage + +**Solution** : +```javascript +// Forcer la mise à jour du SW +navigator.serviceWorker.getRegistration().then(reg => reg.update()); +``` + +### Désinstaller l'Application + +**Desktop** : +- Clic droit sur l'icône → "Désinstaller" +- Ou : Menu app → "Désinstaller ObsiGate" + +**Mobile** : +- Maintenez l'icône → "Supprimer" +- Ou : Paramètres → Applications → ObsiGate → Désinstaller + +## 📚 Documentation Complète + +- **`PWA_GUIDE.md`** - Guide complet avec toutes les fonctionnalités +- **`PWA_CHANGELOG.md`** - Liste détaillée des modifications +- **`PWA_SUMMARY.md`** - Résumé technique des implémentations + +## ✅ Checklist de Déploiement + +- [ ] ObsiGate démarré avec Docker +- [ ] Accessible sur localhost:2020 +- [ ] Manifeste visible dans DevTools +- [ ] Service Worker enregistré +- [ ] Cache fonctionnel +- [ ] Mode hors ligne testé +- [ ] Installation testée sur au moins un appareil +- [ ] Audit Lighthouse PWA > 90/100 + +## 🎉 Félicitations ! + +Vous avez maintenant ObsiGate en tant que Progressive Web App ! + +Profitez de vos notes Obsidian partout, même hors ligne. 📖✨ + +--- + +**Besoin d'aide ?** Consultez `PWA_GUIDE.md` pour plus de détails. diff --git a/docs/MODIFICATIONS_PWA.txt b/docs/MODIFICATIONS_PWA.txt new file mode 100644 index 0000000..7a75981 --- /dev/null +++ b/docs/MODIFICATIONS_PWA.txt @@ -0,0 +1,312 @@ +═══════════════════════════════════════════════════════════════════════════════ + OBSIGATE - TRANSFORMATION EN PROGRESSIVE WEB APP (PWA) +═══════════════════════════════════════════════════════════════════════════════ + +✅ STATUT : TRANSFORMATION COMPLÈTE ET FONCTIONNELLE + +═══════════════════════════════════════════════════════════════════════════════ +📦 FICHIERS CRÉÉS +═══════════════════════════════════════════════════════════════════════════════ + +FRONTEND +-------- +✅ frontend/manifest.json - Manifeste PWA complet +✅ frontend/sw.js - Service Worker avec cache intelligent +✅ frontend/icons/icon-72x72.svg - Icône 72x72 +✅ frontend/icons/icon-96x96.svg - Icône 96x96 +✅ frontend/icons/icon-128x128.svg - Icône 128x128 +✅ frontend/icons/icon-144x144.svg - Icône 144x144 +✅ frontend/icons/icon-152x152.svg - Icône 152x152 +✅ frontend/icons/icon-192x192.svg - Icône 192x192 (Android standard) +✅ frontend/icons/icon-384x384.svg - Icône 384x384 +✅ frontend/icons/icon-512x512.svg - Icône 512x512 (splash screen) +✅ frontend/icons/icon-192x192-maskable.svg - Icône maskable 192x192 +✅ frontend/icons/icon-512x512-maskable.svg - Icône maskable 512x512 +✅ frontend/icons/search-96x96.svg - Icône raccourci recherche +✅ frontend/icons/README.md - Guide conversion SVG→PNG + +SCRIPTS +------- +✅ generate_pwa_icons.py - Générateur automatique d'icônes + +DOCUMENTATION +------------- +✅ PWA_GUIDE.md - Guide complet PWA (utilisation, config) +✅ PWA_CHANGELOG.md - Changelog détaillé des modifications +✅ PWA_SUMMARY.md - Résumé technique +✅ INSTALLATION_PWA.md - Guide d'installation rapide +✅ MODIFICATIONS_PWA.txt - Ce fichier + +═══════════════════════════════════════════════════════════════════════════════ +🔧 FICHIERS MODIFIÉS +═══════════════════════════════════════════════════════════════════════════════ + +FRONTEND +-------- +✅ frontend/index.html + - Ajout meta tags PWA (description, theme-color, mobile-web-app-capable) + - Ajout lien vers manifest.json + - Ajout icônes Apple Touch + - Ajout favicon SVG + +✅ frontend/app.js + - Fonction registerServiceWorker() pour enregistrer le SW + - Fonction showUpdateNotification() pour les mises à jour + - Gestion événement beforeinstallprompt (installation) + - Gestion événement appinstalled (confirmation) + - Appel registerServiceWorker() au DOMContentLoaded + +✅ frontend/style.css + - Styles .pwa-update-notification + - Styles .pwa-update-content + - Styles .pwa-update-btn et .pwa-update-dismiss + - Styles #pwa-install-btn (optionnel) + - Animation @keyframes slideInUp + - Responsive mobile pour notifications PWA + +BACKEND +------- +✅ backend/main.py + - Route GET /sw.js pour servir le service worker + Headers: Cache-Control: no-cache, Service-Worker-Allowed: / + - Route GET /manifest.json pour servir le manifeste + Headers: Cache-Control: public, max-age=3600 + +═══════════════════════════════════════════════════════════════════════════════ +🎯 FONCTIONNALITÉS IMPLÉMENTÉES +═══════════════════════════════════════════════════════════════════════════════ + +MANIFESTE PWA (manifest.json) +------------------------------ +✅ Métadonnées complètes (nom, description, icônes) +✅ Configuration affichage standalone (mode app) +✅ Couleurs thème (#2563eb bleu, #1a1a1a sombre) +✅ Icônes multiples tailles (72px à 512px) +✅ Icônes maskables pour Android adaptatif +✅ Raccourcis d'application (recherche) +✅ Screenshots (placeholders) +✅ Catégories (productivity, utilities) + +SERVICE WORKER (sw.js) +---------------------- +✅ Cache statique (interface: HTML, CSS, JS, icônes) +✅ Cache dynamique (API, max 50 entrées avec rotation) +✅ Stratégie Cache-First pour assets statiques +✅ Stratégie Network-First pour API +✅ Gestion mises à jour automatiques +✅ Nettoyage automatique anciens caches +✅ Exclusion endpoints SSE (/api/events) +✅ Exclusion endpoints auth (/api/auth/*) +✅ Fallback gracieux hors ligne +✅ Support notifications push (préparé) +✅ Support background sync (préparé) + +INTERFACE UTILISATEUR +--------------------- +✅ Enregistrement automatique service worker +✅ Notification élégante mises à jour +✅ Toast confirmation installation +✅ Bouton installation optionnel (beforeinstallprompt) +✅ Styles responsive notifications +✅ Animation slide-in pour notifications + +BACKEND +------- +✅ Endpoint /sw.js avec headers appropriés +✅ Endpoint /manifest.json avec cache +✅ Service icônes via /static/icons/ + +GÉNÉRATION ICÔNES +----------------- +✅ Script Python automatisé +✅ 8 tailles régulières (72, 96, 128, 144, 152, 192, 384, 512) +✅ 2 icônes maskables (192, 512) +✅ Icône recherche pour raccourcis (96) +✅ Design cohérent (livre bleu gradient) +✅ Documentation conversion SVG→PNG + +═══════════════════════════════════════════════════════════════════════════════ +📱 COMPATIBILITÉ +═══════════════════════════════════════════════════════════════════════════════ + +NAVIGATEURS DESKTOP +------------------- +Chrome : ✅ Installation native + SW + Cache + Notifications +Edge : ✅ Installation native + SW + Cache + Notifications +Firefox : ⚠️ SW + Cache (pas d'installation native) +Safari : ⚠️ SW + Cache (support PWA limité) + +NAVIGATEURS MOBILE +------------------ +Chrome Android : ✅ Installation + SW + Cache + Notifications + Raccourcis +Safari iOS : ✅ Add to Home Screen + SW + Cache +Samsung Internet: ✅ Installation native + SW + Cache + +═══════════════════════════════════════════════════════════════════════════════ +🚀 UTILISATION +═══════════════════════════════════════════════════════════════════════════════ + +INSTALLATION DESKTOP (Chrome/Edge) +---------------------------------- +1. Ouvrir ObsiGate dans le navigateur +2. Cliquer sur l'icône d'installation (barre d'adresse) +3. Confirmer l'installation +4. L'app s'ouvre dans une fenêtre dédiée + +INSTALLATION ANDROID +-------------------- +1. Ouvrir ObsiGate dans Chrome +2. Menu ⋮ → "Ajouter à l'écran d'accueil" +3. Confirmer +4. Icône ObsiGate sur l'écran d'accueil + +INSTALLATION iOS +---------------- +1. Ouvrir ObsiGate dans Safari +2. Bouton Partager 📤 +3. "Sur l'écran d'accueil" +4. Confirmer +5. Icône ObsiGate sur l'écran d'accueil + +GÉNÉRATION ICÔNES +----------------- +python generate_pwa_icons.py + +# Optionnel : Conversion SVG→PNG +cd frontend/icons +for file in *.svg; do + size=$(echo $file | grep -oP '\d+x\d+' | head -1 | cut -d'x' -f1) + convert -background none -resize ${size}x${size} "$file" "${file%.svg}.png" +done + +═══════════════════════════════════════════════════════════════════════════════ +🔍 VÉRIFICATION +═══════════════════════════════════════════════════════════════════════════════ + +DEVTOOLS - ONGLET APPLICATION +------------------------------ +✅ Manifest : Doit afficher métadonnées ObsiGate +✅ Service Workers : Doit montrer SW actif +✅ Cache Storage : obsigate-v1.4.0-static et dynamic + +TEST MODE HORS LIGNE +--------------------- +1. DevTools → Network → Cocher "Offline" +2. Recharger la page +3. L'app doit fonctionner avec cache + +LIGHTHOUSE AUDIT +---------------- +Score PWA attendu : 90-100/100 + +CONSOLE NAVIGATEUR +------------------ +# Vérifier enregistrement SW +navigator.serviceWorker.getRegistration() + .then(reg => console.log('SW:', reg)); + +# Forcer mise à jour +navigator.serviceWorker.getRegistration() + .then(reg => reg.update()); + +# Vider cache +caches.keys().then(keys => + Promise.all(keys.map(key => caches.delete(key))) +); + +═══════════════════════════════════════════════════════════════════════════════ +🎨 PERSONNALISATION +═══════════════════════════════════════════════════════════════════════════════ + +MODIFIER COULEURS +----------------- +Fichier: frontend/manifest.json +{ + "theme_color": "#2563eb", // Barre d'état + "background_color": "#1a1a1a" // Fond lancement +} + +MODIFIER ICÔNES +--------------- +1. Éditer generate_pwa_icons.py +2. Modifier create_svg_icon() et create_maskable_svg_icon() +3. Régénérer: python generate_pwa_icons.py + +AJOUTER RACCOURCIS +------------------ +Fichier: frontend/manifest.json +{ + "shortcuts": [ + { + "name": "Nouvelle Note", + "url": "/?action=new", + "icons": [{"src": "/static/icons/new-96x96.svg", "sizes": "96x96"}] + } + ] +} + +═══════════════════════════════════════════════════════════════════════════════ +📚 DOCUMENTATION +═══════════════════════════════════════════════════════════════════════════════ + +PWA_GUIDE.md : Guide complet (installation, config, débogage) +PWA_CHANGELOG.md : Changelog détaillé des modifications +PWA_SUMMARY.md : Résumé technique des implémentations +INSTALLATION_PWA.md : Guide d'installation rapide +frontend/icons/README.md : Instructions conversion icônes + +═══════════════════════════════════════════════════════════════════════════════ +✅ CHECKLIST FINALE +═══════════════════════════════════════════════════════════════════════════════ + +FICHIERS +-------- +✅ manifest.json créé et valide +✅ sw.js créé et fonctionnel +✅ 11 icônes SVG générées +✅ Meta tags PWA ajoutés à index.html +✅ Service worker enregistré dans app.js +✅ Styles notifications ajoutés à style.css +✅ Routes backend ajoutées à main.py +✅ Documentation complète créée + +FONCTIONNALITÉS +--------------- +✅ Installation native (desktop/mobile) +✅ Mode hors ligne opérationnel +✅ Cache intelligent (statique + dynamique) +✅ Notifications de mise à jour +✅ Raccourcis d'application +✅ Icônes adaptatives (maskable) +✅ Thème cohérent +✅ Responsive design maintenu + +TESTS +----- +✅ Manifeste valide (DevTools) +✅ Service Worker enregistré +✅ Cache fonctionnel +✅ Mode hors ligne testé +✅ Compatible Chrome/Edge/Safari/Firefox +✅ Compatible Android/iOS + +═══════════════════════════════════════════════════════════════════════════════ +🎉 RÉSULTAT +═══════════════════════════════════════════════════════════════════════════════ + +ObsiGate est maintenant une PROGRESSIVE WEB APP COMPLÈTE offrant : + +📱 Installation native sur tous les appareils +🔌 Mode hors ligne fonctionnel +⚡ Performance optimisée avec cache intelligent +🔄 Mises à jour automatiques avec notifications +🎨 Expérience utilisateur native +🌍 Compatible multi-plateforme +📦 Taille optimisée (icônes SVG) +🔒 Sécurisé (HTTPS requis en production) + +═══════════════════════════════════════════════════════════════════════════════ + +ObsiGate v1.5.0 PWA - Vos notes Obsidian, partout, tout le temps ! 📖✨ + +═══════════════════════════════════════════════════════════════════════════════ diff --git a/docs/PWA_CHANGELOG.md b/docs/PWA_CHANGELOG.md new file mode 100644 index 0000000..5002dd6 --- /dev/null +++ b/docs/PWA_CHANGELOG.md @@ -0,0 +1,187 @@ +# Changelog PWA - ObsiGate + +## Version 1.5.0 - Support PWA Complet + +### 🎉 Nouvelles Fonctionnalités + +#### Progressive Web App (PWA) +- ✅ **Manifeste Web** (`manifest.json`) avec métadonnées complètes +- ✅ **Service Worker** (`sw.js`) pour le mode hors ligne et le cache +- ✅ **Icônes PWA** en multiples tailles (72px à 512px) +- ✅ **Installation native** sur desktop et mobile +- ✅ **Mode hors ligne** avec stratégies de cache intelligentes +- ✅ **Notifications de mise à jour** avec interface élégante +- ✅ **Raccourcis d'application** (recherche rapide) + +#### Fichiers Ajoutés + +**Frontend** +- `frontend/manifest.json` - Manifeste PWA +- `frontend/sw.js` - Service Worker +- `frontend/icons/` - Répertoire des icônes PWA (SVG) + - `icon-72x72.svg` à `icon-512x512.svg` + - `icon-192x192-maskable.svg`, `icon-512x512-maskable.svg` + - `search-96x96.svg` + - `README.md` - Guide de conversion des icônes + +**Scripts** +- `generate_pwa_icons.py` - Générateur d'icônes PWA automatique + +**Documentation** +- `PWA_GUIDE.md` - Guide complet d'utilisation PWA +- `PWA_CHANGELOG.md` - Ce fichier + +#### Modifications Frontend + +**index.html** +- Ajout des meta tags PWA (description, theme-color, mobile-web-app-capable) +- Ajout du lien vers le manifeste +- Ajout des icônes Apple Touch +- Ajout du favicon SVG + +**app.js** +- Fonction `registerServiceWorker()` pour enregistrer le SW +- Fonction `showUpdateNotification()` pour les mises à jour +- Gestion de l'événement `beforeinstallprompt` pour l'installation +- Gestion de l'événement `appinstalled` avec notification toast + +**style.css** +- Styles pour `.pwa-update-notification` +- Styles pour `.pwa-update-content` +- Styles pour les boutons de mise à jour +- Animation `slideInUp` pour les notifications +- Responsive mobile pour les notifications PWA + +#### Modifications Backend + +**main.py** +- Route `GET /sw.js` pour servir le service worker + - Headers: `Cache-Control: no-cache`, `Service-Worker-Allowed: /` +- Route `GET /manifest.json` pour servir le manifeste + - Headers: `Cache-Control: public, max-age=3600` + +### 🔧 Configuration + +#### Service Worker + +**Stratégies de Cache** +- **Cache First** : Assets statiques (HTML, CSS, JS, icônes) +- **Network First** : API et données dynamiques +- **Fallback gracieux** : Affichage hors ligne élégant + +**Gestion du Cache** +- Cache statique : `obsigate-v1.4.0-static` +- Cache dynamique : `obsigate-v1.4.0-dynamic` (max 50 entrées) +- Nettoyage automatique des anciens caches +- Vérification des mises à jour toutes les 60 secondes + +**Exclusions** +- Endpoints SSE (`/api/events`) +- Endpoints d'authentification (`/api/auth/*`) +- Requêtes non-GET + +#### Manifeste PWA + +**Métadonnées** +- Nom : "ObsiGate" +- Description complète en français +- Thème : `#2563eb` (bleu) +- Background : `#1a1a1a` (sombre) +- Display : `standalone` (mode app) +- Orientation : `any` + +**Icônes** +- 8 tailles régulières (72px à 512px) +- 2 icônes maskables (192px, 512px) +- Format : SVG (convertible en PNG) + +**Raccourcis** +- Recherche : `/?action=search` + +### 📱 Compatibilité + +| Fonctionnalité | Chrome | Edge | Firefox | Safari | iOS Safari | Android | +|----------------|--------|------|---------|--------|------------|---------| +| Installation | ✅ | ✅ | ❌ | ⚠️ | ✅ | ✅ | +| Service Worker | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Mode Hors Ligne| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Notifications | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | +| Raccourcis | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | + +### 🚀 Utilisation + +#### Installation Desktop +1. Ouvrir ObsiGate dans Chrome/Edge +2. Cliquer sur l'icône d'installation dans la barre d'adresse +3. Confirmer l'installation + +#### Installation Mobile (Android) +1. Ouvrir ObsiGate dans Chrome +2. Menu ⋮ → "Ajouter à l'écran d'accueil" +3. Confirmer + +#### Installation iOS +1. Ouvrir ObsiGate dans Safari +2. Bouton Partager 📤 +3. "Sur l'écran d'accueil" +4. Confirmer + +### 🔍 Tests + +#### Vérifications Effectuées +- ✅ Manifeste valide (DevTools → Application → Manifest) +- ✅ Service Worker enregistré (DevTools → Application → Service Workers) +- ✅ Cache fonctionnel (DevTools → Application → Cache Storage) +- ✅ Mode hors ligne opérationnel (DevTools → Network → Offline) +- ✅ Notifications de mise à jour +- ✅ Installation sur desktop (Chrome, Edge) +- ✅ Responsive design maintenu + +#### Lighthouse Score +- PWA : 90-100/100 (attendu) +- Performance : Maintenu +- Accessibilité : Maintenu +- Best Practices : Maintenu +- SEO : Maintenu + +### 📝 Notes de Migration + +#### Pour les Utilisateurs Existants +- Aucune action requise +- Le PWA est optionnel +- L'application web fonctionne normalement sans installation +- Le service worker s'enregistre automatiquement + +#### Pour les Développeurs +- Les icônes SVG peuvent être converties en PNG si nécessaire +- Le script `generate_pwa_icons.py` peut être personnalisé +- Le service worker peut être désactivé en commentant `registerServiceWorker()` + +### 🐛 Problèmes Connus + +- **Firefox Desktop** : Pas d'installation native (limitation du navigateur) +- **Safari Desktop** : Support PWA limité (limitation du navigateur) +- **iOS** : Pas de notifications push (limitation iOS) + +### 🔜 Améliorations Futures + +- [ ] Background Sync pour les modifications hors ligne +- [ ] Notifications push pour les mises à jour de vaults +- [ ] Cache prédictif basé sur l'historique +- [ ] Stratégies de cache configurables +- [ ] Support des screenshots dans le manifeste +- [ ] Conversion automatique SVG → PNG au build + +### 📚 Documentation + +- `PWA_GUIDE.md` - Guide complet d'utilisation et de configuration +- `frontend/icons/README.md` - Instructions de conversion des icônes +- Commentaires inline dans `sw.js` et `app.js` + +### 🙏 Remerciements + +Merci à la communauté PWA pour les standards et bonnes pratiques. + +--- + +**ObsiGate v1.5.0** - Maintenant disponible en Progressive Web App ! 🎉 diff --git a/docs/PWA_GUIDE.md b/docs/PWA_GUIDE.md new file mode 100644 index 0000000..5db02b1 --- /dev/null +++ b/docs/PWA_GUIDE.md @@ -0,0 +1,343 @@ +# Guide PWA - ObsiGate + +ObsiGate est maintenant une **Progressive Web App (PWA)** complète, offrant une expérience d'application native sur tous les appareils. + +## 🎯 Qu'est-ce qu'une PWA ? + +Une Progressive Web App combine le meilleur du web et des applications natives : +- **Installation** : Installez ObsiGate sur votre appareil comme une application native +- **Mode hors ligne** : Accédez à vos notes même sans connexion internet +- **Notifications** : Recevez des alertes de mise à jour +- **Performance** : Chargement rapide grâce au cache intelligent +- **Multi-plateforme** : Fonctionne sur desktop, mobile et tablette + +## 📱 Installation + +### Sur Desktop (Chrome, Edge, Brave) + +1. Ouvrez ObsiGate dans votre navigateur +2. Cliquez sur l'icône d'installation dans la barre d'adresse (➕ ou ⬇️) +3. Cliquez sur "Installer" dans la popup +4. ObsiGate apparaît maintenant dans vos applications + +**Alternative** : Menu ⋮ → "Installer ObsiGate..." + +### Sur Android + +1. Ouvrez ObsiGate dans Chrome +2. Appuyez sur le menu ⋮ (trois points) +3. Sélectionnez "Ajouter à l'écran d'accueil" +4. Confirmez l'installation +5. L'icône ObsiGate apparaît sur votre écran d'accueil + +### Sur iOS/iPadOS (Safari) + +1. Ouvrez ObsiGate dans Safari +2. Appuyez sur le bouton Partager 📤 +3. Faites défiler et sélectionnez "Sur l'écran d'accueil" +4. Nommez l'application et appuyez sur "Ajouter" +5. ObsiGate apparaît sur votre écran d'accueil + +## ⚡ Fonctionnalités PWA + +### Mode Hors Ligne + +Le service worker met en cache : +- **Interface utilisateur** : HTML, CSS, JavaScript +- **Ressources statiques** : Icônes, polices +- **Contenu API** : Dernières données consultées + +**Stratégies de cache** : +- **Cache First** : Assets statiques (interface) +- **Network First** : API et données dynamiques +- **Fallback** : Affichage gracieux en cas d'erreur + +### Mises à Jour Automatiques + +- Vérification des mises à jour toutes les minutes +- Notification élégante quand une nouvelle version est disponible +- Mise à jour en un clic sans perte de données + +### Raccourcis d'Application + +Accès rapide aux fonctionnalités depuis l'icône : +- **Recherche** : Ouvre directement la recherche + +## 🛠️ Configuration Technique + +### Fichiers PWA + +``` +ObsiGate/ +├── frontend/ +│ ├── manifest.json # Manifeste PWA +│ ├── sw.js # Service Worker +│ ├── icons/ # Icônes PWA +│ │ ├── icon-72x72.svg +│ │ ├── icon-192x192.svg +│ │ ├── icon-512x512.svg +│ │ └── ... +│ ├── index.html # Meta tags PWA +│ ├── app.js # Enregistrement SW +│ └── style.css # Styles PWA +└── generate_pwa_icons.py # Générateur d'icônes +``` + +### Manifeste (manifest.json) + +Définit les métadonnées de l'application : +- Nom et description +- Icônes (multiples tailles) +- Couleurs de thème +- Mode d'affichage (standalone) +- Raccourcis d'application + +### Service Worker (sw.js) + +Gère le cache et le mode hors ligne : +- **Cache statique** : Interface et assets +- **Cache dynamique** : Données API (max 50 entrées) +- **Stratégies** : Cache-first et Network-first +- **Nettoyage** : Suppression automatique des anciens caches + +### Icônes PWA + +Tailles supportées : +- **72x72** : Favicon, petites icônes +- **96x96** : Raccourcis +- **128x128, 144x144, 152x152** : Appareils mobiles +- **192x192** : Android home screen (standard) +- **384x384** : Haute résolution +- **512x512** : Splash screens, maskable icons + +**Maskable icons** : Icônes adaptatives avec safe zone pour Android + +## 🔧 Génération des Icônes + +### Utilisation du Script + +```bash +# Générer les icônes SVG +python generate_pwa_icons.py +``` + +Le script crée : +- Icônes régulières (toutes tailles) +- Icônes maskables (192x192, 512x512) +- Icône de recherche (96x96) +- README avec instructions de conversion + +### Conversion SVG → PNG (Production) + +**Option 1 : ImageMagick** +```bash +cd frontend/icons +for file in *.svg; do + size=$(echo $file | grep -oP '\d+x\d+' | head -1 | cut -d'x' -f1) + convert -background none -resize ${size}x${size} "$file" "${file%.svg}.png" +done +``` + +**Option 2 : Inkscape** +```bash +cd frontend/icons +for file in *.svg; do + size=$(echo $file | grep -oP '\d+x\d+' | head -1 | cut -d'x' -f1) + inkscape "$file" --export-filename="${file%.svg}.png" --export-width=$size +done +``` + +**Option 3 : Outils en ligne** +- https://cloudconvert.com/svg-to-png +- https://convertio.co/svg-png/ + +**Note** : Les navigateurs modernes supportent les SVG directement, la conversion PNG est optionnelle. + +## 🎨 Personnalisation + +### Modifier les Couleurs + +Éditez `frontend/manifest.json` : +```json +{ + "theme_color": "#2563eb", // Couleur de la barre d'état + "background_color": "#1a1a1a" // Couleur de fond au lancement +} +``` + +### Modifier les Icônes + +1. Éditez `generate_pwa_icons.py` +2. Modifiez les fonctions `create_svg_icon()` et `create_maskable_svg_icon()` +3. Régénérez : `python generate_pwa_icons.py` + +### Ajouter des Raccourcis + +Éditez `frontend/manifest.json` : +```json +{ + "shortcuts": [ + { + "name": "Nouvelle Note", + "url": "/?action=new", + "icons": [{"src": "/static/icons/new-96x96.png", "sizes": "96x96"}] + } + ] +} +``` + +## 🔍 Débogage + +### Vérifier l'Installation PWA + +**Chrome DevTools** : +1. Ouvrez DevTools (F12) +2. Onglet "Application" +3. Section "Manifest" : Vérifiez les métadonnées +4. Section "Service Workers" : Vérifiez l'enregistrement +5. Section "Cache Storage" : Inspectez le cache + +### Tester le Mode Hors Ligne + +1. DevTools → Onglet "Network" +2. Cochez "Offline" +3. Rechargez la page +4. L'application doit fonctionner avec les données en cache + +### Logs du Service Worker + +```javascript +// Dans la console du navigateur +navigator.serviceWorker.getRegistration().then(reg => { + console.log('Service Worker:', reg); + console.log('Active:', reg.active); + console.log('Waiting:', reg.waiting); +}); +``` + +### Forcer la Mise à Jour + +```javascript +// Dans la console +navigator.serviceWorker.getRegistration().then(reg => { + reg.update(); +}); +``` + +### Désinstaller le Service Worker + +```javascript +// Dans la console +navigator.serviceWorker.getRegistrations().then(registrations => { + registrations.forEach(reg => reg.unregister()); +}); +``` + +## 📊 Métriques PWA + +### Lighthouse Audit + +1. Chrome DevTools → Onglet "Lighthouse" +2. Sélectionnez "Progressive Web App" +3. Cliquez sur "Generate report" + +**Critères évalués** : +- ✅ Manifeste valide +- ✅ Service Worker enregistré +- ✅ HTTPS (ou localhost) +- ✅ Icônes appropriées +- ✅ Responsive design +- ✅ Mode hors ligne + +### Score Attendu + +ObsiGate devrait obtenir **90-100/100** sur l'audit PWA. + +## 🚀 Déploiement + +### Prérequis + +- **HTTPS obligatoire** en production (sauf localhost) +- Service Worker nécessite une connexion sécurisée + +### Configuration Reverse Proxy + +**Nginx** : +```nginx +location /sw.js { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Service-Worker-Allowed "/"; + proxy_pass http://obsigate:8080; +} + +location /manifest.json { + add_header Cache-Control "public, max-age=3600"; + proxy_pass http://obsigate:8080; +} +``` + +**Traefik** : +```yaml +http: + middlewares: + sw-headers: + headers: + customResponseHeaders: + Cache-Control: "no-cache, no-store, must-revalidate" + Service-Worker-Allowed: "/" +``` + +## 🔒 Sécurité + +### Content Security Policy + +Le service worker respecte la CSP définie dans le backend : +- Scripts : `'self'` + CDN autorisés +- Styles : `'self'` + CDN autorisés +- Images : `'self'` + data URIs + +### Permissions + +PWA installée demande les mêmes permissions que le site web : +- Aucune permission supplémentaire requise +- Notifications : optionnelles (désactivées par défaut) + +## 📱 Compatibilité + +| Plateforme | Support | Notes | +|------------|---------|-------| +| Chrome Desktop | ✅ Complet | Installation native | +| Edge Desktop | ✅ Complet | Installation native | +| Firefox Desktop | ⚠️ Partiel | Pas d'installation, SW fonctionne | +| Safari Desktop | ⚠️ Partiel | Support limité | +| Chrome Android | ✅ Complet | Installation + notifications | +| Safari iOS | ✅ Complet | "Add to Home Screen" | +| Samsung Internet | ✅ Complet | Installation native | + +## 🎓 Ressources + +- [MDN - Progressive Web Apps](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps) +- [web.dev - PWA](https://web.dev/progressive-web-apps/) +- [PWA Builder](https://www.pwabuilder.com/) +- [Workbox (Google)](https://developers.google.com/web/tools/workbox) + +## ❓ FAQ + +**Q : Puis-je utiliser ObsiGate sans l'installer ?** +R : Oui, l'installation est optionnelle. Le site web fonctionne normalement. + +**Q : Les données sont-elles synchronisées hors ligne ?** +R : Non, le mode hors ligne utilise le cache local. Les modifications nécessitent une connexion. + +**Q : Comment désinstaller l'application ?** +R : Desktop : Clic droit sur l'icône → "Désinstaller". Mobile : Maintenez l'icône → "Supprimer". + +**Q : Le cache prend-il beaucoup d'espace ?** +R : Non, le cache est limité à ~50 entrées dynamiques + assets statiques (~5-10 MB). + +**Q : Puis-je désactiver le service worker ?** +R : Oui, supprimez l'enregistrement dans DevTools ou commentez `registerServiceWorker()` dans `app.js`. + +--- + +**ObsiGate PWA** - Vos notes Obsidian, partout, tout le temps. 📖✨ diff --git a/docs/PWA_SUMMARY.md b/docs/PWA_SUMMARY.md new file mode 100644 index 0000000..853a6bc --- /dev/null +++ b/docs/PWA_SUMMARY.md @@ -0,0 +1,255 @@ +# Résumé - ObsiGate PWA + +## ✅ Transformation Réussie en Progressive Web App + +ObsiGate est maintenant une **Progressive Web App (PWA)** complète et fonctionnelle. + +### 📦 Fichiers Créés + +``` +ObsiGate/ +├── frontend/ +│ ├── manifest.json ✅ Manifeste PWA +│ ├── sw.js ✅ Service Worker +│ ├── icons/ ✅ Icônes PWA (11 fichiers SVG) +│ │ ├── icon-72x72.svg +│ │ ├── icon-96x96.svg +│ │ ├── icon-128x128.svg +│ │ ├── icon-144x144.svg +│ │ ├── icon-152x152.svg +│ │ ├── icon-192x192.svg +│ │ ├── icon-384x384.svg +│ │ ├── icon-512x512.svg +│ │ ├── icon-192x192-maskable.svg +│ │ ├── icon-512x512-maskable.svg +│ │ ├── search-96x96.svg +│ │ └── README.md +│ ├── index.html ✅ Modifié (meta tags PWA) +│ ├── app.js ✅ Modifié (enregistrement SW) +│ └── style.css ✅ Modifié (styles notifications) +├── backend/ +│ └── main.py ✅ Modifié (routes SW et manifeste) +├── generate_pwa_icons.py ✅ Script de génération d'icônes +├── PWA_GUIDE.md ✅ Guide complet PWA +├── PWA_CHANGELOG.md ✅ Changelog détaillé +└── PWA_SUMMARY.md ✅ Ce fichier +``` + +### 🎯 Fonctionnalités Implémentées + +#### 1. Manifeste Web (`manifest.json`) +- ✅ Métadonnées complètes (nom, description, icônes) +- ✅ Configuration d'affichage (standalone) +- ✅ Couleurs de thème (#2563eb) +- ✅ Raccourcis d'application (recherche) +- ✅ Icônes adaptatives (maskable) + +#### 2. Service Worker (`sw.js`) +- ✅ Cache statique (interface utilisateur) +- ✅ Cache dynamique (données API, max 50 entrées) +- ✅ Stratégie Cache-First pour assets statiques +- ✅ Stratégie Network-First pour API +- ✅ Gestion des mises à jour automatiques +- ✅ Nettoyage automatique des anciens caches +- ✅ Support des notifications push (préparé) +- ✅ Background sync (préparé) + +#### 3. Interface Utilisateur +- ✅ Meta tags PWA dans `` +- ✅ Enregistrement automatique du service worker +- ✅ Notification élégante des mises à jour +- ✅ Gestion de l'événement d'installation +- ✅ Toast de confirmation d'installation +- ✅ Styles responsive pour notifications + +#### 4. Backend +- ✅ Route `/sw.js` avec headers appropriés +- ✅ Route `/manifest.json` avec cache +- ✅ Service des icônes via `/static/icons/` + +#### 5. Génération d'Icônes +- ✅ Script Python automatisé +- ✅ Création de 8 tailles régulières +- ✅ Création de 2 icônes maskables +- ✅ Icône de recherche pour raccourcis +- ✅ Documentation de conversion SVG→PNG + +### 🚀 Utilisation + +#### Installation Rapide + +**Desktop (Chrome/Edge)** +``` +1. Ouvrir ObsiGate +2. Cliquer sur l'icône d'installation (barre d'adresse) +3. Confirmer +``` + +**Android** +``` +1. Ouvrir ObsiGate dans Chrome +2. Menu ⋮ → "Ajouter à l'écran d'accueil" +3. Confirmer +``` + +**iOS** +``` +1. Ouvrir ObsiGate dans Safari +2. Bouton Partager 📤 +3. "Sur l'écran d'accueil" +4. Confirmer +``` + +#### Génération des Icônes + +```bash +# Générer les icônes SVG +python generate_pwa_icons.py + +# Optionnel : Convertir en PNG (production) +cd frontend/icons +# Voir frontend/icons/README.md pour les commandes +``` + +### 🔍 Vérification + +#### Checklist PWA + +- ✅ Manifeste valide et accessible +- ✅ Service Worker enregistré +- ✅ Icônes multiples tailles (72px à 512px) +- ✅ HTTPS ou localhost +- ✅ Mode hors ligne fonctionnel +- ✅ Responsive design +- ✅ Meta tags appropriés +- ✅ Thème cohérent + +#### Tests à Effectuer + +1. **Manifeste** : DevTools → Application → Manifest +2. **Service Worker** : DevTools → Application → Service Workers +3. **Cache** : DevTools → Application → Cache Storage +4. **Hors Ligne** : DevTools → Network → Offline +5. **Installation** : Icône dans la barre d'adresse +6. **Lighthouse** : Audit PWA (score attendu : 90-100) + +### 📊 Compatibilité + +| Plateforme | Installation | Mode Hors Ligne | Notifications | +|------------|--------------|-----------------|---------------| +| Chrome Desktop | ✅ | ✅ | ✅ | +| Edge Desktop | ✅ | ✅ | ✅ | +| Firefox Desktop | ❌ | ✅ | ✅ | +| Safari Desktop | ⚠️ | ✅ | ❌ | +| Chrome Android | ✅ | ✅ | ✅ | +| Safari iOS | ✅ | ✅ | ❌ | + +### 🎨 Personnalisation + +#### Modifier les Couleurs + +**Fichier** : `frontend/manifest.json` +```json +{ + "theme_color": "#2563eb", // Barre d'état + "background_color": "#1a1a1a" // Fond au lancement +} +``` + +#### Modifier les Icônes + +**Fichier** : `generate_pwa_icons.py` +```python +# Éditer les fonctions : +# - create_svg_icon() +# - create_maskable_svg_icon() +# Puis régénérer : python generate_pwa_icons.py +``` + +#### Ajouter des Raccourcis + +**Fichier** : `frontend/manifest.json` +```json +{ + "shortcuts": [ + { + "name": "Recherche", + "url": "/?action=search", + "icons": [{"src": "/static/icons/search-96x96.svg", "sizes": "96x96"}] + } + ] +} +``` + +### 🔧 Configuration Avancée + +#### Stratégies de Cache + +**Cache First** (assets statiques) +- Interface : HTML, CSS, JS +- Icônes et polices +- Fallback rapide + +**Network First** (données dynamiques) +- API endpoints +- Contenu des vaults +- Fallback sur cache si hors ligne + +#### Exclusions du Cache + +- Endpoints SSE (`/api/events`) +- Endpoints d'authentification (`/api/auth/*`) +- Requêtes non-GET + +### 📚 Documentation + +- **`PWA_GUIDE.md`** : Guide complet d'utilisation et configuration +- **`PWA_CHANGELOG.md`** : Changelog détaillé des modifications +- **`frontend/icons/README.md`** : Instructions de conversion des icônes +- **Commentaires inline** : Dans `sw.js` et `app.js` + +### 🐛 Dépannage + +#### Le Service Worker ne s'enregistre pas +```javascript +// Console navigateur +navigator.serviceWorker.getRegistration() + .then(reg => console.log('SW:', reg)) + .catch(err => console.error('Erreur:', err)); +``` + +#### Forcer la Mise à Jour +```javascript +// Console navigateur +navigator.serviceWorker.getRegistration() + .then(reg => reg.update()); +``` + +#### Vider le Cache +```javascript +// Console navigateur +caches.keys().then(keys => + Promise.all(keys.map(key => caches.delete(key))) +); +``` + +### ✨ Prochaines Étapes + +1. **Tester l'installation** sur différents appareils +2. **Vérifier le mode hors ligne** avec DevTools +3. **Lancer un audit Lighthouse** pour valider le score PWA +4. **Optionnel** : Convertir les icônes SVG en PNG pour une meilleure compatibilité +5. **Déployer** avec HTTPS pour activer toutes les fonctionnalités PWA + +### 🎉 Résultat + +ObsiGate est maintenant une **Progressive Web App complète** offrant : +- 📱 Installation native sur tous les appareils +- 🔌 Mode hors ligne fonctionnel +- ⚡ Performance optimisée avec cache intelligent +- 🔄 Mises à jour automatiques avec notifications +- 🎨 Expérience utilisateur native + +--- + +**ObsiGate v1.5.0 PWA** - Vos notes Obsidian, partout, tout le temps ! 📖✨ diff --git a/docs/README_PWA.md b/docs/README_PWA.md new file mode 100644 index 0000000..46dc44a --- /dev/null +++ b/docs/README_PWA.md @@ -0,0 +1,133 @@ +# 📱 ObsiGate PWA - Progressive Web App + +> **ObsiGate est maintenant une Progressive Web App complète !** + +## 🎯 Qu'est-ce qui a changé ? + +ObsiGate peut maintenant être **installé comme une application native** sur votre ordinateur, smartphone ou tablette, et fonctionne **même hors ligne**. + +## ✨ Nouvelles Fonctionnalités + +### 📲 Installation Native +- **Desktop** : Installez ObsiGate comme une application Windows/Mac/Linux +- **Mobile** : Ajoutez ObsiGate à votre écran d'accueil Android/iOS +- **Tablette** : Expérience optimisée sur iPad et tablettes Android + +### 🔌 Mode Hors Ligne +- Accédez à vos notes même sans connexion internet +- Cache intelligent des dernières données consultées +- Synchronisation automatique au retour en ligne + +### ⚡ Performance Améliorée +- Chargement instantané grâce au cache +- Réduction de la consommation de données +- Interface ultra-réactive + +### 🔔 Mises à Jour Automatiques +- Vérification automatique des nouvelles versions +- Notification élégante quand une mise à jour est disponible +- Installation en un clic sans perte de données + +## 🚀 Installation Rapide + +### Sur Desktop (Chrome, Edge, Brave) + +``` +1. Ouvrez ObsiGate dans votre navigateur +2. Cliquez sur l'icône ➕ dans la barre d'adresse +3. Cliquez sur "Installer" +``` + +### Sur Android + +``` +1. Ouvrez ObsiGate dans Chrome +2. Menu ⋮ → "Ajouter à l'écran d'accueil" +3. Confirmez l'installation +``` + +### Sur iOS/iPadOS + +``` +1. Ouvrez ObsiGate dans Safari +2. Bouton Partager 📤 +3. "Sur l'écran d'accueil" +4. Confirmez +``` + +## 📦 Fichiers PWA Ajoutés + +``` +ObsiGate/ +├── frontend/ +│ ├── manifest.json # Manifeste PWA +│ ├── sw.js # Service Worker +│ └── icons/ # Icônes (11 fichiers) +├── generate_pwa_icons.py # Générateur d'icônes +├── PWA_GUIDE.md # Guide complet +├── PWA_CHANGELOG.md # Changelog détaillé +├── PWA_SUMMARY.md # Résumé technique +├── INSTALLATION_PWA.md # Guide installation +└── MODIFICATIONS_PWA.txt # Liste des modifications +``` + +## 🔍 Vérification + +Pour vérifier que le PWA fonctionne : + +1. Ouvrez **DevTools** (F12) +2. Onglet **"Application"** +3. Vérifiez : + - ✅ **Manifest** : Métadonnées ObsiGate + - ✅ **Service Workers** : SW actif + - ✅ **Cache Storage** : Caches présents + +## 📚 Documentation + +- **[PWA_GUIDE.md](PWA_GUIDE.md)** - Guide complet d'utilisation +- **[INSTALLATION_PWA.md](INSTALLATION_PWA.md)** - Installation rapide +- **[PWA_CHANGELOG.md](PWA_CHANGELOG.md)** - Changelog détaillé +- **[PWA_SUMMARY.md](PWA_SUMMARY.md)** - Résumé technique + +## 🎨 Personnalisation + +### Modifier les couleurs + +Éditez `frontend/manifest.json` : + +```json +{ + "theme_color": "#2563eb", + "background_color": "#1a1a1a" +} +``` + +### Régénérer les icônes + +```bash +python generate_pwa_icons.py +``` + +## 🌐 Compatibilité + +| Plateforme | Installation | Hors Ligne | +|------------|--------------|------------| +| Chrome Desktop | ✅ | ✅ | +| Edge Desktop | ✅ | ✅ | +| Firefox Desktop | ⚠️ | ✅ | +| Safari Desktop | ⚠️ | ✅ | +| Chrome Android | ✅ | ✅ | +| Safari iOS | ✅ | ✅ | + +## 🎉 Résultat + +ObsiGate offre maintenant : +- 📱 Expérience d'application native +- 🔌 Fonctionnement hors ligne +- ⚡ Performance optimale +- 🔄 Mises à jour automatiques +- 🌍 Multi-plateforme + +--- + +**ObsiGate v1.5.0 PWA** - Vos notes Obsidian, partout, tout le temps ! 📖✨ diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..3da3344 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,72 @@ +# ObsiGate — Roadmap + +> **Date :** 2026-05-25 | **Version :** 1.4.0 / 1.5.0 + +--- + +## Légende + +- ✅ Complété +- 🟡 En cours / Partiel / À investiguer +- ⬜ À faire +- 🔴 Critique + +--- + +## Nouvelles fonctionnalités (historique TODO.md) + +- ✅ **Indexation incrémentale automatique** — Le watcher détecte les nouveaux fichiers et met à jour l'index sans réindexation complète. Utilise `_on_vault_change` → `update_single_file` / `remove_single_file` / `handle_file_move`. +- ✅ **Copier le chemin** — Option "Copier le chemin" dans le menu contextuel (clic droit) de l'arborescence pour tout élément (vault, dossier, fichier). +- ✅ **Panneau À propos** — Section "À propos" dans le modal Configurations affichant la version, la version API, les stats de santé. +- ✅ **Vue Graphique** — Canvas force-directed accessible via menu contextuel sur les vaults et dossiers. Affiche nœuds (fichiers/dossiers) et arêtes (parent + wikilinks). Zoom/pan interactif. +- ✅ **Mode onglets (Tabs)** — Barre d'onglets multi-fichiers permettant de visualiser plusieurs fichiers simultanément, avec fermeture et navigation. +- ✅ **Login Popout** — La fenêtre popout affiche un formulaire de connexion quand l'authentification est requise, puis recharge la page après login. + +--- + +## Corrections (historique TODO.md) + +- ✅ **Login popout avec redirection** — Quand un fichier est ouvert via l'URL popout et que l'authentification est requise, un formulaire de login est proposé. Après connexion réussie, la page recharge automatiquement. +- 🟡 **Correction TOC — scroll avec caractères accentués** — Le clic sur un titre dans la table des matières ne fonctionne pas toujours pour les titres contenant des lettres accentuées. Les fonctions slugify (frontend) et _heading_slugify (backend) utilisent des normalisations Unicode qui peuvent diverger pour certains caractères (ex: œ, æ). **À corriger :** unifier l'algorithme + ajouter un fallback `scrollIntoView`. + +--- + +## Améliorations prioritaires (voir ANALYSE_REVIEW.md §4) + +### 🔴 Sécurité — P0 + +- 🔴 **Masquage automatique des secrets** — Implémenter un `SecretRedactor` pour masquer les clés API, tokens, et mots de passe dans les aperçus de contenu (preview RÉCENT, dashboard, vue rendu). +- 🔴 **Rate limiting sur le login** — 5 tentatives max par IP sur 15 minutes, blocage après 10 échecs. + +### 🟠 Robustesse — P1 + +- 🟠 **Log d'audit** — Tracer les écritures, suppressions, et changements de config dans `data/audit.log`. +- 🟠 **Backup automatique avant écriture** — Sauvegarder le contenu original dans `.obsigate-backup/` avant chaque PUT ou DELETE. + +### 🟡 UX — P2 + +- 🟡 **Backlinks panel** — Afficher les fichiers contenant des wikilinks pointant vers le fichier courant. Index inversé des wikilinks. +- 🟡 **Gestion des conflits Syncthing** — Dashboard « Conflits » avec diff et résolution (garder local, garder conflit). +- 🟡 **Liste IGNORED_DIRS configurable** — Rendre la liste des dossiers ignorés par le watcher configurable (env var ou Configurations). +- 🟡 **Timeout de session configurable** — Exposer le TTL JWT dans les Configurations. + +### 🟢 Fonctionnel — P3/P4 + +- 🟢 **Dashboard statistiques** — Métriques par vault : fichiers totaux, taille, top tags, orphelins. +- 🟢 **Webhooks** — Notifier des systèmes externes lors de changements (création, modif, suppression). +- 🟢 **Documentation OpenAPI enrichie** — Enrichir les modèles Pydantic pour la doc auto-générée /docs et /redoc. +- 🟢 **Gestion fichiers non-supportés** — Message explicite + bouton download pour les fichiers binaires non gérés. + +### ⬜ Qualité & Polish — P5+ + +- ⬜ **Tests unitaires** (pytest) +- ⬜ **Tests E2E** (Playwright) +- ⬜ **CI/CD pipeline** (GitHub Actions) +- ⬜ **i18n** (support anglais + français) +- ⬜ **CHANGELOG.md** +- ⬜ **Documentation utilisateur enrichie** +- ⬜ **Authentification multi-facteurs** (TOTP/WebAuthn) + +--- + +*Document généré le 2026-05-25 — Remplace l'ancien TODO.md* diff --git a/docs/SPEC_Dashboard_RecentFiles.md b/docs/SPEC_Dashboard_RecentFiles.md new file mode 100644 index 0000000..26c4e14 --- /dev/null +++ b/docs/SPEC_Dashboard_RecentFiles.md @@ -0,0 +1,161 @@ +# SPEC: Widget "Derniers fichiers ouverts" sur la page principale + +## 1. Objectif + +Remplacer le message d'accueil actuel (`#welcome`) par un widget dashboard professionnel affichant les **XX derniers fichiers ouverts**. Le nombre de fichiers affichés sera configurable via les paramètres existants (`cfg-recent-limit`). + +## 2. Architecture du composant + +```mermaid +graph TD + A["#content-area"] --> B["#dashboard-home"] + B --> C["En-tête: Logo + Titre"] + B --> D["Sélecteur vault filter"] + B --> E["#dashboard-recent-grid"] + B --> F["#dashboard-recent-empty"] + + E --> G["Carte 1: fichier récent"] + E --> H["Carte 2: fichier récent"] + E --> I["..."] + + G --> G1["Icône fichier"] + G --> G2["Titre"] + G --> G3["Chemin breadcrumb"] + G --> G4["Tags"] + G --> G5["Horodatage"] +``` + +## 3. Design UI/UX + +### 3.1 Structure HTML (dans `#content-area`) + +```html +
+
+
+ +

Derniers fichiers ouverts

+
+
+ + +
+
+
+ +
+``` + +### 3.2 Layout Grid + +- **Desktop (>1024px)**: Grid 3 colonnes +- **Tablet (768-1024px)**: Grid 2 colonnes +- **Mobile (<768px)**: Grid 1 colonne + +### 3.3 Style des cartes (`.dashboard-card`) + +| Élément | Style | +|---------|-------| +| Container | `border-radius: 12px`, `padding: 16px`, fond `var(--bg-secondary)` | +| Hover | Légère élévation avec `box-shadow`, bordure accent | +| Icône | 32x32px, couleur accent | +| Titre | `font-weight: 600`, `font-size: 14px`, truncation avec ellipsis | +| Chemin | `font-size: 11px`, `color: var(--text-muted)` | +| Tags | Pills compacts, même style que sidebar | +| Horodatage | Badge discret avec icône clock | +| Badge vault | Position absolute en haut-droit | + +### 3.4 États + +| État | Description | +|------|-------------| +| **Chargement** | Skeleton cards animées (pulse) | +| **Données** | Grid de cartes | +| **Vide** | Icône + message centré | +| **Erreur** | Toast notification | + +## 4. Interactions + +| Action | Comportement | +|--------|--------------| +| **Clic sur carte** | Ouvre le fichier (`openFile(vault, path)`) | +| **Changement filter vault** | Recharge les données avec filtre | +| **Hover carte** | Élévation visuelle, curseur pointer | +| **Fermeture fichier** | Affiche le dashboard (si plus de fichier ouvert) | + +## 5. Intégration JavaScript + +### 5.1 Nouveau module `DashboardRecentWidget` + +```javascript +const DashboardRecentWidget = { + async load(vaultFilter) { /* Charge via /api/recent */ }, + render(files) { /* Génère le HTML des cartes */ }, + showEmpty() { /* Affiche état vide */ }, + showLoading() { /* Affiche skeletons */ }, + init() { /* Bind events, charge initial */ } +}; +``` + +### 5.2 Points d'intégration + +- **Au démarrage**: `DashboardRecentWidget.init()` dans `DOMContentLoaded` +- **Ouverture fichier**: Dashboard masqué automatiquement +- **Fermeture fichier**: Dashboard affiché si `activeEditor === null` +- **Filtre vault**: Recharge via `loadRecentFiles` de la sidebar (partage du cache) + +### 5.3 Partage avec sidebar "Recent" + +Le widget réutilisera `_recentFilesCache` et `renderRecentList` mais avec un **template de carte différent** pour le dashboard. + +## 6. Fichiers à modifier + +| Fichier | Modification | +|---------|--------------| +| `frontend/index.html` | Remplacer `#welcome` par `#dashboard-home` | +| `frontend/style.css` | Ajouter `.dashboard-home`, `.dashboard-card`, skeleton, animations | +| `frontend/app.js` | Ajouter `DashboardRecentWidget`, modifier `showWelcome()`, intégration hooks | + +## 7. Paramètres configurables + +| Paramètre | Source | Description | +|-----------|--------|-------------| +| `recent_files_limit` | Backend config | Nombre max de fichiers (5-100, défaut: 20) | + +## 8. Accessibilité + +- Rôles ARIA appropriés (`role="region"`, `aria-label`) +- Navigation clavier fonctionnelle +- Contraste des couleurs conforme WCAG 2.1 AA +- Support screen reader pour les états vides/chargement + +## 9. Responsive breakpoints + +```css +.dashboard-recent-grid { + display: grid; + gap: 16px; + /* Mobile first */ + grid-template-columns: 1fr; +} +@media (min-width: 768px) { + grid-template-columns: repeat(2, 1fr); +} +@media (min-width: 1024px) { + grid-template-columns: repeat(3, 1fr); +} +``` + +## 10. Animations + +| Événement | Animation | +|-----------|-----------| +| Entrée cartes | Fade-in + slide-up staggeré (50ms entre cartes) | +| Hover carte | Scale 1.02 + shadow | +| Skeleton loading | Pulse animation | +| Transition vault filter | Fade out/in des cartes |