diff --git a/internal/customer/form.go b/internal/customer/form.go index 263c68a..e39724c 100644 --- a/internal/customer/form.go +++ b/internal/customer/form.go @@ -45,8 +45,11 @@ type AdminResetPasswordResponse struct { // ListCustomersForm represents the form for listing customers with filters type SearchCustomersForm struct { Search *string `query:"q" valid:"optional"` + FullName *string `query:"full_name" valid:"optional,length(1|100)"` + Email *string `query:"email" valid:"optional,length(1|254)"` Type *string `query:"type" valid:"optional,in(individual|company|government)"` Status *string `query:"status" valid:"optional,in(active|inactive|suspended)"` + Role *string `query:"role" valid:"optional,in(admin|analyst)"` CompanyID *string `query:"company_id" valid:"optional"` } diff --git a/internal/customer/handler.go b/internal/customer/handler.go index 52bdf7a..70451d0 100644 --- a/internal/customer/handler.go +++ b/internal/customer/handler.go @@ -170,14 +170,17 @@ func (h *Handler) DeleteCustomer(c echo.Context) error { // ListCustomers lists customers with filters and pagination // @Summary List customers with filters and pagination -// @Description Retrieve a paginated list of customers with advanced filtering options including search, type, status, company, industry, verification status, and compliance status. Supports sorting and pagination. +// @Description Retrieve a paginated list of customers with filtering by full name, email, company, type, status, and role. Supports sorting and pagination. // @Tags Admin-Customers // @Accept json // @Produce json -// @Param search query string false "Search term to filter customers by name, email, or company name" +// @Param q query string false "Search term to filter customers by email or username" +// @Param full_name query string false "Filter by customer full name (partial match)" +// @Param email query string false "Filter by customer email (partial match)" // @Param type query string false "Filter by customer type" Enums(individual, company, government) -// @Param status query string false "Filter by customer status" Enums(active, inactive, suspended, pending) -// @Param company_id query string false "Filter by company ID" format(uuid) +// @Param status query string false "Filter by customer status" Enums(active, inactive, suspended) +// @Param role query string false "Filter by customer role" Enums(admin, analyst) +// @Param company_id query string false "Filter by assigned company ID" // @Param limit query integer false "Number of customers per page (1-100)" minimum(1) maximum(100) default(20) // @Param offset query integer false "Number of customers to skip for pagination" minimum(0) default(0) // @Param sort_by query string false "Field to sort by" Enums(email, company_name, created_at, updated_at, status) default(created_at) diff --git a/internal/customer/repository.go b/internal/customer/repository.go index 2a409c0..ed52842 100644 --- a/internal/customer/repository.go +++ b/internal/customer/repository.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "regexp" + "strings" "time" "tm/pkg/logger" orm "tm/pkg/mongo" @@ -370,7 +372,30 @@ func (r *customerRepository) Search(ctx context.Context, form *SearchCustomersFo filter := bson.M{} if form.Search != nil { - filter["$text"] = bson.M{"$search": *form.Search} + search := strings.TrimSpace(*form.Search) + if search != "" { + filter["$text"] = bson.M{"$search": search} + } + } + + if form.FullName != nil { + fullName := strings.TrimSpace(*form.FullName) + if fullName != "" { + filter["full_name"] = bson.M{ + "$regex": regexp.QuoteMeta(fullName), + "$options": "i", + } + } + } + + if form.Email != nil { + email := strings.TrimSpace(*form.Email) + if email != "" { + filter["email"] = bson.M{ + "$regex": regexp.QuoteMeta(email), + "$options": "i", + } + } } if form.Type != nil { @@ -381,8 +406,15 @@ func (r *customerRepository) Search(ctx context.Context, form *SearchCustomersFo filter["status"] = *form.Status } + if form.Role != nil { + filter["role"] = *form.Role + } + if form.CompanyID != nil { - filter["company_id"] = *form.CompanyID + companyID := strings.TrimSpace(*form.CompanyID) + if companyID != "" { + filter["companies"] = companyID + } } mongoPagination, err := orm.BuildListPagination(