Regalo Secreto - Juega Amigo Secreto online

22 de Enero de 2020

Banner-Horizontal_low_resultado
En mi familia desde hace unos años tenemos la tradición de entregarnos regalos en navidad, esto lo hacemos jugando al amigo secreto (o santa secreto) el año anterior. Corría el 24 de diciembre de 2018 y los papeles del 2019 se repartieron esa noche, muchos perdieron sus papeles otros no se acordaban de quien les habia tocado, entonces a esos no les quedó más remedio que esperar a que todos terminaran para poder entregar los faltantes. 
Esto me hizo pensar, de que como programador, podría idear una solución a este problema, pero no el típico programa de consola en C o de escritorio en visual basic, entonces como últimamente estoy metido en el desarrollo web, decidílla programar una aplicación web faltando 7 días para el 24 de diciembre. Esta aplicación debía ser un mínimo viable, sencilla de utilizar y que nos sirviera para jugar este año, para continuar con la tradición.
Jugar al amigo secreto de manera tradicional, consiste en anotar los nombres de todos los participantes en papelitos y guardarlos en una bolsa, que posteriormente se irá puesto por puesto y cada quien deberá sacar a alguien que no sea el mismo. Esta dinámica sugiere varios problemas.   
  • Puedes sacarte a ti mismo en el reparto.
  • Se pueden formar círculos cerrados y dejar a otras personas afuera.
  • Todos deben estar presentes, esto es un inconveniente para los que viven lejos y se reúnen en esas fechas especiales. 
  • Corres el riesgo de perder el papel u olvidar el nombre.
[the_ad id="1218"]
Para desarrollar una aplicación que le de solución todos estos problemas, decidí usar el stack de JavaScript preferido para mi en este tipo de proyectos. NodeJS, Express, MongoDB y Bootstrap, y para hacer deploy, Heroku.
Este stack es el ideal para soluciones rápidas, al no tener costo alguno para la economía puedo hacer mis pruebas y validar proyectos.

Paso 1: Crear el servicio de Base de Datos y sus modelos.

Para este paso puedo decir que ya tenía trabajo adelantado, llevaba unas semanas trabajando en pequeños módulos para NodeJS que me permitieran integrar funcionalidades como servicios de carga de imágenes y consultas a distintas bases de datos. 
Este proyecto esta en mi github : modular_database
const { Schema, model } = require('mongoose')
const { ObjectId } = Schema

const RoomSchema = new Schema({
    userId: { type: String, required: true },
    name: { type: String, required: true },
    code: { type: Number, required: true },
    isOpen: {type: Boolean, default:true},
    users: {},
    number: { type: Number, default: 0 },
    createdAt: { type: Date, default: Date.now },
    updatedAt: { type: Date, default: Date.now }
})

module.exports = model('Room', RoomSchema)
const { Schema, model } = require('mongoose')
const { ObjectId } = Schema

const UserSchema = new Schema({
    id: { type: String, unique: true, required: true },
    name: { type: String, required: true },
    username: { type: String, unique: true},
    email: { type: String, unique: true, required: true },
    password: { type: String },
    location: {},
    date: { type: Date },
    image: { type: String, default: 'default.png' },
    lastSign: { type: Date, default: Date.now },
    createdAt: { type: Date, default: Date.now },
    updatedAt: { type: Date, default: Date.now }
})

module.exports = model('User', UserSchema)

Paso 2: Crear las rutas

Para las rutas escogí dos maneras de manejarlas, usando una para vistas y otra para una API que se usaría en cada sala. El enrutador se encargaría de decidir cuáles peticiones irán a la API y cuáles a las vistas, ya cada uno escogería si usar el controlador de usuarios o el de las salas.
[the_ad id="1218"]

Paso 3: Crear los controladores

Siguiendo el patron MVC, la lógica de los controladores no son más que una serie de CRUDs, para usuarios, salas y miembros de sala, estos controladores se conectan al servicio de base de datos, donde hacen sus consultas y operaciones.

Paso 4: Autenticación

Para la autenticación utilice Google OAuth 2.0, a través de una estrategia del módulo Passport de npm, este método nos permite utilizar una sesión abierta de google para iniciar sesión en nuestra propia aplicación, compartiendo datos como un id único, nombre, correo y foto de perfil.

Paso 5: Templates y comportamiento de la aplicación.

Para los templates utilice un motor llamado handlebars de npm, me permite extender cierta lógica sobre los archivos html. Y con JQuery y bootstrap termine el comportamiento de las salas, como agregar y eliminar miembros, etc.

Paso 6: Firebase Real Time Data Base

Este es un paso adicional, ya que con todo lo anterior la aplicación funcionaba perfectamente, pero decidí incluir la integración con una base de datos en tiempo real, para que pudiera obtener un comportamiento reactivo y el frontend cambiará dependiendo de las acciones de los usuarios. 
Entonces cada cambio que realizaba en las salas, se modifica en firebase y los demas usuarios podrían ver ese cambio en tiempo real sin recargar la página, ofreciendo una mejor experiencia de usuario.

Paso 7: Deploy

Ya con la aplicación terminada, es momento de llevarla a producción. Para esto utilizo un servicio gratuito como MLab para la base de datos y Heroku para el deploy. Heroku tiene integración directa con GitHub cualquier cambio en el repositorio automáticamente puede ser llevado nuevamente a producción.
[the_ad id="1235"]

Conclusiones.

La aplicación resultante, fue un muy buen prototipo para poder jugar este famoso juego, funciona hasta la fecha sin ningún problema salvo algunos detalles en la experiencia de usuario. 
El proyecto fue desarrollado en 23 horas esa semana y atrayendo a más de 700 usuarios, de todas partes de latinoamérica en menos de 24 horas. Hasta la fecha hay 106 usuarios registrados y 116 salas creadas.

¿Que viene para el Futuro?

La verdad el futuro de la aplicación es incierto, por un lado está la opción de mejorar ciertos aspectos de la aplicación y agregarle otras características interesantes. Pero no me queda el tiempo ahorita para hacerlo. 
Entre las mejoras que quisiera implementar estan:
- Opción para ver la contraseña del miembro durante la creación de la sala
- Estilos dinamicos dependiendo de la region del mundo y la fecha o celebración.
- Eliminar Bugs y optimizar algunos bloques de codigo.