Sobrerreservas que nadie podía evitar.
Gestionar varios locales de playa en una hoja de cálculo compartida no es un problema de flujo de trabajo. Es un problema de consistencia de datos vestido con la ropa de un problema de flujo de trabajo. Dos gerentes abriendo la misma hoja a la vez, bajando con el tabulador al mismo espacio y pulsando guardar: uno de ellos siempre gana, y el otro nunca sabe que perdió. El operador estaba compensando a huéspedes descontentos dos o tres veces por semana por exactamente esto.
Los proveedores de PMS que habían evaluado requerían todos un servidor on-premise, una licencia por puesto y un onboarding de tres meses. Nada de eso encajaba con un operador pequeño con personal de temporada, sin función de TI y con una fuerte preferencia por no poseer infraestructura. El encargo estaba claro: queremos algo que nuestros gerentes puedan abrir en un navegador, y queremos que no se rompa.
Una consola de reservas multipropiedad, con sincronización de disponibilidad que no sondea.
La consola dio a cada local una cuadrícula de reservas en vivo: llegadas, salidas, disponibilidad por espacio, ocupación por fecha. Un gerente en una propiedad podía ver los cambios concurrentes de otra propiedad en el momento en que ocurrían, sin refrescar la página. Reservar, modificar y cancelar una reserva actualizaban el estado compartido de inmediato. Cada sesión abierta veía cada cambio según aterrizaba.
Bajo la consola: Firestore para los datos de reservas, Realtime Database para la capa de sincronización de disponibilidad, Firebase Auth para la gestión de sesiones y Firebase Hosting para la SPA estática. Sin servidor Node. Sin proceso Express que reiniciar. Sin pipeline de despliegue más allá de un único comando de CLI.
La superficie de analítica corría junto a la operativa: demografía de huéspedes, gráficos de tendencias de reserva mediante Highcharts y una vista de previsión de ingresos extraída de las mismas colecciones de Firestore que la cuadrícula de reservas ya leía. La generación de facturas integrada (jsPDF) y la exportación a CSV/XLSX gestionaban el flujo de cierre de mes del propietario sin una herramienta aparte. Tres meses y medio desde el primer commit hasta producción.
- F · 01Sincronización de disponibilidad en vivo
- Firestore + Realtime Database envían actualizaciones a cada sesión abierta en el momento en que cambia una reserva. Sin sondeo. Sin refresco.
- F · 02Panel multipropiedad
- Una sola consola abarca todos los locales. Cada propiedad tiene su propia cuadrícula; el propietario ve la imagen completa en una sola pestaña.
- F · 03Capa de sesión de Firebase Auth
- Firebase Auth gestiona las sesiones de los usuarios propietario, gerente y personal. Sin servidor de autenticación a medida, sin tabla de permisos que mantener. Comprobaciones de rol a nivel de aplicación restringen las superficies.
- F · 04Generación de facturas
- Confirmaciones de reserva y facturas producidas en el lado del cliente con jsPDF y enviadas por email directamente: sin herramienta de facturación aparte.
- F · 05Importación / exportación masiva
- Importación de CSV y XLSX para carga masiva de temporada. Exportación para el contable del propietario al cierre de mes. Ambas se ejecutan en el navegador.
- F · 06Analítica
- Demografía de huéspedes, tendencias de reserva y una vista de previsión de ingresos construida sobre Highcharts, leyendo las mismas colecciones de Firestore que la cuadrícula de reservas.
La elección de solo Firebase, y por qué sobrevivió a producción.
Los intentos de reserva concurrentes sobre el mismo espacio —dos gerentes reservando la última tumbona de la tarde— eran el fallo exacto por el que el operador seguía pagando. La solución no fue el bloqueo en el lado de escritura; fue la verdad en el lado de lectura. Los listeners en tiempo real de Firestore hacían que cada sesión abierta en cada dispositivo viera una reserva en el instante en que se escribía. Una vez tomado un espacio, la pantalla de cada gerente lo mostraba. El fallo de coordinación de la hoja de cálculo —dos personas trabajando desde vistas obsoletas de la misma fila— no podía ocurrir, porque nadie trabajaba desde una vista obsoleta.
La decisión de prescindir por completo de un servidor backend no fue un atajo para recortar costes. Era la arquitectura correcta para las restricciones de este operador. No había un equipo de DevOps que cuidara de un proceso Node, no había una rotación de guardia que entregarnos y no había tolerancia para un servidor caído un sábado de agosto. Los servicios gestionados por Firebase asumen la garantía de disponibilidad; nosotros asumimos la lógica de la aplicación. La frontera es limpia.
Firebase Auth gestionaba las sesiones sin un servidor de autenticación a medida. El soporte multiidioma para una base de huéspedes internacional corría a través de ngx-translate. El bundle estático se desplegaba en Firebase Hosting en menos de dos minutos. El coste mensual total de infraestructura se mantuvo dentro del nivel gratuito de Firebase durante los primeros seis meses de producción.
Cero dobles reservas. La factura de infraestructura se mantuvo dentro del nivel gratuito.
El problema de sobrerreservas se detuvo. En los primeros doce meses de operación, el operador registró cero reservas en conflicto sobre el mismo espacio. La hoja de cálculo se mantuvo abierta durante una semana tras el lanzamiento, como respaldo que nadie usó.
El sistema entró en producción en tres propiedades simultáneamente. La propietaria impartió ella misma la formación del personal, en una sola tarde, porque la consola era lo bastante simple como para explicarla en una sola sesión. La rotación de personal de temporada —la otra razón por la que la hoja de cálculo había sido tan frágil— dejó de ser un riesgo de integridad de datos una vez que el estado vivió en la base de datos, no en el archivo local de alguien. Los nuevos contratados de temporada recibían una invitación de Firebase Auth y la misma consola que usaban todos los demás.
El producto ha funcionado sin un servidor backend desde 2019. El operador nunca nos ha abierto un aviso de guardia.
Dejamos de compensar a los huéspedes. Esa es toda la historia.
