Diseño e implementación de un sistema de gestión de prácticas profesionales universitarias con Spring Boot y Vue.js

Arquitectura y Tecnologías Base

La coordinación de procesos formativos en entornos académicos exige una plataforma escalable y modular. La solución integra un backend construido con Spring Boot, aprovechando su configuración automática y servidores embebidos para acelerar el ciclo de desarrollo. En la capa de interfaz, se despliega Vue.js, cuyo modelo reactivo basado en el Virtual DOM minimiza manipulaciones costosas del documento y permite actualizaciones instantáneas de la vista. Para la capa de datos, MyBatis-Plus automatiza la generación de mappers y entidades, incorporando capacidades nativas como paginación, consultas dinámicas y gestión de versiones optimista. Adicionalmente, uni-app habilita la synchronización de módulos móviles, garantizando una experiencia unificada entre navegadores de escritorio y dispositivos portátiles.

Gestión de Sesiones y Filtros de Autorización

La seguridad perimetral se articula mediante un esquema de tokens autocontenidos. A continuación se expone una versión refactorizada del endpoint de autenticación y el filtro de validación, estructurada para mejorar la legibilidad y el manejo de respuestas HTTP:

// Punto de entrada para verificación de identidad
@PostMapping("/api/auth/iniciar-sesion")
public ResponseEntity<map object="">> iniciarSesion(@RequestBody CredencialesAuth payload) {
    Usuario registro = repositorioUsuario.buscarPorNombre(payload.getIdentificador());
    
    if (registro == null || !codificador.verifica(payload.getClave(), registro.getHashClave())) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                .body(Map.of("estado", "fallido", "mensaje", "Credenciales no válidas"));
    }

    String sesionActiva = gestorSesion.generarToken(registro.getId(), registro.getPerfiles(), payload.getOrigenTabla());
    return ResponseEntity.ok(Map.of("token", sesionActiva, "estado", "completado"));
}

// Componente interceptador de solicitudes entrantes
@Component
public class ValidadorAcceso implements HandlerInterceptor {

    private static final String CABECERA_SESION = "X-Sesion-Token";
    @Autowired private GestorSesion gestorSesion;

    @Override
    public boolean preHandle(HttpServletRequest peticion, HttpServletResponse respuesta, Object handler) throws Exception {
        // Configuración de cabeceras CORS
        respuesta.setHeader("Access-Control-Allow-Origin", peticion.getHeader("Origin"));
        respuesta.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        
        if ("OPTIONS".equalsIgnoreCase(peticion.getMethod())) {
            return true;
        }

        // Ignorar rutas anotadas como públicas
        if (handler instanceof HandlerMethod && ((HandlerMethod) handler).hasAnnotation(IgnorarAuth.class)) {
            return true;
        }

        String valorToken = peticion.getHeader(CABECERA_SESION);
        EstadoSesion registroSesion = null;

        if (valorToken != null && !valorToken.isEmpty()) {
            registroSesion = gestorSesion.interrogarEstado(valorToken);
        }

        if (registroSesion != null && !registroSesion.valorVencido()) {
            peticion.setAttribute("idUsuario", registroSesion.getIdActor());
            peticion.setAttribute("nivelRol", registroSesion.getPermiso());
            return true;
        }

        respuesta.setStatus(HttpStatus.UNAUTHORIZED.value());
        respuesta.setContentType("application/json; charset=UTF-8");
        try (PrintWriter escritor = respuesta.getWriter()) {
            escritor.write("{\"codigo\": 401, \"nota\": \"Requisito de autenticación incumplido\"}");
        }
        return false;
    }
}</map>

Estratgeia de Validación y Pruebas Funcionales

La garantía de calidad se fundamenta en ensayos de caja negra, replicando trayectorias de usuario reales sin inspeccionar la lógica interna. Este enfoque busca validar el cumplimiento de los especificados funcionales y corregir inconsistencias antes de la distribución en entornos productivos.

Matrices de Verificación para Módulo de Ingreso

Prompt de Entrada Salida Anticipada Salida Observada Justificación Técnica
Identificador correcto + contraseña válida Desbloqueo del dashboard Desbloqueo ejecutado Flujo crítico operante
Contraseña equivocada Notificación de fallo Fallo reflejado correctamente Hashing y comparación funcionales
Omitir campos requeridos Bloqueo previo al envío Prevención activada Validación front-end aplicada
Compatibilidad de rol insuficiente Denegación automática Denegación operativa Control de privilegios estable

Validación sobre Gestión de Registros

Las operaciones CRUD se someten a pruebas con límites numéricos y repeticiones intencionales. Se verifica que la aplicación rechaza creaciones duplicadas, aplica reglas de sintaxis en atributos críticos y refleja modificaciones en el viewport sin recargas parciales.

Acción Ejecutada Comportamiento Esperado Evidencia Recogida Impacto Evaluado
Registro incompleto Abortado con indicador de falta Abortado correctamente Robustez estructural confirmada
Colisión de clave única Deteniod y notificado Detenido y notificado Restriciones de integridad vigentes
Actualización simultánea Conservación de consistencia Sincronización validada Consumo de recursos dentro de parámetros

Evolución del Esquema de Persistencia

La capa de almacenamiento contempla una entidad exclusiva para el control de ciclos de validez. Se han renombreado atributos para priorizar la semántica técnica y se ha mantenido la normalización relacional:

-- Definición de índice para rastro de sesiones activas
CREATE TABLE rastro_secciones (
    id_fila BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'Secuencia identificadora',
    actor_referencia BIGINT NOT NULL COMMENT 'Liga directa al participante registrado',
    cuenta_accion VARCHAR(100) NOT NULL COMMENT 'Alias utilizado durante la entrada',
    modulo_aplicado VARCHAR(100) DEFAULT NULL COMMENT 'Módulo origen (ej: pasantes, profesores)',
    jerarquia_permiso VARCHAR(100) DEFAULT NULL COMMENT 'Nivel otorgado',
    firma_criptografica VARCHAR(200) NOT NULL COMMENT 'Señal temporal emitida',
    instante_apertura TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'Marca inicial',
    limite_vigencia TIMESTAMP DEFAULT '2099-12-31 23:59:59' COMMENT 'Umbral de caducidad',
    INDEX idx_busqueda (actor_referencia, jerarquia_permiso)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Bitácora centralizada de accesos seguros';

-- Carga inicial ilustrativa
INSERT INTO rastro_secciones (actor_referencia, cuenta_accion, modulo_aplicado, jerarquia_permiso, firma_criptografica, instante_apertura, limite_vigencia) VALUES
(102, 'representante_al', 'candidatos', 'consulta', 'mK9pLxZq2rTwVyNhGbFcJdSaWqWeOiIu', '2024-02-05 09:00:00', '2024-02-05 10:00:00'),
(77, 'supervisad_gen', 'coordinacion', 'alteracion', 'aS4dFgHjKlZxCvBnMqWrTyUiOpLkJhGf', '2024-02-08 11:45:00', '2024-02-08 12:45:00');

Etiquetas: SpringBoot vue.js MyBatis-Plus uni-app JWT

Publicado el 9-24 02:05