From 3bfed0dc748c2b6b21ee57235162075a340fd6b8 Mon Sep 17 00:00:00 2001 From: Mazyar Date: Mon, 22 Jun 2026 22:26:26 +0330 Subject: [PATCH] Enhance company search functionality with additional filters - Updated the `SearchForm` to include optional filters for `name`, `email`, `phone`, and `employee_count`, allowing for more granular search capabilities. - Modified the `Search` method in the `companyRepository` to handle the new filters, improving the search logic with regex support for `name`, `email`, and `phone`. - Updated API documentation in the `company` handler to reflect the new query parameters for enhanced clarity. This update improves the search functionality within the company domain, providing users with more flexible and precise search options. --- internal/company/form.go | 4 ++++ internal/company/handler.go | 4 ++++ internal/company/repository.go | 43 ++++++++++++++++++++++++---------- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/internal/company/form.go b/internal/company/form.go index 874de64..a57c97c 100644 --- a/internal/company/form.go +++ b/internal/company/form.go @@ -57,6 +57,10 @@ type ( // SearchForm represents the form for searching companies with filters type SearchForm struct { Search *string `query:"q" valid:"optional"` + Name *string `query:"name" valid:"optional,length(1|200)"` + Email *string `query:"email" valid:"optional,length(1|254)"` + Phone *string `query:"phone" valid:"optional,length(1|20)"` + EmployeeCount *int `query:"employee_count" valid:"optional,min(1)"` Type *string `query:"type" valid:"optional,in(private|public|government|ngo|startup)"` Status *string `query:"status" valid:"optional,in(active|inactive|suspended|pending)"` Industry *string `query:"industry" valid:"optional"` diff --git a/internal/company/handler.go b/internal/company/handler.go index a16d2c5..0dbd924 100644 --- a/internal/company/handler.go +++ b/internal/company/handler.go @@ -265,6 +265,10 @@ func (h *Handler) Delete(c echo.Context) error { // @Accept json // @Produce json // @Param q query string false "Search query" +// @Param name query string false "Filter by company name" +// @Param email query string false "Filter by email" +// @Param phone query string false "Filter by phone" +// @Param employee_count query integer false "Filter by exact employee count" // @Param cpv_codes query array false "CPV codes filter" // @Param categories query array false "Categories filter" // @Param keywords query array false "Keywords filter" diff --git a/internal/company/repository.go b/internal/company/repository.go index c511d58..bf4ed40 100644 --- a/internal/company/repository.go +++ b/internal/company/repository.go @@ -4,7 +4,6 @@ import ( "context" "errors" "regexp" - "strconv" "strings" "time" "tm/pkg/logger" @@ -213,18 +212,36 @@ func (r *companyRepository) Search(ctx context.Context, form *SearchForm, pagina filter := bson.M{} if form.Search != nil { - search := strings.TrimSpace(*form.Search) - if search != "" { - pattern := regexp.QuoteMeta(search) - orConditions := []bson.M{ - {"name": bson.M{"$regex": pattern, "$options": "i"}}, - {"email": bson.M{"$regex": pattern, "$options": "i"}}, - {"phone": bson.M{"$regex": pattern, "$options": "i"}}, + filter["$text"] = bson.M{"$search": *form.Search} + } + + if form.Name != nil { + name := strings.TrimSpace(*form.Name) + if name != "" { + filter["name"] = bson.M{ + "$regex": regexp.QuoteMeta(name), + "$options": "i", } - if employeeCount, err := strconv.Atoi(search); err == nil { - orConditions = append(orConditions, bson.M{"employee_count": employeeCount}) + } + } + + if form.Email != nil { + email := strings.TrimSpace(*form.Email) + if email != "" { + filter["email"] = bson.M{ + "$regex": regexp.QuoteMeta(email), + "$options": "i", + } + } + } + + if form.Phone != nil { + phone := strings.TrimSpace(*form.Phone) + if phone != "" { + filter["phone"] = bson.M{ + "$regex": regexp.QuoteMeta(phone), + "$options": "i", } - filter["$or"] = orConditions } } @@ -274,7 +291,9 @@ func (r *companyRepository) Search(ctx context.Context, form *SearchForm, pagina } // Range filters - if form.EmployeeCountMin != nil || form.EmployeeCountMax != nil { + if form.EmployeeCount != nil { + filter["employee_count"] = *form.EmployeeCount + } else if form.EmployeeCountMin != nil || form.EmployeeCountMax != nil { rangeFilter := bson.M{} if form.EmployeeCountMin != nil { rangeFilter["$gte"] = *form.EmployeeCountMin