UserService.java

package cz.vsb.crm.service;

import cz.vsb.crm.dto.UserRequest;
import cz.vsb.crm.dto.UserResponse;
import cz.vsb.crm.exception.BusinessRuleException;
import cz.vsb.crm.exception.ResourceNotFoundException;
import cz.vsb.crm.model.User;
import cz.vsb.crm.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional
public class UserService {

    private final UserRepository userRepository;

    @Transactional(readOnly = true)
    public List<UserResponse> findAll() {
        return userRepository.findAll().stream().map(UserResponse::from).toList();
    }

    @Transactional(readOnly = true)
    public UserResponse findById(Long id) {
        return UserResponse.from(get(id));
    }

    public UserResponse create(UserRequest request) {
        if (userRepository.existsByUsername(request.username())) {
            throw new BusinessRuleException("Username already exists: " + request.username());
        }
        if (userRepository.existsByEmail(request.email())) {
            throw new BusinessRuleException("Email already exists: " + request.email());
        }
        return UserResponse.from(userRepository.save(request.toEntity()));
    }

    public UserResponse update(Long id, UserRequest request) {
        User user = get(id);
        request.applyTo(user);
        return UserResponse.from(userRepository.save(user));
    }

    public void delete(Long id) {
        userRepository.delete(get(id));
    }

    private User get(Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("User", id));
    }
}