Fix: la búsqueda de estudiantes aplicaba un solo filtro e ignoraba el resto
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 unaSpecification(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 unJOIN. 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.
- Grupo, carrera e ITR usan una subconsulta (
-
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_ESTUDIANTEse ven solo los estudiantes activos, aunque se pida otro estado; - la paginación y el orden por defecto (apellido) siguen igual.
- filtrar sigue exigiendo
-
EstudianteRepository: agregaJpaSpecificationExecutory quita las consultas que solo usabalistar()(buscarPorTexto*,findByGrupo,findByCarrera,findByItr*). Las que usaReporteServiceno se tocaron. - Frontend: no necesita cambios. La pantalla ya mandaba los filtros juntos; el que los descartaba era el backend.
Tests
-
EstudianteServiceTest: los tests delistarverificaban qué consulta vieja se llamaba. Ahora verifican los permisos (403 sinBUSCAR_ESTUDIANTE), la foto (visible u oculta según el carreras, grupos y estudiantes de prueba, y verifica 6 combinaciones:- texto + carrera + estado;
- carrera sola, sin duplicados para un estudiante en dos grupos de esa carrera;
- grupo + estado;
- ITR + texto;
- filtros contradictorios → ningún resultado;
- 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)
- 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.
- Elegir una carrera y un grupo de otra carrera → no aparece ninguno.
- Filtrar por una carrera donde un estudiante esté en dos grupos → aparece una sola vez, y el total coincide con la cantidad de filas.
- 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.