# ObsiGate — Roadmap > **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 --- ## Légende - ✅ Complété - 🟡 En cours / Partiel / À investiguer - ⬜ À faire - 🔴 Critique --- ## Quick Wins (15-30 min cumulées) — Implémenter immédiatement Ces 4 actions prennent moins de 30 minutes au total et ont un impact élevé. ### ✅ `.dockerignore` — Réduire le contexte de build Docker **Impact :** Sécurité (pas de fuite de `.git`), performance (build plus rapide) ### ✅ `.env` pour les secrets — Ne jamais commiter de mots de passe **Impact :** Sécurité (pas de secret dans le repo) ### ✅ Compression GZip — Réduire la bande passante de ~70% **Impact :** Performance (pages plus rapides, moins de data transférée) ### ✅ Cache-Control pour assets statiques — Éviter les re-téléchargements **Impact :** Performance (cache navigateur sur CSS/JS/icons) --- ## 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** — 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). --- ## 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 --- ## Chronologie suggérée | 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 | --- *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.*