Enhance company search functionality with additional filters
continuous-integration/drone/push Build is passing

- 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.
This commit is contained in:
Mazyar
2026-06-22 22:26:26 +03:30
parent 2a9682aea2
commit 3bfed0dc74
3 changed files with 39 additions and 12 deletions
+4
View File
@@ -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"`
+4
View File
@@ -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"
+31 -12
View File
@@ -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