- 1. Preámbulo
- 2. Resumen del proyecto
- 3. Objetivos de aprendizaje
- 4. Consideraciones generales
- 5. Criterios de aceptación mínimos del proyecto
- 6. Pistas, tips y lecturas complementarias
La mensajería instantánea es uno de los usos más populares que tiene la Internet desde que se popularizó su uso. Desde IRC, ICQ y MSN Messenger, a los chats en redes sociales, Slack, Telegram y WhatsApp, poder comunicarnos en tiempo real con otras personas es algo que ya damos por sentado en nuestra vida cotidiana.
Muchas herramientas tienen estas funcionalidades para facilitar las interacciones diarias en nuestro trabajo, pero además existen chats para entregar soporte directo a personas, por la fluidez que ofrecen, incluso llegando al ejemplo de los chatbots.
Incluso siendo parte de una organización de tecnología, muchas veces los equipos de desarrollo se enfrentan a problemas que otros equipos ya vivieron en el pasado y no logran comunicarse por correo o videollamada para pasar sus aprendizajes de forma oportuna, lo que termina frenando la capacidad de la organización completa de responder a los desafíos propios de su negocio.
Has sido seleccionada para formar parte de la creación de una renovada área de desarrollo de esta organización. Uno de los valores más importantes en esta iniciativa es la comunicación abierta y fluida, y se ve que implementar esto producirá un gran cambio cultural en la organización completa. Por esto ha surgido la necesidad de tener un lugar donde las personas desarrolladoras puedan comunicarse rápidamente entre sí.
Has sido invitada a participar de esta iniciativa y te han propuesto la creación de una herramienta de chat propia (para evitar gastos a terceros) para que tus compañeras y compañeros ocupen menos tiempo en resolver problemas, logren masificar experiencias y aprendizaje locales a toda el área de desarrollo y puedan así contribuir al crecimiento técnico de todas.
En este proyecto construirás una aplicación de mensajería instantánea. Esta aplicación requerirá que las personas puedan registrarse e iniciar sesión para poder enviar mensajes a un canal de chat general y a canales temáticos que cada persona puede crear o unirse por su cuenta.
Para acercar este proyecto lo más posible a entornos profesionales le daremos gran importancia al desarrollo a través de Historias de Usuaria para definir alcance y prioridad de las funcionalidades que desarrollarás. Para esto te ayudaremos como coaches jugando el rol de Product Owner. Te entregaremos las primeras historias ya hechas, para que tengas una base inicial , y durante el proceso tendrás que seguir escribiendo tus propias historias para abarcar todas las funcionalidades.
Para implementar mensajes instantáneos en un chat ocuparás la librería Socket.io, que te permitirá implementar web sockets para mantener conexiones abiertas entre las personas que estén conectadas dentro del chat y el “servidor” que centralizará la comunicación, recibiendo los mensajes y enviándolos de nuevo a los “clientes”.
Para construir la UI podrás ocupar uno de los siguientes frameworks: React, Vue o Angular.
Alojarás esta aplicación en la plataforma Heroku y construirás con GitHub Actions tu propio pipeline de Integración Continua/Entrega Continua (o CI/CD por Continuous Integration/Continuous Delivery) para automatizar el despliegue que hará que tu proyecto esté disponible a través de Internet para cualquier persona. Para almacenar los datos ocuparás la base de datos PostgreSQL en la versión que provee nativamente Heroku.
Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo.
-
Callbacks
-
Promesas
-
Pruebas unitarias (unit tests)
- Pruebas de integración (end-to-end)
-
JWT (JSON Web Token)
-
Almacenamiento y acceso de contraseñas
-
Consulta o petición (request) y respuesta (response).
-
Verbos HTTP
-
CORS (Cross-Origin Resource Sharing)
-
Manejo de rutas
-
Uso y creación de middleware
-
Cliente JavaScript de Socket.io
-
Servidor de Node.js de Socket.io
-
Instalación
-
Conexión
-
Queries y comandos (creación, lectura, actualización, eliminación)
-
JSX
-
Componentes y propiedades (props)
-
Manejo de eventos
-
Listas y keys
-
Renderizado condicional
-
Elevación de estado
-
Hooks
-
CSS modules
-
React Router
-
Instancia de Vue.js
-
Datos y métodos
-
Uso y creación de componentes
-
Props
-
Directivas (v-bind | v-model)
-
Iteración (v-for)
-
Eventos (v-on)
-
Propiedades Computadas y Observadores
-
Routing
-
Clases y Estilos
-
Components & templates
-
Directivas estructurales (ngIf / ngFor)
-
@Input | @Ouput
-
Creación y uso de servicios
-
Manejo de rutas
-
Creación y uso Observables.
-
Uso de HttpClient
-
Estilos de componentes (ngStyle / ngClass)
-
Construcción de pipelines (GitHub Actions/CircleCI)
-
Despliegue de servicios (Heroku/GitHub Pages)
-
Aplicación de Trunk-based Development para Integración Continua
-
Validación de cobertura de pruebas en pipeline
-
Pruebas de integración
Las Historias de Usuaria actualmente son esenciales en el desarrollo de software ágil. En pocas palabras, son descripciones en texto de una funcionalidad de la aplicación en desarrollo, desde el punto de vista de quienes la ocuparán, las usuarias. Las usaremos a lo largo de todo el proceso de desarrollo y crearás nuevas historias a medida que vayamos aprendiendo sobre lo que es prioritario y lo que reporte mayor valor para nuestras usuarias.
Ocuparemos la fórmula Persona + Necesidad + Propósito expresada en el siguiente ejemplo:
Yo como fanática de la música funk (Persona)
Quiero encontrar listas de reproducción de ese género musical (Necesidad)
Para descubrir artistas y bandas nuevas (Propósito)
Este rol tiene la responsabilidad de maximizar el valor entregado por el equipo en el desarrollo de un producto. En general, esto implica que la persona PO tiene un mayor conocimiento del “negocio” (o dominio) y contribuye al equipo definiendo la prioridad de las historias desarrolladas, con el objetivo de entregar el mayor valor posible a usuarios.
En este proyecto te apoyarás en una coach que asumirá el rol de PO. Como cualquier equipo de desarrollo, tú y tus compañeras tendrán que conversar con la PO para priorizar las Historias de Usuarias y definir el alcance de las funcionalidades. Durante estas conversaciones esperamos que puedan fortalecer las habilidades de negociación y priorización, que cualquier desarrolladora debe tener.
Los WebSockets son una avanzada tecnología que permiten abrir una comunicación interactiva bidireccional entre el navegador de un “cliente” y un “servidor”. Este tipo de conexiones permiten crear fácilmente, entre otras cosas, chats entre personas a través de la web, que sería muy difícil con conexiones tradicionales.
Imaginemos una aplicación que requiera recargar manualmente la página cada vez que queramos ver los mensajes nuevos, no sería ni muy instantánea ni muy útil. Con WebSockets, cargaremos la página una vez y la conexión quedará abierta para que simplemente recibamos los mensajes de otras personas manejando eventos.
Con la librería Socket.io podemos implementar conexiones de este tipo sin tener que hacer muchas cosas manualmente. Así, familiarizándote con ella podrás agregar la comunicación instantánea a tu aplicación sin muchas demoras y así podrás enfocarte en las funcionalidad más complejas.
Heroku es una plataforma similar a Firebase. Ambas pertenecen a la categoría llamada “Plataforma como Servicio”, en inglés Platform-as-a-Service (PaaS). Estas plataformas permiten alojar aplicaciones para que nuestro trabajo quede disponible por Internet a cualquier persona.
Por otro lado, PostgreSQL, o simplemente Postgres, es un motor de base de datos relacional. Estos tipos de bases de datos son ampliamente usados en la industria y Postgres es una de las más conocidas.
Para el desarrollo de este proyecto trabajarás haciendo despliegues a Heroku y ocupando su servicio nativo de Postgres para almacenar, o persistir, tus datos.
Para que nuestro código esté disponible para usuarias es necesario desplegar
nuestra aplicación. Esto lo hiciste previamente con GitHub Pages y Firebase, en
este último caso ejecutando firebase deploy
.
Una forma de aumentar la productividad en el desarrollo es automatizar el despliegue para evitar posibles errores manuales o algún paso que se nos olvide, como ejecutar las pruebas antes.
Para aprovechar esta mayor productividad usarás
GitHub Actions para construir un
pipeline de Integración Continua/Entrega Continua que ejecutará las pruebas
con cada commit a main
y, una vez que todas pasen con éxito, desplegará tu
aplicación automáticamente a Heroku.
El boilerplate contiene una estructura de archivos como punto de partida:
.
├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── docs/
├── setup/
├── docker-compose.yml
├── package.json
├── proyect.yml
└── README.md
Esta carpeta contiene un punto de partida para tu aplicación, como las primeras historias de usuaria y la base para cuando construyas tu pipeline con GitHub Actions.
Como mínimo tu proyecto debe permitir al usuario hacer lo siguiente:
- Escribir mensajes en un canal de chat general
- Ver mensajes enviados por otras personas en tiempo real
- Guardar el historial de mensajes enviados
- Registrarse en la aplicación
- Iniciar sesión para ingresar al chat
- Crear canales de chat al que puedan acceder otros usuarios
Deberás realizar el desarrollo a partir de Historias de Usuaria, partiendo de la base que te entregamos y luego escribiendo nuevas a medida que vayas progresando.
Además deberás escoger a una de las coaches para que sea PO de tu equipo durante todo el proyecto. Te apoyarás en tu PO para definir y negociar prioridades y el alcance de cada historia. En esta persona también te apoyarás para escribir las historias.
Como punto de partida, agenda una reunión de kick-off con la coach que escojan para definir las prioridades del primer sprint.
Deberás hacer una integración con la librería Socket.io para implementar comunicación a través de WebSockets que permitan a usuarias chatear en tiempo real.
Deberás construir un pipeline con GitHub Actions para desplegar tu aplicación
a Heroku de forma automática con cada push a la rama main
. El despliegue
debe realizarse solo después de que todas las pruebas se hayan ejecutado en el
pipeline y pasado con éxito.
Deberás ocupar el servicio nativo de Postgres en Heroku para persistir los datos de tu aplicación.
Como tendrás que ocupar una librería externa, Socket.io, será muy importante que esa integración se haga de forma ordenada. Para esto tendrás que definir una estructura de carpetas lógica y clara, y procurar separar responsabilidades. Cada script debiera tener solo una responsabilidad y exportar funciones que sean ocupadas por otros.
Deberás incluir pruebas unitarias para tu aplicación y testear aquellas partes más críticas de tu propio código. No vamos a testear que Socket.io funciona como debiera o que la base de datos efectivamente guarda los datos. Si necesitas testear una función que se integra con código no hecho por ti, puedes ocupar test doubles, a veces llamados simplemente mocks.
Aquí te entregamos un checklist para que partas con tu proyecto:
- Revisar las primeras historias de usuario
- Agendar la primera reunión con tu PO
- Desplegar de forma manual un simple "Hola, mundo" en Heroku
- Asegurarte que puedes levantar Postgres localmente con
docker-compose.yml
- Familiarizarte un poco más con CI/CD
- Familiarizarte con GitHub Actions
- Agregar el despliegue automatizado a Heroku con GitHub Actions
Las Historias de Usuaria, aunque útiles, no solucionan automáticamente todos los problemas. Es fácil caer en la trampa de intentar poner absolutamente todos los aspectos de una funcionalidad en una única historia y comprometernos con su desarrollo en un sprint de 1 o 2 semanas, para luego darnos cuenta que el trabajo requerido era mayor al esperado y terminar acarreando la misma historia en progreso por varios sprints.
Para evitar historias muy grandes es importante aplicar un enfoque iterativo al escribirlas. Si es necesario podemos “romper” una historia grande en historias más pequeñas que contengan incrementos de una misma funcionalidad.
Por ejemplo, si vamos implementar el inicio de sesión, podríamos asumir que los datos ingresados por el usuario siempre están correctos. Si necesitamos hacer alguna validación, podríamos priorizar validar lo más importante primero, y luego agregar cosas como la recuperación de la contraseña con una historia aparte que solo tenga eso.
Socket.IO es una librería que permite comunicación bidireccional, en tiempo real y basada en eventos entre el navegador y servidor. Se compone de dos partes:
- un servidor en Node.js: Source | API
- un cliente Javascript para el navegador (que también se puede usar desde Node.js): Source | API
Una de las ventajas de Heroku, es la rapidez del proceso, pues detecta automáticamente algunas características de nuestro proyecto y nos evita tener que hacer muchas configuraciones de forma manual. Es posible tener una aplicación corriendo en Heroku ¡en menos de 5 minutos!
Este tipo de tecnologías es muy importante actualmente en el desarrollo de
aplicaciones, ya sea front-end, back-end o full-stack, puesto que automatizan
una de las tareas esenciales del desarrollo de software: el despliegue. Le
llamamos “desplegar” (hacer deployment) al acto de tomar el código de nuestra
aplicación y moverlo a uno de estos servicios para que nuestros cambios más
actuales queden disponibles para usuarios. Durante el bootcamp muchas veces
hiciste esto con firebase deploy
para desplegar los cambios a Firebase o
quizás configurando tu repositorio para que el código se viera en
GitHub Pages.
Así como Firebase permitía guardar datos en su base de datos Firestore, Heroku permite conectar de forma nativa con Postgres. Usualmente configurar bases de datos puede llegar a ser una tarea compleja, especialmente si queremos configurarlas en los entornos de “producción”. Heroku simplifica todo este proceso con Postgres entregándonos los beneficios y ahorrándonos hacer muchas configuraciones.
Asegúrate de seguir los siguientes pasos:
-
Si ocupas Mac o Windows, instala Docker Desktop.
-
Si ocupas alguna distribución de Linux, instala Docker Engine y Docker Compose.
-
Asegúrate de que la instalación de Docker y Docker Compose se hizo correctamente verificando la salida de los siguientes comandos:
$ docker --version Docker version 20.10.8, build 3967b7d28e # <- Esto significa instalación exitosa $ docker-compose --version docker-compose version 1.29.2, build unknown # <- Esto significa instalación exitosa
-
Para iniciar la base de datos local, ejecuta
npm run db:up
y, luego de unas descargas que se harán solo la primera vez, al final debieras obtener una salida similar a la siguiente:$ npm run db:up > chat-app@1.0.0 db:up > docker-compose up -d Creating network "chat-app_default" with the default driver Creating chat-app_postgres_1 ... done Creating chat-app_pgadmin_1 ... done
-
Inicia sesión en el panel administración de Postgres, llamado pgAdmin, ingresando en tu navegador a
http://localhost:15432
con el usuarioadmin@pgadmin.com
y la contraseñapgadmin
: -
Además puedes verificar el estado de la base de datos local y detener la ejecución con los siguientes comandos:
$ npm run db:status # <- Verifica el estado de la base de datos local > chat-app@1.0.0 db:up > docker-compose up -d Creating network "chat-app_default" with the default driver Creating chat-app_postgres_1 ... done Creating chat-app_pgadmin_1 ... done $ npm run db:down # <- Detiene la base de datos local > chat-app@1.0.0 db:down > docker-compose down Stopping chat-app_pgadmin_1 ... done Stopping chat-app_postgres_1 ... done Removing chat-app_pgadmin_1 ... done Removing chat-app_postgres_1 ... done Removing network chat-app_default
Durante el desarrollo es frecuente que debamos realizar la tarea de desplegar repetidamente, incluso varias veces al día. Esto transforma el despliegue en una tarea recurrente propensa a errores: quizás nos equivocamos en el comando exacto para desplegar; quizás nos olvidamos de correr antes las pruebas o de hacer una verificación manual; incluso puede que necesitemos desplegar a una plataforma que requiera varios pasos adicionales que debamos repetir manualmente una y otra vez.
Como seres humanos, tenemos una gran habilidad para realizar tareas “difusas”, que requieren pensamiento creativo, pero si la tarea es simplemente realizar y marcar acciones de una lista, bueno, ahí no nos va tan bien. Afortunadamente ya se ha vuelto un estándar de la industria (al menos las partes más avanzadas) usar herramientas que permiten ejecutar todos estos pasos de forma automática a través de un pipeline de “Integración Continua”.
Un pipeline es simplemente una “línea de producción”, un proceso que automatizamos para desplegar nuestra aplicación, un canal por donde pasa nuestro código cumpliendo distintas etapas, las que van acercando cada vez más nuestro trabajo a “producción”. Por ejemplo, podríamos tomar nuestro código, correr las pruebas y solo si todas pasaron con éxito entonces podríamos desplegar a alguna plataforma (Firebase, Heroku, etc.).
El rol de Product Owner (PO) se puede encontrar en los equipos ágiles que usualmente usan la metodología Scrum. Sin embargo, pasó a formar parte del ecosistema ágil en general, independiente de la metodología, recibe distintos nombres pero tiene básicamente la misma función.
Aunque este rol suele asumirlo de forma exclusiva una persona que no se involucra en el desarrollo, en la práctica sus responsabilidades no son fijas ni exclusivas del rol mismo, y dependerá de la organización en que se encuentre el equipo.