turash/bugulma/backend/internal/repository/user_repository.go

161 lines
4.0 KiB
Go

package repository
import (
"context"
"encoding/json"
"strings"
"bugulma/backend/internal/domain"
"gorm.io/gorm"
)
// UserRepository implements domain.UserRepository with GORM
type UserRepository struct {
*BaseRepository[domain.User]
db *gorm.DB
}
// NewUserRepository creates a new GORM-based user repository
func NewUserRepository(db *gorm.DB) domain.UserRepository {
return &UserRepository{
BaseRepository: NewBaseRepository[domain.User](db),
db: db,
}
}
// GetByEmail retrieves a user by email
func (r *UserRepository) GetByEmail(ctx context.Context, email string) (*domain.User, error) {
return r.FindOneWhereWithContext(ctx, "email = ?", email)
}
// GetByID retrieves a user by ID
func (r *UserRepository) GetByID(ctx context.Context, id string) (*domain.User, error) {
return r.BaseRepository.GetByID(ctx, id)
}
// Create creates a new user with context
func (r *UserRepository) Create(ctx context.Context, user *domain.User) error {
return r.BaseRepository.Create(ctx, user)
}
// Update updates a user (inherited from BaseRepository)
// Delete deletes a user (inherited from BaseRepository)
// List retrieves users with filters and pagination
func (r *UserRepository) List(ctx context.Context, filters domain.UserListFilters, pagination domain.PaginationParams) (*domain.PaginatedResult[domain.User], error) {
var users []domain.User
var total int64
query := r.db.WithContext(ctx).Model(&domain.User{})
// Apply filters
if filters.Role != nil {
query = query.Where("role = ?", *filters.Role)
}
if filters.IsActive != nil {
query = query.Where("is_active = ?", *filters.IsActive)
}
if filters.Search != "" {
search := "%" + strings.ToLower(filters.Search) + "%"
query = query.Where("LOWER(email) LIKE ? OR LOWER(name) LIKE ?", search, search)
}
// Get total count
if err := query.Count(&total).Error; err != nil {
return nil, err
}
// Apply pagination and get results
result := query.
Order("created_at DESC").
Limit(pagination.Limit).
Offset(pagination.Offset).
Find(&users)
if result.Error != nil {
return nil, result.Error
}
return &domain.PaginatedResult[domain.User]{
Items: users,
Total: total,
}, nil
}
// UpdateRole updates a user's role
func (r *UserRepository) UpdateRole(ctx context.Context, userID string, role domain.UserRole) error {
result := r.db.WithContext(ctx).
Model(&domain.User{}).
Where("id = ?", userID).
Update("role", role)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return ErrNotFound
}
return nil
}
// UpdatePermissions updates a user's permissions
func (r *UserRepository) UpdatePermissions(ctx context.Context, userID string, permissions []string) error {
permissionsJSON, err := json.Marshal(permissions)
if err != nil {
return err
}
result := r.db.WithContext(ctx).
Model(&domain.User{}).
Where("id = ?", userID).
Update("permissions", string(permissionsJSON))
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return ErrNotFound
}
return nil
}
// Deactivate deactivates a user
func (r *UserRepository) Deactivate(ctx context.Context, userID string) error {
result := r.db.WithContext(ctx).
Model(&domain.User{}).
Where("id = ?", userID).
Update("is_active", false)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return ErrNotFound
}
return nil
}
// Activate activates a user
func (r *UserRepository) Activate(ctx context.Context, userID string) error {
result := r.db.WithContext(ctx).
Model(&domain.User{}).
Where("id = ?", userID).
Update("is_active", true)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return ErrNotFound
}
return nil
}
// UpdateLastLogin updates the user's last login timestamp
func (r *UserRepository) UpdateLastLogin(ctx context.Context, userID string) error {
result := r.db.WithContext(ctx).
Model(&domain.User{}).
Where("id = ?", userID).
Update("last_login_at", gorm.Expr("NOW()"))
if result.Error != nil {
return result.Error
}
return nil
}