Arquitectura del Software de UnoSportClub
- 1. Visión General
- 2. Arquitectura por Capas (Modelo OSI)
- 3. Componentes del Sistema
- 4. Estructura del Proyecto
- 5. Flujos de Datos
- 6. Seguridad
- 7. Escalabilidad
- 8. Integraciones
- 9. Infraestructura de Despliegue
- 10. Diagrama de Arquitectura
- 11. Referencias
Este documento describe la arquitectura completa del sistema UnoSportClub, basada en el modelo OSI (Open Systems Interconnection) de 7 capas adaptado para aplicaciones web modernas. Su objetivo es proporcionar una comprensión clara de la estructura, componentes, flujos de datos y decisiones arquitectónicas del sistema.
1. Visión General
1.1 Stack Tecnológico
El sistema está construido con las siguientes tecnologías principales:
-
Frontend: Angular 21.x (4 aplicaciones independientes)
-
Backend: Node.js con Express.js
-
Base de datos: PostgreSQL (Cloud SQL)
-
Almacenamiento/Caché: Redis
-
Mensajería: Apache Kafka
-
Autenticación: Firebase Authentication
-
API REST:
api/index.js -
Realtime: Sistema Relay con Socket.io
-
Infraestructura: Caddy (reverse proxy), PM2 (process manager), Firebase Hosting
1.2 Modelo Arquitectónico
El sistema sigue una arquitectura basada en el modelo OSI (Open Systems Interconnection) de 7 capas, adaptado para aplicaciones web modernas. Esta estructura permite una separación clara de responsabilidades y facilita la escalabilidad, mantenibilidad y seguridad del sistema.
2. Arquitectura por Capas (Modelo OSI)
2.1 Capa 7: Aplicación (Application Layer)
La capa de aplicación contiene la lógica de negocio y las interfaces de usuario del sistema.
2.1.1 Frontend - Aplicaciones Angular
El frontend está organizado en 4 aplicaciones Angular independientes, cada una diseñada para un rol específico:
- Aplicación Principal (
src/) -
Interfaz para usuarios finales (clientes)
Rol:
user(cliente)Funcionalidades: * Dashboard personalizado * Gestión de reservas * Visualización de canchas disponibles * Perfil de usuario * Historial de pagos * Configuración
- Panel de Operador (
projects/panel/) -
Gestión operativa diaria
Roles:
operator,adminFuncionalidades: * Gestión de reservas del día * Administración de canchas * Gestión de clientes * Procesamiento de pagos * Reportes operativos
- Panel de Entrenador (
projects/trainer/) -
Gestión de clases y alumnos
Rol:
trainerFuncionalidades: * Gestión de clases * Alumnos e inscripciones * Registro de asistencia * Dashboard de entrenador
- Panel de Super Administrador (
projects/sudo/) -
Control total del sistema
Rol:
sudoFuncionalidades: * Gestión de usuarios y roles * Configuración del sistema * Auditoría * Políticas de acceso
Tecnologías Frontend: * Angular 21.x con componentes standalone * Signals para gestión de estado reactivo * Tailwind CSS para estilos * Service Workers para funcionalidad offline * RxJS para programación reactiva
2.1.2 Backend - API REST
El backend está implementado con Express.js:
Estructura de Rutas:
/api
├── /admin/* - Operaciones administrativas (operator, admin, sudo)
├── /account/* - Operaciones de cuenta de usuario (user)
├── /trainer/* - Operaciones de entrenador (trainer)
├── /sudo/* - Operaciones de super usuario (sudo)
├── /public/* - Endpoints públicos (sin autenticación)
├── /webhooks/* - Webhooks externos
└── /api-docs - Documentación Swagger
Middleware:
* authenticateFirebaseToken: Verificación de tokens JWT
* requireAdminAccess: Control de acceso para admin/operator/sudo
* requireSudoAccess: Control de acceso solo para sudo
* requireAccountAccess: Control de acceso para usuarios regulares
* requireTrainerAccess: Control de acceso para entrenadores
Servicios Backend:
* UserSyncService: Sincronización de usuarios Firebase con PostgreSQL
* RelayHelper: Sistema de notificaciones en tiempo real
* Pool de conexiones PostgreSQL optimizado
2.1.3 Sistema Realtime (Relay)
Arquitectura Relay:
El sistema utiliza Relay (implementado con Socket.io) para notificaciones y comunicación en tiempo real. Relay es un gateway inmutable y agnóstico que permite a los clientes definir su propia lógica de negocio.
Componentes del Sistema Relay:
-
Socket.io Server:
-
Servidor WebSocket basado en Socket.io
-
Namespace
/realtimepara todas las conexiones -
Autenticación mediante Bearer Token
-
Soporte para múltiples transportes (websocket, polling)
-
-
Redis Adapter:
-
Escalado horizontal mediante Redis
-
Distribución de mensajes entre múltiples instancias
-
Caché de sesiones WebSocket
-
Sistema pub/sub para notificaciones
-
Configurado mediante variable de entorno
REDIS_URL
-
-
Apache Kafka:
-
Cola de mensajes para procesamiento asíncrono
-
Streaming de eventos del sistema Relay
-
Persistencia de mensajes para garantizar entrega
-
Procesamiento de eventos en tiempo real
-
Topics para diferentes tipos de eventos
-
-
RelayHelper:
-
Clase helper para emitir eventos desde rutas Express
-
Métodos principales:
-
notificar(data, destino): Envía notificaciones -
mensaje(data, destino): Envía mensajes -
notificarUsuario(userId, data): Notifica a usuario específico -
mensajeRoom(room, data): Envía mensaje a sala específica
-
API Relay (Inmutable):
El sistema Relay implementa una API inmutable con 4 eventos y 4 destinos:
Eventos:
* identificar: Identificación de usuario en el sistema
* unirse: Unirse a una sala (room) específica
* notificar: Envío de notificaciones en tiempo real
* relay: Mensajería general en tiempo real
Destinos:
* yo: Mensaje al mismo socket que emite
* ustedes: Broadcast a todos los demás sockets (excepto el emisor)
* nosotros: Broadcast a todos los sockets conectados
* room: Mensaje a una sala específica (requiere room en data)
2.1.4 Almacenamiento de Datos
PostgreSQL (Cloud SQL):
PostgreSQL almacena todas las entidades del modelo de datos:
-
Todas las entidades del modelo de datos (RESERVATION, PAYMENT, CLIENT, etc.)
-
Relaciones entre entidades mediante claves foráneas
-
Índices para optimizar consultas de disponibilidad
-
Transacciones para garantizar consistencia de datos
-
Connection pooling para optimización de conexiones
Ver Modelo de Datos para más detalles.
Redis:
Redis es utilizado por el sistema Relay para:
-
Caché de sesiones WebSocket: Almacenamiento de sesiones activas
-
Adapter para Socket.io: Distribución de mensajes entre múltiples instancias del servidor Relay
-
Escalado horizontal: Permite que múltiples instancias de Relay compartan estado
-
Pub/Sub: Sistema de publicación/suscripción para notificaciones en tiempo real
-
Configuración: Mediante variable de entorno
REDIS_URL
Apache Kafka:
Kafka es utilizado por el sistema Relay para:
-
Cola de mensajes: Procesamiento asíncrono de eventos del sistema Relay
-
Streaming de eventos: Captura y procesamiento de eventos en tiempo real
-
Persistencia de mensajes: Almacenamiento temporal de mensajes para garantizar entrega
-
Escalabilidad: Permite procesar grandes volúmenes de mensajes en tiempo real
-
Integración con Relay: Los eventos del sistema Relay se publican en topics de Kafka para procesamiento posterior
2.2 Capa 6: Presentación (Presentation Layer)
Serialización de Datos:
* JSON para intercambio de datos entre frontend y backend
* Content-Type: application/json; charset=utf-8
* Validación y sanitización de datos de entrada
Cifrado y Seguridad:
* HTTPS/TLS para todas las comunicaciones
* Certificados SSL gestionados por Firebase Hosting y Caddy
* Headers de seguridad:
* X-Content-Type-Options: nosniff
* X-Frame-Options: DENY
* X-XSS-Protection: 1; mode=block
* Referrer-Policy: strict-origin-when-cross-origin
* Strict-Transport-Security (HSTS)
Compresión: * Gzip/Brotli para compresión de respuestas HTTP * Optimización automática por Firebase Hosting y Caddy
2.3 Capa 5: Sesión (Session Layer)
Gestión de Sesiones:
* Firebase Authentication para autenticación de usuarios
* JWT (JSON Web Tokens) para gestión de sesiones
* Tokens Bearer en header Authorization: Bearer <token>
* Verificación de tokens mediante Firebase Admin SDK
* Renovación automática de tokens expirados
* Custom Claims para roles y permisos:
* operator: Operador/Recepcionista
* admin: Administrador
* sudo: Super Usuario
* trainer: Entrenador
* user: Usuario regular (implícito)
Sesiones WebSocket (Realtime):
* Socket.io para conexiones WebSocket persistentes
* Sistema Relay para notificaciones en tiempo real
* Namespace /realtime para eventos en vivo
* Autenticación de sockets mediante Bearer Token
Middleware de Autenticación:
* authenticateFirebaseToken: Verificación de tokens JWT en cada request
* Extracción de claims (roles) del token decodificado
* Validación de expiración y formato del token
* Manejo de errores de autenticación (401 Unauthorized)
Middleware de Autorización:
* requireAdminAccess: Control de acceso para roles operator, admin, sudo
* requireSudoAccess: Control de acceso exclusivo para rol sudo
* requireAccountAccess: Control de acceso para usuarios regulares (sin roles administrativos)
* requireTrainerAccess: Control de acceso para rol trainer
* Validación de permisos antes de procesar requests (403 Forbidden)
2.4 Capa 4: Transporte (Transport Layer)
Protocolos de Transporte: * HTTP/1.1 y HTTP/2 para comunicación REST * WebSocket (WS/WSS) para comunicación en tiempo real * TCP para conexiones persistentes
Balanceo de Carga: * Caddy como reverse proxy y load balancer * Balanceo de carga entre instancias de Node.js * Terminación SSL/TLS automática * Health checks para instancias backend * Rate limiting y protección DDoS * Configuración automática de certificados Let’s Encrypt * Routing inteligente basado en paths y headers
Gestión de Procesos Backend: * PM2 para gestión del servicio Node.js * Gestión de procesos Node.js en producción * Auto-restart en caso de fallos * Balanceo de carga entre instancias PM2 * Monitoreo de recursos (CPU, memoria) * Logs centralizados * Zero-downtime deployments * Cluster mode para aprovechar múltiples cores
2.5 Capa 3: Red (Network Layer)
Protocolo IP:
* IPv4 e IPv6
* DNS para resolución de nombres de dominio
* Dominios configurados:
* app.unosportclub.com.co - Aplicación principal
* panel.unosportclub.com.co - Panel de operador
* trainer.unosportclub.com.co - Panel de entrenador
* control.unosportclub.com.co - Panel de control
Firebase Hosting: * CDN global para distribución de contenido estático * Caché inteligente de assets * Redirecciones y rewrites configurables
3. Componentes del Sistema
3.1 Frontend (Angular)
El frontend está organizado en 4 aplicaciones independientes:
-
src/- Aplicación pública para clientes finales (reservas y autogestión) -
projects/panel/- Panel de administración / recepción (backoffice operativo) -
projects/trainer/- Panel del Entrenador, centrado en clases, alumnos e inscripciones -
projects/sudo/- Panel de Super Usuario (configuración, usuarios, políticas, auditoría)
Características: * Componentes reutilizables * Servicios de comunicación con API REST * Guards e interceptores para autenticación y autorización basada en rol * Signals para gestión de estado reactivo * Lazy loading para optimización de bundles
3.2 Backend (Node.js/Express)
El backend está implementado con Node.js y Express.js:
-
api/index.js- Punto de entrada principal de la API REST -
Express.js para manejo de rutas y middleware
-
Conexión a PostgreSQL mediante driver nativo
-
Autenticación mediante Firebase Auth tokens
-
Webhooks para recibir notificaciones de pagos
-
Swagger/OpenAPI para documentación interactiva
Organización por Namespaces:
* /admin/ - Operaciones administrativas
* /account/ - Operaciones de cuenta de usuario
* /trainer/ - Operaciones de entrenador
* /sudo/ - Operaciones de super usuario
* /public/ - Endpoints públicos
* /webhooks/ - Webhooks externos
3.3 Almacenamiento de Datos
PostgreSQL: Almacena todas las entidades del modelo de datos (RESERVATION, PAYMENT, CLIENT, etc.), relaciones mediante claves foráneas, índices para optimizar consultas, transacciones ACID y connection pooling optimizado.
Redis: Utilizado por el sistema Relay para caché de sesiones WebSocket, adapter para Socket.io, escalado horizontal y sistema pub/sub.
Apache Kafka: Utilizado por el sistema Relay para cola de mensajes, streaming de eventos, persistencia de mensajes y procesamiento asíncrono de eventos.
4. Estructura del Proyecto
unosportclub/
├── src/ # Aplicación principal (Cliente)
│ └── app/
│ ├── pages/ # Páginas de la aplicación
│ ├── services/ # Servicios Angular
│ ├── components/ # Componentes reutilizables
│ ├── guards/ # Route guards
│ └── interceptors/ # HTTP interceptors
├── projects/
│ ├── panel/ # Panel de Operador/Admin
│ ├── trainer/ # Panel de Entrenador
│ └── sudo/ # Panel de Super Admin
├── functions/
│ ├── api/
│ │ └── index.js # API REST principal
│ ├── db/ # Utilidades de base de datos
│ ├── routes/ # Rutas organizadas por namespace
│ ├── relay/ # Sistema Relay (Socket.io)
│ └── utils/ # Utilidades
├── docs/ # Documentación
└── ...
5. Flujos de Datos
5.1 Flujo de Autenticación
-
Usuario ingresa credenciales en frontend
-
Frontend llama a Firebase Auth
-
Firebase Auth valida y retorna token JWT
-
Frontend almacena token
-
Frontend envía token en header
Authorization: Bearer <token> -
Backend verifica token con Firebase Admin SDK
-
Backend extrae claims (roles) del token
-
Middleware valida permisos según ruta
-
Si autorizado, procesa request
-
Retorna respuesta al frontend
5.2 Flujo de Reserva
-
Usuario selecciona tipo de cancha
-
Frontend consulta disponibilidad (
/account/courts) -
Backend consulta PostgreSQL para disponibilidad
-
Usuario selecciona fecha/hora
-
Frontend valida disponibilidad localmente
-
Usuario completa detalles de reserva
-
Frontend envía creación de reserva (
/account/bookings) -
Backend valida disponibilidad en BD
-
Backend crea reserva en transacción
-
Backend notifica vía Relay (si está habilitado)
-
Frontend actualiza UI con nueva reserva
5.3 Flujo de Pago
-
Usuario inicia proceso de pago
-
Frontend consulta tipos de pago (
/account/payment-types) -
Usuario selecciona tipo y completa datos
-
Frontend envía pago (
/account/payments) -
Backend procesa pago
-
Backend actualiza estado de reserva relacionada
-
Backend notifica vía Relay
-
Frontend actualiza UI
5.4 Flujo de Registro
-
Usuario completa formulario de registro
-
Frontend valida datos localmente
-
Frontend llama a
AuthService.register() -
Se crea usuario en Firebase Auth
-
Se obtiene token JWT
-
Frontend llama a
/account/clientcon token -
Backend crea registro en PostgreSQL
-
Backend sincroniza con tabla
user -
Frontend redirige a dashboard
6. Seguridad
6.1 Autenticación
-
Firebase Auth maneja la autenticación de usuarios
-
Tokens JWT para sesiones
-
Validación de tokens en cada petición a la API
-
Refresh tokens para renovación automática
-
Bearer Token Authentication mediante header
Authorization: Bearer <token>
6.2 Autorización
-
Roles y permisos por usuario (OPERATOR, ADMIN, SUDO, TRAINER, USER)
-
Validación en backend
-
Guards en frontend (Angular)
-
Verificación de permisos antes de operaciones sensibles
-
Middleware de autorización por namespace
Sistema de Roles:
* operator: Operador/Recepcionista
* admin: Administrador
* sudo: Super Usuario
* trainer: Entrenador
* user: Usuario regular (implícito, sin claim)
6.3 Base de Datos
-
Conexiones seguras mediante SSL/TLS
-
Prepared statements para prevenir SQL injection
-
Validación de datos en múltiples capas
-
Transacciones para operaciones críticas
-
Connection pooling optimizado
6.4 Protección contra Ataques Comunes
-
SQL Injection: Prevenido mediante prepared statements
-
XSS (Cross-Site Scripting): Prevenido mediante sanitización y Content Security Policy
-
CSRF (Cross-Site Request Forgery): Protegido por Firebase Auth y SameSite cookies
-
DDoS: Rate limiting mediante Caddy
-
Man-in-the-Middle: Prevenido mediante HTTPS/TLS obligatorio
7. Escalabilidad
7.1 Frontend
-
Lazy Loading: Carga diferida de módulos
-
Code Splitting: División automática de bundles
-
Service Workers: Caché y funcionalidad offline
-
Optimización de Imágenes: NgOptimizedImage
-
CDN: Firebase Hosting con distribución global
7.2 Backend
-
PM2 Cluster Mode: Aprovecha múltiples cores del servidor
-
Connection Pooling: Pool de conexiones PostgreSQL optimizado
-
Caching: Caché de consultas frecuentes (disponibilidad) mediante Redis
-
Rate Limiting: Límites de requests configurables mediante Caddy
-
Caddy Load Balancing: Distribución de carga entre instancias
-
Auto-scaling: Escalado horizontal mediante PM2 y Caddy
7.3 Base de Datos
-
Índices: Optimización de consultas frecuentes
-
Transacciones: Consistencia de datos ACID
-
Escalado Vertical/Horizontal: PostgreSQL escalable (Cloud SQL)
-
Connection Pooling: Gestión eficiente de conexiones
-
Backups Automáticos: Cloud SQL gestiona backups automáticos
7.4 Sistema Realtime
-
Redis Adapter: Distribución de mensajes entre múltiples instancias del servidor Relay
-
Apache Kafka: Procesamiento asíncrono de eventos y streaming de mensajes
-
Load Balancing: Caddy distribuye conexiones WebSocket entre instancias
-
Escalado Horizontal: Redis y Kafka permiten escalar el sistema Relay horizontalmente
-
TODO: Implementar métricas de conexiones activas y monitoreo
8. Integraciones
8.1 Gateway de Pagos
-
Webhook para recibir notificaciones de pagos
-
Procesamiento asíncrono de pagos huérfanos
-
Alineación automática de pagos con reservas
-
TODO: Documentar integración específica de gateway de pagos
9. Infraestructura de Despliegue
9.1 Arquitectura con Caddy y PM2
Internet
↓
Caddy (Reverse Proxy + Load Balancer)
├── SSL/TLS Termination
├── Health Checks
└── Load Balancing
↓
PM2 Cluster Mode
├── Instance 1 (Core 0) → Node.js Server :3000
├── Instance 2 (Core 1) → Node.js Server :3001
├── Instance 3 (Core 2) → Node.js Server :3002
└── Instance N (Core N) → Node.js Server :300N
↓
Express.js Application
├── Routes Handlers
├── Middleware (Auth, Security)
└── Services
↓
PostgreSQL Database (Cloud SQL)
9.2 Caddy - Reverse Proxy y Load Balancer
Características: * Terminación SSL/TLS automática * Certificados Let’s Encrypt automáticos * Health checks para instancias backend * Rate limiting y protección DDoS * Routing inteligente basado en paths y headers * Balanceo de carga entre múltiples instancias PM2
10. Diagrama de Arquitectura
┌─────────────────────────────────────────────────────────────┐
│ CAPA 7: APLICACIÓN │
├─────────────────────────────────────────────────────────────┤
│ Frontend Angular (4 aplicaciones) │
│ ├── src/ (Cliente) │
│ ├── projects/panel/ (Operador) │
│ ├── projects/trainer/ (Entrenador) │
│ └── projects/sudo/ (Super Admin) │
│ │
│ Backend Express.js │
│ └── /api/* (Rutas REST organizadas por namespace) │
│ │
│ Sistema Relay (Socket.io) │
│ └── /realtime (WebSocket para notificaciones) │
└─────────────────────────────────────────────────────────────┘
│
│ HTTP/REST + WebSocket
│
┌─────────────────────────────────────────────────────────────┐
│ CAPA 4: TRANSPORTE │
├─────────────────────────────────────────────────────────────┤
│ Caddy (Reverse Proxy + Load Balancer) │
│ ├── SSL/TLS Termination │
│ ├── Health Checks │
│ └── Rate Limiting │
│ │
│ PM2 (Process Manager) │
│ ├── Cluster Mode │
│ ├── Auto-restart │
│ └── Zero-downtime Deployments │
└─────────────────────────────────────────────────────────────┘
│
│ TCP/IP
│
┌─────────────────────────────────────────────────────────────┐
│ CAPA 3: RED │
├─────────────────────────────────────────────────────────────┤
│ Firebase Hosting (CDN Global) │
│ └── DNS: app.unosportclub.com.co │
└─────────────────────────────────────────────────────────────┘
│
│
┌─────────────────────────────────────────────────────────────┐
│ CAPA 5: SESIÓN │
├─────────────────────────────────────────────────────────────┤
│ Firebase Authentication │
│ ├── JWT Tokens │
│ ├── Custom Claims (Roles) │
│ └── Token Verification │
└─────────────────────────────────────────────────────────────┘
│
│
┌─────────────────────────────────────────────────────────────┐
│ CAPA 7: APLICACIÓN (BD) │
├─────────────────────────────────────────────────────────────┤
│ PostgreSQL (Cloud SQL) │
│ ├── Connection Pooling │
│ ├── Transactions (ACID) │
│ └── Indexes │
│ │
│ Redis │
│ ├── Caché de sesiones WebSocket │
│ ├── Socket.io Adapter │
│ └── Pub/Sub para Relay │
│ │
│ Apache Kafka │
│ ├── Cola de mensajes │
│ ├── Streaming de eventos │
│ └── Procesamiento asíncrono │
└─────────────────────────────────────────────────────────────┘