diff --git a/.env b/.env index e4e8f39..8fe69fd 100644 --- a/.env +++ b/.env @@ -21,6 +21,10 @@ AUTH_JWT_SECRET=5c020e6ed3d8d6e67e5804d67c83c4bd5ae474df749af6d63d8f20e7e2ba29b3 AUTH_JWT_EXPIRATION=86400 AUTH_REFRESH_EXPIRATION=604800 +# Meili search +MEILISEARCH_URL=http://localhost:7700 +MEILISEARCH_API_KEY=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + # Google Translate Client GOOGLE_APPLICATION_CREDENTIALS=./google-cred.json GOOGLE_CLOUD_PROJECT_ID=translation-343517 diff --git a/app/delivery/web/api/restricted/meiliSearch.go b/app/delivery/web/api/restricted/meiliSearch.go new file mode 100644 index 0000000..d40a38e --- /dev/null +++ b/app/delivery/web/api/restricted/meiliSearch.go @@ -0,0 +1,55 @@ +package restricted + +import ( + "strconv" + + "git.ma-al.com/goc_daniel/b2b/app/service/meiliService" + "git.ma-al.com/goc_daniel/b2b/app/utils/i18n" + "git.ma-al.com/goc_daniel/b2b/app/utils/nullable" + "git.ma-al.com/goc_daniel/b2b/app/utils/response" + "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" + "github.com/gofiber/fiber/v3" +) + +type MeiliSearchHandler struct { + meiliService *meiliService.MeiliService +} + +func NewMeiliSearchHandler() *MeiliSearchHandler { + meiliService := meiliService.New() + return &MeiliSearchHandler{ + meiliService: meiliService, + } +} + +func MeiliSearchHandlerRoutes(r fiber.Router) fiber.Router { + handler := NewMeiliSearchHandler() + + r.Get("/test", handler.Test) + + return r +} + +func (h *MeiliSearchHandler) Test(c fiber.Ctx) error { + + id_shop_attribute := c.Query("shopID") + id_shop, err := strconv.Atoi(id_shop_attribute) + if err != nil { + return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) + } + + id_lang, err := strconv.Atoi(c.Cookies("lang_id", "2")) + if err != nil { + return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute))) + } + + test, err := h.meiliService.Test(uint(id_shop), uint(id_lang)) + if err != nil { + return c.Status(responseErrors.GetErrorStatus(err)). + JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) + } + + return c.JSON(response.Make(&test, 0, i18n.T_(c, response.Message_OK))) +} diff --git a/app/delivery/web/init.go b/app/delivery/web/init.go index 7c8cd63..30a372a 100644 --- a/app/delivery/web/init.go +++ b/app/delivery/web/init.go @@ -106,6 +106,10 @@ func (s *Server) Setup() error { menu := s.restricted.Group("/menu") restricted.MenuHandlerRoutes(menu) + // meili search (restricted) + meiliSearch := s.restricted.Group("/meili-search") + restricted.MeiliSearchHandlerRoutes(meiliSearch) + // // Restricted routes example // restricted := s.api.Group("/restricted") // restricted.Use(middleware.AuthMiddleware()) diff --git a/app/service/meiliService/meiliService.go b/app/service/meiliService/meiliService.go new file mode 100644 index 0000000..ab717ff --- /dev/null +++ b/app/service/meiliService/meiliService.go @@ -0,0 +1,72 @@ +package meiliService + +import ( + "fmt" + "os" + "strconv" + + "github.com/meilisearch/meilisearch-go" +) + +type MeiliService struct { + meiliClient meilisearch.ServiceManager +} + +func New() *MeiliService { + meiliURL := os.Getenv("MEILISEARCH_URL") + meiliAPIKey := os.Getenv("MEILISEARCH_API_KEY") + + client := meilisearch.New( + meiliURL, + meilisearch.WithAPIKey(meiliAPIKey), + ) + + return &MeiliService{ + meiliClient: client, + } +} + +// ==================================== FOR DEBUG ONLY ==================================== +func (s *MeiliService) Test(id_shop uint, id_lang uint) (meilisearch.SearchResponse, error) { + indexName := "products_lang" + strconv.FormatInt(int64(id_lang), 10) + + searchReq := &meilisearch.SearchRequest{ + Limit: 3, + } + + // Perform search + results, err := s.meiliClient.Index(indexName).Search("walek", searchReq) + if err != nil { + fmt.Printf("Meilisearch error: %v\n", err) + return meilisearch.SearchResponse{}, err + } + + fmt.Printf("Search results for query 'walek' in %s: %d hits\n", indexName, len(results.Hits)) + + return *results, nil +} + +// Search performs a full-text search on the specified index +func (s *MeiliService) Search(indexName string, query string, limit int) (meilisearch.SearchResponse, error) { + searchReq := &meilisearch.SearchRequest{ + Limit: int64(limit), + } + + results, err := s.meiliClient.Index(indexName).Search(query, searchReq) + if err != nil { + fmt.Printf("Meilisearch search error: %v\n", err) + return meilisearch.SearchResponse{}, err + } + + return *results, nil +} + +// HealthCheck checks if Meilisearch is healthy and accessible +func (s *MeiliService) HealthCheck() (*meilisearch.Health, error) { + health, err := s.meiliClient.Health() + if err != nil { + return nil, fmt.Errorf("meilisearch health check failed: %w", err) + } + + return health, nil +} diff --git a/go.mod b/go.mod index 0dc9c19..7632dfb 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/meilisearch/meilisearch-go v0.36.1 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect diff --git a/go.sum b/go.sum index 3e65cda..6b02711 100644 --- a/go.sum +++ b/go.sum @@ -109,6 +109,8 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/meilisearch/meilisearch-go v0.36.1 h1:mJTCJE5g7tRvaqKco6DfqOuJEjX+rRltDEnkEC02Y0M= +github.com/meilisearch/meilisearch-go v0.36.1/go.mod h1:hWcR0MuWLSzHfbz9GGzIr3s9rnXLm1jqkmHkJPbUSvM= github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/openai/openai-go/v3 v3.28.0 h1:2+FfrCVMdGXSQrBv1tLWtokm+BU7+3hJ/8rAHPQ63KM=