diff --git a/ROADMAP.md b/ROADMAP.md deleted file mode 100644 index 36ca263..0000000 --- a/ROADMAP.md +++ /dev/null @@ -1,559 +0,0 @@ -# ObsiGate — Roadmap - -> **Version :** 2.0.0-dev | **Dernière mise à jour :** 2026-06-05 -> Voir aussi [CHANGELOG.md](./CHANGELOG.md), [AUDIT_TECHNIQUE.md](./docs/AUDIT_TECHNIQUE_2026-05-27.md) - ---- - -## Légende - -| Icône | Signification | -|---|---| -| ✅ | Terminé | -| 🔵 | En cours | -| ⚪ | Prévu / Backlog | -| 🔴 Impact | Critique / Bloquant | -| 🟡 Impact | Utile / Attendu | -| 🟢 Impact | Nice-to-have / Confort | - ---- - -## ✅ Complété (v1.0.0 → v2.0.0-dev) - -### Fondations (v1.0.0 → v1.4.0) - -| # | Feature | Effort | Impact | -|---|---|---|---| -| 1 | FastAPI backend — CRUD fichiers, vaults, recherche full-text | 5j | 🔴 | -| 2 | Moteur TF-IDF + stemming français (`snowballstemmer`) | 2j | 🔴 | -| 3 | Watchdog — indexation temps réel avec debounce | 1j | 🟡 | -| 4 | Interface SPA vanilla JS — sidebar, viewer, éditeur CodeMirror | 8j | 🔴 | -| 5 | Sécurité : JWT + Argon2id, rate limiting, audit log, CSP headers | 3j | 🔴 | -| 6 | Protection path traversal, utilisateur non-root Docker | 0.5j | 🔴 | -| 7 | Compression GZip SSE-safe, Cache-Control immutable | 0.5j | 🟢 | -| 8 | PWA : manifest, service worker, mode standalone | 1j | 🟡 | - -### UX & Productivité (v1.5.0 → v1.6.0) - -| # | Feature | Effort | Impact | -|---|---|---|---| -| 9 | Publication publique de documents (lien partageable, token) | 1j | 🟡 | -| 10 | Webhooks HTTP avec signature HMAC-SHA256 | 1j | 🟡 | -| 11 | Dashboard statistiques (fichiers, tags, taille, vaults) | 0.5j | 🟡 | -| 12 | Gestion des conflits Syncthing | 0.5j | 🟢 | -| 13 | Index inversé incrémental (hook pattern) | 1j | 🟡 | -| 14 | Backlinks panel dans le viewer | 0.5j | 🟡 | -| 15 | Fichiers non-supportés → UI download | 0.3j | 🟢 | -| 16 | Redaction de secrets (`secret_redactor.py`) | 0.5j | 🟡 | -| 17 | Backup automatique avant écriture, restauration | 1j | 🟡 | -| 18 | Vue graphe — Barnes-Hut, focus, plein écran, export PNG | 3j | 🟡 | -| 19 | Header flat design, sticky panels, navigation historique ← → ↑ | 1j | 🟢 | -| 20 | Ctrl+survol → aperçu contenu formaté | 0.5j | 🟢 | - -### Architecture (v1.5.1) - -| # | Feature | Effort | Impact | -|---|---|---|---| -| 21 | Split `app.js` (8 875 lignes) → 16 modules ES | 3j | 🔴 | -| 22 | Validateur imports/exports CI + tests unitaires frontend Node.js | 0.5j | 🟡 | - -### CI/CD & Qualité (v1.6.0) - -| # | Feature | Effort | Impact | -|---|---|---|---| -| 23 | Pipeline Gitea Actions : lint → test → security → build | 1j | 🔴 | -| 24 | Ruff (0 erreur) + Mypy (0 erreur) + Bandit SAST + Pip-audit | 0.5j | 🟡 | -| 25 | Pytest : 285 tests, 63% coverage | 3j | 🔴 | - -### AI Editor (v1.7.0) - -| # | Feature | Effort | Impact | -|---|---|---|---| -| 26 | Toolbar : Edit, Tone, Translate, Generate, Rewrite, Toolbox | 2j | 🟡 | -| 27 | Multi-provider : DeepSeek, OpenRouter, Gemini | 1j | 🟡 | -| 28 | 16 endpoints REST `/api/ai/{action}` + backend `ai.py` / `ai_routes.py` | 2j | 🟡 | -| 29 | Auto-save silencieux (2s debounce), loading toasts | 0.5j | 🟢 | - -### Fonctionnalités avancées (v1.8.0 → v1.9.0) - -| # | Feature | Effort | Impact | -|---|---|---|---| -| 30 | Export PDF via WeasyPrint (endpoint API + lien share public) | 1j | 🟡 | -| 31 | Palette de commandes `Ctrl+Alt+Space` | 1j | 🟡 | -| 32 | Barre d'outils mobile + palette fichiers/commandes 📱 | 1j | 🟡 | -| 33 | Drag & drop de fichiers | 1j | 🟡 | -| 34 | Filtres recherche avancés : `created:`, `modified:`, `size:` | 0.5j | 🟡 | -| 35 | Fichiers récents par vault | 0.5j | 🟡 | -| 36 | Indicateur AI Actif (header + toast) | 0.3j | 🟢 | -| 37 | Page d'accueil de vault (liste récursive par date, style recherche) | 0.5j | 🟡 | -| 38 | Indexation non-bloquante (background thread) | 0.5j | 🟡 | -| 39 | Git tags semver (v1.8.0, v1.9.0) | 0.2j | 🟢 | - -### Gestion des Backups (v1.9.0) - -| # | Feature | Effort | Impact | -|---|---|---|---| -| 40 | Diff viewer : unifié + côte à côte, restauration depuis backup | 1j | 🟡 | -| 41 | Gestionnaire de backups : page complète, filtre, suppression, purge | 1.5j | 🟡 | -| 42 | Purge par vault avec confirmation, preview contenu (100 Ko) | 0.5j | 🟡 | -| 43 | Compression gzip des vieux backups (niveau 6) | 0.5j | 🟢 | -| 44 | Backup automatique périodique (`POST /api/backups/auto`) | 1j | 🟡 | -| 45 | Restauration depuis le gestionnaire (extraction timestamp, confirmation) | 0.5j | 🟡 | -| 46 | Auto-nettoyage : `max_backups_per_file` (défaut 10) | 0.5j | 🟡 | - -### Mermaid.js (v2.0.0-dev) - -| # | Feature | Effort | Impact | -|---|---|---|---| -| 47 | CDN mermaid@11, `securityLevel: strict`, `startOnLoad: false` | 0.5j | 🟡 | -| 48 | `renderMermaidBlocks()` — parse, rendu SVG, bloc d'erreur stylisé | 1j | 🟡 | -| 49 | 22 templates (flowchart → sankey-beta) | 0.5j | 🟡 | -| 50 | Live preview dans l'éditeur (debounce 500ms, panneau `#mermaid-live-preview`) | 1j | 🟡 | -| 51 | Thème dark/light synchronisé, export SVG + PNG | 1j | 🟡 | -| 52 | Rendu inline dans le viewer Markdown | 0.5j | 🟡 | -| 53 | Zoom molette + drag + boutons +/- | 0.5j | 🟢 | -| 54 | Mode plein écran avec header bar (icônes zoom, copy, download, close) | 0.5j | 🟢 | -| 55 | Focus mode — clic diagramme → panneau latéral 480px | 0.3j | 🟡 | -| 56 | Pré-processeur Obsidian (`[[liens]]`, `![[img]]`, `==highlight==`) | 0.3j | 🟡 | -| 57 | Header bar : type de diagramme + toggle Code/Preview + copy SVG + download PNG | 1j | 🟡 | - ---- - -## 🔵 En cours (P1) - -### 58. Tests E2E Playwright -- **Effort :** 2-3 jours | **Impact :** 🔴 -- **Description :** Tests navigateur automatisés pour les flows critiques : login, navigation vault, recherche full-text, ouverture/édition/sauvegarde de fichier, rendu Mermaid, export PDF. -- **Sous-tâches :** - - [ ] Installation Playwright + config (`playwright.config.ts`) - - [ ] Fixtures : vault de test avec 5-10 fichiers .md variés - - [ ] Test : login admin → dashboard → liste vaults - - [ ] Test : navigation sidebar → ouverture fichier → viewer Markdown - - [ ] Test : recherche full-text → résultats triés par pertinence - - [ ] Test : éditeur CodeMirror → modification → Ctrl+S → backup créé - - [ ] Test : rendu Mermaid (flowchart + sequence) dans le viewer - - [ ] Test : export PDF → téléchargement vérifié - - [ ] Test : mode sombre → toggle → persistence localStorage - - [ ] Test : responsive mobile → toolbar + sidebar repliée - - [ ] Intégration CI : job `e2e` dans `.gitea/workflows/ci.yml` - ---- - -## ⚪ Backlog — Priorité 3 (P3) - -### 59. Mode hors-ligne PWA complet -- **Effort :** 3-4 jours | **Impact :** 🟡 -- **Description :** Service worker avancé avec IndexedDB pour permettre la navigation et la recherche en mode hors-ligne, avec file de synchronisation au retour réseau. -- **Sous-tâches :** - - [ ] IndexedDB : stockage local de l'index des fichiers (paths, titles, tags) - - [ ] Moteur de recherche offline via IndexedDB (cursor + filtre) - - [ ] Cache des fichiers markdown récemment ouverts (derniers 50) - - [ ] Stratégie de cache : Network First avec fallback IndexedDB - - [ ] File de synchronisation : modifications offline → appliquées au retour réseau - - [ ] UI indicateur : badge « Hors-ligne » + compteur de modifications en attente - - [ ] Gestion des conflits : détection et résolution manuelle (choix version locale vs serveur) - -### 60. OAuth2 / OIDC — Authentification SSO -- **Effort :** 2-3 jours | **Impact :** 🟡 -- **Description :** Support de fournisseurs OAuth2/OIDC externes pour permettre l'authentification via Google, GitHub, ou tout provider compatible. Complément à l'auth JWT existante (pas de remplacement). -- **Sous-tâches :** - - [ ] Configuration par provider : `OBSIGATE_OAUTH_GOOGLE_CLIENT_ID`, `OBSIGATE_OAUTH_GITHUB_CLIENT_ID`, etc. - - [ ] Endpoint `GET /api/auth/oauth/login?provider=google` → redirection - - [ ] Endpoint `GET /api/auth/oauth/callback` → échange code → token OIDC → création/liaison compte local - - [ ] Mapping roles : config `OBSIGATE_OAUTH_DEFAULT_ROLE` (défaut `user`) - - [ ] UI : boutons « Se connecter avec Google / GitHub » sur la page login - - [ ] Sécurité : state parameter anti-CSRF, PKCE, nonce validation - - [ ] Stockage : liaison `oauth_provider` + `oauth_sub` dans `users.json` - -### 61. Plugins système — Extensions utilisateur -- **Effort :** 4-5 jours | **Impact :** 🟢 -- **Description :** Système de plugins permettant aux utilisateurs d'étendre ObsiGate avec des renderers personnalisés, des opérateurs de recherche, et des hooks d'UI. Inspiré du modèle de plugins Obsidian. -- **Sous-tâches :** - - [ ] Spécification du format de plugin : `plugin.json` (name, version, hooks, permissions) - - [ ] API de hooks : `onFileRender`, `onSearchFilter`, `onEditorAction`, `onSidebarItem` - - [ ] Sandbox d'exécution : Web Worker isolé pour le code plugin - - [ ] UI : page « Plugins » dans les paramètres (installer, activer/désactiver, désinstaller) - - [ ] Distribution : dépôt de plugins communautaire (fichier JSON index) - - [ ] Hot-reload : activation/désactivation sans rechargement de page - - [ ] Sécurité : manifest de permissions, validation de signature, CSP restrictif - -### 62. Collaboration temps réel — Édition simultanée -- **Effort :** 5-7 jours | **Impact :** 🟢 -- **Description :** Édition collaborative de fichiers markdown via WebSocket + CRDT (Yjs). Plusieurs utilisateurs peuvent éditer le même fichier simultanément avec résolution automatique des conflits. -- **Sous-tâches :** - - [ ] Serveur WebSocket : endpoint `/ws/collab/{vault}/{path}` avec gestion des rooms - - [ ] Intégration Yjs : `Y.Doc` partagé, `Y.Text` pour le contenu markdown - - [ ] Awareness : curseurs colorés par utilisateur, sélections visibles - - [ ] Synchro backend : persistance périodique du document (debounce 2s) - - [ ] Gestion des droits : vérification `check_vault_access` par connexion WS - - [ ] UI : indicateur de présence (avatars dans la barre d'outils éditeur) - - [ ] UI : curseurs distants dans CodeMirror (extension collaborative) - - [ ] Gestion des déconnexions : reconnexion automatique, merge state au retour - - [ ] Tests de charge : 5+ utilisateurs simultanés sur le même fichier - -### 63. Internationalisation (i18n) — Multilingue -- **Effort :** 2-3 jours | **Impact :** 🟡 -- **Description :** Support de l'anglais et du français via un système de clés de traduction. L'interface est actuellement en français uniquement. L'anglais est nécessaire pour une adoption plus large. -- **Sous-tâches :** - - [ ] Extraction des chaînes : inventaire de toutes les chaînes UI (~300) - - [ ] Format : JSON `fr.json` + `en.json` dans `frontend/locales/` - - [ ] Fonction `t(key, fallback)` → détection `navigator.language` - - [ ] Sélecteur de langue dans les paramètres (persisté localStorage) - - [ ] Traduction des messages backend (erreurs API, toasts) - - [ ] Documentation multilingue (README.fr.md, README.md) - -### 64. MFA — Authentification multi-facteurs -- **Effort :** 2 jours | **Impact :** 🟡 -- **Description :** Ajout de TOTP (Time-based One-Time Password) et WebAuthn (clés de sécurité) comme second facteur d'authentification pour les comptes admin. -- **Sous-tâches :** - - [ ] TOTP : génération de secret, QR code, vérification code 6 chiffres - - [ ] WebAuthn : enregistrement de clé, assertion, attestation - - [ ] UI : page « Sécurité du compte » avec activation/désactivation MFA - - [ ] Flow login : mot de passe → challenge TOTP si activé - - [ ] Recovery codes : 8 codes de backup à usage unique - - [ ] Stockage : `totp_secret` + `webauthn_credential_id` dans `users.json` - -### 65. Thèmes personnalisés — CSS variables -- **Effort :** 1-2 jours | **Impact :** 🟢 -- **Description :** Exposition de variables CSS pour permettre aux utilisateurs de créer des thèmes personnalisés. Presets inclus : light, dark, high-contrast, sepia. -- **Sous-tâches :** - - [ ] Audit des variables CSS existantes → liste des 30+ variables - - [ ] Fichier `themes.json` avec presets (light, dark, high-contrast, sepia) - - [ ] UI : sélecteur de thème dans les paramètres (aperçu live) - - [ ] Import/export de thème personnalisé (JSON) - - [ ] Application dynamique sans rechargement (`document.documentElement.style.setProperty`) - -### 66. Export multi-formats -- **Effort :** 1-2 jours | **Impact :** 🟢 -- **Description :** Export de notes individuelles ou de vaults entiers en HTML standalone, bundle Markdown (.zip), et ePub pour liseuses. -- **Sous-tâches :** - - [ ] Export HTML standalone : CSS inliné, images en base64, navigation inter-fichiers - - [ ] Export MD bundle : ZIP du vault avec structure préservée - - [ ] Export ePub : conversion markdown → ePub via `markdown` + `ebooklib` - - [ ] UI : bouton « Exporter » dans le viewer (fichier unique) + dans le menu vault (export complet) - - [ ] Endpoints : `GET /api/export/html`, `GET /api/export/md-bundle`, `GET /api/export/epub` - -### 74. Support complet des documents PDF -- **Effort :** 4-5 jours | **Impact :** 🟡 -- **Description :** Prise en charge native des fichiers PDF dans ObsiGate avec parité fonctionnelle complète avec les documents Markdown : apparition dans l'arborescence, indexation full-text, visualisation inline dans le navigateur, recherche TF-IDF, et téléchargement. Actuellement, les PDF sont traités comme des fichiers binaires non supportés (message « Ce fichier est binaire et ne peut pas être affiché » + bouton download). -- **Architecture actuelle :** - - `SUPPORTED_EXTENSIONS` (`backend/indexer.py:56`) : ne contient pas `.pdf` → les PDF sont ignorés par l'indexeur, le file watcher, et l'arborescence - - `api_file_view()` (`backend/main.py:2303`) : UnicodeDecodeError sur lecture → retourne `unsupported: true` - - `frontend/js/viewer.js:377` : si `data.unsupported` → affiche le message binaire + bouton download - - `pdf_export.py` : exporte du MD → PDF (WeasyPrint) — aucun rapport avec la lecture de PDF existants - - Icone PDF déjà présente dans `EXT_ICONS` frontend (`.pdf` → `file-text`) — inutilisée -- **Sous-tâches :** - -##### A. Backend — Extraction de texte PDF (1-1.5 jour) - - [ ] **A1. Dépendance** : Ajouter `pymupdf` (PyMuPDF/fitz) à `requirements.txt` — bibliothèque C performante avec extraction texte + métadonnées, déjà compatible avec l'image Docker (libs système GTK/Pango déjà présentes pour WeasyPrint). Alternative légère : `pypdf` (pure Python, pas de deps système) si pymupdf pose problème. - - [ ] **A2. Module `backend/pdf_reader.py`** : Créer un module dédié avec les fonctions : - - `extract_pdf_text(file_path: Path) -> str` : extrait tout le texte du PDF, page par page, avec séparateur `\f` entre pages. Gère les PDF encodés, protégés par mot de passe (retourne erreur explicite), et corrompus. - - `extract_pdf_metadata(file_path: Path) -> dict` : extrait titre, auteur, sujet, nombre de pages, taille. - - `extract_pdf_preview(file_path: Path, max_chars: int = 100000) -> str` : extrait les N premiers caractères pour l'indexation (limité par `SEARCH_CONTENT_LIMIT`). - - [ ] **A3. Fallback pypdf** : Si pymupdf non disponible (exception d'import), fallback automatique sur `pypdf` avec un log warning. Code structuré avec une interface abstraite (`PdfReader` protocol) pour swap transparent. - -##### B. Backend — Indexation des PDF (1 jour) - - [ ] **B1. Ajout à `SUPPORTED_EXTENSIONS`** : Ajouter `.pdf` au set dans `backend/indexer.py:56`. Déclencher un rebuild complet de l'index (incrémental via le file watcher pour les nouveaux PDFs). - - [ ] **B2. Modification de `index_document()`** (`backend/indexer.py:524`) : Dans la fonction d'indexation, détecter l'extension `.pdf` et appeler `extract_pdf_text()` au lieu de `read_text()`. Le texte extrait alimente le pipeline TF-IDF existant — aucun changement nécessaire dans `search.py`. - - [ ] **B3. Métadonnées PDF dans le document info** : Enrichir la structure de retour de `index_document()` avec les champs spécifiques PDF : `page_count`, `pdf_title` (titre extrait des métadonnées, prioritaire sur le nom de fichier), `pdf_author`. - - [ ] **B4. Gestion d'erreur robuste** : PDF corrompu → log warning + skip (ne pas bloquer l'indexation). PDF volumineux (>50 Mo) → log info + extraction tronquée à `SEARCH_CONTENT_LIMIT`. Timeout d'extraction configurable (30s par défaut). - -##### C. Backend — API endpoints PDF (0.5 jour) - - [ ] **C1. Modification de `api_file_view()`** (`backend/main.py:2270`) : Avant la tentative de `read_text()`, détecter `.pdf` par extension. Pour les PDF : - - Extraire le texte avec `extract_pdf_text()` - - Extraire les métadonnées (pages, auteur) - - Retourner une réponse structurée : `is_pdf: true`, `page_count`, `pdf_metadata`, `html` (aperçu texte formaté), `raw_length` - - Le champ `html` contient un rendu texte simple (pas de markdown) : texte paginé ou première page formatée - - [ ] **C2. Nouvel endpoint `GET /api/file/{vault}/pdf/stream`** : Sert le fichier PDF brut avec `Content-Type: application/pdf` et `Content-Disposition: inline` pour visualisation dans le navigateur. Supporte le `Range` header (HTTP 206 Partial Content) pour le streaming progressif des gros PDFs — essentiel pour la performance sur des documents volumineux. - - [ ] **C3. Nouvel endpoint `GET /api/file/{vault}/pdf/info`** : Retourne les métadonnées seules (pages, titre, auteur) sans le contenu — permet à l'UI d'afficher les infos avant de charger le PDF lourd. - - [ ] **C4. Endpoint download** : Déjà fonctionnel (`/api/file/{vault}/download`) — aucun changement nécessaire. - -##### D. Frontend — Arborescence de fichiers (0.5 jour) - - [ ] **D1. Icône et filtre** : L'icône PDF (`file-text` de Lucide) est déjà mappée dans `EXT_ICONS` (`frontend/js/utils.js:129`). Une fois `.pdf` dans `SUPPORTED_EXTENSIONS`, les PDFs apparaissent automatiquement dans l'arborescence via l'API `list_directory`. Aucun changement UI nécessaire. - - [ ] **D2. Distinction visuelle** (optionnel) : Sous-titre léger sous le nom du fichier dans l'arborescence indiquant le nombre de pages (ex: « 12 pages ») pour différencier rapidement les PDF des MD. Donnée disponible via l'API `pdf/info`. - - [ ] **D3. Drag & drop et upload** : Le mécanisme d'upload existant (`POST /api/file/{vault}/upload`) fonctionne déjà pour tout type de fichier. Vérifier que le MIME type `application/pdf` est correctement détecté et que le watcher réindexe automatiquement. - -##### E. Frontend — Viewer PDF (1 jour) - - [ ] **E1. Rendu inline natif** : Utiliser le visualiseur PDF intégré du navigateur via `