veza/veza-backend-api/internal/services/user_service_search.go
senke 4b5fe3e4de [BE-API-008] be-api: Implement user search endpoint
- Created SearchUsers method in UserService with pagination support
- SearchUsers searches by username, email, first_name, and last_name using ILIKE
- Added SearchUsers handler in ProfileHandler with query params (q, page, limit)
- Added GET /users/search route in setupUserRoutes
- Returns paginated results with total count
- Password hashes are excluded from results

Phase: PHASE-2
Priority: P1
Progress: 17/267 (6.4%)
2025-12-23 10:42:26 +01:00

69 lines
1.9 KiB
Go

package services
import (
"context"
"errors"
"fmt"
"veza-backend-api/internal/models"
)
// SearchUsersParams représente les paramètres de recherche d'utilisateurs
// BE-API-008: Implement user search endpoint
type SearchUsersParams struct {
Query string // Recherche par username, email, first_name, last_name
Page int // Numéro de page (défaut: 1)
Limit int // Nombre de résultats par page (défaut: 20, max: 100)
}
// SearchUsers recherche des utilisateurs selon les critères fournis
// BE-API-008: Implement user search endpoint
func (s *UserService) SearchUsers(ctx context.Context, params SearchUsersParams) ([]*models.User, int64, error) {
if s.db == nil {
return nil, 0, errors.New("database connection not available")
}
// Appliquer la pagination
if params.Limit <= 0 {
params.Limit = 20
}
if params.Limit > 100 {
params.Limit = 100
}
if params.Page < 1 {
params.Page = 1
}
offset := (params.Page - 1) * params.Limit
// Construire la requête de recherche
query := s.db.WithContext(ctx).Model(&models.User{})
// Recherche par query (username, email, first_name, last_name)
if params.Query != "" {
searchPattern := "%" + params.Query + "%"
query = query.Where(
"username ILIKE ? OR email ILIKE ? OR first_name ILIKE ? OR last_name ILIKE ?",
searchPattern, searchPattern, searchPattern, searchPattern,
)
}
// Compter le total avant pagination
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, 0, fmt.Errorf("failed to count users: %w", err)
}
// Appliquer pagination et récupérer les résultats
var users []*models.User
if err := query.Offset(offset).Limit(params.Limit).Find(&users).Error; err != nil {
return nil, 0, fmt.Errorf("failed to search users: %w", err)
}
// Exclure les mots de passe des résultats
for _, user := range users {
user.PasswordHash = ""
}
return users, total, nil
}