Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Agradecer a Borja, mi tutor, por aceptarme la propuesta de realizar este proyecto adaptándolo
de una base inicial planteada y aportándome la ayuda necesaria en todo momento para la fina-
lización de este.
Agradecer a mi padre, Javier, la confianza, esfuerzo y dedicación durante todos estos años lle-
vándome a las competiciones deportivas y prestándome su confianza duranta mi etapa en el
colegio.
A mis hermanos, Sofía y Gonzalo, por prestarse como mentes pensantes a descifrar y resolver
los problemas de programación día y noche, así como ayudarme en los problemas personales,
universitarios y profesionales.
A mi novia, Claudia, por ser una persona fundamental para desarrollarme en lo personal con-
fiando en todo momento en mis esfuerzos y apoyándome día a día a confiar en mí mismo.
Finalmente, dar las gracias a mis yayos, tíos, primos y amigos por ser el apoyo durante toda esta
etapa.
Página 3 de 58
RESUMEN
La carrera de medicina en España es una de las más demandadas y con nota de acceso más alta
superior a 13 puntos sobre 14.
Después de los seis años de estudios universitarios, los estudiantes deben realizar un examen
convocado por el Ministerio de Sanidad para poder acceder a una plaza en una especialidad
médica de Médico Interno Residente (MIR).
El examen MIR es muy competitivo, ya que el número de plazas disponibles es limitado y el nú-
mero de aspirantes es muy elevado. Durante el sexto curso y hasta la realización del examen los
estudiantes realizan jornadas de estudio superiores a 10 horas día tras día para conseguir la me-
jor posición posible ya que la obtención de una plaza les marcará su futuro profesional.
Durante estos meses de preparación los aspirantes realizarán simulacros de examen para prepa-
rarse de cara al examen oficial.
La creación de este portal web permite al aspirante llevar un registro, progresión y evolución de
los simulacros realizados, así como de conocer las posibilidades de obtención de plaza y de la
especialidad deseada.
Página 4 de 58
ABSTRACT
The medical degree in Spain is one of the most sought-after and has one of the highest entry
grades of more than thirteen points out of fourteen.
After six years of university studies, students must sit an exam organized by the Ministry of
Health in order to gain access to a place in a medical speciality of Internal Medical Resident
(MIR).
The MIR exam is extremely competitive, as the vacances available are limited and the number of
applicants is extremely high. During the sixth year and until the exam have done, students spend
more than 10 hours studying day after day, to get the best possible position, as obtaining a place
will mark their professional future.
During these months of preparation, the candidates will take mock exams to prepare for the
official exam.
The creation of this web portal allows the candidate to keep a record, progress and evolution of
the simulations conducted, as well as to know the possibilities of obtaining a place and the de-
sired speciality.
Página 5 de 58
ÍNDICE
AGRADECIEMIENTOS __________________________________________________________ 3
RESUMEN ___________________________________________________________________ 4
ABSTRACT___________________________________________________________________ 5
1. INTRODUCCIÓN _________________________________________________________ 10
1.2. OBJETIVOS................................................................................................................... 11
3. ARQUITECTURA _________________________________________________________ 14
7. DESARROLLO ___________________________________________________________ 28
Página 6 de 58
7.3. PYTHON (ETL) .............................................................................................................. 47
9. CONCLUSIONES _________________________________________________________ 55
REFERENCIAS _______________________________________________________________ 57
Página 7 de 58
Ilustración 1 - Arquitectura Cliente Servidor ............................................................................................... 15
Ilustración 2 - Diagrama de secuencia de registro de usuario en el portal. ................................................ 19
Ilustración 3- Diagrama de secuencia de inicio sesión de usuario en el portal ........................................... 21
Ilustración 4 - Diagrama de secuencia de registro de un nuevo resultado de simulacro. ........................... 21
Ilustración 5 - Diagrama de secuencia mostrar los resultados guardados por el usuario. ......................... 22
Ilustración 6- Diagrama de secuencia actualizar valores de un registro. ................................................... 23
Ilustración 7- Diagrama de secuencia para eliminar un registro. ............................................................... 24
Ilustración 8 - Ejemplo de JSON .................................................................................................................. 26
Ilustración 9 - Estructura documento colección usuarios ........................................................................... 27
Ilustración 10 - Estructura documento colección simulacros ...................................................................... 28
Ilustración 11- Estructura carpetas React ................................................................................................... 29
Ilustración 12- Vista inicio de sesión ........................................................................................................... 30
Ilustración 13- Vista registrar nuevo simulacro .......................................................................................... 31
Ilustración 14 - Vista listado de simulacros................................................................................................. 32
Ilustración 15 - Vista detalle simulacro (editar) .......................................................................................... 32
Ilustración 16 - Página evolución usuario. .................................................................................................. 33
Ilustración 17 - Funcionalidad generar nuevo pdf con jsPDF. ..................................................................... 34
Ilustración 18 - Funcionalidad generar título superior centrado. ............................................................... 34
Ilustración 19 - Transformación de elemento <canva> a imagen con htmlToImage .................................. 34
Ilustración 20 - Generar tabla en el PDF ..................................................................................................... 35
Ilustración 21 - Añadir metadatos al documento PDF ................................................................................ 35
Ilustración 22 - Estructura de carpetas servidor ......................................................................................... 36
Ilustración 23 - Rutas de auth.js ................................................................................................................. 37
Ilustración 24 - Rutas simulacros.js ............................................................................................................ 37
Ilustración 25 - Lógica para comprobar ser propietario de los simulacros ................................................. 38
Ilustración 26 – Funcionalidad verificar el token de sesión ......................................................................... 39
Ilustración 27 - Función de registro usuario ............................................................................................... 40
Ilustración 28 - Función para iniciar sesión ................................................................................................. 41
Ilustración 29 - Función listar simulacros de usuario .................................................................................. 42
Ilustración 30 - Función registro de simulacro ............................................................................................ 43
Ilustración 31 - Asignar nuevo resultado a un usuario ............................................................................... 43
Ilustración 32 - Función completar campos vacíos. .................................................................................... 44
Ilustración 33 - Eliminar simulacro por identificador .................................................................................. 45
Ilustración 34 - Función recuperar información usuario por identificador ................................................. 45
Ilustración 35 - Funcionalidad eliminar simulacro de un usuario ............................................................... 46
Ilustración 36 – Funcionalidad actualizar información simulacro .............................................................. 46
Ilustración 37 - Página del documento publicado por el Ministerio de Sanidad ......................................... 47
Ilustración 38 - Carga de las librerías a utilizar ........................................................................................... 48
Página 8 de 58
Ilustración 39 - Iteración por cada fichero PDF ........................................................................................... 48
Ilustración 40 - Iteración de líneas del documento PDF .............................................................................. 49
Ilustración 41 - Función extraer datos línea ................................................................................................ 49
Ilustración 42 - Método de separación por espacios y creación del Array.................................................. 49
Ilustración 43 - Ejemplo lectura de líneas del archivo PDF ......................................................................... 49
Ilustración 44 - Diccionario con las variables extraídas .............................................................................. 50
Ilustración 45 - Ejemplo anomalías aspirantes documento PDF ................................................................. 50
Ilustración 46 - Sentencia SQL creación tabla resultados ........................................................................... 51
Ilustración 47 - Tabla SQL resultados .......................................................................................................... 51
Ilustración 48 - Método cálculo posición .................................................................................................... 51
Ilustración 49 - Conexión a la base de datos SQLite3 ................................................................................. 52
Ilustración 50 - Consulta SQL calcular posición........................................................................................... 52
Ilustración 51 - Consulta SQL número de personas misma puntuación ...................................................... 52
Ilustración 52 - Detalle simulacro posición y número de personas ............................................................. 52
Ilustración 53 - Detalle simulacro posición y número de personas ............................................................. 53
Página 9 de 58
1. INTRODUCCIÓN
Cada año se ofertan cerca de 7.500 plazas en las diferentes universidades españolas para estu-
diar el grado de medicina siendo uno de los grados con mayores dificultades en poder ser esco-
gido por los estudiantes debido a su nota de corte en la Evaluación del Bachillerato para el Acceso
a la Universidad (EBAU), superior a 13 puntos sobre un máximo de 14.
Durante los 6 cursos académicos que tiene el grado el alumnado se formará en competencias de
materias preclínicas durante los dos primeros años y en los últimos cuatro años estará más en-
focado en la formación en competencias clínicas. El estudiante irá aprendiendo sobre una gran
cantidad de materias como anestesiología, cardiología, traumatología, medicina preventiva, etc.
Estas materias las aprenderá primeramente de forma más teórica en las clases para luego poder
seguir aprendiendo más de forma práctica en los diferentes hospitales adheridos a las universi-
dades.
Con la misma metodología y presión que se les presento a la hora de escoger el grado de medi-
cina deberán tomar una nueva decisión al finalizar los 6 cursos académicos ¿cuerpo militar de
sanidad? ¿cuerpo nacional de médicos forenses? ¿médico valorador? ¿médico interno resi-
dente?
Es cierto que existen distintas opciones profesionales una vez finalizado el grado universitario,
pero la gran parte de los estudiantes optan intentar ser médico interno residentes (MIR), aunque
para ello deberán volver a estudiar durante cerca de 1 año para realizar el examen del Ministerio
de Sanidad de Formación Sanitaria Especializada(FSE) y estar 3, 4 o 5 años formándote en una
especialidad.
El examen de Formación Sanitaria Especializada del Ministerio de Sanidad consta de una única
prueba de tipo test con 4 opciones y sólo una correcta. Durante los últimos años se han ido
modificando el número de preguntas siendo primeramente 225 preguntas, reduciéndose a 175
años después y finalmente siendo 200 preguntas y 10 de reserva. De la misma forma se ha cam-
biado la forma en la que se calcula la nota final para intentar reducir uno de los mayores proble-
mas que tiene dicha prueba y que está afectando al Sistema Sanitario Nacional “plazas sin esco-
ger”.
En la última convocatoria 2022-2023 se han admitido 13.059 aspirantes para optar a un total de
8.188 plazas siendo finalmente 10.793 aspirantes lo que podrán optar a elegir una plaza de es-
pecialidad.
Página 10 de 58
Pero antes de llegar a este último proceso de elegir plaza los estudiantes han tenido meses de
estudiar el temario no especificado ni limitado de forma diaria con jornadas que pueden ir desde
las 8 horas en distintas academias de preparación (CTO, AMIR, MIR Asturias, etc.) hasta superar
las 12 horas cuando se aproxima el examen por cuenta propia. Durante esos meses de prepara-
ción se centrarán en técnicas de estudio, organización, esquematización y estudio del temario y
la realización de simulacros con el mismo formato que el oficial, 4 horas y 30 minutos de límite
para responder un total de 200 preguntas + 10 de reserva de todo el temario médico existente
y casos clínicos, donde cada acierto tendrá un valor de 3 puntos positivos, cada fallo de 1 punto
negativo y la opción de no responder 0 puntos (neutral).
La forma que utilizan para llevar la evolución de estos suelen realizarla en algún tipo de cuaderno
o de forma digital mediante programas como Microsoft Excel u Hojas de Cálculo de Google Drive
donde predefinen campos como un identificador de ese simulacro, los aciertos, fallos y no res-
pondidas del simulacro o de cada asignatura. En algunas ocasiones las plataformas webs de las
academias ofrecen un panel donde pueden ver la evolución, pero solo de aquellos simulacros
propios de cada academia.
Además, los estudiantes tienen gran interés en saber que posición habrían obtenido a la hora de
elegir plaza según el resultado de dicho simulacro y ver si han podido mejorar su posible posición
con el paso de los meses y las jornadas de estudio.
1.2. OBJETIVOS
Este proyecto se orienta en el desarrollo de un portal unificado para facilitar el registro, evolución
y estimación de los simulacros que realizan los estudiantes de medicina en su preparación para
la elección de plaza tras realizar el examen de Formación Sanitaria Especializada.
Página 11 de 58
1.3. ESTRUCTURA DEL DOCUMENTO
El documento comienza explicando de forma general la situación del grado de medicina el tema-
rio que se estudiará durante los cursos académicos y las opciones profesionales una vez finali-
zado. Se aborda la situación del examen de Formación Sanitaria Especializada y la preparación
que realizan los aspirantes. También se aborda el problema actual que tienen para poder conocer
su evolución y el planteamiento de una solución a este problema.
Finalmente se expondrán las conclusiones de la realización de este portal tanto del punto de
vista técnico, como del punto de vista de usabilidad por parte de una estudiante de medicina en
y el valor que aporta este en su preparación para la realización del examen de Formación Sani-
taria Especializada en enero del 2024, así como el punto de vista y opinión de forma personal
que obtuve durante la realización de este.
Se añade como anexo al final de este una bibliografía, así como enlaces de interés o fuentes de
apoyo que se han utilizado durante la realización del portal.
El entorno desarrollo integrado (IDE - Integrated Development Environment) elegido ha sido Vi-
sual Studio Code de Microsoft ( VSCode) por las funcionalidades que aporta en el desarrollo web
y las ayudas que presenta para facilitar el desarrollo mediante librerías externas.
Para el desarrollo visual (frontend) las tecnologías (frameworks) que más interés están generado
son Angular (Google), Vue (código abierto), Laravel (código abierto) o React (Facebook/Meta).
Página 12 de 58
Los frameworks de Angular, Vue y React basan su código en JavaScript, mientras que Laravel lo
hace en PHP. Las cuatro opciones son altamente interesantes para la realización del proyecto y
están centradas en la creación de elementos reutilizables llamados componentes que se irán
agrupando entre sí hasta dar la forma visual a la página que queremos mostrar.
No contaba con conocimientos en ninguna de los frameworks así que la decisión de cual escoger
se concentraba en ser aquella que tuviera la programación más sencilla e intuitiva, así como que
contara con la mayor cantidad de documentación y comunidad posible.
En este caso se me hacía fácil de entender tanto Angular como React, ambas cuentan con una
estructura similar a la hora de crear componentes. Angular fue publicado en septiembre de 2016
por el equipo de Google como una versión mejorada de AngularJs, mientras que React fue pu-
blicado en mayo de 2013 por el equipo de Facebook.
Con la tecnología escogida en el frontend (cliente) decidí mantener el backend (servidor) usando
la tecnología de JavaScript y para ello la decisión fue usar NodeJS.
NodeJS es un entorno de tiempo de ejecución para JavaScript publicado en mayo de 2009 con-
tando con amplío recorrido y gran soporte por el equipo de mantenimiento y la comunidad.
Además, para la creación de servidores y APIs NodeJS nos facilita el uso de librería o paquetes
de terceros como pueden ser Express, KoaJS o NestJS. Tras haber revisado las tres librerías, Ex-
press es la que cuenta con una mayor comunidad de desarrolladores, así como la que cuenta con
una trayectoria más larga, fue publicada en 2010.
KoaJS fue publicada en 2013 y adaptar el desarrollo creado en Express sería sencillo de realizar
ya que cuenta con una sintaxis similar. Esta librería esta cogiendo día a día más popularidad para
la creación de servidores API, por lo que haber optado por desarrollarlo en esta hubiera de igual
forma una buena elección. Por parte NestJS leyendo su documentación parece estar más
Página 13 de 58
enfocado a un ámbito más profesional y escalable, por lo que se ha descartado en esta primera
versión al tener una curva de aprendizaje menos práctica y amigable.
Todas estas tecnologías tienen sus ventajas e inconvenientes por lo que no se debe decir que
una es mejor que otra de forma generalizada ya que cada tecnología será mejor dependiendo
del problema a resolver.
Python es un lenguaje de programación que apareció en 1990 usado de forma muy variada para
soluciones como backend, inteligencia artificial, la creación de procesos automatizados, etc. En-
focados en esta última opción encontramos los procesos de extracción, transformación-limpieza
y carga de gran cantidad de datos o ETL por su terminología en inglés (Extract, Transform, Load)
siendo estos de gran ayuda en la creación o migración de bases de datos. Estos procesos pueden
realizarse con programas como Pentaho o Microsoft SQL Server, pero estos dos programas no
nos permiten realizar la extracción de la información de los PDF, están más centrados en el pro-
cesamiento e ingesta de bases de datos ya desplegadas.
Python cuenta con una gran variedad de librerías, de forma similar a NodeJS, y para este proceso
con las librerías de pandas y PdfReader la creación de un proceso automatizado ETL nos permite
extraer los datos de los diferentes archivos PDF y hacer la carga de la información en la base de
datos una vez realizados los cálculos y limpiezas oportunos.
Por último, se utilizará el sistema Git y el portal de GitHub para llevar un versionado de cambios.
3. ARQUITECTURA
La arquitectura elegida será la del patrón cliente-servidor, donde se diferencia en dos subsiste-
mas la parte visual del navegador que el usuario visualizará denominada frontend (cliente), con
la parte de interacción con las bases de datos y otros recursos denominada backend (servidor).
Página 14 de 58
Ilustración 1 - Arquitectura Cliente Servidor
Cuando un usuario visite una página web (cliente) se enviará una solicitud al servidor mediante
puntos de entrada endpoints los cuales serán los encargados de realizar las operaciones oportu-
nas contra las bases de datos y devolver el resultado de los cálculos a la parte visual del usuario
(cliente).
Una de las ventajas de esta arquitectura de desarrollo es que tenemos una tolerancia a fallo o
desconexión desagregada por servicio, de esta forma si la parte del servidor falla o una de las
bases de datos falla el servicio solo se va a tener interrupciones contra ese recurso sin afectar de
forma generalizada a la aplicación. Además, nos permite una capa de aislación y seguridad ya
que es el servidor el que se encargara de realizar las conexiones contra la base de datos y las
operaciones a realizar limitando el acceso no deseado por parte del usuario/cliente.
Revisando los diferentes portales con los que cuentan las academias y plataformas de apoyo, se
encontraron distintos puntos de mejoras que ayudaban al estudiante a mejorar su evolución y
preparación.
Página 15 de 58
Con las respuestas obtenidas de los estudiantes se decide crear una versión inicial del portal y
que deberá cumplir como mínimo con los siguientes requisitos funcionales y no funcionales.
Precondición No aplica
Las plataformas de las academias no cuentan con la opción de registrar un simulacro distinto a
los que tienen planificados los estudiantes. Además, si un estudiante realiza distintos intentos
de un mismo simulacro se le muestra solo la última situación sobrescribiendo los resultados an-
teriores. Los estudiantes respondieron que tener un portal donde poder registrar simulacros de
forma flexible al calendario propuesto les ayudaría a tener un mejor seguimiento de sus estudios.
Página 16 de 58
Nombre Visualizar listado de simulacros realizados
Tras preguntar a los estudiantes de medicina de la UCM creen que los portales de las academias
están muy poco centrados en la evolución que tiene cada alumno y más centrada en presentar
el temario oportuno de cada asignatura. Respondieron que tener una página con distintas gráfi-
cas y tablas donde poder filtrar y e interactuar les resultaría útil para entender mejor su evolu-
ción y saber en que focalizarse en el tiempo de estudio.
Página 17 de 58
Nombre Visualizar evolución resultados
Las plataformas actuales de las academias muestran una interfaz consistente si se accede me-
diante dispositivos de gran tamaño como ordenadores, pero al acceder desde dispositivos de
menor estos portales o no se adaptan de forma correcta o siguen mostrando el mismo diseño
que el visto desde un ordenador. Esto provoca una mala impresión y una navegación y uso de los
portales poco útil, amigable o fácil.
Precondición No aplica
Página 18 de 58
5. DIAGRAMAS DE SECUENCIA
Cada una de las funcionalidades descritas anteriormente tendrá asociado un diagrama de se-
cuencia donde se detallará el desarrollo desde que el usuario accede al portal hasta la funciona-
lidad requerida.
Una vez comprobados los valores se ejecutará la función encargada de guardar la información
en la base de datos oportuna. El servidor podría no devolver una respuesta con información,
pero se opta por enviar de nuevo la información completada por el usuario, así como un identi-
ficador inicio de sesión (token) siendo finalmente redirigido a su página de perfil personal.
Página 19 de 58
5.2. INICIO DE SESIÓN
Una vez el usuario haya completado correctamente el formulario de registro, anteriormente ex-
plicado, podrá acceder a su perfil introduciendo información básica como su identificación y la
contraseña elegida.
En este proceso el usuario completará los datos requeridos necesarios (correo y contraseña) que
serán primeramente validados en la parte del cliente y enviados posteriormente al servidor para
realizar una nueva validación. Las comprobaciones que realizará el cliente son comprobar que se
ha introducido un formato de correo válido, así como una contraseña mínima. Una vez esta in-
formación llegar al servidor este realizará una búsqueda en la base de datos para comprobar que
el correo introducido por el usuario ha sido registrado anteriormente, y en caso de existir se
realizará una comprobación entre la contraseña introducida por el usuario y la almacenada en la
base datos.
En este caso se redirigirá al usuario a su página de perfil en caso de que ambos sean correctos y
en caso contrario se le mostrará un aviso de error para que pueda comprobar los datos introdu-
cidos.
Página 20 de 58
Ilustración 3- Diagrama de secuencia de inicio sesión de usuario en el portal
En este caso se le solicitará al usuario campos como el nombre o un alias del simulacro realizado,
el tipo de simulacro realizado y el número de preguntas acertadas, falladas y no respondidas.
Cuando esta información haya sido completada se realizará una comprobación en la parte del
cliente ofreciendo un aviso visual en caso de que alguno de los campos no se haya completado
o se haya completado de forma incorrecta. Esta información posteriormente llegará al servidor
donde se completarán los campos necesarios y validarán nuevamente para comprobar que los
datos introducidos son válidos para posteriormente ser almacenados en la base de datos opor-
tuna.
Página 21 de 58
5.4. VISUALIZAR LISTADO DE SIMULACROS REALIZADOS
La página de perfil del usuario mostrará un listado de todos los resultados almacenados en la
base de datos. De esta forma el usuario podrá saber de forma resumida que resultados ha en-
viado con anterioridad.
Para realizar esta funcionalidad no se necesitan campos adicionales de búsqueda por parte del
usuario, el sistema devolverá todos los registros.
El cliente enviará una petición al servidor “Listar resultados de simulacros”. Al recibir esta peti-
ción en la parte del servidor, este se encargará de realizar las comprobaciones de que el usuario
está con una sesión iniciada y solicitará a la base de datos la información relativa al usuario en-
viando los parámetros de búsqueda.
Una vez la base de datos haya encontrado los distintos resultados, esté se lo hará llegar al servi-
dor para que el cliente lo reciba y evalúe los datos en el visual generando los diferentes compo-
nentes.
Página 22 de 58
5.5. EDITAR RESULTADO DE UN SIMULACRO
Se le da la posibilidad al usuario de poder editar un resultado enviado con anterioridad para
corregir aquellos valores introducidos de forma incorrecta.
En esta situación el usuario deberá identificar el registro erróneo del listado que se le muestra
en su perfil y acceder al detalle de este donde se le mostrará la información que envío y que está
almacenada en la base de datos. Desde esta situación podrá editar los campos que consideré
oportunos como corregir el nombre de identificación del simulacro o las preguntas respondidas.
Una vez introducidos los valores correctos estos serán validados por parte del cliente y del ser-
vidor antes de realizar la actualización necesaria en la base de datos.
Página 23 de 58
5.6. ELIMINAR RESULTADO DE UN SIMULACRO
El usuario tendrá la opción de enviar un resultado enviado desde su página de perfil. Para ello
sólo tendrá que pulsar sobre el botón correspondiente enviando la petición al servidor de elimi-
nar dicho registro de su perfil asociado.
El servidor recepcionará esta solicitud y ejecutará la función interna que se encarga de conectar
con la base de datos. Tras la conexión se comprobará que el usuario ha solicitada la eliminación
de un simulacro que está bajo su autoría y en caso afirmativo se le notificará a la base de datos
de la eliminación de dicho registro.
Si la base de datos consigue borrar el registro de forma correcta, teniendo las casuísticas opor-
tunas, devolverá una confirmación que el servidor hará llegar al cliente.
Página 24 de 58
5.7. VISUALIZAR EVOLUCIÓN RESULTADOS SIMULACRO
Desde la página de estadísticas el usuario podrá ver la evolución y progreso de los resultados
enviados.
Esta funcionalidad utilizará el mismo diagrama que la de “Visualizar listado de simulacros reali-
zados”. La diferencia que se tiene la encontramos en la forma que el cliente interpretará los datos
que el servidor le haga llegar.
Mientras que en el diagrama anterior se creaba una lista con los resultados obtenidos, en esta
se generarán las gráficas y selectores de filtros oportunos para que el usuario pueda conocer su
evolución de forma visual y seleccionar aquellos que quiera tener mayor interés.
6. BASE DE DATOS
La base de datos se ha implementado usando NoSQL y más concretamente MongoDB. Esta tec-
nología fue desarrollada en el 2007 como una alternativa a las bases de datos relacionales SQL.
Su gran diferencia es la forma de almacenar la información, mientras que en las bases de datos
SQL el diseño es mediante tablas y filas con relaciones hacía otras tablas, las NoSQL pueden
Página 25 de 58
almacenar toda la información necesaria en colecciones y documentos sin ser necesaria la crea-
ción de una relación, aunque nos dan la posibilidad de realizar una relación flexible (populate).
La información o documentos en este caso es almacenada en formato JSON (JavaScript Object
Notation).
Para crear la base de datos para el proyecto se optó por crear 2 colecciones uno para almacenar
la información de los usuarios enviada del registro y otra para almacenar la información de si-
mulacros registrados.
Página 26 de 58
Ilustración 9 - Estructura documento colección usuarios
Los campos comunes que todos los simulacros tienen son un campo de fecha generado automá-
ticamente; un campo de tipo objeto JSON que guardará información relativa a nombre que será
un campo de texto requerido, un campo de tiempo empleado y tiempo máximo que se expresará
en formato número y minutos; un campo denominado global que almacenará las preguntas acer-
tadas, falladas, no respondidas y valor neto; y un listado de las asignaturas que almacenará las
preguntas acertadas, falladas y no respondidas de cada una, este campo es opcional a la hora de
guardar la información.
Página 27 de 58
Ilustración 10 - Estructura documento colección simulacros
7. DESARROLLO
Una vez definida la estructura de la base de datos y el diseño visual se realizará las funcionalida-
des para dotar de interactividad al portal.
Página 28 de 58
Ilustración 11- Estructura carpetas React
La carpeta pages contiene las diferentes vistas que el usuario podrá ver al visitar el portal.
• Inicio: es la página de visitar la vista principal, desde esta vista podrá navegar hacia el
resto de las vistas.
• Auth: es la vista que nos muestra la funcionalidad de iniciar sesión o registrarnos en el
portal.
• ProtectedRoute: es un manejador de estados para comprobar si el usuario ha iniciado
sesión y en caso de no estarlo y querer visitar una página en la que es necesario estarlo
mostrar la vista de iniciar sesión.
• Perfil: es la vista que nos muestra el listado de simulacros enviados por el usuario y desde
la cual se da la opción de editar, eliminar o añadir un simulacro.
• DetalleSimulacro: muestra la información de cada simulacro de forma individual y nos
da la opción de editar o cambiar los valores si el usuario lo desea.
• Stats: es la vista donde el usuario va a poder conocer la evolución de los simulacros que
ha ido realizando.
La carpeta de components contiene los objetos visuales reutilizables que se han usado en el por-
tal manteniendo una estética homogénea para ser más amigable la navegación y el uso.
Página 29 de 58
Gracias a la tecnología de Tailwind es posible crear un diseño adaptativo a los distintos tamaños
de dispositivos de forma sencilla.
Página 30 de 58
Ilustración 13- Vista registrar nuevo simulacro
Página 31 de 58
Ilustración 14 - Vista listado de simulacros
Página 32 de 58
Una de las funcionalidades más requeridas es tener una pestaña de evolución o progreso de los
simulacros que se han realizado.
Para ello se ha usado la librería de Recharts (www.recharts.org) que nos facilita la generación de
gráficos interactivos como gráficos de líneas, gráficos de barras, etc. Se opta por esta librería por
la versatilidad que nos proporciona y facilidad de uso respecto a otras como d3.js.
Siguiendo con los criterios de requisitos funcionales se decide crear una sección de estadísticas
donde el usuario va a poder ver la progresión que está teniendo de forma general (puntuación
neta) así como de forma más detallada en caso de completar la información de aciertos y fallos
de cada una de las asignaturas.
Para llevar a cabo esta solución se decide crear dos gráficos de línea donde se muestra el eje y
como la calificación neta (aciertos-fallos*1/3).
En un primer momento esta funcionalidad iba a ser realizada por el servidor enviando los pará-
metros necesarios (identificadores de los simulacros y asignaturas seleccionadas), pero se deci-
dió generar el documento desde la parte del cliente con los filtros que el usuario tuviera visual-
mente. De esta forma reducimos las acciones que el servidor deba realizar y podemos focalizar-
nos en mejoras de rendimiento.
Página 33 de 58
Para poder llevar a cabo esta funcionalidad se hace uso de las librerías htmlToImage y jsPDF.
Primeramente, realizaremos las acciones previas de crear un pdf con la librería jsPDF con los
parámetros que deseamos de tamaño y orientación.
Una vez creada la página del documento, generamos un título centrado en la parte superior. Para
realizar este posicionamiento debemos obtener el ancho y alto de la página, así como una lon-
gitud del texto para que se posicione centrado.
htmlToImage es una librería que nos permite convertir los elementos <canva> y SVG en una ima-
gen con formato png/jpg los estándares en los formatos de imagen.
Se añadirán fotografía de los dos gráficos en doble columna y un título descriptivo para cada uno.
Página 34 de 58
A continuación, se adjuntará una tabla con los resultados y filtros usados para la generación de
los gráficos.
Y se añadirán las propiedades al archivo PDF en los metadatos, para finalmente abrir el archivo
final en una nueva ventana en el navegador del usuario.
Página 35 de 58
7.2. SERVIDOR (BACKEND)
La parte del servidor ha sido implementada con la tecnología de Express.js, tecnología que apa-
reció en el año 2010 y que en la tecnología de backend de NodeJS es una de las más utilizadas.
En esta parte se decidió mantener una estructura de carpetas propia en la que se separan los
archivos de rutas, modelos y funcionalidades.
La carpeta de routes (rutas) contiene dos ficheros, auth.js y simulacros.js, que son los puntos de
entrada (endpoints) desde los que se conectará el cliente.
El archivo auth.js es el que maneja los endpoints de inicio de sesión, registro y cerrar sesión, así
como un punto de entrada para renovar el token de seguridad.
Los 4 puntos de entrada son de tipo POST en los que el vendrá la información del usuario por el
campo body de cada petición y será el servidor quien recupere la información para realizar las
comprobaciones.
Página 36 de 58
Ilustración 23 - Rutas de auth.js
El archivo simulacros.js contiene los puntos de entrada para aquellas peticiones relacionadas con
los registros de simulacros (creación, edición, eliminación y listado).
Página 37 de 58
El servidor realizará una comprobación en cada acción para asegurarse de que el usuario que ha
solicitado la acción es autor de los simulacros afectados.
Todas estas rutas solo son accesibles en caso de que el usuario haya iniciado sesión, en caso de
no haber iniciado sesión el servidor enviará un mensaje de error y no permitirá la acción solici-
tada.
Con este planteamiento nos aseguramos de que no es posible modificar registros de simulacros
por personas terceras ni acceder a los registros de otra persona.
Página 38 de 58
Ilustración 26 – Funcionalidad verificar el token de sesión
Página 39 de 58
Cuando el usuario quiere registrarse en el portal se enviarán los campos completados en el
cliente (frontend), se realizarán las validaciones oportunas en la parte del cliente y se ejecutará
la operación de registro:
Esta función recibe dos parámetros, req y res, que representan la solicitud del cliente y la res-
puesta del servidor, respectivamente, cuando se recibe la solicitud del cliente esta debe de llevar
en su campo body los valores de nombre, correo y contraseña.
El proceso que sigue la función para guardar la información en la base de datos es la siguiente:
• Se genera un valor de sal utilizando la función bcrypt.genSalt(). La sal se utiliza para cifrar
la contraseña del usuario. El número 10 indica el número de rondas de cifrado que se
realizarán en la generación del hash de la contraseña.
Página 40 de 58
• Se crea un nuevo objeto Usuario con los datos recibidos del cliente (nombre, correo y
contraseña cifrada).
• Se crea un token JSON Web utilizando la función jwt.sign(). Este token incluirá el identi-
ficador único _id del usuario registrado. También se incluye un secreto compartido (pro-
cess.env.JWT_TOKEN o 'localhost') y la duración del token ({ expiresIn: '4days' }).
• Finalmente, se devuelve una respuesta al cliente mediante el objeto res con el código de
estado 201 (creado) y un mensaje indicando que el registro se realizó correctamente, así
como incluir el token JSON Web (jwt) en la respuesta.
Si ocurre un error durante el registro (por ejemplo, el usuario ya está registrado o falta algún
dato requerido), se captura el error y se devuelve una respuesta al cliente con el código de estado
400 (solicitud incorrecta) y un mensaje de error adecuado.
Página 41 de 58
Esta función se ejecuta cuando el usuario envía una solicitud para iniciar sesión en la aplicación.
Dentro de la función, se espera que la solicitud del cliente incluya el correo electrónico y la con-
traseña del usuario que se están utilizando para iniciar sesión. Estos datos se obtienen de
req.body y se asignan a las variables correo y password.
Luego, la función utiliza el método findOne() proporcionado por la biblioteca Mongoose para
buscar en la base de datos un objeto Usuario que tenga el correo electrónico proporcionado por
el usuario.
A continuación, se utiliza una estructura condicional para comprobar si el objeto usuario no está
definido o si la comparación de contraseñas falla. En caso de que alguno de estos casos sea ver-
dadero, se devuelve una respuesta al cliente con un código de estado HTTP 403 (Prohibido) y un
mensaje de error.
Finalmente, se devuelve una respuesta al cliente con un código de estado HTTP 200 (OK) y los
datos del usuario autenticado, incluyendo el token JSON Web.
Una vez el usuario haya iniciado sesión en su cuenta, el portal le redirigirá a su página de perfil
desde done podrá visualizar un listado de los registros anteriores, en caso de haberlos, así como
crear un nuevo resultado.
Página 42 de 58
Cuando el simulacro llega al sistema del servidor la función enviarSimulacro utilizará la función
auxiliar completarCamposVacios pasando como argumento los campos completados por el usua-
rio que se encargará de verificar y rellenar aquellos campos que no haya completado el usuario
y sean necesarios para el correcto funcionamiento. A continuación, el sistema asignará este
nuevo simulacro al perfil de usuario mediante la función registrarFormularioAsignar que recibe
los datos validados y el identificador único del usuario en la base de datos.
Página 43 de 58
Ilustración 32 - Función completar campos vacíos.
En caso de que todas las validaciones y operaciones se realicen con éxito se devuelve una res-
puesta HTTP 201 indicando la finalización del registro en la base de datos.
Como se ha comentado el usuario además podrá eliminar un registro que envió con anterioridad,
así como modificar los valores de uno en caso de haber cometido algún error a la hora de en-
viarlo. Para estas funcionalidades se deberá de tener un inicio de sesión en vigor, Json Web To-
ken, y ser propietario de este registro, tenerlo asignado a su perfil.
Página 44 de 58
Ilustración 33 - Eliminar simulacro por identificador
De la misma forma que se ha explicado con anterioridad el sistema comprobará que el usuario
es el propietario del simulacro. Para realizar esta comprobación se buscará al usuario mediante
su identificador en la colección de “Usuarios” de la base de datos de MongoDB.
Este método nos devolverá los valores del usuario en caso de existir, para posteriormente com-
probar en su campo simulacros si el identificador del simulacro a borrar está en la lista de simu-
lacros de la que es propietario. En caso de que el resultado de esPropietario sea distinto de -1
significará que el usuario tiene en una de las posiciones del array el identificador de dicho simu-
lacro y por lo tanto se puede realizar la acción de eliminado del simulacro.
Página 45 de 58
Ilustración 35 - Funcionalidad eliminar simulacro de un usuario
Si todas las acciones iniciadas finalizan de forma satisfactoria se enviará una respuesta al cliente
con código HTTP 200 indicando que la eliminación se ha realizado con éxito. En caso de no existir
el usuario, no ser propietario o que se provoque algún error durante la ejecución se paralizará la
acción sin afectar al sistema y se enviará una respuesta de error al cliente.
Página 46 de 58
7.3. PYTHON (ETL)
Como se ha descrito Python brinda un gran abanico de posibilidades para realizar procesos de
extracción, limpieza y procesamiento de datos con gran cantidad de información.
Esta operación si se quisiera realizar de forma manual sería una tarea muy laboriosa que haría
invertir mucho tiempo por lo que se ha decido por automatizar este proceso utilizando las fun-
cionalidades que nos da el lenguaje de programación de Python.
Para poder realizar la extracción de la información de cada página se opta por utilizar la librería
PyPDF. Antes de empezar con la extracción debemos visualizar diferentes páginas para compren-
der si el formato puede verse modificado por alguna anomalía, así como buscar posibles
Página 47 de 58
patrones que puedan servirnos para abordar el problema. En este sentido encontramos que to-
das las páginas cuentan con una parte superior de encabezado con la información explicativa por
parte del Ministerio de Sanidad seguido de una tabla con los resultados de los aspirantes y una
nota de pie de página donde se referencia la disposición del Boletín Oficial del Estado donde ha
sido publicada y aprobada la convocatoria.
Viendo este diseño vamos a descartar el encabezado y la nota de pie de página al no ser una
información de interés ya que se busca extraer los resultados de los aspirantes contenidos en la
tabla.
El resultado que queremos obtener será una lista que será transformada a un conjunto de datos
de Pandas, librería que nos permite realizar operaciones con tablas de datos.
Actualmente se tiene acceso a los documentos PDF de las convocatorias desde la 2017 hasta la
2022 por lo que debemos iterar por cada archivo para extraer la información oportuna.
PdfReader recibe como parámetro el fichero que debe abrir, así como un parámetro opcional de
aquellas páginas que se desean leer, en caso de no establecer este parámetro la librería tiene
predefinida la lectura completa del archivo devolviendo un Array del contenido de cada página.
Se realizará una separación por los saltos de línea para luego iterar por cada línea y extraer la
información relacionada con la tabla deseada.
Para ello debemos indicar a partir de que línea o que patrón debe el programa empezar a extraer
información, ya que como he comentado la cabecera y el pie de página no nos interesa, pero
además no todas las líneas nos interesan por el formato que tiene creado el documento.
Página 48 de 58
Ilustración 40 - Iteración de líneas del documento PDF
Este programa una vez ha encontrado las líneas de las que deseamos extraer información enca-
dena con otra funcionalidad para extraer dicha información recibiendo como parámetros la línea
de donde extraer las diferentes columnas y el año de la convocatoria (nombre del fichero).
La información que recibe esta función de cada línea es un Array generado por la separación de
espacios en blanco mediante el método split.
Página 49 de 58
Tras realizar los diferentes cálculos y operaciones se devuelve un diccionario con la información
que se encuentra en la tabla del documento.
Durante este proceso se encontraron anomalías en el documento ya que no todos los aspirantes
tenían la misma longitud en sus nombres por lo que aquellos aspirantes que tuvieran un nombre
y apellidos excesivamente largos ocuparían dos líneas fragmentando los datos entre las dos lí-
neas. Para solucionar estas anomolías se genera un sistema de detección de líneas separadas y
generar una nueva línea con la información unificada.
Con la información extraída de los archivos PDF del Ministerio de Sanidad se opta por cargar la
información en una base de datos SQL ya que todos los registros deben de tener las mismas
columnas.
Página 50 de 58
Ilustración 46 - Sentencia SQL creación tabla resultados
Una vez se ha finalizado el proceso de extracción, limpieza y transformación y carga de los PDF
se decide incorporar está en la parte frontend para añadir más información al usuario acerca del
resultado enviado.
Para ello en la parte del servidor se crea un nuevo método que será el encargado de acceder a
la base de datos de los resultados del Ministerio de Sanidad calcular la posición en la que hubiera
quedado para dicha convocatoria.
Este nuevo método recibe como parámetros el número de aciertos, fallos y el año del simulacro
que ha realizado, sólo se calculará para aquellos que el usuario haya marcado que el simulacro
realizado es de tipo “Ministerio de Sanidad” y haya introducido en su campo de nombre el año
de la convocatoria realizada.
Página 51 de 58
Este método creará una conexión a la base de datos SQL para realizar las consultas.
Primeramente, se obtendrá la posición en la que hubiera quedado con la consulta de SQL, para
el cálculo será necesario contabilizar las preguntas netas tomando como valor en caso de acer-
tada +1 punto y en caso de fallada -1/3 punto.
Finalmente, se calculará el número de personas que han obtenido esa misma puntuación para
que el usuario sepa si dicha cantidad de aciertos y fallos es común obtenerlos.
Una vez ha sido calculada la posición y el número de personas con la misma puntuación, cuando
el usuario entré en un resultado de sus simulacros se le mostrará dicha información en la parte
superior.
Página 52 de 58
Ilustración 53 - Detalle simulacro posición y número de personas
8. PRUEBAS Y MEJORAS
El desarrollo de este proyecto surgió por una necesidad de Claudia, estudiante de medicina de
la Universidad Complutense de Madrid, para poder llevar su preparación de cara a la realización
del examen de Formación Sanitaria Especializada ya que la academia externa de estudio le brinda
un portal, pero este se encontraba limitado a los simulacros realizados por la academia.
Durante el desarrollo Claudia ha ido añadiendo los resultados de sus simulacros y advirtiéndome
de los fallos, necesidades y mejoras que se la presentaban, para que siempre que estuviera a mi
alcance pudiera implementarlo.
Una de las mejoras que se solicitó fue la posibilidad de incorporar el tiempo máximo y empleado
por cada simulacro cuando se guardaban los resultados. Y se incorporó esta funcionalidad días
más tarde permitiendo a la usuaria añadir dicho tiempo y el sistema lo convertiría en formato
número de minutos.
Estos han sido solamente algunas de las peticiones realizadas, pero que me han permitido tra-
bajar bajo presión para poder solventar las necesidades e implementarlas de la forma más eficaz.
Página 53 de 58
La aplicación tiene una funcionalidad del 100%, no obstante, puede seguir mejorándose, aña-
diendo información más precisa como la posición exacta teniendo como referencia la nota aca-
démica del usuario.
También, podría añadir información sobre las plazas convocadas por hospital y la asignación real
de las plazas por los aspirantes, documentos publicados por el Ministerio de Sanidad en su pá-
gina web y en el Boletín Oficial del Estado.
Otra mejora sería la creación de un portal de administrador desde donde se puedan reasignar o
eliminar simulacros de usuarios, bloquear usuarios o añadir nuevos campos en el registro.
Página 54 de 58
9. CONCLUSIONES
Una vez completa esta memoria y teniendo el portal con una funcionalidad completa, este pro-
yecto me ha servido para adentrarme en el desarrollo backend y frontend dos especialidades
que había tenido tiempo, ocasión ni proyectos para aprenderlos.
Este ha sido el primero proyecto que he podido desarrollar con la tecnología de React y Tailwind
haciéndose muy amena la combinación de ambas para la creación de aplicaciones y portales
web.
También he podido aprender sobre las diferentes tecnologías de backend y sus ventajas, incon-
venientes y seguridad al respecto de la creación de servidores.
A lo largo de este proyecto se han ido incorporando nuevas funcionalidades y mejoras depen-
diendo de los requisitos necesarios en cada momento. Gracias a React, en el caso del cliente y
de ExpressJS en la parte del servidor realizar modificaciones e incorporar mejoras ha sido una
tarea relativamente sencilla y rápida.
Una de las mejores que me hubieran gustado realizar es incorporar algún sistema de generación
de simulacros de forma que cualquier estudiante de medicina pudiera tener acceso a preguntas
de preparación sin tener que desembolsar grandes cantidades de dinero como tienen las acade-
mias.
Página 55 de 58
10. ANEXO
10.1. ASPECTOS ÉTICOS
El portal planteado está cerrado y contralado, pero debemos asegurar la protección de acceso a
los diferentes puntos de llamada hacía el servidor y la base de datos debido a que contiene in-
formación de cada usuario. Si bien es cierto que esta información que se almacena en la base de
datos no contiene información ni valores personales críticos mantenerlos protegidos es siempre
necesario para preservar la propiedad de cada usuario. Por este motivo, la implementación del
sistema en un sistema de producción público conllevará tomar las medidas oportunas como li-
mitar el acceso mediante IP a las rutas del servidor y realizar diferentes exámenes de prueba
contra vulnerabilidades.
Página 56 de 58
REFERENCIAS
AcademiAMIR. (s.f.). "El examen". Obtenido de https://academiamir.com/el-mir/el-examen/
AcademiAMIR. (s.f.). "MIR 2022: El Ministerio publica la lista de admitidos definitiva". Obtenido
de https://academiamir.com/mir-2022-el-ministerio-publica-la-lista-de-admitidos-
definitiva/
Boletín Oficial del Estado. (s.f.). Comisión de Recursos Humanos del Sistema Nacional de Salud.
Obtenido de https://www.boe.es/boe/dias/2021/09/11/pdfs/BOE-A-2021-14809.pdf
BuiltWith. (s.f.). "Framework Usage Distribution in the Top 1 Million Sites". Obtenido de
https://trends.builtwith.com/framework
ConSalud. (s.f.). "En 2021-2022 un 14% de los estudiantes de Medicina no acabó la carrera, 10%
más que en prepandemia". Obtenido de https://www.consalud.es/especial-mir/en-
2021-2022-14-estudiantes-medicina-no-acabo-carrera-10-mas-
prepandemia_122074_102.html
Ministerio de Trabajo y Economía Social. (s.f.). "MIR 2022: Convocatoria de plazas y de pruebas
selectivas para formación sanitaria". Obtenido de
https://www.sepe.es/HomeSepe/que-es-el-sepe/comunicacion-
institucional/noticias/historico-de-noticias/2021/detalle-
noticia.html?folder=/2021/Septiembre/&detail=convocatoria-mir-2022-plazas-
pruebas-selectiva-formacion-sanitaria
Mirial. (s.f.). "Cómo funciona el examen MIR 2024: todo lo que debes saber del examen de
medicina". Obtenido de https://mirial.es/examen-mir
Página 57 de 58
MongoDB. (s.f.). MongoDB. Obtenido de https://docs.mongodb.com/
Redacción Médica. (s.f.). "Consulta las cuatro versiones del examen MIR 2022". Obtenido de
https://www.redaccionmedica.com/secciones/formacion/documento-consulta-las-
cuatro-versiones-del-examen-mir-2022-4334
Redacción Médica. (s.f.). "Las plazas para estudiar Medicina se consolidan con un nuevo récord:
7.445". Obtenido de https://www.redaccionmedica.com/secciones/estudiantes/las-
plazas-para-estudiar-medicina-se-consolidan-con-un-nuevo-record-7-445-6754
Redacción Médica. (s.f.). "Sí, se puede trabajar como médico sin tener que enfrentarse al MIR".
Obtenido de https://www.redaccionmedica.com/virico/noticias/-si-se-puede-trabajar-
como-medico-sin-tener-que-enfrentarse-al-mir--5548
Redacción Médica. (s.f.). ¿Faltan médicos? Hay más facultades, pero 741 alumnos menos que
hace 4 años. Obtenido de https://www.redaccionmedica.com/secciones/estudiantes/-
faltan-medicos-hay-mas-facultades-pero-741-alumnos-menos-que-hace-4-anos-2944
RTVE. (s.f.). "¿Merece la pena estudiar la carrera de Medicina? - PLAYZ". Obtenido de RTVE.es:
https://www.rtve.es/playz/20210622/merece-pena-estudiar-medicina-
futuro/2104003.shtml
Página 58 de 58