Add real-time file synchronization with watchdog, SSE notifications, and dynamic vault management API

This commit is contained in:
2026-03-23 14:16:45 -04:00
parent d8e5d0ef57
commit 757b72c549
9 changed files with 1365 additions and 8 deletions
+53 -4
View File
@@ -55,7 +55,10 @@
- **🖼️ Images Obsidian** : Support complet des syntaxes d'images Obsidian avec résolution intelligente
- **🎨 Syntax highlight** : Coloration syntaxique des blocs de code
- **🌓 Thème clair/sombre** : Toggle persisté en localStorage
- **🐳 Docker multi-platform** : linux/amd64, linux/arm64, linux/arm/v7, linux/386
- **� Synchronisation temps réel** : Surveillance automatique des fichiers via watchdog avec mise à jour incrémentale de l'index
- **📡 Server-Sent Events** : Notifications SSE pour les changements d'index avec reconnexion automatique
- **➕ Gestion dynamique des vaults** : Ajout/suppression de vaults via API sans redémarrage
- **�🐳 Docker multi-platform** : linux/amd64, linux/arm64, linux/arm/v7, linux/386
- **🔒 Sécurité** : Protection contre le path traversal, utilisateur non-root dans Docker
- **❤️ Healthcheck** : Endpoint `/api/health` intégré pour Docker et monitoring
@@ -228,6 +231,20 @@ Les vaults sont configurées par paires de variables `VAULT_N_NAME` / `VAULT_N_P
curl http://localhost:2020/api/index/reload
```
### Méthode 3 : API dynamique (sans redémarrage)
Ajoutez une vault à chaud via l'API (le volume doit déjà être monté) :
```bash
curl -X POST http://localhost:2020/api/vaults/add \
-H "Content-Type: application/json" \
-d '{"name": "NouvelleVault", "path": "/vaults/NouvelleVault"}'
```
Supprimez une vault :
```bash
curl -X DELETE http://localhost:2020/api/vaults/NouvelleVault
```
---
## 🔨 Build multi-platform
@@ -356,6 +373,10 @@ ObsiGate expose une API REST complète :
| `/api/tags/suggest?q=&vault=&limit=` | Suggestions de tags (autocomplétion) | GET |
| `/api/tags?vault=` | Tags uniques avec compteurs | GET |
| `/api/index/reload` | Force un re-scan des vaults | GET |
| `/api/events` | Flux SSE temps réel (index updates, vault changes) | GET |
| `/api/vaults/add` | Ajouter une vault dynamiquement | POST |
| `/api/vaults/{name}` | Supprimer une vault | DELETE |
| `/api/vaults/status` | Statut détaillé des vaults (fichiers, watching) | GET |
| `/api/image/{vault}?path=` | Servir une image avec MIME type approprié | GET |
| `/api/attachments/rescan/{vault}` | Rescanner les images d'un vault | POST |
| `/api/attachments/stats?vault=` | Statistiques d'images indexées | GET |
@@ -520,11 +541,12 @@ Ces paramètres sont configurables via l'interface (Settings) ou l'API `/api/con
## 🏗️ Stack technique
- **Backend** : Python 3.11 + FastAPI 0.110 + Uvicorn
- **File Watcher** : watchdog 4.x (inotify natif + fallback polling)
- **Frontend** : Vanilla JS + HTML + CSS (zéro framework, zéro build)
- **Rendu Markdown** : mistune 3.x
- **Image Docker** : python:3.11-slim (multi-stage)
- **Base de données** : Aucune (index en mémoire uniquement)
- **Architecture** : SPA + API REST
- **Architecture** : SPA + API REST + SSE
---
@@ -558,8 +580,11 @@ Ces paramètres sont configurables via l'interface (Settings) ou l'API `/api/con
1. Au démarrage, `indexer.py` scanne tous les vaults en parallèle (thread pool)
2. Le contenu, les tags (YAML + inline) et les métadonnées sont mis en cache en mémoire
3. Une table de lookup O(1) est construite pour la résolution des wikilinks
4. Les requêtes de recherche utilisent l'index en mémoire (zéro I/O disque)
5. Le frontend SPA communique via REST et gère l'état côté client
4. `watcher.py` démarre la surveillance des fichiers (watchdog natif ou polling)
5. Les modifications détectées déclenchent une mise à jour incrémentale de l'index
6. Les changements sont notifiés au frontend via Server-Sent Events (SSE)
7. Les requêtes de recherche utilisent l'index en mémoire (zéro I/O disque)
8. Le frontend SPA communique via REST + SSE et gère l'état côté client
---
@@ -572,6 +597,7 @@ ObsiGate/
│ ├── main.py # Endpoints, Pydantic models, rendu markdown
│ ├── indexer.py # Scan des vaults, index en mémoire, lookup table
│ ├── search.py # Moteur de recherche fulltext avec scoring
│ ├── watcher.py # Surveillance fichiers (watchdog + debounce)
│ └── requirements.txt
├── frontend/ # Interface web (Vanilla JS, zéro framework)
│ ├── index.html # Page SPA + modales (aide, config, éditeur)
@@ -605,6 +631,29 @@ Ce projet est sous licence **MIT** - voir le fichier [LICENSE](LICENSE) pour les
## 📝 Changelog
### 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)**