Recherche plein texte dans le contenu des schémas

- /api/search cherche dans les noms et dans le texte des schémas (textes et
  libellés, noms de cadres, liens) ; tous les mots requis, casse et accents
  ignorés, correspondances sur le nom en premier.
- Index en mémoire côté serveur : texte extrait à la première recherche, relu
  seulement si le fichier change (date ou taille), rien d'écrit sur le volume.
- L'explorateur affiche l'extrait correspondant sous le nom.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H6J7vKwXx7uopxKhWfFJpm
This commit is contained in:
claude BotandClaude Opus 5.5 committed 2026-10-07 18:04:21 +02:00
1 parent 9f9ec3b3a4
commit c78df092c1
8 files changed
+329 -45

No files matched your search

+1 -38
View File
@@ -57,6 +57,7 @@ type Store struct {
History HistoryPolicy
settingsMu sync.Mutex // sérialise les lectures-modifications de .settings.json
index textIndex // texte des schémas pour la recherche (search.go)
}
// New crée le répertoire racine si besoin et renvoie un Store.
@@ -183,44 +184,6 @@ func (s *Store) List(rel string) ([]Entry, error) {
return out, nil
}
// Search parcourt l'arborescence et renvoie les entrées dont le nom contient q.
func (s *Store) Search(q string, limit int) ([]Entry, error) {
q = strings.ToLower(strings.TrimSpace(q))
if q == "" {
return []Entry{}, nil
}
out := []Entry{}
errStop := errors.New("stop")
err := filepath.WalkDir(s.root, func(p string, d fs.DirEntry, err error) error {
if err != nil || p == s.root {
return nil
}
if strings.HasPrefix(d.Name(), ".") {
if d.IsDir() {
return filepath.SkipDir
}
return nil
}
if !visible(d.Name(), d.IsDir()) || !strings.Contains(strings.ToLower(d.Name()), q) {
return nil
}
fi, err := d.Info()
if err != nil {
return nil
}
rel, _ := filepath.Rel(s.root, p)
out = append(out, toEntry(filepath.ToSlash(rel), fi))
if len(out) >= limit {
return errStop
}
return nil
})
if err != nil && !errors.Is(err, errStop) {
return nil, err
}
return out, nil
}
// ETag calcule l'empreinte d'un contenu (utilisée pour l'écriture optimiste).
func ETag(b []byte) string {
h := sha256.Sum256(b)