Undécima Entrada de la Bitácora (4/5/26)

Hora de Inicio 1: 9:05 am (4/29/26)

Hora de Fin 1: 12:17 pm (4/29/26)

Hora de Inicio 2: 7:13 pm (4/5/26)

Hora de Fin 2: 10:43 pm (4/5/26)

Cantidad de horas trabajadas: ~2 (4/29/26) + ~3 (4/5/26) = ~5 (ignorando ratos para comer y demás)

Para esta entrada me voy a dedicar a trabajar en la funcionalidad restante, y conectarla al front end.

A la hora de trabajar en el desarrollo de toda la funcionalidad de los movimientos tuve que investigar cuál sería la mejor manera de hacerlo, y ya que nuevamente, en R2 se menciona que los ids deben estar escondidos, tuve que investigar cómo conseguir los ids de empleado y tipoMovimiento en medio procedimiento almacenado para poder insertarlos en el nuevo movimiento, y tras revisar muchas fuentes y videos en internet, básicamente parece que, o utilizo una palabra clave DECLARE, o utilizo SELECT dentro del VALUES en el INSERT, por ahora decidí usar la opción de SELECT, para la cual me basé un poco en este video (SQL SERVER INSERT INTO SELECT | HOW TO COPY DATA TO ANOTHER DATABASE - YouTube), aunque realmente entendiendo que se puede utilizar el SELECT de esta forma pues ya lo adapté específicamente a los estándares de codificación de la clase y básicamente copié el SELECT que hacía en otros procedimientos almacenados, si esto no funciona consideraré usar DECLARE, pero en las fuentes que vi algunas mencionaban que utilizar variables locales no era muy recomendado, pero en fin, veré si eso funciona cuando conecte el front end con el back end y demás.

Para el tema del XML se me complicó un poco, no estaba muy seguro si la idea era hacer múltiples INSERT normales, estuve viendo nuevamente las opciones posibles, y revisé varias posibles opciones que podrían funcionar, XQuery (XQuery Language Reference (SQL Server) - SQL Server | Microsoft Learn Xquery in SQL Server - Stack Overflow / Filtering XML Columns using XQuery in SQL Server), o haciendo bulk import (Bulk import & export of XML documents - SQL Server | Microsoft Learn), o haciendo bulk insert con nodejs (javascript - Bulk inserting with Node mssql package - Stack Overflow / Node.js SQL Server: Bulk Insert / mssql - npm), o algo como lo de este tutorial: Working with XML Data in SQL Server.

Pero bueno, revisando esas opciones de forma un poco superficial, me pareció que XQuery (sobre todo por el tutorial de SQL Shack) parece relativamente sencillo, así que voy a intentarlo así y veré si funciona, también, para agregar con ids "personalizados" para que todas las tareas tengan los mismos ids según el XML, me basé en esto: sql server - SQL statement to insert record into table that has identity column? - Stack Overflow

En la clase el profe está comentando que la inserción de movimientos se hace de forma iterativa, entonces los movimientos del XML los voy a insertar de forma iterativa, pero para la otra información igual creo que tiene sentido usar XQuery.

El profe también comentó que Empleado debe insertarse de forma iterativa, ya que depende de las fechas, pero luego aclaró que para esta tarea simplemente queda como un así "debería ser", pero por ahora solo los movimientos se insertarán de manera iterativa.

Revisando nuevamente las instrucciones del proyecto me di cuenta que en R1 se menciona "ese usuario en esa ip", así que tuve que cambiar un poco la funcionalidad del bloqueo por cantidad de intentos para que se haga según una combinación de ambos, esto realmente también trajo un problema, y es qué hacer cuando el usuario ingresa un username que no existe, inicialmente había hecho que la tabla BitacoraEvento no pueda tener NULL en IdPostByUser, ya que el profe constantemente menciona que NULL es el enemigo número uno de un desarrollador de base de datos, pero me puse a investigar un poco más del tema, y parece no ser algo tan sencillo como nunca permitir NULL, por ejemplo en Why should I avoid NULL values in a SQL database? - Stack Overflow se menciona que "If something is not known, saying it is unknown doesn't make it known (...) From this perspective, unknown things should not be recorded - they are not useful facts.", por lo tanto según esto no debería guardar el id del usuario como NULL, pero nuevamente, si el username no existe entonces no hay cómo obtener un id correspondiente, y basado en las instrucciones y la existencia del error 50001 "Username no existe", esto sí o sí hay que registrarlo en BitacoraEvento, por lo que no parece ser tan simple.

Leyendo más a detalle las respuestas a la pregunta en Stack Overflow que puse anteriormente, otra respuesta da a entender que parecen haber dos perspectivas: "Two-Valued Logic (2VL: TRUE and FALSE)", la cual rechaza NULL, y "Three-Valued Logic too (TRUE, FALSE and UNKNOWN)", la cual curiosamente se menciona que es apoyada por Ted Codd (Edgar F. Codd), el cual el profe ha mencionado por sus famosas "12 reglas", y para ser específicos, NULL and UNKNOWN (Transact-SQL) - SQL Server | Microsoft Learn menciona que NULL es básicamente que un valor no se conoce, lo cual realmente tiene mucho sentido para BitacoraEvento cuando el username no existe, entonces voy a dejar que permita NULL, y si en un futuro encuentro algún problema con algún otro requerimiento, pues me tocará buscar otra solución, pero por ahora parece no ser algo tan sencillo como simplemente evitar siempre NULL.

