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 }