Skip to content

Fix: la búsqueda de estudiantes aplicaba un solo filtro e ignoraba el resto

belen.varsi requested to merge pft/fix/filtros-combinados-estudiantes into dev

Qué se corrigió

En el listado de estudiantes (GET /estudiantes), los filtros no se combinaban: el backend aplicaba uno solo y descartaba el resto sin avisar. Ahora se aplican todos juntos, como pide el RF08 ("búsqueda y filtrado por nombre, cédula, carrera, grupo, estado").

El bug

EstudianteService.listar() elegía una única consulta según el primer filtro presente, en este orden: texto → grupo → carrera → ITR. Los demás se ignoraban. La pantalla deja elegir varios filtros a la vez, así que los resultados eran incorrectos sin que nadie se diera cuenta:

Búsqueda Antes devolvía Ahora devuelve
"Ana" + carrera LTI Todas las "Ana", de cualquier carrera Solo las "Ana" de LTI
Texto + ITR Coincidencias de texto de cualquier ITR Solo las del ITR elegido
Carrera A + grupo de la carrera B Los del grupo (la carrera se ignoraba) Ninguno (los filtros se contradicen)

Cambios

  • EstudianteSpecs (nuevo, repository/): cada filtro como una Specification (texto, grupo, carrera, ITR, estado), con las mismas reglas que las consultas que reemplaza. El texto busca en nombre, apellido o documento, de forma parcial y sin distinguir mayúsculas.
    • Grupo, carrera e ITR usan una subconsulta (idUsuario IN ...) en lugar de un JOIN. Así un estudiante que está en dos grupos de la misma carrera aparece una sola vez, y el total de la paginación es exacto.
  • EstudianteService.listar(): combina con AND todos los filtros que lleguen, en una sola consulta. Las reglas de permisos no cambian:
    • filtrar sigue exigiendo BUSCAR_ESTUDIANTE (si no, 403);
    • sin VER_ESTUDIANTE se ven solo los estudiantes activos, aunque se pida otro estado;
    • la paginación y el orden por defecto (apellido) siguen igual.
  • EstudianteRepository: agrega JpaSpecificationExecutor y quita las consultas que solo usaba listar() (buscarPorTexto*, findByGrupo, findByCarrera, findByItr*). Las que usa ReporteService no se tocaron.
  • Frontend: no necesita cambios. La pantalla ya mandaba los filtros juntos; el que los descartaba era el backend.

Tests

  • EstudianteServiceTest: los tests de listar verificaban qué consulta vieja se llamaba. Ahora verifican los permisos (403 sin BUSCAR_ESTUDIANTE), la foto (visible u oculta según el carreras, grupos y estudiantes de prueba, y verifica 6 combinaciones:

    1. texto + carrera + estado;
    2. carrera sola, sin duplicados para un estudiante en dos grupos de esa carrera;
    3. grupo + estado;
    4. ITR + texto;
    5. filtros contradictorios → ningún resultado;
    6. sin VER_ESTUDIANTE → solo activos, también con filtros.

    Contra el código anterior fallan 3 de los 6 (los de combinación); con el arreglo pasan todos.

    Igual que ComentarioConfidencialInstanciaIT, no corre con ./mvnw test. Se corre con:

    docker compose up -d
    ./mvnw test -Dtest=EstudianteBusquedaIT -Dspring.profiles.active=integration
  • ./mvnw test: pasan los 773 tests.

Cómo probar (en la pantalla de Estudiantes)

  1. Buscar un nombre que exista en dos carreras distintas y elegir una de ellas en el filtro de carrera → aparecen solo los de esa carrera.
  2. Elegir una carrera y un grupo de otra carrera → no aparece ninguno.
  3. Filtrar por una carrera donde un estudiante esté en dos grupos → aparece una sola vez, y el total coincide con la cantidad de filas.
  4. Con un usuario sin VER_ESTUDIANTE (ej. TUTOR), filtrar por estado "Inactivo" → sigue viendo solo activos.

🗄️ Cambios en la base de datos

Ninguno. Se puede mergear y levantar sin tocar la BD.

Compatibilidad

No choca con los MRs de backend abiertos (!95 (merged) a !98). Los reportes siguen usando sus consultas de siempre.

Merge request reports

Loading