Español
Es muy probable que el hosting del sitio no funcione del todo bien. Esto se debe a que los hosting son gratuitos y es probable que si no se ha ingresado en un tiempo (bastante corto) tarde en responder el servidor:
-
Con Railway posiblemente aparezca un error, pero no quiere decir que no funcione. Puede entonces tardar entre un minuto o dos en responder adecuadamente desde la primera vez que se ingresa. Luego de esto, debería funcionar correctamente: Ir al sitio en Railway
-
Con Render es probable que tarde alrededor de 30 segundos en cargar la apicación, y una vez cargada suele andar mal un par de minutos: Ir al sitio en Render
Usuario: user@fake.test
Contraseña: 123456
Una aplicación para administración de presupuesto personal, donde puedes guardar con detalle tus ingresos y egresos de dinero y ver un balance de tus operaciones registradas. También puedes tener una mejor organización de ellas clasificándolas por concepto, tipo y categoría.
Este es un proyecto desarrollado para el desafío Full Stack JS de la aceleración de Alkemy. Tomé como un reto personal el realizarlo en el menor tiempo posible con una deadline de diez días y aplicar el nuevo conocimiento adquirido en PostgreSQL
, Sequelize
, Redux Toolkit
y Material UI
, reforzando la práctica de React
.
Esta sección lista las tecnologías o frameworks que fueron utilizados para hacer le proyecto, con una breve descripción y la razón o intención de utlizarlas.
Node JS
Node.js es un entorno de ejecución orientado a eventos asíncronos para JavaScript construido con V8, motor de JavaScript de Chrome, y diseñado para crear aplicaciones network escalables. Por supuesto Node.js tiene varios pros y contras comparado con otros lenguajes y frameworks con los que compite, pero las principales razones que explican por qué lo elegí para este pequeño proyecto son, primero, por la ventaja de poder utilizar "Javascript en todos lados", siendo que Node.js soporta Javascript tanto en el lado del cliente como en el lado del servidor, y segundo, el vasto repositorio de librerías al que se tiene acceso con Node Package Manager.
Express
Express es una infraestructura web rápida, minimalista y flexible para Node.js que proporciona un conjunto sólido de prestaciones. La principal razón por la cual la elegí es que, sin agregar muchas restricciones, hace mucho más claro y fácil el control de las peticiones y las respuestas y el diseño de rutas con, como dice en su sitio oficial, "con miles de métodos de programa de utilidad HTTP y middleware a su disposición".
PostgreSQL
PostgreSQL es un poderoso sistema de bases de datos objeto-relacional. Como fue requerida una base de datos relacional en el desafío la elegí, pero una de las razones para tomar esta decisión en lugar de elegir otra base de datos relacional es que es de código abierto con más de 30 años de actividad y hay una gran cantidad de información fácil de encontrar que describe cómo instalarla y utilizarla en la documentación oficial. Otra razón importante es que algunas funciones, como crear, actualizar o eliminar, en mi opinión, tienen un mejor retorno de información luego de que la acción es realizada.
Sequelize
Sequelize es un moderno Mapeador de Objetos Relacionales u ORM (por las siglas en inglés de Object Relational Mapping) para TypeScript y Node.js en conjunto con PostgresSQL y otras bases de datos relacionales SQL. Siendo un ORM, Sequelize me permite acceder a la base de datos usando una lógica orientada a objetos con Javascript, una gran ventaja considerando que me fue solicitado que las URLS de mi servidor respondan utilizando datos JSON.
Json Web Token
JSON Web Token (JWT) es un estándar abierto (RFC 7519) que define una forma compacta y contenida en sí misma de transmitir de forma segura información entre dos partes en formato de objeto JSON. Esta información puede ser verificada y es confiable porque está cifrada digitalmente, ya que los tokens pueden ser cifrados utilizando un secreto o un par de llaves público/privado. Elegí esto para mis métodos de autorización y autenticación porque resulta en una manera bastante sencilla de llevarlos a cabo y, habiendo utilizado Passport antes, quería aprender algo más. Lo encontré mejor porque tiene menos restricciones, aunque Passport provea un middleware ya incluído que tuve que desarrollar en este caso.
React JS
React es una librería de Javascript de código abierto eficiente, declarativa, y flexible para construir interfaces de usuario simples, rápidas, y escalables para el frontend de aplicaciones web. Utiliza JSX que es una extensión de sintaxis de JavaScript que permite mezclar HTML, lo que facilita el desarrollo de componentes. Como yo ya he elegido aprender React primero en mi proceso de aprendizaje, decidí utilizarlo nuevamente para este proyecto para aprender más y ganar experiencia. Elegí React en su momento por recomendaciones, siendo que estoy de acuerdo con las razones que me dieron: que es más fácil de aprender y usar en un principio y que tiene un enorme potencial cuando se lo aprende en profundidad, que tiene un gran apoyo de la comunidad y que es empleado ampliamente en el mercado laboral IT; junto con otras ventajas tecnológicas como un renderizado rápido.
Redux - Redux Toolkit
Redux es un contenedor predecible del estado de aplicaciones JavaScript que ayuda a manejarlo y escribir aplicaciones que se comporten consistentemente. Redux Toolkit es el set de herramientas oficial, estructurado y con baterías incluídas para un desarrollo eficiente con Redux, construído sobre Redux pero con muchas más ventajas. Decidí utilizarlos con la intención de aprender más tecnologías, conocía Redux pero nunca la había implementado en un proyecto, siempre me pareció correcto y más fácil y mejor usar el contexto de React. Pero el conocer Redux Toolkit me hizo querer probarlos, y encontré una tecnología fantástica. Aún teniendo mucho que aprender, me resultan excelentes para manejar las peticiones a APIs con createAsyncThunk y una gran manera de mejorar la separación de intereses creando fragmentos ( o rebanadas- slices) del estado para manejarlo.
Material UI
Material UI es un proyecto de código abierto que cuenta con componentes de React que implementan Material Design de Google. Estaba decidido a empezar mi viaje con los frameworks de css para frontend e iba a construir una aplicación de React pequeña y simple, entonces en esa situación me vi atraído hacia Material UI, teniendo en consderación Bootstrap para aprender más adelante. También intenté sacar ventaja de la paleta de colores que viene por default gracias al diseño "material".
Extra libraries
- bcryptjs: es una librería que ayuda a encriptar las constraseñas, para una mejor seguridad.
- express-session: ayuda a crear un middleware de sesión, que necesitaba para poder almacenar el código y la dirección de correo electrónico para el proceso de verificación de identidad del usuario.
- express-async-handler: un middleware simple para manejar excepciones dentro de una ruta asíncrona de express y pasarlas a un controlador de error de express, que también usé porque resulta en un código mucho más claro y limpio.
- nodemailer: es un módulo para aplicaciones de Node.js que permite enviar correos elctrónicos de manera muy fácil.
- axios: es un cliente HTTP basado en promesas para node.js y el navegador, no es que lo necesitara realmente, solo intenté cambiar fetch y aprender axios también.
- material-react-toastify: permite agregar barritas de notificaciones a la aplicación de manera sencilla, y esta creado en cumplimiento con la hoja de especificaciones de diseño de Material.io.
- react-router-dom: es la librería de mapeo de rutas de React estándar, mantiene la Interfaz de Usuario en sintonía con la URL y tiene una colección de componentes de navegación.
- react-beforeunload: Un componente y hook de React que escucha el evento beforeunload de la ventana.
El proyecto se encuentra terminado en su mayor parte. En lo relativo a la consigna a cumplir, sólo resta crear un observer que restrinja el renderizado de los registros a diez y únicamente muestre los restantes si el usuario así lo solicita. Además, aunque el diseño que responda a los distintos tamaños de pantalla funciona, se lo ve bastante pobre, debiendo revisar puntos claves para una mejor experiencia del usuario. La página de inicio claramente necesita una mejora. Por otro lado, personalmente considero de importancia agregar algunas funcionalidades extra. Aunque la aplicación es sencilla, resulta básico el permitir agregar y quitar opciones a los filtros a gusto, la posibilidad de acotar los registros a fechas determinadas y que el usuario pueda disponer de otra suma resultante de los filtros aplicados. Considerando el código, algunos componentes aún pueden ser modularizados de mejor manera.
La API que brinda el servidor, creada para la aplicación, está documentada y publicada con Postman. Ahí puedes cargar y correr la API en postman directamente o usar postman en el navegador, utilizando el botón que dice "Run in Postman" ubicado en la esquina superior derecha de la ventana.
Para instalar esta aplicación y probarla en desarrollo necesitas tener instaladas en tu computadora versiones actualizadas de Node.js
, NPM
y Git
para poder:
-
Crear e ir a un nuevo directorio.
-
Inicializar un nuevo repositorio con el comando
git init
. -
Obtener este repositorio con el comando
git pull https://github.com/andressiri/alkemy-full-stack
. -
Instalar las dependencias del directorio raíz con el comando
npm install
. -
Ir al directorio
/frontend
e instalar las dependencias con el comandonpm install
nuevamente. -
Crear la base de datos PostgreSQL requerida:
Instalar el servidor PostgreSQL en tu computadora.
- Descargar el instalador en el sitio oficial.
- En Windows considerar que es necesario haber ingresado como administrador o superusuario para realizar la instalación. De ser necesario, se recomienda seguir las instrucciones para Windows provistas en el sitio oficial.
- En Mac OS considerar que hay que correr el paquete dmg descargado como usuario administrador. De ser necesario, se recomienda seguir las instrucciones para Mac OS provistas en el sitio oficial.
- En Ubuntu para Linux seguir las instrucciones provistas en el sitio oficial para Ubuntu.
- Necesitarás la constraseña que ingreses en la instalación para conectarte a la base de datos.
Crear la base de datos y sus tablas:
Recomendado: correr el archivo
createDatabase.sql
provisto en este repositorio.-
Conectar a la consola
SQL shell (psql)
(instalada al instalar el servidor PostgreSQL). Los valores por defecto para la conexión son:- para Server: "localhost".
- para Database: "postgres".
- para Port: "5432".
- para Username: "postgres".
Inmediatamente después de ingresar el nombre de usuario (Username), se debe ingresar la contraseña para ese usuario. Para el usuario por defecto (postgres), es la contraseña que se ingresó durante la instalación.
- Ya en la consola
psql
correr el comando\i ruta/a/createDatabase.sql;
, donderuta/a/
es la ruta al directorio raíz del proyecto. En caso de tener problemas con el nombre de la ruta, considerar cambiar el nombre de los directorios, o mejor aún, simplemente copiar el archivocreateDatabase.sql
a otro directorio y correrlo desde ahí. También considerar que la ruta puede fallar si no se usa el estilo de barra Unix ("/"). - Una vez realizado lo anterior con éxito, el proceso debería crear una base de datos llamada andres-siri-alkemy-test, conectarse a ella, crear dos tablas (people y records) y hacer varias (31) inserciones para un usuario falso provisto para probar la aplicación. El email de este usuario es "user@fake.test" y su contraseña es "123456".
- Si por algún motivo no es posible instalar el archivo
createDataba.sql
, se puede correr las líneas del archivo en la consolapsql
o usar pgAdmin 4.
Crearlas usando pgAdmin 4
-
Abrir la aplicación
pgAdmin 4
(instalada con el servidor PostgreSQL). -
Usar la contraseña que se ingresó durante la instalación.
-
Crear una nueva base de datos.
-
Nombrarla "andres-siri-alkemy-test" o un nombre a elección.
-
Crear la primer tabla.
-
Nombrar la primer tabla como "people".
-
Definir las columnas de la tabla "people".
-
Crear la restricción de valor único para la columna "email".
-
Crear una segunda tabla.
-
Nombrar la segunda tabla como "records".
-
Definir las columnas de la tabla "records".
-
Crear la restricción de llave foránea para la columna "user_uuid".
-
Crear la restricción de valores válidos para la columna "operation_type".
-
Crear un archivo .env en el directorio raíz con las siguientes variables:
NODE_ENV = development DB_NAME = < andres-siri-alkemy-test o el nombre de tu base de datos PostgreSQL > DB_USERNAME = < "postgres" (default) o tu nombre de usuario para esa base de datos de PostgreSQL > DB_PASSWORD = < la contraseña para ese usuario de PostgreSQL > JWT_SECRET = < una cadena que quieras usar como secreto para el token de JWT > MAILER_MAIL = < tu dirección de email de gmail > MAIL_PASSWORD" = < tu "contraseña de aplicación" generada desde google" > (no es la constraseña de tu email)
Cómo generar una contraseña de aplicación en Google
Para generar una nueva contraseña de aplicación seguir los siguientes pasos:
-
En una nueva pestaña de Chrome ir a "Gestionar tu cuenta de Google".
-
Ir a "Iniciar sesión en Google" en la sección de "Seguridad" y clickear en "Contraseñas de aplicaciones". Notar que es necesario tener la verificación en dos pasos activada para poder hacer esto.
-
Crear una nueva constraseña de aplicación, el nombre es indistinto.
-
Obtener la nueva contraseña de aplicación creada.
-
-
Finalmente, para correr el cliente en el puerto 3000 usar el comando
npm run client
en el directorio raíz, y para el servidor en el puerto 8080 usar el comandonpm run server
, también en el directorio raíz.
El código está organizado en archivos y directorios teniendo en cuenta la separación de intereses lo más posible. De esta manera los archivos tratan de ser lo más concisos que puedan y hacerse cargo de una sola acción de ser posible, incluso dando como resultado un archivo realmente corto, como algunos controladores en el directorio backend. Pero algunos de ellos deben agrupar varias acciones para encapsular una funcionalidad o una lógica, incluso si resultan en un archivo realmente largo, como los "slices" para el manejo de estados. Dicho esto, la mayor parte de la estructura y los nombres de los directorios en frontend siguen lo que es dado al usar create-react-app
y el paquete react-redux
que incluye Redux Toolkit.
English
It is very likely that the hosting of the site is not working properly. This is because the hosting is free and it is probable that if the had not been used for certain (fairly short) time, it will take a while for the server to respond:
-
With Railway you may possibly get an error, but it doesn't mean it won't work. It will then take a minute or two for the server to respond properly from the first time you tried to enter. After that, it should work fine: Go to site on Railway
-
With Render it is likely to take about 30 seconds to load the application, and once it is loaded it usually runs poorly for a couple of minutes: Go to site in Render
User: user@fake.test
Password: 123456
An app for personal budget administration, where you can save your money incomes and outcomes with detail and see a balance of your registered operations. You can also get a better organization sorting them by concept, type and category.
This is a project developed for the Full Stack Challenge JS of Alkemy's acceleration. I took it as a personal defiance making it in the lesser time possible with a ten days deadline and apply the recently acquired knowledge of PostgreSQL
, Sequelize
, Redux Toolkit
and Material UI
, strengthening the React
practice.
This section lists technologies or frameworks that have been used to do the project, with a brief description and the reason or intention of using them.
Node JS
Node.js is an asynchronous event-driven JavaScript runtime built on Chrome's V8 JavaScript engine designed to build scalable network applications. Of course Node.js has many pros and cons compared with other copeting languages and frameworks, but the main reasons that explain why I chose it for this small project are, first, because of the "Javascript everywhere" advantage, as Node.js supports JavaScript both client-side and server-side, and second, the vast libraries repository you can access with the Node Package Manager.
Express
Express is a fast, unopinionated and minimalist web framework for Node.js that provides a robust set of features. The main reason I chose it is because, without adding many restrictions, it makes much more clear and easier to control requests and responses and to design routes with, as it says in it's official site, "a myriad of HTTP utility methods and middleware at your disposal".
PostgreSQL
PostgreSQL is a powerful object-relational database system. As it was required a relational database in the challenge I chose it, but one of the reasons for this decision over choosing other relational databases is that it is open-source with over 30 years of active and there is a wealth of information to be found describing how to install and use it through the official documentation. Other important reason is that some features, like create, update or delete, in my opinion, have better feedback or information returned after the action is done.
Sequelize
Sequelize is a modern TypeScript and Node.js Object Relational Mapping tool for PostgresSQL and more relational SQL databases. As an ORM Sequelize allows me to access the database using the object-oriented logic with Javascript, a great advantage considering I was required that my server URLS should return JSON data.
Json Web Token
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret or a public/private key pair. I chose this to use for my authorization and authentication methods as it results in a pretty simple way of doing it, and having used Passport before, I wanted to learn something else. I found it better as it has less restrictions, besides Passport provides a middleware built on that I had to develop instead.
React JS
React is an efficient, declarative, and flexible open-source JavaScript library for building simple, fast, and scalable user interfaces for frontends of web applications. It uses JSX which is basic JavaScript that allows HTML quoting, what facilitates developing components. As I have chosen to first learn React in my path, I decided to use it again for this project to learn more about it and gain experience. I chose React because it had been recommended to me and I agree that it is easier to learn and use at start and has a giant potencial when learned in depth, it has a strong community support and is widely used in the IT market, with other technological advantages as fast rendering.
Redux - Redux Toolkit
Redux is a Predictable State Container for Javascript Apps that helps managing state and write applications that behave consistently. Redux Toolkit is the official, opinionated, batteries-included toolset for efficient Redux development, built over Redux but with much more advantages. I decided to use them with the intention of learning more technologies, I knew Redux but never used it properly in a project before, it always seemed easier and a better option to use React context. But knowing about Redux Toolkit made me wanna try it, and I found out a fantastic technology. Still having a lot to learn, I found that it is great for managing queries to APIs with createAsyncThunk and a great way to boost the separation of concerns creating slices to manage the state.
Material UI
Material UI is an open-source project that features React components that implement Google's Material Design. I was decided to start my journey with frontend css frameworks and I was going to build a small and simple React application, so in that situation I was attracted to use Material UI, putting a pin in Bootstrap to learn it later. I also tried to take advantage of the material design default colors pallette.
Extra libraries
- bcryptjs: it is a library that helps hash passwords, for a better security.
- express-session: helps create a session middleware, that I needed to store the code and the email address for user identity verification process.
- express-async-handler: Simple middleware for handling exceptions inside of async express routes and passing them to your express error handlers, which I used also because it results in a much cleaner code.
- nodemailer: is a module for Node.js applications to allow easy as cake email sending.
- axios: is a promise-based HTTP Client for node.js and the browser, not that I really needed it, just trying to change from fetch and learn axios too.
- material-react-toastify: it allows you to add notification snackbars to your app with ease, and it has been made in compliance with Material.io design spec-sheet.
- react-router-dom: is the standard routing library for React, it keeps your UI in sync with the URL and has a collection of navigational components.
- react-beforeunload: React component and hook which listens to the beforeunload window event.
The project is mostly finished. In relation to the assignment to fulfill, it's just missing the creation of an observer that restricts the records rendering to ten and just shows the rest of them if the user requires to do so. Furthermore, besides the design is responsive, it seems pretty poor, so it's important to check some breakpoints for a better user experience. The landing page clearly needs an improvement. On the other hand, I personally think that it is important to incorporate some functionalities, like allow adding or deleting options to the filters as pleased, the possibility to delimit the records to certain dates and that the user can have another addition after filters are applied. Regarding the code, some components may be modularized in a better way.
The API that provides the server, created for the application, is documented and published with Postman. There you can load and run the API in postman directly or use postman in the web browser, using the button that says "Run in Postman" located in the right superior corner of the window.
To install this app for development mode testing you need to have installed in your computer updated versions of Node.js
, NPM
and Git
in order to follow this steps:
-
Create and go to a new directory.
-
Initialize a new repository with
git init
command. -
Git pull this repository with
git pull https://github.com/andressiri/alkemy-full-stack
command. -
Install root directory dependencies with
npm install
command. -
Move to
/frontend
directory and install client dependencies with thenpm install
command again. -
Create the PostgreSQL required database:
Install PostgreSQL server in your computer.
- Download the installer at official site.
- In Windows consider you need to be logged as administrator or superuser to perform and installation. If needed, follow the instructions provided at official site for Windows.
- In Mac OS consider you have to run the downloaded dmg package as administrator user. If needed, follow the instructions provided at official site for Mac OS.
- In Ubuntu for Linux follow the instructions provided at official site for Ubuntu.
- You will need the password your enter in the installation to connect to the database.
Create the database and it's tables:
Recommended: run the
createDatabase.sql
file provided in this repository.-
Connect to the
SQL shell (psql)
console (installed with the PostgreSQL server). The default values for connection are:- for Server: "localhost".
- for Database: "postgres".
- for Port: "5432".
- for Username: "postgres".
Right after entering the username, you should enter the password for that user. For the default user (postgres), it is the password you provided in the installation.
- In the
psql
console run the command\i path/to/createDatabase.sql;
, wherepath/to/
is the path to this project root folder. If you have problems with the path name, consider changing the directories names or, better, just copy thecreateDatabase.sql
file to another directory and run it from there. Also notice that the path may be wrong if you don't use the Unix style slash ("/"). - Once you have successfully done this, it should create a database named andres-siri-alkemy-test, connect to it, create two tables (people and records) and make many (31) insertions for a fake user created for testing. This user email is "user@fake.test" and it's password is "123456".
- If for some reason you can't install the
createDataba.sql
file, you can run the lines of that file in the psql console or use pgAdmin 4.
Create them using pgAdmin 4
-
Open the
pgAdmin 4
application (installed with the PostgreSQL server). -
Use the password you entered during the installation.
-
Create a new database.
-
Name it "andres-siri-alkemy-test" or a name of your choice.
-
Create the first table.
-
Name the first table as "people".
-
Define "people" table columns.
-
Set "email" column unique constraint.
-
Create a second table.
-
Name second table as "records".
-
Define "records" table columns.
-
Set foreign constraint to the "user_uuid" column.
-
Set operation_type column valid values.
-
Create a .env file at the root directory with the following variables:
NODE_ENV = development DB_NAME = < andres-siri-alkemy-test or your PostgreSQL database name > DB_USERNAME = < "postgres" (default) or your PostgreSQL user name > DB_PASSWORD = < your PostgreSQL password for previous username > JWT_SECRET = < whatever you want, to use as JWT secret > MAILER_MAIL = < your gmail email address > MAIL_PASSWORD" = < the "application password" generated with google > (not your email password)
How to generate application password
To generate a new application password follow the next steps:
-
In a new Chrome tab go to "Manage your Google Account".
-
Go to "Signing in to Google" in the "Security" section and click into "App passwords". Notice you must have your 2-Step Verification activated in order to do this.
-
Create a new application password, you can name it as you want.
-
Get the new password created.
-
-
Finally, to run the client at port 3000 use "npm run client" command at root directory, and for the server at port 8080 use "npm run server" command, also at root directory.
The code is arranged in files and directories taking in consideration the separation of concerns the most possible. In that way files try to be the more consice they can be and take care of just one action if possible, even giving as result really short files, like some controllers at the backend directory. But some of them must group many actions to encapsulate a functionality or a logic, even if it results in a really large file, like the states management slices. With that said, most of the structure and directories names at frontend follow what is given by using "create-react-app" and "react-redux" package that includes Redux Toolkit.