Tras implementar los controladores para el catálogo, para cargar el XML y para los movimientos, y sus respectivos procedimientos almacenados, hice el commit en GitHub.

En su momento se me olvidó terminar la bitácora de ese día (4/29/26) porque justo tenía que ir a otras clases en la tarde, y posteriormente mi compañero hizo otra entrada, así que decidí simplemente continuar esta entrada hoy (4/5/26).

Hoy me dediqué a conectar el front end y el backend junto con mi compañero.

Al trabajar en esto tuve algunos problemas en la carga del XML, ya que el XML se carga cada vez que se inicia el servidor, y el servidor se reinicia con cualquier cambio (gracias a nodemon), entonces tras conectar el backend y el frontend, noté que los movimientos, puestos y otros datos cargados del XML se estaban constantemente agregando, haciendo que por ejemplo algunos empleados tuvieran días de vacaciones negativos en los cientos (lo cual no ocurre con una sola carga de los datos del XML), y claramente no era lo que debía ocurrir.

Los datos en negativo no fueron el único problema, también ocasionó que procedimientos como insertar empleado no funcionaran, ya que al mantener los ids de todo ocultos entonces el procedimiento para insertar empleado utiliza el nombre del puesto para obtener el id respectivo, y esto quizás se podría haber arreglado simplemente poniendo un "SELECT 1", pero realmente arreglarlo así sería ignorar el problema original, el cual era que los datos del XML se están insertando constantemente. Por lo tanto, primero investigué cómo limpiar las tablas por completo, y para lograrlo me basé en:

https://www.w3schools.com/sql/sql_delete.asp#:~:text=Sweden-,Delete%20All%20Records,-It%20is%20possible

Reset identity seed after deleting records in SQL Server - Stack Overflow

Con las tablas "reiniciadas", hice un cambio en el procedimiento almacenado de carga de XML, agregando validaciones "WHERE NOT EXISTS", y de esta forma se arregló el problema en los procedimientos como InsertarEmpleado, pero no se arregló lo de los saldos de vacaciones negativos, por lo que tuve que pensar directamente cómo validar si ya se había realizado la carga del XML.

Inicialmente en el frontend para pruebas se estaba usando almacenamiento local, pero no tiene mucho sentido aquí, luego se me ocurrió hacer un nuevo evento para BitacoraEvento que funcione como "marcador" de que ya se realizó la carga, pero viendo la estructura de los datos del XML y las instrucciones del proyecto me pareció que hacer algo así se saldría de lo que quería el profesor, ya que directamente tendría que agregar un nuevo TipoEvento, y demás, entonces pensé en cómo hacer un procedimiento almacenado que revise si ya existen todos los datos del XML, pero esto se me hizo demasiado complicado, la verdad ni siquiera estoy seguro de cómo haría algo así, entonces finalmente pensé que, ya que el problema son los movimientos (y además los movimientos es lo último que se carga), podría validar si ya existen movimientos en la base de datos, y según esta respuesta determinar si ya se realizó la carga del XML por completo. Ciertamente es un poco una solución no ideal, porque en caso de que sí se haya realizado PARTE de la carga de los datos del XML, pero se haya detenido en medio proceso (por ejemplo, si ocurre algún problema y solo se cargan algunos movimientos, no todos), entonces esto haría que incorrectamente se determine que ya se cargaron todos los datos del XML, pero realizando varias pruebas no parece ocurrir, así que por lo menos funciona.

Entonces bueno, habiendo logrado eso, mi compañero y yo realizamos pruebas para cada requerimiento, y todo parece funcionar, aunque mi compañero y yo notamos que las IPs capturadas son curiosas, probablemente por estar corriendo el backend en localhost, y parece detectar nuestro cliente como IPv6, por lo que las IPs se guardan como "" o incluso "::1", pero esto es normal, según Using express, on localhost req.ip is returning ::1 is that right? (Example) | Treehouse Community y node.js - Nodejs ip address result ::1 - Stack Overflow.

Por lo tanto, para finalizar me dediqué a terminar la documentación, para lo cual hice los respectivos diagramas, y ayudé a mi compañero a llenar toda la información.

Como dato interesante por aquí, para las líneas de código busqué en internet y parece que Git ayuda a contar las mismas utilizando el comando:

git ls-files '*.[extensionArchivo1]' '*.[extensionArchivo2] | xargs wc -l


Comments

Popular posts from this blog

Sexta Entrada de la Bitácora (24/4/26)

Quinta Entrada de Bitácora (24/4/26)

Octava Entrada de la Bitácora (4/26/26)