package com.imprimelibros.erp.users; import org.springframework.stereotype.Repository; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; @Repository public interface UserDao extends JpaRepository, JpaSpecificationExecutor { // Aplicamos EntityGraph a la versión con Specification+Pageable @Override @EntityGraph(attributePaths = { "rolesLink", "rolesLink.role" }) @NonNull Page findAll(@Nullable Specification spec, @NonNull Pageable pageable); Optional findByUserNameIgnoreCase(String userName); boolean existsByUserNameIgnoreCase(String userName); // Para comprobar si existe al hacer signup @Query(value = """ SELECT id, deleted, enabled FROM users WHERE LOWER(username) = LOWER(:userName) LIMIT 1 """, nativeQuery = true) Optional findLiteByUserNameIgnoreCase(@Param("userName") String userName); boolean existsByUserNameIgnoreCaseAndIdNot(String userName, Long id); // Nuevo: para login/negocio "activo" @EntityGraph(attributePaths = { "rolesLink", "rolesLink.role" }) Optional findByUserNameIgnoreCaseAndEnabledTrueAndDeletedFalse(String userName); // Para poder restaurar, necesitas leer ignorando @Where (native): @Query(value = "SELECT * FROM users WHERE id = :id", nativeQuery = true) Optional findByIdIncludingDeleted(@Param("id") Long id); @Query(value = "SELECT * FROM users WHERE deleted = TRUE", nativeQuery = true) List findAllDeleted(); @Query("select u.id from User u where lower(u.userName) = lower(:userName)") Optional findIdByUserNameIgnoreCase(@Param("userName") String userName); }