veza/veza-backend-api/internal/api/routes_search.go
senke 171a154763 feat(v0.10.2): Recherche fulltext Elasticsearch - F361-F365
- Elasticsearch 8.x dans docker-compose.dev
- Package internal/elasticsearch: client, config, mappings, indices
- Sync PG→ES: reindex tracks/users/playlists, IndexTrack/DeleteTrack
- SearchService ES: multi_match + fuzziness (typo tolerance), highlighting
- Fallback gracieux: PostgreSQL si ELASTICSEARCH_URL absent
- Routes: GET /search, GET /search/suggestions, POST /admin/search/reindex
- Frontend: searchApi cursor/limit params (extensibilité)
- docs/ENV_VARIABLES: ELASTICSEARCH_URL, ELASTICSEARCH_INDEX, ELASTICSEARCH_AUTO_INDEX
- Roadmap v0.10.2 → DONE
2026-03-09 10:13:18 +01:00

42 lines
1.5 KiB
Go

package api
import (
"context"
"os"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"veza-backend-api/internal/handlers"
"veza-backend-api/internal/services"
elasticsearch "veza-backend-api/internal/elasticsearch"
)
// setupSearchRoutes configure la route de recherche unifiée GET /search et autocomplete (v0.10.2 F363-F365)
// Uses Elasticsearch when ELASTICSEARCH_URL is set, else falls back to PostgreSQL
func (r *APIRouter) setupSearchRoutes(router *gin.RouterGroup) {
esCfg := elasticsearch.LoadConfig()
var searchSvc handlers.SearchServiceInterface
if esCfg.Enabled {
esClient, err := elasticsearch.NewClient(esCfg, r.logger)
if err != nil {
r.logger.Warn("Elasticsearch unavailable, falling back to PostgreSQL search", zap.Error(err))
searchSvc = services.NewSearchService(r.db, r.logger)
} else {
// Optional: run reindex at startup if ELASTICSEARCH_AUTO_INDEX
if os.Getenv("ELASTICSEARCH_AUTO_INDEX") == "true" {
idx := elasticsearch.NewIndexer(esClient, r.db.GormDB, r.logger)
if err := idx.ReindexAll(context.Background()); err != nil {
r.logger.Warn("Elasticsearch auto-reindex failed", zap.Error(err))
}
}
searchSvc = elasticsearch.NewSearchService(esClient, r.logger)
}
} else {
searchSvc = services.NewSearchService(r.db, r.logger)
}
handlers.NewSearchHandlersWithInterface(searchSvc)
router.GET("/search", handlers.SearchHandlersInstance.Search)
router.GET("/search/suggestions", handlers.SearchHandlersInstance.Suggestions)
}