Files
ObsiGate/docs/ROADMAP.md
T
bruno 58a0ffc76c feat: quick wins - dockerignore, env secrets, gzip, cache-control
- Add .dockerignore to exclude .git, __pycache__, docs, etc. from Docker context
- Create .env.example template with documented env vars
- Move OBSIGATE_ADMIN_PASSWORD from docker-compose.yml to env_file: .env
- Add .env.* to .gitignore (excluding .env.example)
- Enable GZipMiddleware for ~70% bandwidth reduction on text responses
- Add Cache-Control: immutable for /static/ assets
- Update ROADMAP: mark all 4 quick wins as done, add audit findings
- Add comprehensive technical audit report (AUDIT_TECHNIQUE_2026-05-27.md)
2026-05-27 20:35:08 -04:00

248 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.*