Manual de Integración

Este manual proporciona información sobre integración, instalación y configuración del sistema UnoSportClub (v0.4.1).

UnoSportClub es una plataforma para gestión de clubes deportivos: monorepo Angular 21 + Express 5, OAuth2 local y PostgreSQL. Cinco SPAs (cliente, panel, trainer, sudo, accounting) comparten API en functions/server.js.

Arquitectura del Sistema

Componentes Principales

Frontend (Angular 21)

  • App cliente (src/, puerto 6100)

  • Panel operador (projects/panel/, 6101)

  • Panel entrenador (projects/trainer/, 6102)

  • Panel sudo (projects/sudo/, 6103)

  • Contabilidad (projects/accounting/, 6104)

Backend (Express 5, Node >= 24)

  • API REST bajo /api

  • OAuth2 local OIDC + JWT RS256

  • PostgreSQL principal + DB_NAME_ACCOUNTING

Infraestructura (v0.4)

  • Imagen Docker unificada → GHCR

  • Nginx por virtual host dentro del contenedor

  • Caddy opcional para TLS en borde

Flujo de Datos

  1. El usuario accede a una SPA (desarrollo: npm run dev:serve; producción: DNS → contenedor)

  2. Login OAuth2 local; el cliente guarda JWT

  3. Peticiones a /api/* con Authorization: Bearer

  4. Express valida JWT y consulta PostgreSQL

  5. Respuesta JSON al cliente

Estructura del Proyecto

unosportclub/
├── src/                  # App cliente
├── projects/             # panel, trainer, sudo, accounting, common
├── functions/            # API Express, migraciones, OAuth2
├── docs/                 # Antora (este manual)
├── docker/               # Imagen unificada
└── Dockerfile

Instalación y Configuración

Resumen

  1. git clone del monorepo (sin submódulos)

  2. npm install

  3. Configurar functions/.env (ver functions/.env.example)

  4. npm run db:migrate y node functions/db/install-accounting.js si aplica

  5. Desarrollo: npm run dev:serve

  6. Producción: Despliegue con Docker

Variables de entorno

PostgreSQL

DB_HOST=localhost
DB_PORT=5432
DB_NAME=postgres
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME_ACCOUNTING=postgres
DB_SSL=false

OAuth2 local (requerido)

OAUTH2_ISSUER_BASE_URL=http://localhost:6000/
OAUTH2_ISSUER_ID=unosportclub
OAUTH2_AUDIENCE=unosportclub
OAUTH2_CLIENT_ID=...
OAUTH2_CLIENT_SECRET=...

Claves RSA en functions/ssl/ para firma JWT. No se requiere FIREBASE_PROJECT_ID.

Opcional

  • BOT_API_KEYS, SMTP, Pusher, Redis/Kafka (Relay)

Integración de Componentes

Comunicación Frontend-Backend

El frontend llama a /api (proxy en dev o nginx en producción):

private http = inject(HttpClient);
getData() {
  return this.http.get('/api/admin/example');
}

Autenticación

Interceptor HTTP añade Authorization: Bearer <access_token> obtenido del flujo OAuth2 local.

Despliegue

Detalle completo: Despliegue con Caddy y Docker

Apéndice: referencia legado pre-v0.4

Las secciones siguientes de este archivo pueden mencionar Firebase Hosting, emuladores o firebase deploy. No aplican a v0.4.1; se conservan solo como histórico.

Entornos (referencia histórica)

Production

  • app.unosportclub.com.co - Aplicación principal

  • panel.unosportclub.com.co - Panel de operador

  • entrenador.unosportclub.com.co - Panel de entrenador

  • control.unosportclub.com.co - Panel de super administrador

  • Base de datos: Cloud SQL externa (PostgreSQL)

  • Imágenes: Tags específicos de versión

Staging

  • Dominios:

  • app.staging.unosportclub.com.co

  • panel.staging.unosportclub.com.co

  • entrenador.staging.unosportclub.com.co

  • control.staging.unosportclub.com.co

  • Base de datos: PostgreSQL en contenedor Docker

  • Imágenes: Tag staging

QA

  • Dominios:

  • app.qa.unosportclub.com.co

  • panel.qa.unosportclub.com.co

  • entrenador.qa.unosportclub.com.co

  • contabilidad.* — SPA accounting (v0.4)

  • Base de datos: PostgreSQL en contenedor Docker

  • Imágenes: Tag staging

Desarrollo Local

El sistema puede ejecutarse localmente de dos formas:

Opción 1: Desarrollo local (recomendado)

npm run dev:serve

Levanta API (:6000) y las cinco SPAs (:6100:6104).

Opción 2: Desarrollo local con Docker (pruebas completas)

Para ejecutar el sistema completo localmente usando Docker, puedes crear un archivo docker-compose.local.yml:

version: '3.8'

services:
  # Base de datos local
  unosport-db-local:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: unosportclub_local
      POSTGRES_USER: unosport_admin
      POSTGRES_PASSWORD: local_password
    ports:
      - "5432:5432"
    volumes:
      - unosport_db_local:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U unosport_admin"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - unosport_local

  # Backend local (desde código fuente)
  unosport-backend-local:
    build:
      context: .
      dockerfile: Dockerfile.functions
    restart: unless-stopped
    depends_on:
      unosport-db-local:
        condition: service_healthy
    environment:
      NODE_ENV: development
      DATABASE_URL: postgresql://unosport_admin:local_password@unosport-db-local:5432/unosportclub_local
      DB_HOST: unosport-db-local
      DB_PORT: 5432
      DB_NAME: unosportclub_local
      DB_USER: unosport_admin
      DB_PASSWORD: local_password
      DB_SSL: "false"
      PORT: 6000
      HOST: 0.0.0.0
    ports:
      - "6000:6000"
    volumes:
      - ./functions:/app
      - /app/node_modules
    command: >
      sh -c "
        cd /app &&
        npm install &&
        node db/install.js &&
        node server_wrapper.js
      "
    networks:
      - unosport_local

  # Frontend - Aplicación Principal
  unosport-app-local:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        PROJECT: unosportclub
    restart: unless-stopped
    ports:
      - "6100:80"
    environment:
      API_URL: http://unosport-backend-local:6000
    networks:
      - unosport_local

  # Frontend - Panel
  unosport-panel-local:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        PROJECT: panel
    restart: unless-stopped
    ports:
      - "6101:80"
    environment:
      API_URL: http://unosport-backend-local:6000
    networks:
      - unosport_local

networks:
  unosport_local:

volumes:
  unosport_db_local:
Requisitos Previos

Antes de usar Docker localmente, asegúrate de tener instalado:

  • Docker: Versión 20.10 o superior

  • Docker Compose: Versión 2.0 o superior

Verifica la instalación:

docker --version
docker-compose --version
Configuración Inicial
  1. Crear archivo de configuración Docker Compose:

Crea un archivo docker-compose.local.yml en la raíz del proyecto con la configuración mostrada arriba.

  1. Configurar variables de entorno:

Crea un archivo .env.local en la raíz del proyecto:

# Base de datos local
DB_NAME=unosportclub_local
DB_USER=unosport_admin
DB_PASSWORD=local_password

# Backend
PORT=6000
NODE_ENV=development
  1. Iniciar servicios:

# Construir e iniciar todos los servicios
docker-compose -f docker-compose.local.yml up -d --build

# Ver logs de todos los servicios
docker-compose -f docker-compose.local.yml logs -f

# Ver logs de un servicio específico
docker-compose -f docker-compose.local.yml logs -f unosport-backend-local
Acceso a los Servicios

Una vez iniciados los servicios, estarán disponibles en:

Gestión de Base de Datos Local

Ejecutar migraciones manualmente:

# Ejecutar migraciones dentro del contenedor
docker-compose -f docker-compose.local.yml exec unosport-backend-local sh -c "cd /app && node db/install.js"

Acceder a la base de datos:

# Conectarse a PostgreSQL
docker-compose -f docker-compose.local.yml exec unosport-db-local psql -U unosport_admin -d unosportclub_local

# O desde fuera del contenedor (si tienes psql instalado)
psql -h localhost -U unosport_admin -d unosportclub_local
# Password: local_password

Ver estado de migraciones:

docker-compose -f docker-compose.local.yml exec unosport-db-local psql -U unosport_admin -d unosportclub_local -c "SELECT * FROM schema_migrations ORDER BY id;"

Resetear base de datos:

# Detener servicios
docker-compose -f docker-compose.local.yml down

# Eliminar volumen de base de datos (CUIDADO: elimina todos los datos)
docker volume rm unosportclub_unosport_db_local

# Reiniciar servicios (creará nueva base de datos)
docker-compose -f docker-compose.local.yml up -d
Desarrollo con Hot Reload

Para desarrollo con recarga automática, puedes montar el código fuente como volumen:

volumes:
  - ./functions:/app
  - /app/node_modules  # Evita sobrescribir node_modules del contenedor

Luego usa herramientas como nodemon o node --watch en el contenedor:

# Modificar el comando en docker-compose para usar nodemon
command: >
  sh -c "
    cd /app &&
    npm install &&
    npx nodemon server_wrapper.js
  "
Comandos Útiles

Ver estado de servicios:

docker-compose -f docker-compose.local.yml ps

Reiniciar un servicio:

docker-compose -f docker-compose.local.yml restart unosport-backend-local

Detener todos los servicios:

docker-compose -f docker-compose.local.yml down

Detener y eliminar volúmenes:

docker-compose -f docker-compose.local.yml down -v

Reconstruir un servicio específico:

docker-compose -f docker-compose.local.yml build --no-cache unosport-backend-local
docker-compose -f docker-compose.local.yml up -d unosport-backend-local

Ver logs en tiempo real:

# Todos los servicios
docker-compose -f docker-compose.local.yml logs -f

# Servicio específico
docker-compose -f docker-compose.local.yml logs -f unosport-backend-local

# Últimas 100 líneas
docker-compose -f docker-compose.local.yml logs --tail=100 unosport-backend-local

Ejecutar comandos dentro del contenedor:

# Shell interactivo en el contenedor de backend
docker-compose -f docker-compose.local.yml exec unosport-backend-local sh

# Ejecutar comando específico
docker-compose -f docker-compose.local.yml exec unosport-backend-local npm test
Solución de Problemas Comunes

Error: Puerto ya en uso

Si un puerto está ocupado, puedes cambiarlo en docker-compose.local.yml:

ports:
  - "6001:6000"  # Cambiar puerto externo

Error: Base de datos no conecta

Verifica que el servicio de base de datos esté saludable:

docker-compose -f docker-compose.local.yml ps unosport-db-local
docker-compose -f docker-compose.local.yml logs unosport-db-local

Error: Permisos en volúmenes

En Linux, puede ser necesario ajustar permisos:

sudo chown -R $USER:$USER ./functions

Limpiar todo y empezar de nuevo:

# Detener y eliminar contenedores, redes y volúmenes
docker-compose -f docker-compose.local.yml down -v

# Limpiar imágenes no utilizadas
docker system prune -a

# Reconstruir e iniciar
docker-compose -f docker-compose.local.yml up -d --build

Despliegue con Docker Compose

Para desplegar en servidor con Docker Compose:

# Iniciar todos los servicios
docker-compose up -d

# Actualizar servicios específicos
docker-compose pull unosport-backend
docker-compose up -d unosport-backend

# Ver logs
docker-compose logs -f unosport-backend

# Reiniciar servicios
docker-compose restart unosport-backend

Para más detalles sobre el despliegue con Docker y Caddy, consulta: Despliegue con Caddy y Docker

Gestión de Base de Datos

Migraciones

Las migraciones se ejecutan automáticamente durante npm install o manualmente:

npm run db:migrate

Seeders

Los seeders cargan datos iniciales:

npm run db:seed

Reset de Base de Datos

Para resetear completamente la base de datos (CUIDADO):

npm run db:reset

Monitoreo y Logs

Logs de Firebase Functions

Ver logs en tiempo real:

firebase functions:log --follow

Ver logs de una función específica:

firebase functions:log --only api

Verificación de Estado

Listar todas las funciones desplegadas:

firebase functions:list

Seguridad

Autenticación

  • Todos los endpoints requieren autenticación (excepto endpoints públicos)

  • Los tokens JWT se validan en cada petición

  • Los custom claims determinan los permisos

Autorización

El sistema implementa control de acceso basado en roles (RBAC):

  • Cada endpoint verifica el rol del usuario

  • Los middlewares validan los permisos antes de procesar las peticiones

Variables Sensibles

Las variables sensibles (como credenciales de base de datos) deben almacenarse usando Firebase Secret Manager en producción.

Solución de Problemas Comunes

Error de Conexión a Base de Datos

  • Verifica que PostgreSQL esté corriendo

  • Verifica las credenciales en functions/.env

  • Verifica que el firewall permita conexiones

  • Para bases de datos en la nube, verifica la configuración de SSL

Error de Autenticación

  • Verifica que OAuth2 local authentication esté configurado

  • Verifica que los custom claims estén asignados correctamente

  • Revisa los logs de Firebase Functions para más detalles

Error de Build

  • Verifica que todas las dependencias estén instaladas: npm install

  • Verifica la versión de Node.js (debe ser 22 o superior)

  • Revisa los errores de TypeScript: npm run build

Próximos Pasos

Una vez completada la integración:

  1. Revisa la Documentación del Desarrollador

  2. Consulta la Referencia de API

  3. Configura dominios personalizados si es necesario

  4. Configura monitoreo y alertas

Actualización del Sistema

Proceso de Actualización

Para actualizar el sistema a una nueva versión:

  1. Backup: Realiza un backup completo antes de actualizar

  2. Revisa el changelog: Consulta los cambios en la nueva versión

  3. Actualiza código: git pull o descarga la nueva versión

  4. Actualiza dependencias: npm install en el proyecto principal y functions/

  5. Ejecuta migraciones: npm run db:migrate si hay nuevas migraciones

  6. Reconstruye: npm run build:all

  7. Despliega: npm run deploy:firebase

  8. Verifica: Prueba las funcionalidades principales

Migraciones de Base de Datos

Si hay nuevas migraciones:

  • Revisa las migraciones antes de ejecutarlas

  • Prueba en un entorno de desarrollo primero

  • Realiza backup antes de ejecutar migraciones

  • Verifica que las migraciones se completen correctamente

Actualización de Dependencias

Para actualizar dependencias:

# Actualizar dependencias del proyecto principal
npm update

# Actualizar dependencias de Functions
cd functions
npm update
cd ..
Prueba siempre las actualizaciones en un entorno de desarrollo antes de producción.

Mantenimiento Regular

Tareas de Mantenimiento Diarias

  • Revisar logs de errores

  • Verificar que los backups se ejecuten correctamente

  • Monitorear el uso de recursos

  • Revisar métricas de rendimiento

Tareas de Mantenimiento Semanales

  • Revisar y limpiar logs antiguos

  • Verificar la integridad de backups

  • Analizar métricas de uso

  • Revisar actualizaciones de seguridad

Tareas de Mantenimiento Mensuales

  • Actualizar dependencias (si es necesario)

  • Revisar y optimizar la base de datos

  • Analizar costos de Firebase

  • Revisar y actualizar documentación

Monitoreo y Alertas

Configurar Monitoreo

Configura monitoreo para:

  • Errores críticos: Alertas inmediatas para errores críticos

  • Rendimiento: Monitoreo de tiempos de respuesta

  • Disponibilidad: Verificación de que los servicios estén disponibles

  • Recursos: Monitoreo de uso de CPU, memoria, almacenamiento

Alertas Recomendadas

Configura alertas para:

  • Errores en Functions

  • Tiempos de respuesta altos

  • Fallos en conexión a base de datos

  • Backups fallidos

  • Uso de recursos alto