# 🔍 Guide Recherche, PDF, Excel & Excalidraw ObsiGate va au-delà de la simple lecture : recherche puissante, rendu des documents riches (PDF, diagrammes) et indexation de leur contenu pour que tout soit retrouvable. > **Public :** tous les utilisateurs > **Fiches techniques :** [`features/semantic-search.md`](../features/semantic-search.md) · > [`features/pdf.md`](../features/pdf.md) · [`features/excalidraw.md`](../features/excalidraw.md) --- ## 1. Recherche plein texte (TF-IDF) Le moteur d'ObsiGate s'appuie sur un **index inversé** et un scoring **TF-IDF** avec : - **Boost titre** — une correspondance dans le titre pèse 3× plus. - **Normalisation des accents** — `resume` trouve `résumé`, `elephant` trouve `éléphant`. - **Stemming français** — les variantes des mots sont rapprochées. - **Snippets surlignés** — les termes trouvés sont mis en `` dans l'extrait. - **Facettes** — compteurs par vault, par tag et par extension sur les résultats, panneau repliable d'un clic (chevron, état mémorisé). - **Pagination** — 50 résultats par page. - **Tri** — par pertinence (TF-IDF) ou par date de modification. - **Chips de filtres** — les filtres actifs apparaissent sous forme de puces retirables. - **Historique** — les 50 dernières recherches sont conservées en `localStorage`. La recherche s'effectue **sans I/O disque** : le contenu est déjà en mémoire. --- ## 2. Syntaxe de requête | Opérateur | Description | Exemple | |---|---|---| | `tag:` | Filtre par tag | `tag:recette docker` | | `#` | Raccourci de tag | `#linux serveur` | | `vault:` | Filtre par vault | `vault:IT kubernetes` | | `title:` | Filtre par titre | `title:pizza` | | `path:` | Filtre par chemin | `path:recettes/soupes` | | `ext:` | Filtre par type de fichier | `ext:md kubernetes` | | `"phrase exacte"` | Recherche d'une phrase | `tag:"multi mots"` | Les opérateurs sont **combinables** : ```text tag:linux vault:IT ext:md serveur web ``` Cette requête cherche « serveur web » dans les fichiers Markdown de la vault `IT` portant le tag `linux`. ### Filtres par extension | Extension | Contenu | |---|---| | `ext:md` | Notes Markdown | | `ext:py`, `ext:sh`, `ext:js` | Scripts et code | | `ext:pdf` | Documents PDF (texte extrait) | | `ext:excalidraw` | Diagrammes Excalidraw (texte extrait) | --- ## 3. Autocomplétion et suggestions - **`/api/suggest`** — suggère des titres de fichiers. - **`/api/tags/suggest`** — suggère des tags. - Navigation clavier : `↑` / `↓` puis `Entrée` ; `Échap` ferme les suggestions. ### Raccourcis de recherche | Raccourci | Action | |---|---| | `Ctrl + K` / `Cmd + K` | Focaliser la barre de recherche | | `/` | Focaliser la recherche (hors champ texte) | | `↑` / `↓` | Naviguer dans les suggestions | | `Entrée` | Sélectionner la suggestion active ou lancer la recherche | | `Échap` | Fermer les suggestions / quitter la recherche | Recherches sauvegardées et signets sont disponibles via l'API (`/api/saved-searches`, `/api/bookmarks`). --- ## 4. Recherche sémantique (optionnelle) Au classement TF-IDF peut s'ajouter un classement **par embeddings**, fusionné via la méthode **RRF** (Reciprocal Rank Fusion). Activation : touche `~` (ou `Alt + S`) dans la recherche. Deux modes : 1. **Sans dépendance** — un *embedder* par hachage fournit une base utilisable immédiatement. 2. **Embeddings réels** — installez `backend/requirements-semantic.txt` et/ou renseignez les variables `OBSIGATE_EMBEDDING_*` pour utiliser `all-MiniLM-L6-v2`. Détails et configuration : [`features/semantic-search.md`](../features/semantic-search.md). --- ## 5. Support PDF ### Lecture Les fichiers PDF de vos vaults s'affichent **en ligne** dans le navigateur via le visualiseur PDF natif (iframe + ``). Le fichier est **streamé** en HTTP Range (`206 Partial Content`) : les gros PDF se chargent progressivement. ### Recherche Le texte est **extrait à l'indexation** (`pypdf` / `pymupdf`), donc le contenu des PDF est recherchable via la recherche plein texte. Utilisez `ext:pdf` pour limiter les résultats aux PDF. ### Métadonnées `GET /api/file/{vault}/pdf/info` renvoie les métadonnées (pages, titre, auteur) **sans transférer** le document. ```bash curl "http://localhost:2020/api/file/Recettes/pdf/info?path=menu.pdf" ``` ### Limites - **Pas d'OCR** : les PDF scannés (images) ne sont pas recherchables. - Pas d'annotation ni d'édition du PDF lui-même. --- ## 6. Tableurs Excel (XLSX) ### Créer un classeur Pour démarrer un tableur, clic droit sur un vault ou un dossier → **Nouveau fichier** (ou **Nouveau fichier ici**), choisissez le type **Excel (.xlsx)** et saisissez un nom : le classeur est créé avec une feuille **Feuille1** et s'ouvre directement dans l'éditeur, prêt à être saisi. La même liste de types est accessible depuis la palette de commandes (`Ctrl+Alt+Space`). ### Affichage et édition Un fichier `.xlsx` s'ouvre dans une visionneuse dédiée : un tableau par feuille, des onglets pour naviguer entre elles (toujours visibles, même à une seule feuille), les en-têtes A1/B1 et les numéros de ligne. La barre de commandes reprend l'ordre de Google Sheets (recherche, annuler/rétablir, impression, peinture, zoom, formats de nombre, police, couleurs, bordures, fusion, alignements, retour ligne, rotation, options) et le bouton **⋮** regroupe figeage, tri, filtre, dimensions, lien, commentaire ; les menus **Mise en forme** / **Structure** restent disponibles. Elle est **épinglée en haut** de la page et l'éditeur occupe toute la largeur du contenu, pour que les commandes restent atteignables pendant le défilement d'un grand tableau. Les largeurs de colonnes et hauteurs de lignes s'ajustent en **glissant le bord des en-têtes** (souris et tactile) : en plaçant le pointeur sur le bord d'un en-tête de colonne (`A`, `B`, `C`…) ou de ligne (`1`, `2`, `3`…), le curseur change pour indiquer l'ajustement. ### Sélectionner et saisir Comme dans Google Sheets et Excel, une cellule est **sélectionnée** ou **en cours de saisie** — jamais les deux à la fois. - **Sélectionner** — un clic ou les flèches : la cellule s'entoure, sans curseur clignotant. - **Saisir** — un **double-clic** (le curseur se place sous le pointeur, la saisie se fait en place), la **première frappe** (qui *remplace* le contenu au lieu de s'y ajouter), ou `F2`. - **Valider et descendre** — `Entrée` pendant la saisie enregistre et place le focus **sur la cellule du dessous**. `Entrée` sur une cellule simplement sélectionnée la bascule en saisie. `Tab` fait de même vers la droite. Les **flèches** valident aussi et déplacent la sélection. - **Quitter la saisie** — `Échap` restaure la valeur d'origine ; un clic ailleurs conserve ce qui a été tapé. - `Alt`+flèche insère un saut de ligne **dans** la cellule. **Sélection multiple** — `Maj`+clic ou `Maj`+flèches étendent la plage depuis la cellule d'origine ; glisser à la souris fait de même. Un **clic simple** réduit toujours la sélection à la cellule cliquée. La plage est **contourée** comme dans Excel, et les en-têtes couverts (lettres et numéros de ligne) sont mis en évidence. Depuis les **marges**, un clic sur un numéro de ligne ou une lettre de colonne sélectionne la **ligne ou la colonne entière**, et glisser — ou `Maj`+clic — étend à **plusieurs lignes ou colonnes** (`A1:Z5`). Une sélection de plusieurs cellules affiche une mini-barre (lien, commentaire, réinitialiser le filtre, somme). **Enregistrer**, placé à droite des onglets de feuilles, envoie les cellules modifiées à `PUT /api/file/{vault}/xlsx/save` : une sauvegarde par feuille, avec **backup automatique** du fichier avant écriture, et une écriture **atomique** (le classeur n'est jamais laissé à moitié écrit). Le bouton **« + »** à côté des onglets ajoute une nouvelle feuille. Une pastille **« Lecture seule »** rappelle la seule limite de la vue : les formats `.xls`/`.ods`. ObsiGate calcule par ailleurs les formules courantes à l'écran (arithmétique, `SOMME`, `MOYENNE`, `SI`…) ; les fonctions non prises en charge affichent la formule telle qu'enregistrée, Excel la recalcule à l'ouverture. Le tableau suit le **thème de l'application** : fond, en-têtes, bordures et lignes alternées sont dérivés du thème actif (tous les thèmes, y compris contrasté élevé et sépia). La grille montre toujours les colonnes **A à Z** et **1000 lignes**, comme un tableur : les lignes et colonnes inutilisées restent affichées et leurs cellules vides sont **éditables** comme les autres. Seule la feuille affichée est étendue, à son ouverture. ### Avertissement avant enregistrement Certains classeurs contiennent des éléments qu'ObsiGate ne sait pas réécrire : **valeurs calculées** mises en cache par Excel, segments (slicers), chronologies, contrôles de formulaire, connexions/requêtes, XML personnalisé, signature numérique, commentaires enrichis, macros. L'ouverture affiche alors un bandeau qui les liste, et la première sauvegarde demande confirmation dans une fenêtre intégrée au thème de l'application. Si vous refusez, rien n'est écrit. > Les **graphiques, images et tableaux croisés** sont, eux, bien conservés. Si le classeur est modifié ailleurs entre-temps (autre poste, Excel, synchronisation…), ObsiGate n'interrompt pas votre travail : un bandeau vous propose de **réessayer**. Le bouton **Réessayer** relit d'abord le fichier pour récupérer la version courante, puis rejoue l'enregistrement — vos modifications restent en place pendant tout ce temps. ### Formules Par sécurité, une valeur saisie commençant par `=` ou `@` est **stockée comme texte** (une formule injectée s'exécuterait à l'ouverture du fichier dans Excel). Le bouton `f(x)` de la barre d'outils active les vraies formules pour la session en cours. ```bash curl -X PUT "http://localhost:2020/api/file/Recettes/xlsx/save?path=budget.xlsx" -H "Content-Type: application/json" -d '{"sheet": "Budget", "cells": {"B1": "250"}, "allow_formula": false, "force": false}' ``` - `allow_formula` : `true` pour écrire une vraie formule (`=B1*2`). - `force` : `true` pour enregistrer malgré les éléments non préservés (sinon l'API répond **409** `xlsx_lossy_content`). - `if_match` (facultatif) : la **version** du fichier attendue, telle que la lecture la renvoie (`xlsx_revision` ou `revision`). Si le fichier a changé depuis, l'écriture est refusée (**409** `conflict`, `details.reason = "stale_revision"`) au lieu d'écraser le travail de l'autre écrivain ; relisez le fichier puis renvoyez la nouvelle version. Les trois routes d'écriture (`xlsx/save`, `xlsx/structure`, `csv/save`) acceptent l'en-tête `If-Match` ou le champ `if_match` et renvoient la version à jour dans `revision`. ### Feuilles volumineuses et lecture par fenêtres Le rendu est plafonné à **500 lignes × 40 colonnes** par feuille. Quand une feuille dépasse ce plafond, un bandeau **« Feuille tronquée »** l'annonce explicitement (par exemple « 500 lignes affichées sur 520 ») au lieu de présenter une table courte comme complète — le classeur, lui, n'est jamais modifié. La ligne d'en-têtes de colonnes reste visible pendant le défilement vertical. Côté API, `GET /api/file/{vault}/xlsx/sheet` sert une feuille **par fenêtres de lignes**, y compris au-delà du plafond d'affichage — les coordonnées A1 renvoyées sont celles de la feuille réelle : ```bash curl "http://localhost:2020/api/file/Recettes/xlsx/sheet?path=budget.xlsx&sheet=Budget&offset=500&limit=200" ``` - `offset` : première ligne renvoyée (0-based) ; `limit` : nombre de lignes (1 à 1 000 par requête). - La réponse porte `total_rows`, `truncated` et `has_more` pour paginer. - Erreurs : **404** si la feuille n'existe pas, **415** si le fichier n'est ni un `.xlsx` ni un `.xlsm`. ### Fonctions avancées **Barre de formule, zone Nom et navigation clavier** — au-dessus du tableau, la **zone Nom** affiche l'adresse de la cellule active (`B12`) ou de la plage sélectionnée (`A1:B3`) et elle est **éditable** (« Atteindre ») : saisissez une référence puis `Entrée` pour y aller (`B12`, `A1:B3`, `$A$1`, ou `Feuille2!A1` pour changer d'onglet) ; une référence inconnue est refusée avec un message et l'adresse précédente est restaurée. La barre de formule reflète la cellule active et propose les **noms de fonctions** courants pendant la saisie. `Tab`/`Maj+Tab` et les flèches circulent entre les cellules, `Maj+flèches` étend la sélection, `Entrée` valide, `Maj+Entrée` insère un saut de ligne **dans** la cellule, `F2` ouvre la cellule en édition, `Suppr` vide la sélection, `Échap` restaure la valeur d'origine ; `Origine`/`Fin` vont au bord de la ligne, `Ctrl+Origine`/`Ctrl+Fin` aux coins de la feuille affichée, `PgPréc`/`PgSuiv` font défiler d'un écran, `Ctrl+flèches` saute au bout de la plage de données, `Ctrl+A` sélectionne toute la feuille affichée et `Ctrl+S` enregistre. Tant que la cellule n'est pas en cours d'édition, `Suppr` efface la sélection plutôt qu'un caractère. **Presse-papiers de plage** — copier, couper et coller un **bloc** de cellules (`Ctrl+C`, `Ctrl+X`, `Ctrl+V`, ou les entrées correspondantes du menu contextuel) : coller un bloc copié ici **ou depuis Excel** remplit la plage à partir de la cellule active et la laisse sélectionnée. Le collage est du **texte** (formules et valeurs recopiées telles quelles) et reste **annulable** ; « couper » efface la source après le collage (un collage sur place ne l'efface pas). Un bloc plus large que la grille affichée est tronqué, avec un message. **Annuler / rétablir** — `Ctrl+Z` (ou le bouton **Annuler** du ruban) revient sur les dernières éditions de cellules, `Ctrl+Maj+Z` / `Ctrl+Y` les rétablit. **Sélection et menu contextuel** — cliquer une cellule l'active, **glisser** ou `Maj+clic` sélectionne une plage (affichée dans la zone Nom, ex. `A1:B3`), et cliquer un **en-tête** sélectionne toute la ligne ou colonne. Un **clic droit** (ou un **appui long** sur mobile) ouvre un menu : copier, couper, coller, insérer/supprimer une ligne ou une colonne, trier A→Z / Z→A, effacer le contenu. Chaque entrée porte une **icône** ; le menu se referme dès qu'il perd le focus (clic ailleurs, `Échap`) et se parcourt au clavier (`↑`/`↓`). **Tri, filtre, recherche, export** — le tri (ascendant / descendant) s'applique depuis le menu contextuel et n'affecte que l'affichage ; les lignes se filtrent et la recherche (`Ctrl+F` du panneau) parcourt **toutes les feuilles** : le compteur indique le nombre de feuilles concernées et passer sur une correspondance **active l'onglet** qui la contient. La sortie est rassemblée dans un seul menu **Fichier**, placé à droite des onglets de feuilles, juste avant le bouton **Enregistrer**. Il propose cinq actions, toujours sur le **contenu affiché** (et jamais sur les valeurs calculées en cache) : - **Télécharger le fichier** — le classeur d'origine, tel qu'il est sur le disque ; - **CSV** — exporte la **sélection** quand une plage de plusieurs cellules est active (le nom du fichier reprend la plage, ex. `Fruits-A1B2.csv`), sinon la feuille entière ; - **Markdown** et **HTML** — tableau markdown ou document HTML autonome, mêmes règles de sélection ; - **Imprimer** — imprime la feuille ou la sélection seule, sans le ruban ni les panneaux de l'application. Le menu se ferme au clic extérieur, à la perte de focus, avec `Échap` ou au défilement, et se parcourt aux flèches. Rien de tout cela ne modifie le classeur. **Structure** — le menu **Structure** de la barre d'outils ajoute, renomme, duplique ou supprime une feuille, et insère/supprime des lignes ou colonnes autour de la cellule active (`PUT …/xlsx/structure`, backup automatique et confirmation, comme pour l'édition des cellules). **Mise en forme** — le bouton **Mise en forme** ouvre un menu qui agit sur la **sélection courante** (une cellule ou une plage), repris aussi dans la barre d'outils (gras, italique, barré, souligné, taille, couleurs, bordures, alignements, retour ligne, rotation) : - **caractère** — gras, italique, souligné, barré, taille de police, effacer la mise en forme ; - **alignement** — gauche, centré, droite, justifié (+ vertical, retour à la ligne, rotation) ; - **bordures** — toutes, extérieures, aucune ; - **couleurs** — couleur de police et couleur de fond, via un **panneau façon Google Sheets** : *Réinitialiser*, une palette de 80 pastilles (une ligne de gris du noir au blanc, puis huit teintes du clair au foncé), une section **Standard** de huit couleurs prédéfinies et une section **Personnalisé**. Un clic sur une pastille referme le panneau et applique la couleur à la cellule ou à la plage sélectionnée. Le bouton **+** ouvre le sélecteur du système pour une teinte libre. « Mise en forme conditionnelle » et « Couleurs en alternance » sont annoncées mais pas encore disponibles ; - **format de nombre** — général, nombre, pourcentage, devise, date, texte ; - **structure** — fusionner / défusionner les cellules, figer / libérer les volets, largeur de colonne, hauteur de ligne (fusionner exige une vraie plage). L'écriture passe par `PUT …/xlsx/style`, avec les mêmes garanties que l'édition des cellules : backup automatique, écriture atomique, confirmation si l'opération détruirait des éléments non préservables (graphiques, valeurs calculées en cache…) et **détection d'un écrivain externe** (`If-Match` → message « Réessayer »). Un `.csv` ne portant pas de mise en forme, le bouton n'y est pas proposé (il est également absent d'une grille en lecture seule). La lecture restitue par ailleurs les couleurs, polices, cellules fusionnées et volets figés du fichier ; l'ancrage de la zone figée est conservé au défilement. Les **commentaires** se lisent (pastille) et s'éditent (mini-barre ou menu ⋮) ; les liens s'insèrent comme formules `=LIEN(url;libellé)` (ouvr. `Ctrl+clic`). Restent hors périmètre : validation de données, mise en forme conditionnelle, graphiques et tableaux croisés dynamiques. **Formats de fichiers** — `.xlsm` s'édite comme un `.xlsx` et ses **macros sont préservées** à l'enregistrement (y compris le chargement des lignes au-delà du plafond) ; `.xls` et `.ods` s'affichent en **lecture seule** ; un `.csv` s'ouvre dans la même grille et se réécrit conformément à la RFC 4180 (les guillemets et séparateurs sont échappés). Le **séparateur du CSV est détecté** (`;`, `,` ou tabulation) à la lecture et **réutilisé à l'enregistrement** : un fichier exporté par Excel en français (point-virgule) s'affiche donc en colonnes distinctes et le reste après édition. **Tableau de bord** — le bouton **Tableau de bord** ouvre un **inspecteur latéral droit** (la grille reste visible à côté) qui liste les plages nommées du classeur (nom, référence, portée), signale les feuilles contenant des graphiques ou des tableaux croisés, et donne pour chaque feuille un résumé (cellules, lignes, colonnes, formules, valeurs numériques) avec quelques chiffres clés. Cliquer une **plage nommée** sélectionne sa première cellule dans la grille, et le panneau est **redimensionnable**. L'en-tête de l'inspecteur offre aussi un accès direct à l'**assistant IA**, qui peut ensuite exploiter ces plages. Ses outils couvrent désormais les **trois formats édités** (`.xlsx`, `.xlsm`, `.csv`) : `list_xlsx_sheets` et `xlsx_to_markdown` pour lire, `search_workbook` (recherche dans toutes les feuilles, comptée par feuille), `analyze_range` (agrégats — nombre, somme, moyenne, min, max — d'une plage A1), `update_xlsx_cells` et `append_xlsx_rows` pour modifier, et `edit_xlsx_structure` pour la structure (ajouter/renommer/dupliquer/supprimer une feuille, insérer/supprimer des lignes ou des colonnes). ### Limites - L'affichage intégré démarre à **500 lignes × 40 colonnes** par feuille ; sous une feuille plus grande, le bouton **« Charger la suite »** (ou le défilement vers le bas du tableau) ajoute les lignes suivantes par fenêtres de 500 — elles deviennent aussitôt éditables et sauvegardables. Le chargement paresseux est **vertical uniquement** : l'axe des colonnes reste tronqué à 40 (les colonnes au-delà ne sont ni affichées ni exportées). - Un **format de nombre personnalisé** (devise, pourcentage…) est signalé par une police à chasse fixe à la lecture ; depuis le bouton **Mise en forme**, appliquer un format ne change que le format de la cellule, **pas** la valeur affichée (aucun recalcul n'est fait, cf. les limites d'export ci-dessous). - `.xls` et `.ods` restent en lecture seule (convertir vers `.xlsx` pour éditer) ; les macros d'un `.xlsm` sont conservées mais ne s'exécutent pas dans ObsiGate. - La **poignée de recopie** (fill), la multi-sélection `Ctrl+clic` et le glisser-déposer de lignes/colonnes ne sont pas proposés ; un collage de plusieurs cellules s'annule **cellule par cellule** (`Ctrl+Z` répété). - Les exports (CSV, Markdown, HTML, impression) reflètent ce qui est **affiché** : une feuille tronquée s'exporte tronquée, et les formules sortent telles qu'enregistrées (aucune valeur calculée n'est recalculée). Un classeur reste la source de vérité : utilisez **Charger la suite** pour exporter au-delà du plafond. - **Moteur de formule local** : ObsiGate calcule à l'écran l'arithmétique, les références, les plages et une trentaine de fonctions en français et en anglais (`SOMME`, `MOYENNE`, `SI`, `LIEN`…). Une saisie commençant par `=` ou `@` reste stockée comme **texte** (garde anti-DDE) tant que le bouton `f(x)` n'est pas activé ; l'enregistrement vous le signale par un message. Les fonctions non prises en charge affichent la valeur mise en cache par Excel quand elle existe. Excel reste la référence pour les valeurs calculées. - L'**annulation** couvre l'édition, l'effacement, le tri/filtre et les actions de structure ; en revanche une **suppression** (feuille, ligne, colonne) n'est pas annulable, faute d'inverse. --- ## 7. Diagrammes Excalidraw Les fichiers `.excalidraw` et `.excalidraw.md` (dont le format compressé du **plugin Obsidian Excalidraw**) s'ouvrent dans un **éditeur visuel Excalidraw complet**, dans une iframe sandboxée. - **Dessin et édition** sans quitter ObsiGate. - **Sauvegarde automatique** (débounce 2 s) ou `Ctrl + S`. - **Thème** clair/sombre suivi automatiquement. - **Texte indexé** : le texte des éléments du diagramme est extrait à l'indexation et donc recherchable (`ext:excalidraw`). Fiche technique : [`features/excalidraw.md`](../features/excalidraw.md). --- ## 8. Autres contenus riches ### Mermaid Les blocs de code ` ```mermaid ` sont rendus en diagrammes interactifs (live preview, thèmes, zoom, plein écran, pré-processeur compatible syntaxe Obsidian). ### Images Obsidian Toutes les syntaxes d'images sont supportées avec résolution intelligente en 7 stratégies : 1. chemin absolu ; 2. dossier d'attachements configuré (`VAULT_N_ATTACHMENTS_PATH`) ; 3. index de démarrage (correspondance unique) ; 4. même répertoire que la note ; 5. racine de la vault ; 6. index de démarrage (correspondance la plus proche) ; 7. repli : `[image not found: fichier.ext]`. Rescan manuel des attachements : ```bash curl -X POST "http://localhost:2020/api/attachments/rescan/Recettes" ``` ### Graphe et backlinks - **Graphe** : vue force-directed (Barnes-Hut), filtres (tag, type), profondeur, mode focus, export PNG, aperçu au survol (`Ctrl + clic`). - **Backlinks** : `GET /api/file/{vault}/backlinks?path=…` liste les notes pointant vers un document. --- ## 9. Dépannage | Symptôme | Piste | |---|---| | Un PDF ne s'affiche pas | Vérifier la taille (`OBSIGATE_PDF_MAX_SIZE_MB`, défaut 50 Mo) | | Le texte d'un PDF scanné n'est pas trouvé | Pas d'OCR : normal | | Une image reste introuvable | Configurer `VAULT_N_ATTACHMENTS_PATH`, puis rescan | | La recherche sémantique ne s'active pas | Vérifier le toggle `~` et `OBSIGATE_EMBEDDING_*` | | Résultats obsolètes | Forcer une réindexation : `GET /api/index/reload` |