DESARROLLO DE UNA APLICACIÓN WEB PARA EMPRESA DE ALIMENTACIÓN WEB APPLICATION DEVELOPMENT FOR A FOOD ENTERPRISE TRABAJO FIN DE GRADO CURSO 2023-2024 AUTOR BRUNO AFÁN DE RIBERA COIMBRA DE MATOS DIRECTOR RAMÓN GONZÁLEZ DEL CAMPO RODRÍGUEZ BARBERO GRADO EN INGENIERÍA DE SOFTWARE FACULTAD DE INFORMÁTICA UNIVERSIDAD COMPLUTENSE DE MADRID 2 ÍNDICE 1 RESUMEN ………………………………………………………………………………………………………………………………………………………… 3 2 INTRODUCCIÓN 2.1 Contextualización ……………………………………………………………………………………………………………….. 5 2.2 Estudio de Mercado …………………………………………………………………………………………………………. 7 2.3 Objetivos ……………………………………………………………………………………………………………………………………… 11 3 DESARROLLO DE LA APLICACIÓN WEB 3.1 Herramientas Utilizadas………………………………………………………………………………………………… 14 3.2 Tecnologías Utilizadas …………………………………………………………………………………………………… 18 3.3 Funcionalidades ……………………………………………………………………………….…………………………………. 20 3.4 Estructura de base de datos ……………………………………………………………………………………. 29 3.5 Seguridad ……………………………………………………………………………….…………………………………………………. 30 3.6 Posicionamiento SEO ……………………………………………………………………………….……………………. 35 4 FUTURAS LINEAS DE DESARROLLO …………………………………………………………………………………… 38 5 CONCLUSIONES ……………………………………………………………………………….……………………………………………………… 42 6 BIBLIOGRAFÍA ……………………………………………………………………………….……………………………………………………………. 43 3 1 RESUMEN El objetivo de mi Trabajo de Fin de Grado fue desarrollar una aplicación web para una empresa de alimentación, real y en funcionamiento. El propósito de negocio de esta aplicación es dar una pequeña visión de la empresa, presentar y vender sus productos, compartir su amplia gama de recetas a partir de estos, y facilitar a sus clientes su localización. El propósito informático es conseguir mantener la limpieza, velocidad y eficiencia de la aplicación web al máximo, además de otros temas también importantes, como son la seguridad o la escalabilidad de esta. Al ser una aplicación que va a tener una continuación, decidí mantener una buena organización y limpieza. Por ello, consta de dos puntos principales: el cliente o Front-End y el servidor o Back-End. Ambos lados dentro de la misma carpeta del proyecto en conjunto. Durante todo el desarrollo, de la mano del lenguaje JavaScript, he buscado que la aplicación sea liviana y que mantenga la simpleza requerida, no cayendo en lo pueril e intentando no olvidar aspectos esenciales de este tipo de proyectos, como puede ser la seguridad o la consistencia. Para alcanzarlo, he buscado ayuda de expertos en el sector, que me han podido dar ciertas claves para que el proyecto pueda alcanzar su máximo exponente dentro de las posibilidades existentes. [English] My Bachelor’s Degree Final Project involved developing a web application for a real and running food company. The business purpose of this application is to provide a brief overview of the company, showcase and sell its products, share a wide range of recipes based on these products, and make it easy for customers to locate them. On the other hand, the IT purpose is to maintain the cleanliness, speed and efficiency of the web application at maximum, in addition to other important issues, such as security and scalability. 4 This application is intended to have a follow-up, so I decided to maintain proper organization and neatness. Therefore, it consists of two main parts: the client or Front-End and the server or Back-End. Both sides are inside the same project folder as a whole. Throughout the development process, using JavaScript, I aimed to keep the application lightweight while maintaining the required simplicity, avoiding overly simplistic approaches, and ensuring essential aspects, such as security and consistency, are not overlooked. To achieve this, I sought guidance from experts in the field who provided insights to help the project reach its full potential within the existing possibilities. 5 2 INTRODUCCIÓN 2.1 Contextualización Al Gusto de Belela es la imagen de marca de la empresa Proguiso S.L. Fue formada por mi abuelo, Santiago Rodríguez, en su afán de seguir su buen ojo para los negocios después de dar nombre, junto a un pequeño equipo de personas, al Papel Albal por primera vez en España, además de introducir las sartenes antiadherentes y promocionar el cambio de casquillos de cobre en los focos de luz por casquillos de aluminio. Más tarde, le siguió la pista mi padre, Fernando Afán de Ribera. La empresa, aún con la cantidad de trabajo que ha llevado a cabo, nunca ha tenido más de 5 trabajadores. El Guiso fue la primera imagen de marca para esta empresa y llegó a ser la mayor productora de ventas de vinos en España. Después de algunos problemas familiares, perdieron los derechos sobre el nombre El Guiso y pasó al actual nombre, Al Gusto de Belela. Después de este revés, perdió mucha reputación ganada con muchos años de trabajo, ya que nadie supo de este cambio ni se hizo ningún tipo de publicidad. Fue como empezar de nuevo con los mismos productos. Las conservas, el vino y el vinagre. Unos años más tarde, y hasta la actualidad, se llegó a un acuerdo con MasterChef España. El vino blanco para cocinar estaría expuesto en todos los puestos de cocina de los concursantes y sería el vino que utilizasen para cocinar. Como en el canal de televisión La 1 no puede aparecer publicidad, el brik seguiría teniendo el mismo diseño, pero sin el logo de Al Gusto, por lo que no llegó a producir un cambio significativo. Por otro lado, el logo de MasterChef sí se podría poner en los productos Al Gusto a la hora de venderlo de cara al público, lo que da cierto renombre al producto, aunque tampoco provocó una relevante mejora. También sacó su spot publicitario en televisión, junto con Mediaset. Al Gusto de Belela sigue sin llegar a donde un día estuvo El Guiso, siendo la calidad de sus productos igual, o mejor, debido a los incesantes intentos de volver a situar el producto interior español en la posición que merece. 6 En la actualidad, MasterChef ha sacado su aplicación a nivel mundial para foodies, es decir, una aplicación para aprender a cocinar según tu nivel de experiencia. Sabiendo la calidad del producto que ofrece Al Gusto y de las relaciones que existen entre las dos empresas, esta es una de las puertas que se le abre a la pequeña empresa con una posibilidad de crecimiento muy grande. El verdadero fallo que puede existir en esto es que Al Gusto no está al día en lo que a la tecnología se refiere. ¿Por qué no está al día? Principalmente porque es difícil de localizar. Tiene una página web que no funciona bien y no da una buena impresión sobre la empresa. Con ello, la proposición que hay encima de la mesa con mi aplicación web es de hacer algo sustancialmente diferente a lo que existe. Una web sencilla, que presente lo esencial de la empresa, mostrando alguna información, sus productos, su localización de tiendas, recetas propuestas y que funcione también como tienda online. [English] Al Gusto de Belela is the brand image of the company Proguiso S.L. It was founded by my grandfather, Santiago Rodríguez, in his pursuit to continue his successful business ventures after giving name to the first Papel Albal in Spain along with a small team, introducing non-stick pans, and promoting the shift from copper lamp casings to aluminum. Following his path was my father, Fernando Afán de Ribera. Despite the substantial work the company has undertaken, it has never had more than five employees. El Guiso was the initial brand image for this company and became the largest wine sales producer in Spain. However, due to some family issues, they lost the rights to the name El Guiso, leading to the current name, Al Gusto de Belela. This setback resulted in a significant loss of reputation earned over many years, as no one knew about this change, and no advertising was done. It was like starting over with the same products: canned preserves, wine, and vinegar. Years later, and up to the present day, an agreement was reached with MasterChef Spain. The white cooking wine would be featured in all 7 contestants' kitchen stations and used for cooking. As advertising isn’t allowed on La 1’s channel, the packaging continued with the same design but without the Al Gusto logo, thus not creating a significant change. However, the MasterChef logo could be placed on Al Gusto products when sold to the public, adding some prestige to the product, though it didn't result in a notable improvement. They also aired their advertising spot on television alongside Mediaset. Al Gusto de Belela still hasn't reached the level where El Guiso once stood, despite the quality of its products being equal or better, due to relentless efforts to reposition spanish-made products where they belong. Presently, MasterChef has launched its worldwide application for foodies, a platform to learn how to cook based on the experience level. Given the quality of Al Gusto’s products and the existing relationship between the two companies, this opens a door for significant growth for the small company. The real issue for Al Gusto lies in its lack of technological advancement. Why is it not up to date? Primarily because it’s challenging to locate. Their website doesn’t function properly and doesn’t give a good impression of the company. Thus, the proposal on the table with my web application is to create something substantially different from what currently exists: a simple website presenting essential information about the company, showcasing products, store locations, proposed recipes, and functioning as an online store. 2.2 Estudio de Mercado Uno de los puntos importantes para tener en cuenta al realizar el estudio de mercado era analizar empresas de alimentación que tuviesen un cierto nivel. Ejemplos de ello serían páginas como Heinz, Barillia, Bimbo, Casa Tarradellas, etc. 8 En todas estas páginas se sigue más o menos la misma estructura. Muestran sus productos, algo de su historia, su compromiso con el medio ambiente y sus recetas, entre otros. Prácticamente ninguna de ellas tiene una tienda online, donde se les pueda comprar directamente a esa empresa. Algunas como Gallina Blanca tienen enlaces a otras páginas donde puedes encontrar sus productos. Otras como Navidul o Hida sí ofrecen la posibilidad de comprar en su web. Pero estas opciones son pocas. Posiblemente, porque los costes que conllevan en relación con los ingresos que obtendrían no se justifican o, incluso, porque al ser empresas tan conocidas no tienen la necesidad de 9 vender directamente su producto, ya que se puede encontrar en prácticamente cualquier lado. Todas estas empresas tienen ya un gran tamaño y llevan años funcionando, además de contar con buenas reputaciones, nunca quedándose completamente para atrás. En el momento en el que estamos, en el que la tecnología avanza a pasos agigantados, todas estas empresas han dedicado parte de sus recursos a seguir los pasos necesarios para no quedarse “anticuados” y seguir en la “cresta de la ola”. La mayoría de estas empresas tienen sus aplicaciones web desde hace ya algún tiempo. Tanto es así, que la mayoría de ellas están construidas sobre lenguajes y tecnologías más primitivas. Es decir, con más años de vida, resultando en una mayor lentitud, con más dificultad para escalar y más complejas. Hay que decir que la antigüedad es un contra, pero también tiene sus beneficios, como una mayor estabilidad y seguridad, más madurez, una comunidad mayor con más información adicional de ayuda, entre otros. Las más destacables que he analizado son PHP (lenguaje de scripting del lado del servidor, programación originalmente procedural) junto a jQuery (manipulación del DOM); Java (también del lado del servidor, programación orientada a objetos) junto a Java Servlet (procesamiento de solicitudes HTTP para Java); GitHub, como plataforma de alojamiento de código; varios tipos de CDNs (para distribuir contenido web de forma rápida y eficiente a los usuarios) y CMSs (de los que se utilizan ciertos plugins para soportar ciertas funcionalidades); existen muchas herramientas de análisis de datos (para comprender el comportamiento de los usuarios y el rendimiento de la aplicación), entre muchas otras. Pocas aplicaciones web utilizan herramientas y tecnologías punteras, se mantienen en zonas más seguras. Sí es cierto que he encontrado alguna de ellas, como Navidul, usando tecnologías como Apollo GraphQL, una plataforma completa para el desarrollo de APIs con GraphQL (es un lenguaje de consulta para APIs que te permite especificar exactamente qué datos necesitas) o Next.js, que se basa en React, ofreciendo características adicionales como el SSR, el pre-renderizado estático y la navegación sin 10 redireccionamientos, y he de decir que, en términos de usabilidad, es mucho más cómodo, sencillo y fácil para el usuario. Además, es también de las pocas que tiene Ecommerce, probablemente por la facilidad que presentan estas tecnologías para montar una funcionalidad así. [English] An essential aspect of the market analysis was to examine food companies of a certain caliber. Examples include pages like Heinz, Barilla, Bimbo, Casa Tarradellas, etc. Most of these pages follow a similar structure, showcasing products, some history, their commitment to the environment, and recipes, among others. Practically none of them have an online store where customers can directly buy from the company. Some, like Gallina Blanca, have links to other pages where their products are available. Others like Navidul or Hida do offer the option to purchase on their website. However, these options are few, possibly because the costs involved in relation to the revenue they’d generate are not justified, or because as they are well-known companies, they don't need to sell their products directly since they’re available almost everywhere. All these companies are large and have been operating for years, maintaining good reputations, and never falling completely behind. In this era of rapid technological advancement, these companies have allocated resources to stay updated and not become outdated. Most of these companies have had their web applications for some time. Indeed, most of them are built on primitive languages and technologies. In other words, they are older, resulting in slower, more complex, and more difficult to scale apps. Admittedly, age is a disadvantage, but it also has its benefits, such as greater stability and security, more maturity, a larger community with additional help information, among others. The most remarkable I have analyzed are PHP (server-side scripting language, originally procedural programming) together with jQuery (DOM manipulation); Java (also 11 server-side, object-oriented programming) together with Java Servlet (HTTP request processing for Java); GitHub, as a code hosting platform; various types of CDNs (to distribute web content quickly and efficiently to users) and CMSs ( from which certain plugins are used to support certain functionalities); there are many data analysis tools (to understand user behavior and application performance), among many others. Not many web applications use leading edge tools and technologies, they remain in safer zones. It is true that I have also found some of them, such as Navidul, using technologies like Apollo GraphQL, a complete platform for API development with GraphQL ( a query language for APIs that allows you to specify exactly what data you need) or Next.js, which is based on React, offering additional features such as SSR, static pre-rendering and navigation without redirects, and I must say that, in terms of usability, it is much more comfortable, simpler and easier for the user. In addition, it is also one of the few that has Ecommerce, probably because of the ease that these technologies allow to set up such a functionality. 2.3 Objetivos Volviendo al problema de Al Gusto, el fallo más visible se aprecia en el plano tecnológico. Teniendo en cuenta que innovar es muy complicado en el aspecto web en una empresa de alimentación, y más aun empezando de cero, lo que se puede llevar a cabo es seguir parte de los pasos que considero como correctos para darle un cierto status quo en este plano, estando más acorde con el nivel de sus productos. A partir de ahí, empezar a valorar opciones “fuera de la caja” que pueda revolucionar este sector. Para conseguirlo, una de las peticiones más importantes de Al Gusto fue mantener el máximo de simpleza en su página. En otras palabras, eliminar el exceso de información que puede existir y que el público no necesita o, incluso, incluirlo de una manera más sutil. 12 Otro de los objetivos que tenían era que su público entrase a comprar con cierta rapidez y fluidez, es decir, no dando muchas vueltas para comprar algún producto y que no fuese tedioso. Otra petición mencionada era la posibilidad de ubicarlos de manera más sencilla en tiendas físicas. Al ser una empresa pequeña, situarla en el mapa le daría cierta relevancia e importancia. Por último, querían tener una página fiable en la que sus usuarios pudiesen ver diversas recetas a partir de sus productos. En este último punto, alternativamente a la gran mayoría de las demás empresas, decidí proponer la posibilidad de que los usuarios pudiesen valorar las recetas con Me Gusta o No Me Gusta, para que se puedan adaptar y mejorar, acercándose más a los gustos de estos. Basándome en todo lo expuesto anteriormente, mi workflow durante la realización de todo el proyecto seria guiado por comunicaciones abiertas y continuas con miembros de Proguiso S.L., ya que en un principio les era complicado describir lo que querían. Esto me permitió mantener el diseño y la funcionalidad en constante evolución, acercando nuestras perspectivas y teniendo en cuenta sus gustos y necesidades. Por ello, decidí trabajar por módulos, recogiendo los requisitos de cada uno, diseñando, verificando y, finalmente, entregando para su revisión. Al tener un alto porcentaje de cada módulo realizado, avanzaba al siguiente. Esto hizo que aplicara mi energía de manera más eficiente, ahorrando una gran cantidad de tiempo y esfuerzo. Cabe decir también que escogí que el desarrollo del Back-End empezara posterior al desarrollo de cierta parte del Front-End, ya que, para mí, es más fácil asimilar el funcionamiento de lo programado si hay algo tangible que analizar. Al acercarme al ecuador del trabajo, ambas partes se nivelarían y avanzarían en sincronía. [English] Returning to Al Gusto's problem, the most visible flaw lies in the technological aspect. Web innovation in a food company is very challenging, especially starting from scratch. What I can achieve is to follow some solid steps to 13 establish a certain status quo in this area, aligning it with the quality of their products. From there, I can start to consider out-of-the-box solutions that could transfigure this sector. To achieve this, one of Al Gusto's main requests was to maintain maximum simplicity on their page. In other words, eliminate excessive information that the public doesn’t need or include it subtly. Another goal was facilitating quick and smooth purchases, without unnecessary steps, ensuring a hassle-free experience. They also desired an easier way for customers to locate their physical stores, as this would give the small company some relevance and importance. Lastly, they wanted a reliable page where users could explore various recipes using their products. In this last point, unlike most other companies, I proposed the option for users to rate the recipes with Like or Dislike, enabling adjustments and improvements that align more with their tastes. Considering all the above, my workflow throughout the project was guided by open and continuous communication with Proguiso S.L. members, as initially, it was challenging for them to articulate what they wanted. This allowed me to keep the design and functionality in constant evolution, aligning our perspectives and considering their preferences and needs. Therefore, I chose to work in modules, collecting the requirements for each one, designing, verifying, and finally, delivering them for review. As a high percentage of each module was completed, I moved on to the next one. This approach made my energy more efficient, saving a considerable amount of time and effort. It's worth mentioning that I decided to start the Back-End development after a certain part of the Front-End was completed because, for me, it’s easier to understand the functioning of what's programmed when there’s something tangible to analyze. As I approached the midpoint of the work, both parts would align and progress synchronously. 14 3 DESARROLLO DE LA APLICACIÓN WEB Teniendo en cuenta el grado en el que estoy y mi experiencia en el sector, considero de vital importancia encontrar y conocer las herramientas y tecnologías existentes, que acompañarán el desarrollo de mi aplicación, ya que cuanto más a la orden del día estén, más sólida se podrá considerar. Por otro lado, también considero de especial relevancia la documentación de la funcionalidad y de la estructura de la base de datos para poder asegurar su escalabilidad a lo largo del tiempo. Al ser una aplicación web, no se puede dejar para atrás el posicionamiento SEO, para su visibilidad, ni tampoco la seguridad, debido a la constante evolución de los ataques informáticos. En cuanto a la estructura, he tomado la decisión de dividirlo en dos carpetas: el lado del cliente y el lado del servidor. Para el cliente, la estructura son dos carpetas: ‘public’ y ‘src’. Dentro de ‘public’, iría el favicon y el ‘index.html’, a partir de donde se construye la raíz del proyecto React. En ‘src’, los componentes comunes para toda la aplicación, las distintas páginas o secciones con las que cuenta, los ‘assets’ y hojas de estilo. Para el servidor, dentro de ‘src’, la división es por rutas para cada entidad, donde están las peticiones API, seguido de los controladores, que manejan el funcionamiento, y de sus modelos, que trabajan con la base de datos, además de una carpeta de configuraciones y del archivo inicial de donde parte y se reúne todo, ‘app.js’; ‘uploads’, con la carpeta de imágenes y de vídeos; y el índice, como raíz de programa. Cabe mencionar también package.json, .gitignore, README.md y .env, son documentos comunes a ambas carpetas de servidor y cliente. Durante los siguientes puntos, trataré estos temas para describir lo realizado en mi proyecto. 3.1 Herramientas Utilizadas Las herramientas son recursos que se utilizan para facilitar tareas específicas en el desarrollo software. Algunas de las siguientes, las he elegido debido a ciertas asignaturas cursadas a lo largo de la carrera. Otras, debido a mi 15 experiencia laboral o aprendizaje autónomo, han sido escogidas porque, en mi opinión, se adaptan mejor a la actualidad del sector y considero más eficientes y seguras. Visual Studio Code La principal herramienta utilizada para construir mi aplicación fue VS Code. Debido a la facilidad de uso, y porque es una herramienta altamente personalizable, liviana y eficiente. Soporta muchos lenguajes de programación, es posible la depuración de código y tiene un terminal integrado, que también es personalizable. Los colores en el texto, la detección de errores y las ayudas al escribir código, es una parte que veo relevante para la elección de la herramienta. Son varias las ventajas que, a mi gusto, presenta esta herramienta. Sublime Text 3 Para cierta parte del código del Front-End he utilizado Sublime Text 3. Rápido, liviano y altamente personalizable. Es fácil de instalar y minimalista, lo que se agradece para construir la base del código rápidamente y sin distracciones. También tiene la posibilidad de personalizar a tu gusto el editor e instalar ciertos plugins, que hace programar más ameno. pgAdmin Al utilizar PostgreSQL, para hacer uso de su tecnología, se podía hacer por la línea de comandos, pero era una tarea que requería un aprendizaje más avanzado y que no necesité. En su defecto, pgAdmin es una herramienta gráfica distribuida para facilitar el uso de PostgreSQL de manera más visual y sencilla. Es bastante cómoda y ofrece muchas funcionalidades distintas, lo que incitó mi continuación con ella. Postman He utilizado Postman para probar y desarrollar las APIs que he creado, tanto las peticiones GET, como las peticiones POST. Con ella, conseguía ver las diferentes respuestas que daba mi aplicación y me permitía tener variables almacenadas, lo que me permitía probar la funcionalidad desarrollada. 16 Además, tiene una interfaz amigable y sencilla, ahorrándome tiempo en las pruebas. Ethereal Email Service Ethereal Email es un servicio Mailtrap. Este, proporciona direcciones de correo electrónico de prueba y un servidor SMTP (Simple Mail Transfer Protocol) simulado. Lo he utilizado para probar y desarrollar todas las funcionalidades que incluían el trabajo con emails, para que, de esta manera, no sea necesario sobrecargar ni modificar la seguridad de correos reales. Esta herramienta es utilizada más comúnmente para Nodemailer, utilizado para mandar emails desde aplicaciones desarrolladas con Node.js. Google Cloud Platform Google Cloud es la plataforma de servicios en la nube brindada por Google. Ofrece distintos servicios y herramientas para desarrollar, implementar y administrar aplicaciones y recursos en la nube. En mi caso ha sido utilizado para integrar el mapa de Google con mi aplicación. Para ello, solo necesité crear un proyecto y habilitar las APIs de Google Maps, y editar el tipo de mapa que quería que se viera. Con esto, se generó una clave que tuve que incluir en mi aplicación y pude trabajar con ello. Framer Motion Cuando empecé a desarrollar mi Front-End, comencé a sentir la necesidad de crear ciertas animaciones sutiles que mejorasen la experiencia del usuario de manera sustancial. Dado que con CSS es más complicado realizar ciertos movimientos de elementos y sabiendo que React está creado para optimizar este tipo de efectos, busqué una biblioteca que cumpliera con la función, encontrando Framer Motion. Es una biblioteca poderosa para agregar animaciones de manera sencilla y efectiva. Bootstrap El framework Bootstrap me ha facilitado mucho la vida y ha optimizado el tiempo de desarrollo del Front-End, ya que me permitía estar solo 17 desarrollando mi código HTML incluyendo sus clases ya generadas, sin necesidad de estar creando clases personalizadas todo el rato. Cuando ya tenía casi finalizada una sección, en la mayoría de los casos, creaba mi clase para cierto elemento con CSS. En otros, donde no había necesidad, debido aspectos muy puntuales, dejé estas clases de estilo. CryptoJS La biblioteca crypto-js de JavaScript es la que he usado para cifrar datos en el Front-End. Esta biblioteca proporciona una serie de algoritmos criptográficos y funciones para el cifrado y descifrado de datos. Su uso es sencillo y seguro en aplicaciones web. React Google Maps La biblioteca de React que utilice para la gestión del mapa de Google fue react-google-maps, ya que me facilitó la integración y el uso de los servicios y la API de Google Maps en mi aplicación. Además, proporciona componentes reutilizables, y una interfaz de React para trabajar con mapas interactivos y servicios de ubicación proporcionados por Google Maps. Bcrypt A diferencia de crypto-js, bcrypt lo he utilizado en mi Back-End. Es una biblioteca de cifrado de contraseñas que se utiliza en aplicaciones web y sistemas para almacenar contraseñas de manera segura. Aplica funciones de hash seguras y técnicas de salting para proteger las contraseñas de manera efectiva contra ataques. Lo he elegido por ser una opción confiable para garantizar la seguridad y privacidad de los usuarios. Cors La biblioteca cors de npm vino a solucionar mis problemas de COR (Cross- Origin Request). Es decir, al tener montados el Back-End y el Front-End en distintos dominios, necesité de una solución para resolver el problema de las solicitudes y este vino con el CORS (Cross-Origin Resource Sharing). Además, es fundamental para evitar vulnerabilidades de seguridad y acceso no 18 autorizado a recursos del servidor, limitando los orígenes permitidos para acceder a estos solo desde las URLs de mi aplicación. Nodemailer Al necesitar enviar correos electrónicos, como confirmaciones de cuentas de correos o restablecimiento de contraseñas, busqué una herramienta que me automatizara el proceso. Encontré nodemailer, una biblioteca de Node.js que permite enviar correos electrónicos desde aplicaciones web y servidores utilizando el protocolo SMTP. Stripe Es una plataforma de pagos en línea que ofrece una API para integrar procesamiento de pagos en aplicaciones web y móviles. Me permite aceptar pagos con tarjeta de crédito y débito, así como otros métodos de pago. Se pueden personalizar experiencias de pago, realizar transacciones seguras y eficientes, etc. Su enfoque en la seguridad y capacidad para manejar pagos es lo que hizo que la escogiera. Además, me elimina la necesidad de almacenar tarjetas de crédito. 3.2 Tecnologías Utilizadas Las tecnologías son componentes fundamentales que forman la base de la aplicación. Para este apartado, me he basado en el aprendizaje de la asignatura de Aplicaciones Web, dado que creo que se adecua muy bien a las necesidades de mi proyecto. He incluido tanto tecnologías de esta asignatura, como otras exteriores, que creo más interesantes y relevantes, sobre las que he tenido que indagar algo más para entenderlas y aplicarlas de manera correcta. JavaScript Este lenguaje de programación ha sido el elegido para toda mi aplicación web. Tanto por su versatilidad como por el hecho de ser un lenguaje poco 19 pesado y con mucha documentación. Además, es un lenguaje sobre el que he podido construir mi Front-End y mi Back-End, teniendo numerosas bibliotecas y frameworks propias que facilitan el desarrollo de la aplicación de manera más compleja y dinámica, y que, a su vez, son compatibles con los principales navegadores, permitiendo experiencias de usuario ricas y atractivas. React React es una biblioteca de JavaScript con la que se construye interfaces de usuario interactivas y reactivas. Con ella, se pueden construir componentes reutilizables que se actualizan según los cambios de ciertos datos. Es decir, no tiene necesidad de estar siempre recargando la página entera, actualizando únicamente los componentes que han cambiado, lo que da lugar a experiencias de usuario más rápidas. Esta es una de las razones de más peso para elegir esta biblioteca, en lugar de las páginas web estáticas. Node.js Al querer usar también JavaScript en el lado del servidor, he recurrido a Node.js, un entorno de tiempo de ejecución de código abierto. Permite la ejecución de JavaScript en el servidor, ampliando sus capacidades más allá del navegador. Es importante destacar que Node.js se basa en el potente motor V8 de Google Chrome para lograrlo. Utiliza un modelo de programación asíncrono y no bloqueante, lo que lo hace especialmente eficiente para manejar múltiples conexiones simultáneas. Express Express, a su vez, es un framework web para Node.js que simplifica la creación de aplicaciones web y APIs. Proporciona una serie de utilidades y herramientas para manejar enrutamiento, manejo de solicitudes y respuestas, administración de sesiones, manejo de middlewares, etc. Agrega una capa de abstracción sobre Node.js, lo que facilita el desarrollo rápido y estructurado. PostgreSQL 20 Para construir mi base de datos he utilizado PostgreSQL. Esta herramienta es un sistema de gestión de bases de datos relacional de código abierto y altamente potente. Tiene un sólido soporte para transacciones y garantía ACID (Atomicidad, Consistencia, Aislamiento, Durabilidad), además de gestionar de manera eficaz la concurrencia, garantizando la integridad de los datos. Al mismo tiempo, tiene una comunidad activa de desarrolladores, lo que la hace más fiable. Por ello, lo elegí por delante de MySQL y me puse a aprender sobre ella. Es una herramienta que ha crecido mucho en el entorno empresarial durante los últimos años y que me llamó la atención debido a sus características. JSON Web Token Para gestionar los accesos y las sesiones de los usuarios, he decidido usar JSON Web Tokens. Es un estándar abierto para transmitir información de forma segura en Internet, por medio de archivos en formato JSON, en mi caso, entre el Back-End y el Front-End. Tiene tres partes, Header, con el tipo de token y algoritmo de firma; Payload, con la información relevante a transmitir; y la firma, que asegura que no se haya alterado en el camino entre un punto y otro de la comunicación. La biblioteca utilizada para realizar la función es jsonwebtoken. UUID Universally Unique Identifier, son identificadores únicos universales. Los he utilizado para mi base de datos, ya que identifica de manera exclusiva a cada una de las inserciones en las que lo utilizo, siendo una forma efectiva y confiable de generar identificadores en sistemas de software. Para aplicarlo, he utilizado la biblioteca UUID. 3.3 Funcionalidades Durante este apartado recorreremos las distintas acciones que los usuarios pueden realizar durante la navegación en la aplicación web. 21 El primer paso será abrir la página de Al Gusto. Una vez abierta, saldrá un spot publicitario en toda la pantalla, además de los distintos iconos sobre los que podremos pulsar en la zona superior. El primero es el logo de la empresa, que accederá a la página principal. El segundo, el del menú, que abrirá las distintas secciones por las que podremos navegar. El tercero es el carrito de compra, que tiene la posibilidad mantener el ratón por encima, visualizándose así los productos, o pulsar, que abrirá su sección propia. Por último, el icono de autenticación de usuario, que ofrece la posibilidad de iniciar sesión al mantener el ratón por encima o, en su defecto, pulsarlo, abriendo la sección autenticación o el perfil, en caso de ya haber iniciado sesión. Si nos mantenemos en la misma página, al deslizar hacia abajo, podremos explorar un poco sobre la empresa, ver algunas imágenes de productos, entre otra información. 22 Comenzando ahora por los iconos descritos antes, veremos la sección del carrito de compra. Como hemos comprobado antes, existe la posibilidad de ver el carrito sin entrar. Al mantener el ratón por encima, podremos visualizar los productos añadidos junto con el número de unidades por caja, la cantidad de productos que hay incluida de cada uno de ellos, el precio total de cada producto y una basura, que elimina una unidad. Al pulsar sobre el icono del carrito abrirá lo siguiente: Se muestra el resumen del carrito para, ya sí, finalizar la compra. Ahora, para modificar la cantidad de cada producto que se pretende comprar, se usan los símbolos de más y menos a la izquierda, y la basura servirá para eliminar la totalidad del producto, sin tener en cuenta la cantidad incluida. Al pulsar sobre el botón de finalizar, en caso de que no haya una sesión iniciada, se pide al usuario que se identifique o se registre. 23 Una vez hecho, se pedirá que se seleccione una dirección de envío. Además, dará la posibilidad de añadir una dirección de facturación distinta a la de envío, ofreciendo también las ya guardadas. Al pulsar sobre el botón de Finalizar y Pagar, se redirige a Stripe para introducir los datos bancarios del comprador y realizar el pago. Los webhooks de Stripe en el lado del servidor ayudarán a mantener actualizado el estado de pago del pedido. Por parte del icono de autenticación de usuario, se podrá iniciar sesión sin tener que entrar específicamente en su sección, simplemente manteniendo el ratón por encima del botón. Si ambos campos del formulario se rellenan con éxito, se podrá pulsar sobre el botón Iniciar Sesión. En caso de fallo, se distingue tanto el de correo inexistente, como el de error en la contraseña. La otra opción sería pulsar sobre Registrarse o, lo que sería lo mismo, sobre el icono del usuario. De esta manera, se redirige a la página de autenticación. 24 La primera vista sería la del registro, pero hay posibilidad de acceder al espacio de inicio de sesión en caso de que el usuario ya disponga de cuenta. Todos los campos del registro y del inicio de sesión deben de rellenarse con valores válidos para que los botones del envío de los formularios puedan ser pulsados. Cabe decir también que estos campos se revisan tanto en el lado del cliente, como en el lado del servidor, para una mayor seguridad y consistencia. Además, los campos cuentan con autocompletado, para facilitar a los usuarios la cumplimentación del formulario. Al concluir con éxito cualquiera de los dos formularios, la aplicación vuelve al mismo punto donde se dejó. Es decir, si estaba en la sección del carrito de compra antes de acceder a la sección de autenticación, volverá a ese punto, mejorando la experiencia del usuario. En este momento ya debería existir una sesión, junto a una web token creada que llevará la información del usuario, lo que hará con que el estado del icono del usuario cambie para mostrar algunos de sus datos. Podemos ver en la imagen de la izquierda que se muestra la foto de perfil y el nombre. En caso de que la imagen de perfil no existiera, ya que no es un requisito obligatorio de registro, solo saldría el nombre. También figuran los botones de Cerrar Sesión, para destruir el token, y el de Mi Cuenta, para poder acceder a algunos apartados propios de la cuenta en uso. En este momento el botón del usuario cumple la misma función que el de Mi Cuenta, dirigiendo a la sección que veremos a continuación. 25 Podemos observar varios puntos. Aquí, se muestran el nombre y apellido, el correo en uso y la imagen del usuario. En caso de no existir imagen, se mostraría una por defecto anónima. Además, tenemos el texto que nos indica si el correo ya ha sido verificado o no. En caso negativo, se podrá pinchar sobre él para enviar un nuevo correo. En otro caso, solo avisará que está confirmado. Por debajo, tenemos la zona de edición de perfil. En este apartado solo se dejará cambiar el nombre, el apellido y la imagen. Para cualquiera de los campos, se comprobará que cumplen con las mismas condiciones que en el registro. Además, hay un checkbox que se puede activar para eliminar la imagen de perfil. Existe también la posibilidad de cambiar la contraseña de la cuenta. Lo he separado del resto de información de perfil para poder manejarla individualmente y aportar más seguridad. Para ello, existen dos pasos: el primero, para escribir la contraseña actual y confirmar si es correcta, y, el segundo, para escribir una nueva y verificarla. En el primer paso, solo se podrá pulsar en Siguiente cuando el campo tenga un valor. En caso de fallo, abrirá la posibilidad de recibir un correo para cambiarla directamente. En el segundo, en el momento en el 26 que se ingresa la contraseña correctamente, para una mayor seguridad, comenzará un contador de cinco minutos para actualizarla. En caso de que se cumpla el tiempo límite, volverá a la página del perfil. En estos campos también se revisan los valores para comprobar que cumplen con los requisitos requeridos. También se permite a los usuarios que puedan guardar un máximo de dos direcciones para los envios de sus compras. Se requieren campos como el nombre de destinatario, direccion de envio, ciudad, etc. Todos con autocompletado disponible, que facilita la inserción de datos al usuario. Para el campo del país, se ofrecen solo los destinos a los que la empresa es capaz de enviar sus productos. He añadido un campo adicional que permite seleccionar el prefijo internacional. Esto brinda la posibilidad a las personas que tienen un número de teléfono de otro país de ingresar su número correctamente. Para la consistencia de los datos y mayor seguridad, se comprueban todos los datos tanto en el lado del cliente, como en el del servidor. Una vez guardadas las direcciones, se muestran, y se ofrece la posibilidad de editarlas o borrarlas. Al editarlas, los campos se rellenan con los valores existentes. Por último, en esta sección de perfil, tenemos el apartado de pedidos realizados por parte del usuario. En el se mostrará algo parecido al componente de direcciones. Filas de pedidos ordenados por fecha de forma ascendente, siendo el primero el más reciente. Se muestra la fecha de realización del pedido, el número del 27 pedido que ha realizado el usuario, el estado y el importe total. Además, se pueden ver los detalles de cada uno, que se mostrarán en una ventana modal. Los detalles muestran el identificador del pedido, la fecha, el estado, la dirección de envío y de facturación y el resumen de los productos incluidos. Si el pedido no se ha finalizado o cancelado, se podrán realizar diferentes acciones. Es decir, si se produjo un fallo en el pago, se ofrece la opción de volver a pagar. Si está en proceso de entrega, se ofrece la posibilidad de intentar cancelarlo. Veremos ahora la sección de Productos. Nada más entrar, habrá un pequeño slogan junto a todos los productos en imagen expuestos, y los usuarios deberán deslizar hacia abajo para poder ver cada uno de ellos. Habrá una barra de navegación sobre la que se deliza el ratón para cambiar de tipo de productos. Por debajo de esta, se muestra una fila por producto que incluirá el nombre, descripción, cantidad por unidad, etc. Además, hay un pequeño texto de Ver más info que mostrará detalles más específicos sobre el producto. A la derecha, los usuarios tendrán las distintas posibilidades de unidades por caja que se quieran adquirir. Al pulsar sobre el botón de Añadir al carrito, el carrito de compra de la esquina superior derecha se mostrará durante dos segundos para que el usuario sepa que lleva incluido hasta el momento y que entienda que la acción se ha realizado con éxito. 28 Al entrar en el apartado de Localización, veremos en toda la pantalla un mapa integrado de Google Maps en el que se facilitaran las ubicaciones de las tiendas físicas donde hay existencias de productos Al Gusto. El usuario podrá ver los distintos marcadores distribuidos por el mapa señalados con el logo. Al pinchar en cualquiera de ellos se abrirá un enlace a la tienda en Google Maps, facilitando más información y posibilitando también establecer la ruta rápidamente hacia la misma. A la derecha vemos un buscador personalizado donde los usuarios podrán encontrar la provincia deseada. Al seleccionar una de ellas, se mostrarán las tiendas existentes en esa región. En caso de pulsar sobre una de las tiendas, el mapa acercará automáticamente sobre el punto deseado. También cambiará la vista si el usuario pulsa sobre la provincia seleccionada, reseteando el zoom al estado inicial. Por último, tenemos la sección de recetas de Al Gusto. En ella se verán todas las recetas hechas personalmente por la Belela que se han subido. Lo primero que veremos será la barra de filtros, en donde podremos buscar la receta por el nombre de la receta, filtrarlas por tiempo o por producto incluido de Al Gusto en la receta. La disposición es en mosaico, en filas de dos columnas. Al pulsar en cualquiera de ellas, se expandirá a toda la fila para mostrar sus ingredientes, la preparación, el tiempo de cocinado, el número de raciones, algunos consejos para realizarla, los productos Al Gusto incluidos (con la opción de añadir al carrito) y una sección de valoración total de los usuarios (Like o 29 Dislike). En esta última sección, solo se podrá votar en caso de estar identificado. Además, podremos tener acceso a la pestaña de video, que mostrará la realización de la propia receta. 3.4 Estructura de base de datos Una de las tecnologías que he aprendido de manera autónoma es PostgreSQL. ¿Por qué? Ofrece soporte para características avanzadas, como tipos de datos personalizados, funciones y procedimientos almacenados más complejos, lo que puede ser beneficioso para escenarios más complicados y requisitos más específicos del proyecto. Se conoce por su robustez y confiabilidad. Tiene un modelo de transacciones ACID-compliant que garantiza la integridad de los datos y la consistencia de la base de datos, incluso en entornos de alta concurrencia. Además, es altamente escalable y puede manejar grandes volúmenes de datos, con un rendimiento en operaciones complejas que en algunos casos supera a MySQL. Ofrece muchos índices y funciones avanzadas de búsqueda, útiles para operaciones de búsqueda más dificultosas. Al seguir más de cerca los estándares ANSI-SQL, es más compatible con otras bases de datos y facilita la migración entre plataformas. Aunque no utilice al máximo todas sus características, lo he escogido pensando en la flexibilidad que ofrece a futuro. Al final mi estructura acaba siendo formada por las siguientes tablas: locations, almacena la información necesaria para pintar los puntos en el mapa; products, que es la tabla que contiene los productos de Al Gusto y su 30 información; recipes, que contiene la información de las recetas; opinions_user_recipe, relacionada con la tabla recipes y users por sus identificadores para llevar el registro de todos los Likes y Dislikes del usuario a cada receta; users, que almacena alguna información del usuario; verification_email, relacionada con users para que en el momento de creación del usuario se almacene una instancia con el código enviado al usuario para verificar el correo; password_recovery_code, relacionada con users para almacenar la instancia con el código generado para el cambio de contraseña; shipping_addresses, que se relaciona con users para almacenar las distintas direcciones del usuario y no cargar mucho la tabla del usuario; orders, relacionada con users para llevar la información básica de los pedidos de usuario; y orders_details, relacionada con la tabla orders para llevar los detalles de los pedidos. La separación de información en tablas distintas, como las tablas de orders y order_details, se realiza con el propósito de mejorar la eficiencia en el acceso a los datos. No siempre se requieren todos los campos al realizar consultas, y este enfoque permite acceder de manera más ligera y específica a la información necesaria en cada momento. Otro aspecto que tuve en cuenta fueron los identificadores. El identificador UUID (Universal Unique Identifier), tiene la intención de ser único en el tiempo y el espacio. Es altamente improbable que dos UUID generados al azar sean idénticos, incluso si se generan en diferentes sistemas en el mundo. Por lo que los identificadores que podrían ser más sensibles, como los de los usuarios, llevan este tipo integrado. He intentado mantener la máxima limpieza y simpleza, para poder escalar lo más fácilmente el sistema, y que genere el mínimo de errores posibles. 3.5 Seguridad La seguridad es esencial para sitios web para proteger los sistemas contra diversos ataques. Es un tema delicado que tratar, porque, por mucho que se implementen medidas de seguridad, los avances en los ataques son 31 continuos. He explorado algunas medidas que puedan garantizar la integridad de nuestros datos y el acceso seguro a los usuarios autorizados. CSRF y el CORS El CSRF (Cross-Site Request Forgery) representa una amenaza potencial al permitir peticiones no autorizadas desde sitios externos. El CORS (Cross-Origin Resource Sharing) es un mecanismo que permite a los servidores web controlar qué dominios pueden acceder a los recursos y qué tipo de solicitudes HTTP están permitidas desde otros dominios. Lo he implementado para evitar estas solicitudes maliciosas, asegurando que las peticiones solo se originen desde dominios específicos, previniendo así posibles ataques de este tipo. En la imagen, muestro el código donde implemento y configuro el CORS, usándolo como un middleware en mi aplicación Express. El atributo Origin determina de donde va a recibir las peticiones el servidor y Credentials habilita el envío de datos confidenciales o autenticación mediante cookies o encabezados de autorización. Crypto-js, Protección Contra Ataques MITM Los ataques MITM (Man-In-The-Middle) representan una seria vulnerabilidad. Crypto-js es una biblioteca versátil que proporciona capacidades criptográficas en el navegador. Permite implementar medidas de seguridad adicionales para proteger la integridad y confidencialidad de los datos en aplicaciones web. He utilizamos Crypto-js para cifrar los datos enviados entre el servidor y el cliente, mitigando la posibilidad de que un atacante intercepte y manipule la información durante la transferencia. Un ejemplo de uso es en la transmisión de las contraseñas en el proceso de autenticación. Lo realizo con SHA-256, una función de hash criptográfica perteneciente a la familia de algoritmos Secure Hash Algorithm (SHA). Estos hashes son únicos para cada conjunto de 32 datos y no se pueden revertir para obtener la entrada original. En estas dos imágenes se muestra el ejemplo de parte del cifrado de la contraseña. Almacenamiento Seguro de Contraseñas con Bcrypt La seguridad de las contraseñas es fundamental. Bcrypt es un algoritmo de hashing diseñado específicamente para el almacenamiento seguro de contraseñas. Se diferencia de los métodos de hash convencionales en que está diseñado para ser lento y resistente a ataques de fuerza bruta, lo que lo hace ideal para proteger contraseñas, incluso si la base de datos se ve comprometida. Lo implemento al cifrar las contraseñas de los usuarios en el lado del servidor, antes de almacenarlas en la base de datos. Esto garantiza que incluso si la base de datos se ve expuesta, las contraseñas permanezcan protegidas y no sean vulnerables. En la imagen muestro la verificación de la contraseña. Para cifrar, saltRounds determina el número de rondas de encriptación, salt añade la cadena aleatoria que se añade a la contraseña antes de realizar el hash para hacer el proceso más resistente a los ataques de fuerza bruta y tablas de arco iris, y con hash se genera la contraseña segura. Para verificarla, la función compare contrasta la contraseña proporcionada con el hash almacenado, devolviendo un booleano. Acaban teniendo dos capas de cifrado, lo que haría las contraseñas muy seguras. JsonWebToken para el Control de Acceso Hay ciertas rutas que solo son funcionales para usuarios autenticados, por lo que para controlar el acceso a estas he decidido utilizar JWT (JsonWebToken). Es un estándar abierto que define un formato compacto y autenticado para transmitir información de forma segura entre partes como un objeto JSON. Esta medida garantiza que solo aquellos con los permisos adecuados puedan acceder a funcionalidades sensibles, mejorando la seguridad global del sistema. Los JWT son versátiles y permiten una comunicación segura, 33 ofreciendo una solución ligera y eficiente para la autenticación y autorización en aplicaciones web y sistemas distribuidos. Para crear este token es necesario incluir la información que se quiere enviar en el payload. Sign genera el token con el payload, la clave secreta guardada en el .env y el tiempo de duración de la cookie. A continuación, a la respuesta se le manda una cookie llamada “token”, con la información del token generado y, el tercer argumento, es un objeto de opciones para la cookie que la configura como accesible solo a través de HTTP y no a través de JavaScript en el navegador. Esto último, proporciona cierta protección contra ataques XSS (cross-site scripting). En las rutas que se necesita estar verificado, se comprueba si el token existe y es válido, para poder cumplir con las funciones de cada una. Al hacer el logout, la cookie se destruye. Validación de Subida de Archivos y Textos Para asegurarme de la protección contra los ataques que se puedan hacer vía input, he implementado restricciones en las extensiones de imágenes aceptadas para cargar en nuestra plataforma. Esto evita la subida de archivos con extensiones potencialmente peligrosas, como .exe o .php, minimizando riesgos de seguridad. Las comprobaciones se hacen tanto en el lado del cliente, como en el del servidor. También hago uso de la biblioteca 34 Clamscan (de ClamAV), para verificar si los archivos subidos tienen contenido malicioso. Además, establezco límites en los textos permitidos para prevenir posibles vulnerabilidades por sobrecarga de datos, como también limitación de caracteres y símbolos especiales. Estas medidas se implementan en el lado del cliente y, cuando el servidor recibe los datos, también corrobora la fiabilidad de estos. Inyecciones SQL y Consultas Parametrizadas Las inyecciones SQL representan una brecha significativa en la seguridad de aplicaciones web, permitiendo a los atacantes ejecutar comandos no autorizados en la base de datos. Para contrarrestar este riesgo, se implementan consultas parametrizadas en el código, separando los datos de las instrucciones SQL. Adopto esta práctica, porque disminuye drásticamente la probabilidad de inyecciones SQL, ya que los parámetros de las consultas se manejan como datos en lugar de porciones ejecutables de código. De esta forma, establezco una barrera eficaz para prevenir intentos maliciosos de manipular las consultas y salvaguardar la integridad de los datos almacenados en la base de datos. 35 En la imagen anterior, se puede comprobar que hago uso tanto de transacciones -para controlar el proceso se hace de forma íntegra y consistente-, como de consultas parametrizadas. Todo para evitar la concatenación directa de datos proporcionados por el usuario en la consulta SQL. Mi prioridad ha sido intentar mantener al máximo, dentro de mis capacidades técnicas, la integridad y seguridad de los sistemas web. A través de estas medidas, aseguro un entorno en el que los datos de nuestros usuarios están algunos pasos más protegidos y las vulnerabilidades potenciales se minimizan. 3.6 Posicionamiento SEO El posicionamiento SEO (Search Engine Optimization) para una aplicación web es el proceso de optimización de esta para que aparezca lo más alto posible en los resultados de búsqueda orgánica de los motores de búsqueda, como Google, Bing o Yahoo. Esto implica implementar estrategias y técnicas que mejoren la visibilidad y la clasificación de la aplicación en los resultados de búsqueda. Para lograrlo, he considerado, entre otros, los siguientes aspectos. Optimización de Palabras Clave y Contenido de Calidad Utilizar en el contenido palabras clave relevantes para la aplicación, enlaces de calidad que aumenten la credibilidad o proporcionar contenido relevante y útil, actualizado que responda a las necesidades de los usuarios, entre otros, es lo que he intentado plasmar en el proyecto para mejorar la relevancia, la calidad y la autoridad percibida de la aplicación. - No hay contenido irrelevante ni información de relleno, está cuidadosamente seleccionado. Fundamental para el SEO, ya que el 36 contenido irrelevante perjudica la clasificación en los motores de búsqueda. - Hay recetas y productos de alimentación. La aplicación web se vuelve más relevante para búsquedas relacionadas con esos temas, mejorando las posibilidades de que aparezca en los resultados de búsqueda. - Palabras clave en lugar de enlaces genéricos. Esto no solo mejora la experiencia del usuario, sino que también ayuda a los motores de búsqueda a comprender mejor el contenido al que se accede a través de esos enlaces. Experiencia del Usuario Una buena experiencia del usuario en una aplicación web significa que esta sea fácil de usar, rápida para cargar y accesible desde diferentes dispositivos y navegadores. Los usuarios pasan más tiempo en ella y es menos probable que se vayan rápidamente. React es altamente valorado por su eficiencia, rendimiento y flexibilidad en el desarrollo de aplicaciones web. Los componentes reutilizables simplifican el desarrollo y simplicidad de la web. Framer Motion, por otro lado, crea animaciones personalizadas de manera sencilla. Transiciones y animaciones fluidas, lo que contribuye a hacer la aplicación más atractiva visualmente. He querido mantener un diseño simple y limpio, con algunas interacciones para facilitar el camino y navegación del usuario. También he incluido páginas de errores amigables, para facilitar la comprensión del usuario. Ya que no soy diseñador gráfico, contacté a un conocido que me ayudó puntualmente a perfeccionar ciertos aspectos de la estética. Optimización Técnica Es importante también mejorar la estructura de la aplicación, la utilización de metaetiquetas, la velocidad de carga y la indexación adecuada para que los motores de búsqueda puedan rastrear y comprender la aplicación web 37 fácilmente, y proporcionar una experiencia fluida. Utilizando tecnologías como React, Express, Node.js, PostgreSQL y un VPS, he podido lograr varios aspectos. - Estructura: En React se organiza de manera modular y estructurada, facilitando la gestión y mantenimiento del código. Hay Incluidas metaetiquetas que distinguen entre distintas secciones y elementos del código, descripción y título de la web, idioma y localización, URL, etc. También he tratado de recoger todos los errores o warnings de la consola. - Velocidad de carga: React y estrategias de carga eficiente, como mantener una caché del lado del cliente, ayudan a este aspecto crucial para retener a los usuarios. - Indexación y rendimiento del servidor: Utilizar un VPS con Node.js y Express puede ofrecer un rendimiento robusto y escalable, garantizando que sea accesible y responda eficientemente a las solicitudes de usuarios y motores de búsqueda. En cuanto a PostgreSQL, como base de datos, no influye directamente en el SEO, pero su uso eficiente impacta en aspectos técnicos relevantes como: rendimiento optimizado, que ejecuta consultas eficientes, reduciendo tiempos de carga; gestión estructurada de datos, crucial para una presentación relevante de contenido; escalabilidad y estabilidad, ya que maneja grandes volúmenes de datos, entre otros. Desde la gestión eficiente del código, hasta la mejora del rendimiento y seguridad del servidor, y la base de datos, busco contribuir a una mejor experiencia de usuario, un buen posicionamiento en los motores de búsqueda, atraer tráfico relevante y un mayor éxito online. 38 4 FUTURAS LINEAS DE DESARROLLO En resumidas cuentas, he hecho una aplicación web desde cero para una empresa real en funcionamiento, como es Al Gusto. Mi trabajo se ha centrado principalmente en crear una base sólida sobre la que seguir construyendo durante el futuro, correspondiendo a las necesidades que se produzcan. No obstante, para facilitar y optimizar el trabajo, tanto mío como el de la empresa, el siguiente paso que considero tomar es el de construir una pequeña página interna de administración. Es decir, facilitar el acceso y manipulación de la base de datos, con una interfaz sencilla e intuitiva, y con la que podrían hacer su contenido más dinámico. Esto aumentaría mi foco en seguir desarrollando otras funcionalidades o mejoras, optimizando el tiempo. Lo siguiente es crear un espacio VPS con algún proveedor de hosting. Pienso en Hostinger por la calidad-precio del servicio y por sus beneficios, como puede ser su detector de Malware. Tendría que configurar un sistema nuevo, actualizarlo y configurarlo para que pueda correr mi aplicación web con todos los servicios que necesito. Además, de mí dependería la seguridad y gestión del propio servidor, lo que me mantendría en constante contacto con el mismo. El mundo tecnológico avanza rápidamente, y para mantenerme al día, tengo la intención de perfeccionar el lado del cliente usando Next.js, un framework de React. Complementa y extiende las capacidades de React para aplicaciones web. React se encarga de la parte de la interfaz de usuario dinámica, la lógica y la gestión del estado, mientras que Next.js agrega enrutamiento, renderizado del lado del servidor, generación de páginas estáticas y herramientas de optimización. Esta combinación me permite construir una aplicación web más moderna, rápida y más amigable para SEO. Otro de los pasos a tomar, sería añadir a la sección de los Productos una caja flotante fija a la que pudieras hacer un drag de los productos. Ahora mismo, solo se mandan cajas de un número específico de unidades, debido a cuestiones de pesaje, pero, al tener el peso de la unidad de producto, mi propuesta es la de crear una caja personalizada que consiga combinar 39 distintos productos, incentivando una compra más variada. El objetivo sería mejorar las ventas de los productos y fidelización de clientes. Además, para este último punto, también quiero implementar la posibilidad de recibir comentarios de las recetas por parte de los usuarios, incluyendo cajas en las recetas y en los mismos productos que admitan esta funcionalidad. Para mantener una base de datos más sólida, voy a implementar funciones que la mantengan más actualizada, como puede ser el ejemplo de la eliminación de cuentas o pedidos expirados que no se hayan confirmado. Así te deshaces de datos irrelevantes que solo añaden peso. Por último, considerando el potencial crecimiento de la empresa, estoy contemplando la integración de una herramienta de Inteligencia Artificial. Esto podría proporcionar recursos para mejorar la empresa, como ofrecer recomendaciones personalizadas, analizar datos de ventas pasadas y tendencias del mercado, o implementar un chatbot impulsado por IA que brinde asistencia instantánea. 40 5 CONCLUSIONES Cuando llegó el momento de realizar el Trabajo de Fin de Grado, se me presentó una oportunidad muy grande por delante: realizar una aplicación web para una empresa real. Curiosamente, realicé mis prácticas en una start- up, donde también estuve involucrado en el desarrollo de una plataforma web. De ello pude extraer experiencia que se ha visto reflejada directamente en este trabajo, como puede ser en el caso de React. Lo he desarrollado con el fin de tener la posibilidad de impulsar una pequeña empresa a un plano tecnológico en el que no se encontraba, para darle el reconocimiento que creo merecido. Obviamente, existen muchas mejoras que se pueden realizar y cosas que debería cubrir, para llegar a cumplir ese objetivo con creces, pero pienso que he creado una base sólida sobre la que seguir construyendo. Mi intención ha sido llevarlo un paso más adelante, desarrollándolo como un proyecto más cercano al plano laboral que al de un trabajo para la universidad. Es decir, he querido subir mi nivel personal y desafiar mi capacidad como Ingeniero de Software. Ello me ha llevado a decepciones y dolores de cabeza al encontrarme con problemas que nunca había explorado, teniendo que hacer uso de los conocimientos que me ha aportado la carrera, y ¡mucha imaginación! Claro que ahora, mirando mis resultados y evolución, puedo decir con seguridad que estoy orgulloso de mi progreso y me siento motivado para seguir afrontando desafíos con serenidad. A nivel personal, este trabajo ha retado mis creencias y me ha cambiado la dirección de pensamiento. Ha requerido mantener siempre la cabeza fría e ir sumando miguitas de pan sin parar, para que los problemas no frenasen mi impulso. Podría decir que los años que he estado en el grado han sido un crecimiento sobre estos dos aspectos, que se ven representados en este último proyecto. Aunque quede un largo camino por delante, estoy convencido de la actitud necesaria para alcanzar las metas que me impongo. Para concluir, me gustaría mencionar que la carrera ha aportado mucho a nivel personal. Me he dado cuenta de que la importancia no reside en la 41 herramienta en sí, en este caso la Ingeniería del Software, sino en aprender a utilizarla. La teoría es muy importante, como también lo es la práctica. Quiero mantener mi crecimiento y, para ello, sé que es necesario seguir avanzando sin detenerse, pero sin agotarse. [English] When the time came to work on my Bachelor’s Degree Final Project, a significant opportunity presented itself: to develop a web application for a real company. Interestingly, I had previously completed my internship at a start-up, where I was also involved in the development of a web platform. This experience directly influenced my project, as may be the case of React. I aimed to impel a small company to a technological level it hadn't reached before, giving it the recognition I believe it deserves. While there are many improvements and areas to cover to surpass this goal, I feel I've laid a solid base to build upon. My intention was to take it a step further, treating it more like a project in a professional setting rather than just a university assignment. I wanted to elevate my personal skill level and challenge myself as a software engineer. This journey led me to disappointments and headaches as I encountered previously unexplored problems, requiring me to draw upon the knowledge from my academic background and a lot of imagination. Yet, looking at my results and progress now, I can confidently say that I'm proud of how far I've come and feel motivated to continue handling challenges calmly. On a personal level, this project challenged my beliefs and shifted my way of thinking. It demanded maintaining a cool head and consistently problem- solving so that obstacles wouldn't stall my progress. I'd say the years spent in my degree have been a growth journey in these two aspects, and they are reflected in this final project. Although there's still a long road ahead, I'm convinced of the attitude required to achieve the goals I set for myself. 42 In conclusion, this degree has contributed significantly on a personal level. I've come to realize that the importance doesn't solely lie in the tool itself, in this case, Software Engineering, but in how we learn to use it. Theory is crucial, as is practice. I want to sustain my growth, and for that, I know it's essential to keep moving forward without stopping, yet without wearing myself out. 43 6 BIBLIOGRAFÍA - Páginas de aprendizaje: https://scrimba.com/learn/learnreact https://stackoverflow.com/ https://medium.com/ https://www.reddit.com/ https://chat.openai.com/ https://www.youtube.com/ - Páginas de ayuda al desarrollo: https://www.npmjs.com/ https://fonts.google.com/ https://developers.google.com/ https://console.cloud.google.com/ https://es.react.dev/ https://www.framer.com/motion/ https://ethereal.email/ - Páginas adicionales: https://www.navidul.es/ https://casatarradellas.es/ https://www.gallinablanca.es/ https://www.bimbo.es/ https://hida.es/ https://www.barilla.com/es-es https://scrimba.com/learn/learnreact https://stackoverflow.com/ https://medium.com/ https://www.reddit.com/ https://chat.openai.com/ https://www.youtube.com/ https://www.npmjs.com/ https://fonts.google.com/ https://developers.google.com/ https://console.cloud.google.com/ https://es.react.dev/ https://www.framer.com/motion/ https://ethereal.email/ https://www.navidul.es/ https://casatarradellas.es/ https://www.gallinablanca.es/ https://www.bimbo.es/ https://hida.es/ https://www.barilla.com/es-es