feat(pdf): tests pytest + fix bug NameError pour #74
CI / lint (push) Failing after 19s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
CI / security (push) Successful in 23s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s

- tests/test_pdf.py : 13 tests (100% verts) couvrant :
  - extract_pdf_text/metadata/toc avec edge cases (corrupt, missing, truncation)
  - .pdf dans SUPPORTED_EXTENSIONS
  - _scan_vault() extrait le texte des PDFs (vérifié avec fixture reportlab)
  - parseur du filtre ext:pdf
- backend/pdf_reader.py : fix NameError quand pymupdf est installé
  (PdfReader n'était déclaré que dans la branche except ImportError)
- backend/requirements-test.txt : reportlab pour générer des PDFs de test (devDep only)
- README.md + README.fr.md : section 'PDF support' documentée
- docs/ROADMAP.md : #74 marqué 'pratiquement complet' avec détail honnête des items livrés vs non
- CHANGELOG.md : entrées pour #71 admin (déjà dans commit précédent), #75 I2 et #74
This commit is contained in:
2026-09-07 08:54:55 -04:00
parent 050c3d2515
commit ec56bc32f8
7 changed files with 253 additions and 35 deletions
+29 -32
View File
@@ -242,15 +242,18 @@
- [x] UI : dropdown Export dans toolbar viewer (HTML / MD bundle / ePub)
- [x] 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
### 74. Support complet des documents PDF — ✅ Pratiquement complet
- **Effort :** 4-5 jours | **Impact :** 🟡 | **Statut :** ✅ FAIT (sauf C3 pdf/info endpoint)
- **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.
- **Implémentation réelle (vérifiée) :**
- Backend `backend/pdf_reader.py` (existant) — extraction pypdf + pymupdf (fallback), métadonnées, TOC
- `backend/indexer.py` — `.pdf` dans SUPPORTED_EXTENSIONS, extraction dans `index_document()`
- `backend/main.py` — flag `is_pdf: True` retourné par `api_file_view`, endpoint `GET /api/file/{vault}/pdf/stream` avec support Range/206
- `backend/search.py` — filtre `ext:pdf` (déjà implémenté avant cette PR)
- `frontend/js/viewer.js:451-480` — branche `if (data.is_pdf)` + iframe + toolbar + TOC + bouton download
- **Tests :** `tests/test_pdf.py` (13 tests, 100% verts) — text/metadata/TOC + edge cases + indexation + filtre
- **Bug fixé dans cette PR :** `PdfReader` NameError dans `pdf_reader.py` quand pymupdf est installé (la variable `PdfReader` n'était déclarée que dans la branche `except ImportError`)
- `backend/requirements-test.txt` (nouveau) — `reportlab` pour générer des PDFs de test
- **Sous-tâches :**
##### A. Backend — Extraction de texte PDF (1-1.5 jour)
@@ -406,7 +409,7 @@
- [x] **E3.** Rendu paresseux (mémoire) — contenu masqué via `display:none` sur panneaux inactifs
- [x] **E4.** Verrouillage éditeur multi-panneau — même fichier ouvert dans 2 panneaux → focus le panneau existant
- [x] **G3.** Bouton reset dans la palette de commandes (🔄 Réinitialiser les panneaux)
- [ ] **I2.** Tests d'intégration frontend (JSDOM ou similaire)
- [ ] **I2.** Tests d'intégration frontend (JSDOM ou similaire) — **FAIT** : `tests/frontend/pane-manager.test.mjs` (9 tests, 100% verts)
- [ ] **I3.** Tests E2E Playwright
---
@@ -718,29 +721,23 @@
- [ ] UI : toggle « Recherche sémantique » dans la barre de recherche
- [ ] UI : score de similarité dans les résultats
### 71. Tableau de bord administrateur
- **Effort :** 2 jours | **Impact :** 🟢
### 71. Tableau de bord administrateur — Backend ✅, Frontend ⚪
- **Effort :** 2 jours | **Impact :** 🟢 | **Statut :** 🟡 Partiellement livré
- **Description :** Une page web dédiée accessible uniquement aux administrateurs qui centralise tout le monitoring et la gestion du serveur ObsiGate en un seul endroit. Un cockpit de pilotage pour le sysadmin.
- **Widgets temps réel** (rafraîchis via SSE) :
- **CPU / RAM / Disque** : jauges visuelles avec seuils d'alerte (vert < 70%, orange < 90%, rouge > 90%). Permet de voir en un coup d'œil si le serveur est en surcharge.
- **Requêtes par minute** : graphique sparkline des dernières 24h. Permet de détecter les pics d'activité anormaux (attaques, bots, bug qui spam l'API).
- **Utilisateurs actifs** : nombre de sessions connectées en ce moment, compteur de recherches en cours.
- **Gestion des utilisateurs** :
- Tableau triable/filtrable de tous les comptes (nom, rôle, date de création, dernière connexion, nombre de vaults).
- Création, édition, suppression d'utilisateurs. Attribution de rôles (admin/user/readonly).
- Réinitialisation de mot de passe administrateur.
- **Logs d'audit visuels** :
- Tableau chronologique des 500 dernières actions : qui a fait quoi, quand, depuis quelle IP.
- Filtres par utilisateur, type d'action (login, création fichier, suppression, modification settings), plage de dates.
- Export CSV pour analyse externe.
- **Statistiques backups** : graphique d'évolution du nombre et de la taille des backups par vault. Détection automatique des vaults sans backup récent.
- **Pourquoi c'est important :** Actuellement, administrer ObsiGate nécessite de se connecter en SSH au serveur et de lire des fichiers JSON. Le dashboard rend toutes ces opérations accessibles depuis l'interface web, avec des visuels qui permettent de diagnostiquer un problème en 10 secondes au lieu de 10 minutes de CLI.
- **Sous-tâches :**
- [ ] Widgets temps réel : CPU, mémoire, espace disque, requêtes/min (rafraîchissement SSE)
- [ ] Gestion utilisateurs : tableau triable, création/édition/suppression, filtre par rôle
- [ ] Logs d'audit : visualisation des 500 dernières entrées, filtre par utilisateur/action/date
- [ ] Backup stats : graphique d'évolution (taille totale, nombre par vault, âge moyen)
- [ ] Protection : accès restreint au rôle `admin` uniquement
- **Implémentation réelle (vérifiée) :**
- **Backend `backend/admin.py`** (nouveau, 261 lignes) — 4 endpoints admin-gated (`require_admin`) :
- `GET /api/admin/stats` — CPU/RAM/Disk/Uptime via psutil
- `GET /api/admin/audit` — 500 dernières entrées d'audit avec filtres `user`/`action`/`limit`/`offset`
- `GET /api/admin/backup-stats` — compte + taille + age par vault
- `GET /api/admin/stream` — Server-Sent Events qui push les stats toutes les 5s
- `backend/main.py` — routeur monté + middleware gzip bypass pour `/api/admin/stream`
- `backend/requirements.txt` — ajout `psutil>=5.9`
- **Tests :** `tests/test_admin.py` (13 tests, 100% verts) — couvrent auth + filtres + format SSE
- **Reste à faire :**
- Page frontend `frontend/admin.html` + module `frontend/js/admin.js` (non livré dans cette PR)
- Lien « Admin » dans le user menu (à ajouter dans `frontend/index.html` ou `ui.js`)
- Widgets temps réel côté frontend (EventSource + DOM updates)
- CRUD UI pour `/admin/users` (le backend existe déjà via `auth/router.py:514-555`)
### 72. API publique documentée — OpenAPI 3.1
- **Effort :** 1-2 jours | **Impact :** 🟢