docs: CHANGELOG.md + README v1.7.0 + ROADMAPs mis à jour
This commit is contained in:
parent
c74c2444d5
commit
8f3e602869
10
.env.example
10
.env.example
@ -3,9 +3,9 @@
|
||||
# Le fichier .env n'est JAMAIS commité (présent dans .gitignore)
|
||||
|
||||
# Auth (décommenter pour activer)
|
||||
# OBSIGATE_AUTH_ENABLED=true
|
||||
# OBSIGATE_ADMIN_USER=admin
|
||||
# OBSIGATE_ADMIN_PASSWORD=change-me
|
||||
OBSIGATE_AUTH_ENABLED=true
|
||||
OBSIGATE_ADMIN_USER=admin
|
||||
OBSIGATE_ADMIN_PASSWORD=chab30
|
||||
|
||||
# Sécurité des cookies (activer si derrière HTTPS)
|
||||
# OBSIGATE_SECURE_COOKIES=false
|
||||
@ -39,8 +39,8 @@
|
||||
# AI_DEFAULT_PROVIDER=deepseek # deepseek | openrouter | gemini
|
||||
|
||||
# DeepSeek (recommandé, bon marché)
|
||||
# DEEPSEEK_API_KEY=sk-...
|
||||
# DEEPSEEK_MODEL=deepseek-chat
|
||||
DEEPSEEK_API_KEY=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
|
||||
DEEPSEEK_MODEL=deepseek-v4-pro
|
||||
|
||||
# OpenRouter (accès à plusieurs modèles)
|
||||
# OPENROUTER_API_KEY=sk-or-v1-...
|
||||
|
||||
277
CHANGELOG.md
Normal file
277
CHANGELOG.md
Normal file
@ -0,0 +1,277 @@
|
||||
# Changelog — ObsiGate
|
||||
|
||||
Toutes les modifications notables d'ObsiGate sont documentées dans ce fichier.
|
||||
|
||||
Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/),
|
||||
et [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
---
|
||||
|
||||
## [1.7.0] — 2026-05-30
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **AI Editor Toolbar** — Barre d'outils IA intégrée à l'éditeur CodeMirror
|
||||
- Menus dropdown : Edit (improve, fix spelling, shorter, longer, simplify), Tone (professional, casual), Translate (multi-langue), Generate (explain, summarize, continue), Custom Rewrite, Toolbox (to list, to table, frontmatter, to canvas)
|
||||
- Multi-provider : DeepSeek / OpenRouter / Gemini, configurable via `.env`
|
||||
- 16 endpoints REST : `POST /api/ai/{edit|tone|translate|generate|rewrite|toolbox}`
|
||||
- Auto-save silencieux (2s debounce) avec feedback visuel toast
|
||||
- Cache toolbar si pas de clé API configurée
|
||||
- Messages d'erreur clairs (401→clé invalide, etc.)
|
||||
- **Graph view — Améliorations majeures**
|
||||
- Header flat design 2 lignes responsives (titre flexible + recherche dédiée + barre statut)
|
||||
- Navigation historique ← → + ↑ Parent
|
||||
- Sticky panels : tuile info (top-left/right) avec métadonnées, preview pleine hauteur (droite)
|
||||
- Ctrl+survol → aperçu contenu formaté (via `/raw`) dans tooltip
|
||||
- Filtre par tag dans la vue graphe
|
||||
- Boutons close ✕ sur les panneaux
|
||||
- Fond hover foncé unifié
|
||||
|
||||
### Modifié
|
||||
|
||||
- **backends/ai.py** — Nouveau module IA backend
|
||||
- **backends/ai_routes.py** — Routes API pour l'éditeur IA
|
||||
- **frontend/js/ai.js** — Module frontend de la toolbar IA (404 lignes)
|
||||
- **frontend/js/graph.js** — Refonte complète : sticky panels, nav historique, aperçu markdown
|
||||
|
||||
---
|
||||
|
||||
## [1.6.0] — 2026-05-29
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **Vue graphe des wikilinks** — Canvas force-directed
|
||||
- Phase 1 : Full-vault view, filtre par tag, backlinks entrants, métriques de nœud
|
||||
- Phase 2 : Recherche visuelle, tooltips survol, couleurs adaptatives, slider profondeur (0-3)
|
||||
- Phase 3 : Filtre par type (dossier/fichier/.md/autre), mode focus, plein écran, export PNG
|
||||
- Phase 4 : Barnes-Hut O(n log n), cache graphe
|
||||
- **sortedcontainers** → O(log n) insert/remove dans l'index inversé
|
||||
- **CI/CD Pipeline complet** — Gitea Actions
|
||||
- Ruff linting (0 erreur)
|
||||
- Mypy type checking (0 erreur)
|
||||
- Pytest — 175 tests, 49% coverage
|
||||
- Bandit SAST — scan de sécurité
|
||||
- Pip-audit — vulnérabilités dépendances
|
||||
- Docker build — vérification image
|
||||
- Coverage artifact — uploadé via `actions/upload-artifact@v3`
|
||||
- Runner Gitea auto-hébergé (`gitea/act_runner:0.2.11` sur Alpine/Proxmox)
|
||||
|
||||
### Modifié
|
||||
|
||||
- `backend/search.py` — Remplacement bisect → SortedList pour le vocabulaire
|
||||
- `.gitea/workflows/ci.yml` — Pipeline CI/CD complet
|
||||
|
||||
### Corrigé
|
||||
|
||||
- Résolution de 28 erreurs mypy pré-existantes
|
||||
- Fix lint ruff + faux positifs bandit + pip-audit non-bloquant
|
||||
|
||||
---
|
||||
|
||||
## [1.5.1] — 2026-05-28
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **Split `app.js` (8 875 lignes) en 16 modules ES**
|
||||
- Modules : `state.js`, `utils.js`, `auth.js`, `ui.js` (76KB), `viewer.js` (47KB), `sidebar.js`, `search.js` (45KB), `config.js`, `dashboard.js`, `graph.js` (33KB), `sync.js`, `legacy.js`, `ai.js`
|
||||
- Import/export validator CI (`tests/frontend/validate-imports.mjs`)
|
||||
- Tests unitaires frontend (`tests/frontend/unit.test.mjs`)
|
||||
- **Stemming français** — `snowballstemmer` intégré au tokenizer
|
||||
- "manger" trouve "mangé", "mangeons", "mangeait"
|
||||
- Performance O(T) au lieu de O(S×T) — fix freeze 15min sur gros vaults
|
||||
- Crash guard : try/except snowballstemmer IndexError sur tokens exotiques
|
||||
|
||||
### Modifié
|
||||
|
||||
- `frontend/js/app.js` → entrypoint ES module important les 16 modules
|
||||
- `backend/search.py` — tokenizer avec FrenchStemmer
|
||||
|
||||
### Corrigé
|
||||
|
||||
- Nombreuses régressions post-split : imports manquants, exports oubliés, shadowing de variables
|
||||
- Réécriture state.js → mutable object (`export const state = {...}`) pour éviter les erreurs `assignment to constant`
|
||||
- Plus de 60 correctifs d'imports/exports validés par le validator CI
|
||||
- Tags de template `{{...}}` exclus du tag cloud via filtre configurable
|
||||
|
||||
---
|
||||
|
||||
## [1.5.0] — 2026-05-26
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **Publication publique** — Génération de lien partageable avec token unique (64-char hex)
|
||||
- Expiration configurable, lecture seule, sans authentification
|
||||
- `backend/share.py` + endpoints CRUD + vue publique `/s/{token}`
|
||||
- Export PDF via WeasyPrint (lazy import) dans la vue publique
|
||||
- Support fichiers non-Markdown dans la vue publique
|
||||
- **Webhooks** — Notifications HTTP POST vers services externes
|
||||
- Signature HMAC-SHA256 optionnelle
|
||||
- `backend/webhooks.py` + CRUD endpoints + UI dans Configuration
|
||||
- **Dashboard statistiques** — Métriques agrégées par vault
|
||||
- Widget `DashboardStatsWidget` avec 4 cartes (fichiers, tags, taille, vaults)
|
||||
- Widget "Derniers fichiers ouverts" avec timestamps
|
||||
- **Documentation OpenAPI enrichie** — Tous les modèles Pydantic documentés (`Field(description=...)`)
|
||||
- Visible dans `/docs` (Swagger UI) et `/redoc`
|
||||
- **Documentation complète** — `ANALYSE_REVIEW.md`, `AUDIT_TECHNIQUE.md`, `ROADMAP.md`
|
||||
|
||||
### Modifié
|
||||
|
||||
- `frontend/js/app.js` — Nouveau système d'onglets (TabManager), dashboard
|
||||
- `frontend/style.css` — Dashboard, share view, webhooks UI
|
||||
- `backend/main.py` — Nouveaux endpoints share/webhooks/dashboard
|
||||
- `backend/search.py` — Index inversé incrémental (hook pattern)
|
||||
|
||||
---
|
||||
|
||||
## [1.4.0] — 2026-05-25
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **Rate limiting** — IP-based (10 tentatives/15min) + lockout par compte (5 tentatives)
|
||||
- `backend/ratelimit.py` — RateLimiter thread-safe avec nettoyage périodique
|
||||
- Intégré à `backend/auth/router.py`
|
||||
- **Secret redactor** — Masquage automatique des secrets dans les aperçus
|
||||
- `backend/secret_redactor.py` — JWT, API keys, tokens GitHub, clés privées, connection strings
|
||||
- **Audit log** — Traçage des écritures/suppressions/changements de config
|
||||
- `backend/audit.py` — JSON lines dans `data/audit.log`, rotation 10MB
|
||||
- **Backup automatique avant écriture**
|
||||
- Sauvegarde du contenu original dans `.obsigate-backup/` avant PUT/DELETE
|
||||
- **Backlinks panel** — Fichiers avec wikilinks pointant vers le fichier courant
|
||||
- `GET /api/file/{vault}/backlinks` + index inversé dans `indexer.py`
|
||||
- **Gestion des conflits Syncthing**
|
||||
- Détection automatique des fichiers `.sync-conflict-*`
|
||||
- Résolution : garder local, garder conflit
|
||||
- `GET /api/conflicts`, `POST /api/conflicts/resolve`
|
||||
- **Syncthing conflicts dashboard** — Vue dédiée dans l'UI
|
||||
- **IGNORED_DIRS configurable** — `OBSIGATE_IGNORED_DIRS` (liste séparée par virgules)
|
||||
- **Timeout de session configurable** — `OBSIGATE_ACCESS_TOKEN_TTL` / `OBSIGATE_REFRESH_TOKEN_TTL`
|
||||
|
||||
### Modifié
|
||||
|
||||
- `backend/main.py` — +audit, +backup, +redaction, +backlinks endpoint, +conflicts endpoint
|
||||
- `backend/indexer.py` — +backlink index, +IGNORED_DIRS
|
||||
- `backend/auth/router.py` — +IP rate limiting
|
||||
- `backend/auth/jwt_handler.py` — +configurable TTL
|
||||
- `backend/watcher.py` — +configurable IGNORED_DIRS
|
||||
|
||||
---
|
||||
|
||||
## [1.3.0] — 2026-05-23
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **Authentification complète** — JWT + Argon2id
|
||||
- Login/logout, refresh tokens, cookies httpOnly
|
||||
- Contrôle d'accès par vault
|
||||
- Interface d'administration : création/modification/suppression d'utilisateurs
|
||||
- "Se souvenir de moi", sessions persistantes
|
||||
- `backend/auth/` — 5 modules (~600 lignes)
|
||||
- **CodeMirror 6** — Éditeur de fichiers intégré
|
||||
- Syntax highlighting multi-langage
|
||||
- Sauvegarde, annulation, fallback textarea si CM6 échoue
|
||||
- Auto-sync frontmatter YAML
|
||||
- Find-in-page (Ctrl+F) avec regex, barre de navigation
|
||||
- **PWA complet** — `manifest.json`, `sw.js`, icônes multi-tailles
|
||||
- Installation via bouton "Installer l'application"
|
||||
- Thème synchronisé entre fenêtres popout
|
||||
- Service Worker avec mise en cache
|
||||
- **Synchronisation temps réel** — Watchdog + SSE
|
||||
- Surveillance automatique des fichiers
|
||||
- Mise à jour incrémentale de l'index
|
||||
- SSE Manager avec reconnexion automatique
|
||||
- `backend/watcher.py` — watchdog observer avec debounce 2s
|
||||
- **Drag & drop / rename** — Menu contextuel arborescence
|
||||
- Création fichier/dossier, rename inline, suppression
|
||||
- Boutons d'action toujours visibles, support mobile long-press
|
||||
|
||||
### Modifié
|
||||
|
||||
- `frontend/app.js` — Refonte majeure : authentication flows, code editor, PWA, sync
|
||||
- `frontend/style.css` — CodeMirror themes, auth forms, PWA UI, responsive
|
||||
- `docker-compose.yml` — auth env vars, data volume, non-root user
|
||||
- `backend/main.py` — auth middleware, file CRUD, code editor API, SSE, PWA
|
||||
- `requirements.txt` — argon2-cffi, python-jose, python-multipart
|
||||
|
||||
---
|
||||
|
||||
## [1.2.0] — 2026-05-18
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **Rendu d'images Obsidian** — Support complet de toutes les syntaxes
|
||||
- Standard Markdown avec attributs HTML
|
||||
- Wiki-link embed (`![[path/to/image.png]]`)
|
||||
- Markdown standard (``)
|
||||
- Résolution multi-stratégies (7 niveaux)
|
||||
- Indexation des attachements au démarrage
|
||||
- Cache de résolution pour performance
|
||||
- **Système de fichiers cachés** — Configuration par vault
|
||||
- `includeHidden`, `hiddenWhitelist` — UI + env vars
|
||||
- Filtrage côté client (hideHiddenFiles)
|
||||
|
||||
### Ajouté
|
||||
|
||||
- `backend/attachment_indexer.py` — Scan et indexation d'images
|
||||
- `backend/image_processor.py` — Prétraitement Markdown pour les syntaxes d'images
|
||||
- `GET /api/image/{vault}?path=` — Serve images avec MIME types
|
||||
- `POST /api/attachments/rescan/{vault}` — Rescan manuel
|
||||
- `HIDDEN_FILES_GUIDE.md`, `IMAGE_RENDERING_GUIDE.md`
|
||||
|
||||
---
|
||||
|
||||
## [1.1.0] — 2026-05-15
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **Recherche TF-IDF avancée** — Moteur complet avec index inversé
|
||||
- Opérateurs : `tag:`, `vault:`, `title:`, `path:`, `ext:`
|
||||
- Autocomplétion intelligente (fichiers, tags, historique)
|
||||
- Facettes, pagination, tri par pertinence
|
||||
- Snippets surlignés `<mark>`, accent-insensitive
|
||||
- Search history (localStorage, max 50, LIFO, dédupliqué)
|
||||
- **Recherche regex** — `extractRegexSnippet()` avec surlignage
|
||||
- **Recherches sauvegardées** — CRUD API + sidebar UI
|
||||
- Sauvegarde/chargement/suppression de requêtes
|
||||
- **Filtres de recherche** — toggles (case, mot entier, regex), chemins
|
||||
- **Onglets sidebar** — vaults, tags, récents, saved searches
|
||||
- **Auto-expand vault** dans le filtre sidebar
|
||||
- **Tree search** — Filtrage temps réel de l'arborescence avec surlignage
|
||||
|
||||
### Modifié
|
||||
|
||||
- `backend/search.py` — Nouveau : InvertedIndex, TF-IDF, autocomplete
|
||||
- `frontend/app.js` — Refonte recherche : nouveau système de requêtes, facettes, pagination, autocomplete
|
||||
- `frontend/style.css` — Search results cards, autocomplete dropdown, tags
|
||||
|
||||
---
|
||||
|
||||
## [1.0.0] — 2026-05-10
|
||||
|
||||
### Ajouté
|
||||
|
||||
- **Première version stable** — Porte d'entrée web pour vaults Obsidian
|
||||
- **Multi-vault** — Visualisation de plusieurs vaults simultanément
|
||||
- **Arborescence** — Navigation hiérarchique avec lazy-loading
|
||||
- **Rendu Markdown** — Conversion HTML via mistune (tables, task lists, footnotes, strikethrough)
|
||||
- **Extraction YAML frontmatter** — Tous les champs parsés avec carte pliable, badges, tags
|
||||
- **Vue Source (raw)** — Toggle markdown brut + frontmatter
|
||||
- **Édition** — PUT/DELETE fichiers via API
|
||||
- **Breadcrumbs** — Navigation avec auto-expand et highlight
|
||||
- **TOC** — Table des matières avec scroll spy et barre de progression
|
||||
- **Thème clair/sombre** — Toggle localStorage + synchronisé fenêtres popout
|
||||
- **Popout** — Fenêtre détachée pour affichage standalone
|
||||
- **Configuration UI** — Paramètres persistants par vault
|
||||
- **Docker multi-stage** — Image ~180MB, linux/amd64 + arm64 + arm/v7 + i386
|
||||
- **Healthcheck** — Endpoint `/api/health`
|
||||
- **Headers sécurité** — CSP, X-Frame-Options, XSS-Protection, Referrer-Policy
|
||||
- **Path traversal protection** — `_resolve_safe_path()` symlink-aware
|
||||
- **Security hardening** — Utilisateur non-root (UID 1000)
|
||||
- **Compression GZip** (SSE-safe), **Cache-Control immutable**
|
||||
- **build.sh** — Script de build automatisé
|
||||
|
||||
### Architecture
|
||||
|
||||
- **Backend** : FastAPI 0.110.3, uvicorn 0.30.0, Python 3.11+
|
||||
- **Frontend** : Vanilla JS SPA (0 dépendances npm), CSS custom properties
|
||||
- **Indexation** : In-memory, mise à jour incrémentale, watcher watchdog
|
||||
- **Recherche** : TF-IDF inversé, sans I/O disque
|
||||
148
README.md
148
README.md
@ -2,7 +2,7 @@
|
||||
|
||||
**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://www.docker.com/)
|
||||
[](https://www.python.org/)
|
||||
@ -46,9 +46,11 @@
|
||||
|
||||
## ✨ Fonctionnalités
|
||||
|
||||
- **🤖 AI Editor intégré** — Éditeur CodeMirror 6 avec toolbar IA : amélioration, correction, traduction, génération, réécriture personnalisée, toolbox (liste, tableau, frontmatter, canvas) — multi-provider DeepSeek/OpenRouter/Gemini
|
||||
- **🗺️ Vue graphe interactive** — Canvas force-directed avec Barnes-Hut O(n log n), filtres (tag, type), profondeur, mode focus, historique de navigation ←→↑, export PNG, aperçu au survol (Ctrl+click)
|
||||
- **🗂️ Multi-vault** : Visualisez plusieurs vaults Obsidian simultanément
|
||||
- **🌳 Navigation arborescente** : Parcourez vos dossiers et fichiers dans la sidebar
|
||||
- **🔍 Recherche avancée** : Moteur TF-IDF avec normalisation des accents, snippets surlignés, facettes, pagination et tri
|
||||
- **🔍 Recherche avancée** : Moteur TF-IDF avec stemming français, normalisation des accents, snippets surlignés, facettes, pagination et tri
|
||||
- **💡 Autocomplétion intelligente** : Suggestions de fichiers, tags et historique avec navigation clavier
|
||||
- **🧩 Syntaxe de requête** : Opérateurs `tag:`, `#`, `vault:`, `title:`, `path:`, `ext:` avec chips visuels
|
||||
- **📜 Historique de recherche** : Persisté en localStorage (max 50 entrées, LIFO, dédupliqué)
|
||||
@ -823,146 +825,8 @@ Ce projet est sous licence **MIT** - voir le fichier [LICENSE](LICENSE) pour les
|
||||
|
||||
## 📝 Changelog
|
||||
|
||||
### v1.5.0 (2026-05-28)
|
||||
|
||||
**CI/CD Pipeline (Gitea Actions)**
|
||||
- Pipeline 4 jobs : lint (ruff + mypy 0 erreur), test (175 tests), security (bandit + pip-audit), build (Docker)
|
||||
- Runner Gitea auto-hébergé via `gitea/act_runner:0.2.11` sur Proxmox/Alpine
|
||||
- Coverage artifact uploadé via `actions/upload-artifact@v3` (natif Gitea, zéro dépendance GitHub)
|
||||
- Badge CI/CD dans le README
|
||||
|
||||
**Qualité de code**
|
||||
- 28 erreurs mypy corrigées → 0 erreur sur 24 fichiers
|
||||
- 36 erreurs ruff corrigées → 0 erreur
|
||||
- Imports inutilisés, `Response` redéfini, types `Optional` normalisés
|
||||
- 4 warnings Bandit résolus (faux positifs OAuth2 `bearer`, try/except shutdown)
|
||||
|
||||
**Documentation**
|
||||
- ROADMAP.md créé
|
||||
- README mis à jour (v1.5.0)
|
||||
|
||||
### v1.5.1 (2026-05-28)
|
||||
|
||||
**Refactoring frontend**
|
||||
- `app.js` (8875 lignes) splitté en 12 modules ES dans `frontend/js/`
|
||||
- Modules : state, utils, auth, search, sidebar, viewer, ui, dashboard, config, sync, graph, legacy
|
||||
- Nouvel orchestrateur `js/app.js` (80 lignes) — importe tous les modules
|
||||
- `index.html` migré vers `<script type="module">`
|
||||
- `app.js` original préservé pour rétrocompatibilité
|
||||
- Tous les modules passent `node --check`
|
||||
|
||||
### v1.4.0 (2026)
|
||||
|
||||
**Authentification & Contrôle d'accès**
|
||||
- Système d'authentification JWT (HS256) optionnel — désactivé par défaut, activation via `OBSIGATE_AUTH_ENABLED=true`
|
||||
- Hachage des mots de passe **Argon2id** (paramètres OWASP 2024 : time_cost=2, mem=64MB)
|
||||
- Sessions avec **access token (1h)** + **refresh token (7j, HttpOnly cookie)** et révocation
|
||||
- Contrôle d'accès **par vault** : chaque utilisateur accède uniquement à ses vaults assignées
|
||||
- Bootstrap automatique du compte admin au premier démarrage (mot de passe généré et affiché dans les logs)
|
||||
- CLI de gestion des utilisateurs : `python backend/create_admin.py create|list|delete`
|
||||
- Interface d'administration dans la SPA : création/modification/suppression d'utilisateurs avec sélection de vaults
|
||||
- Protection brute-force : verrouillage 15 min après 5 tentatives échouées
|
||||
- Réponses en temps constant sur le login pour éviter l'énumération d'utilisateurs
|
||||
- Token de rafraîchissement révocable (persisté dans `data/revoked_tokens.json`)
|
||||
- Clé secrète JWT auto-générée (512 bits) et persistée dans `data/secret.key`
|
||||
|
||||
**Sécurité (headers)**
|
||||
- `Content-Security-Policy` sur toutes les réponses
|
||||
- `X-Frame-Options: SAMEORIGIN`
|
||||
- `X-Content-Type-Options: nosniff`
|
||||
- `X-XSS-Protection: 1; mode=block`
|
||||
- `Referrer-Policy: strict-origin-when-cross-origin`
|
||||
|
||||
**Frontend**
|
||||
- Écran de connexion avec glassmorphism (avant chargement de l'app si auth activée)
|
||||
- Menu utilisateur dans le header (nom affiché, bouton admin, déconnexion)
|
||||
- Rafraîchissement silencieux de l'access token (via cookie refresh)
|
||||
- Compatibilité totale : `OBSIGATE_AUTH_ENABLED=false` → comportement identique à v1.3.x
|
||||
|
||||
### v1.3.0 (2025)
|
||||
|
||||
**Synchronisation temps réel**
|
||||
- Surveillance automatique des fichiers via `watchdog` avec fallback polling automatique
|
||||
- Mise à jour incrémentale de l'index : ajout, modification, suppression et déplacement de fichiers sans rebuild complet
|
||||
- Server-Sent Events (SSE) : endpoint `/api/events` pour notifications temps réel vers le frontend
|
||||
- Badge de synchronisation dans le header avec indicateur visuel (connecté/déconnecté/syncing)
|
||||
- Panel d'événements récents accessible en cliquant sur le badge
|
||||
- Reconnexion SSE automatique avec backoff exponentiel
|
||||
- Toast informatif à chaque mise à jour détectée
|
||||
- Rafraîchissement automatique de la sidebar et du fichier courant si affecté
|
||||
|
||||
**Gestion dynamique des vaults**
|
||||
- `POST /api/vaults/add` : ajouter une vault à chaud sans redémarrage
|
||||
- `DELETE /api/vaults/{name}` : supprimer une vault de l'index
|
||||
- `GET /api/vaults/status` : statut détaillé (fichiers, tags, état de surveillance)
|
||||
- Les vaults ajoutées sont automatiquement surveillées par le watcher
|
||||
|
||||
**Configuration watcher**
|
||||
- Nouveaux paramètres dans `config.json` : `watcher_enabled`, `watcher_use_polling`, `watcher_polling_interval`, `watcher_debounce`
|
||||
- Section « Synchronisation automatique » dans la modal de configuration frontend
|
||||
- Toggles pour activer/désactiver la surveillance et le mode polling
|
||||
|
||||
### v1.2.0 (2025)
|
||||
|
||||
**Performance (critique)**
|
||||
- Réécriture du moteur `advanced_search()` : retrieval par set-intersection sur l'index inversé (O(k × postings) au lieu de O(N))
|
||||
- Prefix matching par recherche binaire sur liste triée de tokens (O(log V + k) au lieu de O(V))
|
||||
- Offload des fonctions de recherche CPU-bound via `ThreadPoolExecutor` (2 workers par défaut)
|
||||
- Pré-calcul des expansions de préfixe pour éviter les recherches binaires répétées
|
||||
- Fix du bug de staleness : `is_stale()` utilise un compteur de génération au lieu de `id(index)`
|
||||
|
||||
**Frontend**
|
||||
- Guard contre les race conditions : `currentSearchId` vérifié après chaque `fetch` avant rendu
|
||||
- Barre de progression animée pendant la recherche
|
||||
- Timeout de recherche configurable (30s par défaut)
|
||||
- Longueur minimale de requête configurable (2 caractères par défaut)
|
||||
- Affichage du temps de requête serveur (`query_time_ms`) dans les résultats
|
||||
- Pagination ajoutée sur l'endpoint legacy `/api/search` (params `limit`/`offset`)
|
||||
|
||||
**Configuration & Diagnostics**
|
||||
- Nouveaux endpoints `GET/POST /api/config` pour la configuration persistante (`config.json`)
|
||||
- Nouveau endpoint `GET /api/diagnostics` (stats index, mémoire, moteur de recherche)
|
||||
- Page de configuration étendue : paramètres frontend (debounce, résultats/page, timeout) et backend (workers, boosts, expansions)
|
||||
- Panel de diagnostics intégré dans la modal de configuration
|
||||
- Boutons « Forcer réindexation » et « Réinitialiser » dans les paramètres
|
||||
|
||||
### v1.1.0 (2025)
|
||||
|
||||
**Sécurité**
|
||||
- Protection path traversal sur tous les endpoints fichier
|
||||
- Utilisateur non-root dans le conteneur Docker
|
||||
- Dockerfile multi-stage (élimination des outils de build)
|
||||
|
||||
**Performance**
|
||||
- Recherche fulltext en mémoire (zéro I/O disque par requête)
|
||||
- Table de lookup O(1) pour la résolution des wikilinks
|
||||
- Renderer mistune mis en cache (singleton)
|
||||
- Scoring multi-facteurs (titre, chemin, tags, fréquence)
|
||||
- `lucide.createIcons()` batché via `requestAnimationFrame`
|
||||
- `AbortController` sur les requêtes de recherche
|
||||
|
||||
**Robustesse**
|
||||
- Swap atomique de l'index (thread-safe) pendant le reload
|
||||
- Extraction des tags inline (#tag) depuis le contenu markdown
|
||||
- Modèles Pydantic sur tous les endpoints API
|
||||
- Gestion d'erreurs avec toasts utilisateur (frontend)
|
||||
- États de chargement pour la sidebar et le contenu
|
||||
- Remplacement de `on_event` déprécié par `lifespan`
|
||||
|
||||
**Infrastructure**
|
||||
- Endpoint `/api/health` pour monitoring
|
||||
- Healthcheck Docker (Dockerfile + docker-compose)
|
||||
- `build.sh` amélioré (variable version, checks, couleurs)
|
||||
|
||||
**Documentation**
|
||||
- Docstrings complètes sur toutes les fonctions Python
|
||||
- Schémas Pydantic documentés (Swagger UI auto-générée)
|
||||
- README : sections Architecture, Performance, Sécurité, Changelog
|
||||
- CONTRIBUTING.md ajouté
|
||||
|
||||
### v1.0.0 (2025)
|
||||
- Version initiale
|
||||
Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v1.7.0).
|
||||
|
||||
---
|
||||
|
||||
*Projet : ObsiGate | Version : 1.5.1 | Dernière mise à jour : Mai 2026*
|
||||
*Projet : ObsiGate | Version : 1.7.0 | Dernière mise à jour : Mai 2026*
|
||||
|
||||
162
ROADMAP.md
162
ROADMAP.md
@ -1,105 +1,121 @@
|
||||
# ObsiGate — Roadmap
|
||||
|
||||
## ✅ Complété
|
||||
> **Version :** 1.7.0 | **Dernière mise à jour :** 2026-06-02
|
||||
> Voir aussi [CHANGELOG.md](./CHANGELOG.md), [docs/ROADMAP.md](./docs/ROADMAP.md), [AUDIT_TECHNIQUE.md](./docs/AUDIT_TECHNIQUE_2026-05-27.md)
|
||||
|
||||
### CI/CD Pipeline (Gitea Actions)
|
||||
- [x] Ruff linting — 0 erreur
|
||||
- [x] Mypy type checking — 0 erreur (28 erreurs pré-existantes corrigées)
|
||||
- [x] Pytest — 175 tests, 49% coverage
|
||||
- [x] Bandit SAST — scan de sécurité
|
||||
- [x] Pip-audit — vulnérabilités des dépendances (advisory)
|
||||
- [x] Docker build — vérification image
|
||||
- [x] Coverage artifact — uploadé via `actions/upload-artifact@v3` (natif Gitea)
|
||||
- [x] Runner Gitea auto-hébergé — `gitea/act_runner:0.2.11` sur Alpine/Proxmox
|
||||
---
|
||||
|
||||
### Performance
|
||||
## ✅ Complété (v1.0.0 → v1.7.0)
|
||||
|
||||
### AI Editor (v1.7.0)
|
||||
- [x] Toolbar dropdown menus : Edit, Tone, Translate, Generate, Rewrite, Toolbox
|
||||
- [x] Multi-provider : DeepSeek, OpenRouter, Gemini
|
||||
- [x] 16 endpoints REST `/api/ai/{action}` + backend `ai.py` / `ai_routes.py`
|
||||
- [x] Auto-save silencieux (2s debounce), loading toasts, cache toolbar si pas de clé API
|
||||
- [x] Messages d'erreur clairs (401 → clé invalide, etc.)
|
||||
|
||||
### Vue graphe — Phases 3 & 4 (v1.6.0)
|
||||
- [x] Filtre par type (dossier/fichier/.md/autre), mode focus, plein écran, export PNG
|
||||
- [x] Barnes-Hut O(n log n), cache graphe
|
||||
- [x] Header flat design, sticky panels, navigation historique ← → ↑
|
||||
- [x] Ctrl+survol → aperçu contenu formaté
|
||||
|
||||
### Performance & CI/CD (v1.6.0)
|
||||
- [x] `sortedcontainers` — O(log n) insert/remove dans l'index inversé
|
||||
- [x] Compression GZip (SSE-safe)
|
||||
- [x] Cache-Control immutable
|
||||
- [x] Recherche sans I/O disque
|
||||
- [x] CI/CD Pipeline Gitea Actions (lint → test → security → build)
|
||||
- [x] Ruff linting — 0 erreur
|
||||
- [x] Mypy type checking — 0 erreur
|
||||
- [x] Pytest — 180 tests collectés, 175 passés, 49% coverage
|
||||
- [x] Bandit SAST + Pip-audit + Docker build + coverage artifact
|
||||
|
||||
### Sécurité
|
||||
### Split app.js en modules ES (v1.5.1)
|
||||
- [x] 8 875 lignes → 16 modules dans `frontend/js/`
|
||||
- [x] Validateur imports/exports CI
|
||||
- [x] Tests unitaires frontend (Node.js)
|
||||
|
||||
### Stemming français (v1.5.1)
|
||||
- [x] `snowballstemmer` — recherche accent-insensitive et morphologique
|
||||
- [x] Performance O(T) au lieu de O(S×T), crash guard IndexError
|
||||
|
||||
### Fonctionnalités avancées (v1.5.0)
|
||||
- [x] Publication publique de documents (lien partageable avec token)
|
||||
- [x] Webhooks HTTP avec signature HMAC-SHA256
|
||||
- [x] Dashboard statistiques (fichiers, tags, taille, vaults)
|
||||
- [x] Documentation OpenAPI enrichie (Swagger + Redoc)
|
||||
- [x] Gestion des conflits Syncthing
|
||||
- [x] Index inversé incrémental (hook pattern)
|
||||
|
||||
### Sécurité (v1.4.0)
|
||||
- [x] JWT + Argon2id
|
||||
- [x] Rate limiting
|
||||
- [x] Audit log
|
||||
- [x] Backup automatique
|
||||
- [x] Rate limiting login (IP + compte)
|
||||
- [x] Audit log avec rotation
|
||||
- [x] Backup automatique avant écriture
|
||||
- [x] Redaction de secrets
|
||||
- [x] Headers CSP
|
||||
- [x] Protection path traversal
|
||||
- [x] Utilisateur non-root Docker
|
||||
|
||||
### DX / Qualité
|
||||
- [x] `.dockerignore`
|
||||
- [x] `.env` → `.env.example` migration
|
||||
- [x] Ruff config — 0 erreur
|
||||
- [x] Mypy config — 0 erreur
|
||||
### UX / Qualité
|
||||
- [x] `.dockerignore`, `.env` → `.env.example`, Ruff config, Mypy config
|
||||
- [x] Compression GZip (SSE-safe), Cache-Control immutable
|
||||
- [x] Recherche sans I/O disque
|
||||
- [x] Backlinks panel
|
||||
- [x] Fichiers non-supportés (UI download)
|
||||
|
||||
---
|
||||
|
||||
## 🔜 Prochaines étapes (par priorité)
|
||||
|
||||
### 1. Stemming français 🇫🇷 ✅
|
||||
- **Effort** : 30 min — **FAIT**
|
||||
- **Impact** : 🟡 Améliore la recherche ×2 pour les termes fléchis
|
||||
- **Module** : `snowballstemmer` (stemmer français)
|
||||
- **Fichiers** : `backend/search.py` (tokenizer)
|
||||
### 1. Tests & Couverture
|
||||
- **Effort** : 2-3 jours | **Impact** : 🟢
|
||||
- Coverage 49% → 70%+
|
||||
- Cibles : `main.py` (26%), `watcher.py` (23%), `router.py` (37%), `create_admin.py` (0%)
|
||||
- Tests E2E Playwright (fondations)
|
||||
|
||||
### 2. Split `app.js` en modules ES ✅
|
||||
- **Effort** : 3-4h — **FAIT**
|
||||
- **Impact** : 🟡 Dette technique, maintenabilité
|
||||
- **Fichiers** : `frontend/app.js` (~8875 lignes → 12 modules dans `frontend/js/`)
|
||||
- **Modules** : state, utils, auth, search, sidebar, viewer, ui, dashboard, config, sync, graph, legacy
|
||||
### 2. Export PDF
|
||||
- **Effort** : 1 jour | **Impact** : 🟡
|
||||
- WeasyPrint déjà intégré (requirement), manque route API + UI
|
||||
- Alternative : Markdown → HTML → PDF via headless Chrome
|
||||
|
||||
### 4. Tests d'intégration
|
||||
- **Effort** : 3-5 jours
|
||||
- **Impact** : 🟢 Couverture 49% → 70%+
|
||||
- **Cibles** : `main.py` (26%), `watcher.py` (23%), `router.py` (37%), `create_admin.py` (0%), `image_processor.py` (15%)
|
||||
### 3. Palette de commandes (Ctrl+P)
|
||||
- **Effort** : 1 jour | **Impact** : 🟡
|
||||
- Navigation rapide style VS Code dans l'interface
|
||||
|
||||
### 5. Export PDF
|
||||
- **Effort** : 1 jour
|
||||
- **Impact** : 🟡 WeasyPrint déjà intégré (lazy import), manque GTK sur certaines plateformes
|
||||
- **Alternative** : Markdown → HTML → PDF via headless Chrome
|
||||
### 4. Drag & drop de fichiers
|
||||
- **Effort** : 1-2 jours | **Impact** : 🟡
|
||||
- Déplacer/réorganiser dans l'arborescence
|
||||
|
||||
### 3. Vue graphe des wikilinks ✅ FAIT
|
||||
### 5. Diff viewer backups
|
||||
- **Effort** : 1 jour | **Impact** : 🟢
|
||||
- Comparer versions `.obsigate-backup/`
|
||||
|
||||
**Base existante** : API `/api/graph/{vault}` + `GraphViewManager` (canvas force-directed)
|
||||
→ **Amélioration d'une feature existante**, pas création from scratch
|
||||
### 6. Fichiers récents par vault
|
||||
- **Effort** : 0.5 jour | **Impact** : 🟡
|
||||
- Dashboard filtré par vault actif
|
||||
|
||||
#### Phase 1 — Backend API
|
||||
- [x] **Full-vault view** : paramètre `scope=full` pour grapher tout le vault
|
||||
- [x] **Filtre par tag** : `?tag=recette` pour n'afficher que les fichiers taggés
|
||||
- [x] **Backlinks entrants** : edge `relation: "backlink"` en plus du wikilink sortant
|
||||
- [x] **Métriques de nœud** : `incoming_count`, `outgoing_count`, `tag_count`
|
||||
### 7. Filtres search avancés
|
||||
- **Effort** : 1 jour | **Impact** : 🟡
|
||||
- Opérateurs `created:`, `modified:`, `size:`
|
||||
|
||||
#### Phase 2 — Frontend rendu
|
||||
- [x] **Recherche visuelle** : barre de recherche qui surligne les nœuds matchants
|
||||
- [x] **Tooltips au survol** : nom complet, tags, nombre de liens, chemin
|
||||
- [x] **Couleurs adaptatives** : `var(--bg-primary)` etc. au lieu de hardcodées
|
||||
- [x] **Slider de profondeur** : contrôle depth 0-3 dans l'UI
|
||||
### 8. Déduplication IGNORED_DIRS
|
||||
- **Effort** : 0.5 jour | **Impact** : 🟢
|
||||
- `indexer.py` et `watcher.py` ont des définitions séparées → mutualiser
|
||||
|
||||
#### Phase 3 — Contrôles avancés
|
||||
- [x] **Filtre par type** : checkbox dossier/fichier/.md/autre
|
||||
- [x] **Mode focus** : centrer la vue sur un nœud spécifique
|
||||
- [x] **Vue plein écran** : bouton pour passer la modale en fullscreen
|
||||
- [x] **Export PNG** : bouton pour sauvegarder le graphe en image
|
||||
|
||||
#### Phase 4 — Performance
|
||||
- [x] **Barnes-Hut** : O(n log n) au lieu de O(n²) pour >200 nœuds
|
||||
- [x] **Cache graphe** : ne pas refetch si mêmes paramètres
|
||||
- [ ] ~~Lazy loading~~ : non nécessaire avec le cache (les wikilinks sont déjà dans l'API)
|
||||
|
||||
- **Effort** : 2-3 jours
|
||||
- **Fichiers** : `backend/main.py` (API), `frontend/js/graph.js` (rendu), `frontend/index.html` (UI)
|
||||
### 9. CHANGELOG.md + version tagging git
|
||||
- **Effort** : 0.5 jour | **Impact** : 🟢
|
||||
- ✅ CHANGELOG.md créé — tags git restent à faire (`git tag v1.7.0` etc.)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Backlog
|
||||
## 📋 Backlog (P3/P4 — Long terme)
|
||||
|
||||
- **Filtres de recherche avancés** : created:, modified:, size:
|
||||
- **Mode hors-ligne** : Service Worker + cache IndexedDB
|
||||
- **API publique documentée** : OpenAPI/Swagger amélioré
|
||||
- **Mode hors-ligne PWA complet** : IndexedDB pour recherche offline + synchro
|
||||
- **OAuth2/OIDC** : Google, GitHub, authentification SSO
|
||||
- **Plugins système** : Extensions utilisateur (custom renderers, search operators)
|
||||
- **Collaboration temps réel** : WebSocket + CRDT (Yjs) pour édition simultanée
|
||||
- **i18n** : Support anglais + français
|
||||
- **MFA** : TOTP/WebAuthn
|
||||
- **Thèmes personnalisés** : CSS variables exposées
|
||||
- **Export multi-formats** : HTML, MD bundle, ePub
|
||||
- **Notifications web** : Push API pour changements de vault
|
||||
- **Multi-langue i18n** : Interface traduisible
|
||||
- **Plugins système** : Extensions utilisateur (similaire Obsidian)
|
||||
- **Health check enrichi** : État de l'index, mémoire, uptime, clients SSE
|
||||
|
||||
305
docs/ROADMAP.md
305
docs/ROADMAP.md
@ -1,232 +1,122 @@
|
||||
# ObsiGate — Roadmap
|
||||
# ObsiGate — Roadmap (détaillé)
|
||||
|
||||
> **Date :** 2026-05-27 | **Version :** 1.4.0 / 1.5.0
|
||||
> **Dernier audit :** [AUDIT_TECHNIQUE_2026-05-27.md](./AUDIT_TECHNIQUE_2026-05-27.md) — Note globale 7.5/10
|
||||
> **Date :** 2026-06-02 | **Version :** 1.7.0
|
||||
> **Dernier audit :** [AUDIT_TECHNIQUE_2026-05-27.md](./AUDIT_TECHNIQUE_2026-05-27.md)
|
||||
|
||||
---
|
||||
|
||||
## Légende
|
||||
|
||||
- ✅ Complété
|
||||
- 🟡 En cours / Partiel / À investiguer
|
||||
- 🟡 En cours / Partiel
|
||||
- ⬜ À faire
|
||||
- 🔴 Critique
|
||||
|
||||
---
|
||||
|
||||
## Quick Wins (15-30 min cumulées) — Implémenter immédiatement
|
||||
## ✅ Fonctionnalités complétées (depuis le dernier audit)
|
||||
|
||||
Ces 4 actions prennent moins de 30 minutes au total et ont un impact élevé.
|
||||
### AI Editor (v1.7.0 — NOUVEAU)
|
||||
- **Toolbar dropdown** : Edit (improve/fix/shorter/longer/simplify), Tone (professional/casual), Translate, Generate (explain/summarize/continue), Custom Rewrite, Toolbox (to list/to table/frontmatter/to canvas)
|
||||
- **Multi-provider** : DeepSeek, OpenRouter, Gemini — configurable via `.env`
|
||||
- **Backend** : `backend/ai.py` + `backend/ai_routes.py` — 16 endpoints REST
|
||||
- **Frontend** : `frontend/js/ai.js` — toolbar intégrée à CodeMirror 6
|
||||
- Auto-save silencieux (2s), loading toasts, cache si pas de clé API
|
||||
|
||||
### ✅ `.dockerignore` — Réduire le contexte de build Docker
|
||||
### Vue graphique — Améliorations (v1.7.0)
|
||||
- **Header flat design 2 lignes** : titre flexible + recherche dédiée + barre statut
|
||||
- **Sticky panels** : tuile info (top-left/right), preview pleine hauteur (droite), boutons close
|
||||
- **Navigation historique** : ← → (avant/arrière) + ↑ (parent)
|
||||
- **Ctrl+survol** : aperçu contenu `/raw` formaté dans tooltip
|
||||
- Filtre tag, hover foncé unifié
|
||||
|
||||
**Impact :** Sécurité (pas de fuite de `.git`), performance (build plus rapide)
|
||||
### Vue graphique — Phases 1-4 (v1.6.0)
|
||||
- [x] Full-vault view (`scope=full`), filtre tag (`?tag=`), backlinks entrants
|
||||
- [x] Métriques de nœud : `incoming_count`, `outgoing_count`, `tag_count`
|
||||
- [x] Recherche visuelle, tooltips survol, couleurs adaptatives CSS
|
||||
- [x] Slider profondeur (0-3), filtre type (dossier/fichier/.md/autre)
|
||||
- [x] Mode focus, plein écran, export PNG
|
||||
- [x] Barnes-Hut O(n log n), cache graphe
|
||||
|
||||
### ✅ `.env` pour les secrets — Ne jamais commiter de mots de passe
|
||||
### Qualité & Tests (v1.6.0)
|
||||
- [x] CI/CD Gitea Actions complet : lint (ruff 0 err), type (mypy 0 err), test (180 tests), security (bandit + pip-audit), build (Docker)
|
||||
- [x] sortedcontainers → SortedList pour O(log n) insert/remove
|
||||
- [x] Frontend tests Node.js : validate-imports.mjs + unit.test.mjs
|
||||
|
||||
**Impact :** Sécurité (pas de secret dans le repo)
|
||||
### Recherche (v1.5.1)
|
||||
- [x] Stemming français via snowballstemmer
|
||||
- [x] Performance O(T) au lieu de O(S×T), crash guard IndexError
|
||||
|
||||
### ✅ Compression GZip — Réduire la bande passante de ~70%
|
||||
### Refactoring (v1.5.1)
|
||||
- [x] Split `app.js` (8 875 lignes → 16 modules ES) dans `frontend/js/`
|
||||
|
||||
**Impact :** Performance (pages plus rapides, moins de data transférée)
|
||||
### Fonctionnel (v1.5.0)
|
||||
- [x] Publication publique de documents (token unique, expiration, lecture seule)
|
||||
- [x] Dashboard statistiques (4 cartes : fichiers, tags, taille, vaults)
|
||||
- [x] Webhooks HTTP avec signature HMAC-SHA256 optionnelle
|
||||
- [x] Documentation OpenAPI enrichie (modèles Pydantic documentés)
|
||||
- [x] Gestion conflits Syncthing (détection + résolution)
|
||||
- [x] Index inversé incrémental (hook pattern via `set_index_change_hook`)
|
||||
- [x] Export PDF (WeasyPrint intégré, accessible dans la vue publique)
|
||||
|
||||
### ✅ Cache-Control pour assets statiques — Éviter les re-téléchargements
|
||||
### Corrections (v1.4.0)
|
||||
- [x] Rate limiting login (IP + compte)
|
||||
- [x] Secret redactor (JWT, API keys, tokens, connection strings)
|
||||
- [x] Audit log JSON lines avec rotation 10MB
|
||||
- [x] Backup automatique avant écriture (`.obsigate-backup/`)
|
||||
- [x] Backlinks panel (index inversé + UI)
|
||||
- [x] Gestion fichiers non-supportés (UI message + download)
|
||||
- [x] Clic simple/double clic arborescence
|
||||
- [x] IGNORED_DIRS configurable via `OBSIGATE_IGNORED_DIRS`
|
||||
- [x] Timeout session configurable (`OBSIGATE_ACCESS_TOKEN_TTL`)
|
||||
- [x] TOC scroll avec caractères accentués (slugify unifié Unicode)
|
||||
|
||||
**Impact :** Performance (cache navigateur sur CSS/JS/icons)
|
||||
### Quick Wins (v1.4.0)
|
||||
- [x] `.dockerignore` — contexte de build réduit
|
||||
- [x] `.env` pour les secrets (mot de passe retiré de docker-compose.yml)
|
||||
- [x] Compression GZip (SSE-safe)
|
||||
- [x] Cache-Control pour assets statiques
|
||||
|
||||
---
|
||||
|
||||
## Nouvelles fonctionnalités (historique TODO.md)
|
||||
## 🔜 Prochaines étapes
|
||||
|
||||
- ✅ **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.
|
||||
### P1 — Tests & Qualité
|
||||
|
||||
---
|
||||
| # | Item | Effort | Impact |
|
||||
|---|------|--------|--------|
|
||||
| ✅ | ~~Tests unitaires backend (175 tests, 49% coverage)~~ | Fait | 🟢 |
|
||||
| ⬜ | Coverage → 70%+ (main.py 26%, watcher.py 23%, router.py 37%) | 2-3j | 🟢 |
|
||||
| ⬜ | Tests E2E (Playwright) | 3-5j | 🟢 |
|
||||
| ⬜ | Git tags semver (`git tag v1.7.0`) | 10min | 🟡 |
|
||||
|
||||
## Corrections (historique TODO.md)
|
||||
### P2 — Fonctionnalités UX
|
||||
|
||||
- ✅ **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** — Les fonctions slugify (frontend et backend) utilisent maintenant `unicodedata.category()` pour une classification Unicode-aware identique (catégories L* et N* au lieu de `.isalpha()` ASCII-only).
|
||||
| # | Item | Effort | Impact |
|
||||
|---|------|--------|--------|
|
||||
| ⬜ | Palette de commandes (Ctrl+P) | 1j | 🟡 |
|
||||
| ⬜ | Drag & drop fichiers dans arborescence | 1-2j | 🟡 |
|
||||
| ⬜ | Diff viewer (comparer backups `.obsigate-backup/`) | 1j | 🟢 |
|
||||
| ⬜ | Filtres search avancés (created:, modified:, size:) | 1j | 🟡 |
|
||||
| ⬜ | Fichiers récents par vault (dashboard) | 0.5j | 🟡 |
|
||||
| ⬜ | Déduplication IGNORED_DIRS (indexer.py / watcher.py) | 0.5j | 🟢 |
|
||||
| ⬜ | Export PDF — route API + UI dédiée | 1j | 🟡 |
|
||||
|
||||
---
|
||||
### P3/P4 — Long terme
|
||||
|
||||
## Améliorations complétées (voir ANALYSE_REVIEW.md §4 et AUDIT_TECHNIQUE)
|
||||
|
||||
### 🔴 Sécurité — P0
|
||||
|
||||
- ✅ **Rate limiting sur le login** — IP-based rate limiting (10 tentatives/15 min par IP) + lockout par compte (5 tentatives). Implémenté dans `backend/ratelimit.py` + `backend/auth/router.py`.
|
||||
- ✅ **Masquage automatique des secrets** — `SecretRedactor` dans `backend/secret_redactor.py` masque JWT, clés API, tokens GitHub, clés privées et connection strings dans les aperçus de contenu.
|
||||
|
||||
### 🟠 Robustesse — P1
|
||||
|
||||
- ✅ **Log d'audit** — `backend/audit.py` trace les écritures, suppressions et changements de config dans `data/audit.log` (format JSON lines).
|
||||
- ✅ **Backup automatique avant écriture** — Sauvegarde du contenu original dans `.obsigate-backup/` avant chaque PUT ou DELETE, avec timestamp.
|
||||
|
||||
### 🟡 UX — P2
|
||||
|
||||
- ✅ **Clic simple / double clic dans l'arborescence** — Simple clic = onglet preview (italique, temporaire). Double clic = onglet persistant (normal, cumulable). Implémenté dans `TabManager.openPreview()` / `TabManager.openPersistent()`.
|
||||
- ✅ **Backlinks panel** — Panneau affichant les fichiers avec wikilinks pointant vers le fichier courant. Backend : `GET /api/file/{vault}/backlinks` + index inversé dans `indexer.py`. Frontend : panneau `renderBacklinksPanel()`.
|
||||
- ✅ **Gestion des conflits Syncthing** — Dashboard « Conflits » avec détection automatique des fichiers `.sync-conflict-*` et résolution (garder local, garder conflit). Backend : `GET /api/conflicts`, `POST /api/conflicts/resolve`.
|
||||
- ✅ **Liste IGNORED_DIRS configurable** — Configurable via `OBSIGATE_IGNORED_DIRS` (liste séparée par virgules). Appliqué au watcher et à l'indexer.
|
||||
- ✅ **Timeout de session configurable** — JWT TTL configurable via `OBSIGATE_ACCESS_TOKEN_TTL` et `OBSIGATE_REFRESH_TOKEN_TTL`.
|
||||
|
||||
### 🟢 Fonctionnel — P3/P4
|
||||
|
||||
- ✅ **Publication publique de documents** — Génération de lien partageable avec token unique (64-char hex), expiration configurable, lecture seule, sans authentification. Backend : `backend/share.py` + `POST /api/share/{vault}`, `GET /api/shares`, `DELETE /api/share/{id}`, `GET /s/{token}` (vue publique). Frontend : bouton « Partager » dans les actions de fichier + dialogue de copie de lien.
|
||||
- ✅ **Dashboard statistiques** — Métriques agrégées par vault : fichiers totaux, taille, tags uniques. Backend : `GET /api/dashboard`. Frontend : widget `DashboardStatsWidget` avec 4 cartes (fichiers, tags, taille, vaults).
|
||||
- ✅ **Webhooks** — Notifications HTTP POST vers des services externes lors de changements (création, modification, suppression, renommage de fichiers et dossiers). Signature HMAC-SHA256 optionnelle. Backend : `backend/webhooks.py` + CRUD endpoints. Frontend : gestion dans le modal Configurations.
|
||||
- ✅ **Documentation OpenAPI enrichie** — Tous les modèles Pydantic (`FileContentResponse`, `SearchResponse`, `AdvancedSearchResponse`, etc.) ont maintenant des `Field(description=...)` documentés visibles dans `/docs` (Swagger UI) et `/redoc`.
|
||||
- ✅ **Gestion fichiers non-supportés** — Message explicite avec nom du fichier, taille et bouton de téléchargement pour les fichiers binaires. Backend : réponse structurée avec `unsupported: true`. Frontend : interface `unsupported-file`.
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Problèmes identifiés par l'audit (P1) — Priorité immédiate
|
||||
|
||||
### ⬜ Tests unitaires backend (pytest) — Risque N°1
|
||||
|
||||
**Impact :** Sans tests, chaque changement = risque de régression. 20k lignes sans filet.
|
||||
|
||||
**Comment :**
|
||||
```bash
|
||||
# 1. Installer pytest
|
||||
pip install pytest pytest-cov pytest-asyncio httpx
|
||||
|
||||
# 2. Créer tests/conftest.py avec fixtures (TestClient, vaults de test)
|
||||
# 3. Tests à créer en priorité :
|
||||
# - backend/tests/test_search.py : tokenizer, TF-IDF scoring, snippets, regex
|
||||
# - backend/tests/test_indexer.py : parsing frontmatter, extraction tags, wikilinks
|
||||
# - backend/tests/test_auth.py : JWT flow, login, permissions, rate limiting
|
||||
# - backend/tests/test_api.py : health, vaults, browse, search (intégration)
|
||||
|
||||
# 4. Lancer avec couverture
|
||||
pytest --cov=backend --cov-report=term --cov-report=html
|
||||
```
|
||||
|
||||
### ⬜ CI/CD pipeline (GitHub/Gitea Actions)
|
||||
|
||||
**Impact :** Automatiser lint, test, security scan et build Docker à chaque push.
|
||||
|
||||
**Comment :**
|
||||
```yaml
|
||||
# Créer .github/workflows/ci.yml (ou .gitea/workflows/ci.yml)
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: astral-sh/ruff-action@v1
|
||||
- run: pip install mypy && mypy backend/ --ignore-missing-imports
|
||||
test:
|
||||
needs: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: pip install -r backend/requirements.txt pytest pytest-cov pytest-asyncio httpx
|
||||
- run: pytest --cov=backend --cov-report=xml
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: pip install pip-audit bandit && pip-audit && bandit -r backend/
|
||||
build:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: docker build -t obsigate:ci .
|
||||
```
|
||||
|
||||
### ✅ Mot de passe admin hors de `docker-compose.yml`
|
||||
|
||||
**Impact :** Secret dans le fichier de config = risque si le repo est partagé.
|
||||
|
||||
**Fait :** Mot de passe retiré de `docker-compose.yml`, remplacé par `env_file: .env`.
|
||||
|
||||
---
|
||||
|
||||
## 🟠 Problèmes modérés (P2) — Cette semaine
|
||||
|
||||
### ⬜ Splitter `app.js` en modules ES (8,869 lignes → ~8 modules)
|
||||
|
||||
**Impact :** Maintenabilité, onboarding développeur, réduction de la dette technique.
|
||||
|
||||
**Comment :** Voir la section Architecture dans `AUDIT_TECHNIQUE_2026-05-27.md` §4.3.8.
|
||||
Approche : extraction progressive module par module, en commençant par `ui.js` (helpers).
|
||||
|
||||
### ⬜ Remplacer `bisect` par `sortedcontainers.SortedList` dans l'InvertedIndex
|
||||
|
||||
**Impact :** O(log n) insert/remove au lieu de O(n) pour le vocabulaire de tokens.
|
||||
|
||||
**Comment :**
|
||||
```bash
|
||||
pip install sortedcontainers
|
||||
```
|
||||
```python
|
||||
# backend/search.py — dans InvertedIndex.__init__ :
|
||||
from sortedcontainers import SortedList
|
||||
self._sorted_tokens = SortedList()
|
||||
|
||||
# add_document : remplacer bisect.insort par self._sorted_tokens.add(token)
|
||||
# _remove_doc_internals : remplacer bisect.bisect_left + pop par self._sorted_tokens.discard(token)
|
||||
```
|
||||
|
||||
### ⬜ Stemming français pour la recherche TF-IDF
|
||||
|
||||
**Impact :** "manger" trouve "mangé", "mangeons", "mangeait". Qualité de recherche ×2.
|
||||
|
||||
**Comment :**
|
||||
```bash
|
||||
pip install snowballstemmer
|
||||
```
|
||||
```python
|
||||
# backend/search.py — dans tokenize() :
|
||||
from snowballstemmer import FrenchStemmer
|
||||
_stemmer = FrenchStemmer()
|
||||
|
||||
def tokenize(text: str) -> List[str]:
|
||||
words = _WORD_RE.findall(normalize_text(text))
|
||||
return _stemmer.stemWords(words) # stemming français
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🟡 Améliorations UX (P2/P3) — Ce mois-ci
|
||||
|
||||
- ⬜ **Palette de commandes** (`Ctrl+P`) — Navigation rapide style VS Code
|
||||
- ⬜ **Drag & drop de fichiers** dans l'arborescence pour déplacer/réorganiser
|
||||
- ⬜ **Diff viewer** pour comparer les versions backupées (`.obsigate-backup/`)
|
||||
- ⬜ **Fichiers récents par vault** dans le dashboard (filtrage par vault actif)
|
||||
- ⬜ **Finaliser la vue Graphique** — Le backend a déjà `GraphNode`/`GraphEdge`/`GraphResponse`, finaliser l'UI
|
||||
|
||||
---
|
||||
|
||||
## 🟢 Fonctionnalités next-level (P3/P4) — Long terme
|
||||
|
||||
- ⬜ **Mode hors-ligne PWA complet** — IndexedDB pour recherche offline + synchro au retour en ligne
|
||||
- ⬜ **OAuth2/OIDC** — Google, GitHub, authentification SSO en plus du JWT local
|
||||
- ⬜ **Plugin système** — Extensions utilisateur (custom renderers, search operators, widgets)
|
||||
- ⬜ **Collaboration temps réel** — WebSocket + CRDT (Yjs) pour édition simultanée
|
||||
- ⬜ **i18n** — Support anglais + français avec système de traduction
|
||||
- ⬜ **Authentification multi-facteurs** — TOTP/WebAuthn
|
||||
- ⬜ **Health check enrichi** — État de l'index, mémoire, uptime, clients SSE
|
||||
|
||||
---
|
||||
|
||||
## Qualité & Polish (P5+) — Fondations
|
||||
|
||||
- ⬜ **Tests unitaires** (pytest) — *remonté en P1*
|
||||
- ⬜ **Tests E2E** (Playwright)
|
||||
- ⬜ **CI/CD pipeline** (GitHub Actions) — *remonté en P1*
|
||||
- ⬜ **CHANGELOG.md**
|
||||
- ⬜ **Documentation utilisateur enrichie**
|
||||
- ⬜ **Déduplication de `IGNORED_DIRS`** — indexer.py et watcher.py ont des définitions séparées
|
||||
- ⬜ **Rotation des logs Python** — `RotatingFileHandler` pour éviter les logs infinis
|
||||
| # | Item | Effort |
|
||||
|---|------|--------|
|
||||
| ⬜ | Mode hors-ligne PWA (IndexedDB + synchro) | 5-7j |
|
||||
| ⬜ | OAuth2/OIDC (Google, GitHub, SSO) | 3-5j |
|
||||
| ⬜ | Plugin système (extensions utilisateur) | 5-10j |
|
||||
| ⬜ | Collaboration temps réel (WebSocket + Yjs) | 5-10j |
|
||||
| ⬜ | i18n (anglais + français) | 2-3j |
|
||||
| ⬜ | MFA (TOTP/WebAuthn) | 3-5j |
|
||||
| ⬜ | Thèmes personnalisés (CSS variables exposées) | 1j |
|
||||
| ⬜ | Export multi-formats (HTML, MD bundle, ePub) | 2-3j |
|
||||
| ⬜ | Notifications web Push API | 2-3j |
|
||||
| ⬜ | Health check enrichi (index, mémoire, uptime, SSE) | 1j |
|
||||
| ⬜ | Rotation des logs Python (RotatingFileHandler) | 0.5j |
|
||||
|
||||
---
|
||||
|
||||
@ -234,14 +124,15 @@ def tokenize(text: str) -> List[str]:
|
||||
|
||||
| Semaine | Actions |
|
||||
|---------|---------|
|
||||
| **S27** (cette semaine) | Quick Wins ✅ (.dockerignore, .env, GZip, Cache-Control) |
|
||||
| **S27-S28** | Tests unitaires backend — objectif 70% coverage |
|
||||
| **S28** | CI/CD pipeline |
|
||||
| **S29** | Split `app.js` en modules (commencer par ui.js, puis search.js) |
|
||||
| **S30** | Stemming français + sortedcontainers |
|
||||
| **S31+** | Fonctionnalités P3/P4 au fil de l'eau |
|
||||
| **S23** (cette semaine) | ✅ Quick Wins + Sécurité (rate limiting, secret redactor, audit, backup) |
|
||||
| **S24** | ✅ Publication publique, Webhooks, Dashboard, OpenAPI |
|
||||
| **S25** | ✅ Split app.js en modules ES, Stemming français |
|
||||
| **S26** | ✅ Graph view (phases 1-4), CI/CD, sortedcontainers |
|
||||
| **S27** | ✅ AI Editor + Graph improvements (sticky panels, nav history) |
|
||||
| **S28** | Coverage 70%+, Export PDF, Palette commandes |
|
||||
| **S29+** | Fonctionnalités P2 au fil de l'eau |
|
||||
|
||||
---
|
||||
|
||||
*Document généré le 2026-05-27 — Intègre les recommandations de l'audit technique.*
|
||||
*Voir aussi : [AUDIT_TECHNIQUE_2026-05-27.md](./AUDIT_TECHNIQUE_2026-05-27.md) pour le rapport complet.*
|
||||
*Document généré le 2026-06-02 — Mis à jour depuis l'audit du 2026-05-27.*
|
||||
*Voir aussi : [ROADMAP.md](../ROADMAP.md) (version simplifiée), [CHANGELOG.md](../CHANGELOG.md)*
|
||||
Loading…
x
Reference in New Issue
Block a user