← /projects

Completed

Intranet Arousa Fútbol 7

Panel de Gestión Deportiva Full-Stack

Intranet AF7 es una aplicación web de administración interna desarrollada íntegramente para Arousa Fútbol 7. El objetivo era reemplazar un ecosistema disperso de hojas de cálculo, correos y herramientas de terceros por una única plataforma centralizada que cubriera todas las operaciones del evento: gestión editorial, logística de viajes, control de acceso por QR, tienda oficial, patrocinadores, colaboradores, redes sociales y monitorización de infraestructura.

AngularTypeScriptRxJSTailwindCSSNode-REDJasmineKarma
Captura de Intranet Arousa Fútbol 7

El problema de partida

La organización gestionaba sus operaciones con herramientas completamente desconectadas entre sí. Las inscripciones de equipos llegaban por formularios web y se volcaban manualmente a hojas de cálculo. Las acreditaciones de prensa se imprimían a mano. Los tickets de entrada se vendían por una plataforma externa sin ningún control interno. Los patrocinadores y sus comisiones se seguían en Excel. No había visibilidad del estado de los vuelos de los equipos participantes ni de la disponibilidad del equipo organizador. Cada área trabajaba en su silo.

El reto no era solo técnico: había que diseñar una arquitectura que permitiera a perfiles muy distintos (administradores, editores de contenido, personal de logística, controladores de acceso, responsables de redes sociales) trabajar sobre la misma plataforma con acceso restringido a sus áreas y sin interferir entre sí.

Arquitectura y decisiones técnicas

La aplicación es un monolito Angular con routing centralizado y carga eager de todos los componentes. Esta decisión fue deliberada: el equipo de usuarios es reducido y la prioridad era la velocidad de desarrollo y el mantenimiento sencillo, no la optimización de bundle para usuarios anónimos. El backend es Strapi CMS (headless), que actúa como fuente de verdad para todos los datos y expone una API REST que la aplicación consume a través de un servicio centralizado (`StrapiService`) con más de 1.000 líneas de métodos tipados.

El control de acceso se implementó con un RoleGuard que intercepta cada navegación, recupera el token JWT de la cookie, llama al endpoint `/users/me?populate=role` de Strapi y compara el rol del usuario con los roles permitidos declarados en los metadatos de cada ruta. Si el rol no coincide, redirige a `/unauthorized`. Los roles disponibles son: `admin`, `editor`, `analista`, `logística`, `control de acceso` y `social media`.

Módulo de Noticias — CMS editorial completo

El módulo de noticias es un CMS editorial completo con creación, edición y eliminación de artículos. El formulario de edición usa Reactive Forms con validaciones en todos los campos: título (máximo 200 caracteres), slug con validación de formato URL, fecha, categoría obligatoria y metadatos SEO.

El slug se genera automáticamente desde el título mediante una función que normaliza caracteres Unicode (NFD), elimina tildes, sustituye ñ y ç, y convierte espacios en guiones. El editor de contenido usa **TinyMCE** con tema oscuro, configurado con plugins de listas, imágenes, tablas y enlaces.

La funcionalidad más destacada de este módulo es la generación de metadatos SEO con OpenAI. Al pulsar un botón, el sistema llama al modelo con un prompt estructurado que incluye el título, la introducción y el cuerpo del artículo, y devuelve entre 8 y 15 palabras clave optimizadas para posicionamiento en buscadores. El token de OpenAI se obtiene dinámicamente desde la configuración de Strapi (no está hardcodeado en el cliente) y se cachea en memoria durante la sesión para evitar llamadas redundantes.

Las imágenes de portada se suben directamente a Strapi mediante `FormData` y se asocian al artículo en el mismo flujo de guardado, con preview en tiempo real antes de confirmar.

Módulo de Gestión de Equipos — Fase Previa y Fase Final

La gestión del torneo se divide en dos fases con módulos independientes.

Fase Previa: gestiona las inscripciones de equipos con un panel de estadísticas que usa ngx-charts para visualizar la distribución de equipos por previa (Previa 1, Previa 2, etc.) y el estado de pagos. Los datos se transforman en tiempo real para agrupar inscripciones por fase y calcular totales. Al hacer clic en un segmento del gráfico de pagos, se abre un modal con el listado detallado de equipos en ese estado, ordenados alfabéticamente.

Fase Final: el módulo más complejo de la aplicación. Cada equipo participante tiene una ficha detallada con múltiples paneles colapsables que gestionan:

  • Confirmación de asistencia: marca el equipo como confirmado en Strapi.
  • Transporte: formulario de edición del tipo de viaje (vuelo, tren, bus) con subformularios específicos para cada modalidad (número de vuelo, horarios, etc.).
  • Hotel: edición inline de nombre del hotel, fechas de entrada/salida y observaciones.
  • Plantilla (Roster): editor dinámico de jugadores y staff técnico, con campos por jugador y por miembro del staff.
  • Contactos: gestión de contactos del equipo.
  • Gestiones: log de gestiones realizadas con el equipo (fecha, persona responsable, comentarios), ordenadas cronológicamente de más reciente a más antigua.
  • Envío al FTF: botón que formatea y envía la plantilla completa al sistema federativo externo (FTF), normalizando nombres propios y mapeando roles a sus IDs federativos.

El módulo de estadísticas de la fase final se conecta a la API del FTF para obtener temporadas disponibles, las combina con años locales calculados dinámicamente (año actual y siguiente, ajustando por mes para determinar la temporada activa), y permite consultar informes por equipo y temporada.

Módulo de Logística — Hoteles, Vuelos y Traslados

Hoteles: gestión de reservas de alojamiento con paginación personalizada, filtros por nombre, email, teléfono y estado de pago. Cada reserva puede contener múltiples habitaciones (individual, doble, triple) con sus huéspedes, fechas y opciones de comida. El módulo incluye un generador de correos HTML estructurados que se envían directamente al hotel con todos los detalles de la reserva formateados, incluyendo un campo de comentarios adicionales que el gestor puede añadir antes de enviar.

Vuelos: el módulo más visualmente impactante de la aplicación. Integra OpenLayers para renderizar un mapa interactivo con tiles de OpenStreetMap. Los equipos que viajan en avión aparecen como marcadores con icono de avión sobre el mapa. Al hacer clic en "Añadir vuelo", el sistema consulta la API de AirLabs con el número de vuelo y, si el vuelo está en ruta, coloca un marcador en las coordenadas GPS actuales del avión con un tooltip que muestra número de vuelo, origen, destino, altitud, velocidad y ETA. Si el vuelo ya ha aterrizado o está programado, muestra el estado correspondiente. Los marcadores se actualizan al volver a consultar, eliminando el anterior antes de añadir el nuevo.

Módulo de Tickets — Venta y Control de Acceso por QR

El módulo de tickets tiene dos partes diferenciadas con acceso por rol.

Gestión de entradas: listado paginado con filtros. Permite crear entradas manualmente con validación completa del formulario. Cada entrada tiene un QR asociado generado por el backend. Desde el panel se puede:

  • Visualizar el QR de la entrada directamente en la interfaz.
  • Confirmar el pago de una entrada.
  • Reenviar la entrada por email: el sistema descarga el archivo QR del servidor como `File`, construye un email HTML personalizado con el nombre del asistente y lo envía con el QR adjunto.
  • Compartir por WhatsApp o Telegram: posibilidad de compartir el archivo QR directamente desde el navegador, con detección de compatibilidad del dispositivo.

Lector QR (módulo de control de acceso): un scanner para activar la cámara del dispositivo y leer códigos QR en tiempo real. Soporta múltiples cámaras con cambio entre ellas. También permite introducción manual del código. Al escanear:

  • 1. Descifra el QR contra el backend para obtener los datos de la entrada.
  • 2. Verifica si la entrada ya fue usada consultando el registro de entradas usadas.
  • 3. Valida que el evento de la entrada coincide con el evento activo del día, calculado dinámicamente a partir de la configuración (fechas de inicio/fin, tipo de evento, división en fases para la previa).
  • 4. Muestra el resultado (entrada válida, ya usada, o evento incorrecto) y permite confirmar el acceso, lo que registra la entrada como usada en el backend.

Módulo de Acreditaciones — Diseño y Envío de Credenciales

El módulo de acreditaciones gestiona las credenciales de prensa y personal para cada evento y edición. Las acreditaciones se filtran por evento (Fase Final, Fase Previa, Indoor) y edición, con ordenación manual por tipo de evento y año descendente.

La funcionalidad central es la generación de credenciales en PDF con diseño gráfico personalizado, construida íntegramente con jsPDF sin ninguna plantilla externa:

Las credenciales se pueden imprimir directamente (abre el diálogo de impresión del navegador) o enviarse por email con el PDF adjunto, generando el documento en el cliente y enviándolo al backend para su distribución. El sistema marca automáticamente la acreditación como enviada tras el primer envío y actualiza el estado en Strapi.

Módulo de Patrocinadores — Gestión Financiera y Comisiones

El módulo de patrocinadores gestiona los contratos de publicidad del evento con un sistema de filtrado avanzado y cálculo de comisiones.

Filtrado: los filtros combinan búsqueda parcial por client, rango de fechas, tipo , estado de pago y colaborador responsable. El sistema de filtros está construido sobre un método genérico en `StrapiService` que serializa cualquier combinación de filtros al formato de query string de Strapi.

Cálculo de totales: además de la paginación estándar, el módulo calcula el importe total de todos los registros que cumplen los filtros activos (no solo la página visible). Esto se implementa con una segunda consulta paralela que itera en páginas de 100 registros para encadenar llamadas hasta agotar los resultados, acumulando el total con `reduce`.

Comisiones: un modal dedicado permite seleccionar un colaborador y ver el total de comisiones generadas, con opción de exportar un informe PDF con tabla formateada, totales calculados y formato de moneda localizado.

Integración con Dolibarr: las publicidades de tipo "factura" pueden tener asociado un número de factura del ERP Dolibarr. Desde la tabla, un botón permite descargar directamente el PDF de la factura desde el sistema ERP.

Módulo de Colaboradores — Disponibilidad y Reuniones

Disponibilidad: panel de gestión de turnos del equipo organizador. Los eventos se crean definiendo un nombre y un rango de fechas; el sistema genera automáticamente franjas de mañana y tarde para cada día del rango para crear todas las entradas en paralelo. La vista muestra una cuadrícula de fechas × franjas con los colaboradores disponibles en cada celda.

La edición de disponibilidad de un colaborador usa un modal con checkboxes para cada franja. Al guardar, el sistema compara el estado actual con el nuevo y solo envía las actualizaciones necesarias (añadir o quitar al colaborador de cada franja), también para paraleliza todas las llamadas. El resultado se exporta a PDF con tablas de doble columna (mañana/tarde) por fecha, con salto de página automático.

Reuniones: gestión del calendario de reuniones del equipo organizador con integración con OpenAI para generación automática de actas a partir de los puntos tratados.

Módulo de RRSS — Dashboard de Redes Sociales

Panel de monitorización de la presencia digital del evento en tiempo real. Al cargar, lanza peticiones paralelas (una por red social) a través de Node-RED, que actúa como proxy y agregador de APIs:

Cada métrica tiene su propio estado de carga independiente, por lo que los datos aparecen progresivamente según llegan. Además, incluye un gráfico de líneas temporal (ngx-charts) que muestra la evolución de seguidores en un rango de fechas configurable, con los datos transformados al formato de series temporales que espera la librería.

Módulo IT — Monitorización e Infraestructura

Monitoring: panel de estado de los servicios del evento. Consume una API de monitorización externa que devuelve datos de uptime y tiempos de respuesta. Los datos se transforman en series temporales y se visualizan con un gráfico de líneas múltiple con esquema de colores personalizado. El gráfico es responsive y actualiza las dimensiones del contenedor en tiempo real.

Analytics: integración con herramientas de analítica web para visualizar métricas de tráfico del sitio del evento.

Módulo logísitica en Tiempo Real — WebSockets

El servicio `SocketService` establece una conexión persistente con un servidor Socket.io. El estado de la conexión se expone como un `Observable<boolean>` mediante `BehaviorSubject`, permitiendo que cualquier componente muestre el estado de conectividad en tiempo real.

Esto se usa en el módulo de logística para tener un control real de la flota de autobuses durante los eventos, mediante una pantalla adaptada a moviles se puede ver la localización de los autobuses, los equipos que viajan en cada autobus y el destino para poder mantener una trazabilidad y poder tomar decisiones de rutas de forma eficiente.

Sistema de Notificaciones del Menú

El sidebar implementa un sistema de badges de notificación por sección. Al cargar, consulta el endpoint `alertas-menus` de Strapi y muestra contadores sobre los ítems del menú que tienen actividad nueva. Al navegar a una sección, el contador se resetea automáticamente a 0 mediante una llamada PUT al backend.

Integración con 7 APIs externas

  • Strapi CMS — Backend headless, API REST, autenticación JWT, gestión de roles
  • OpenAI — Generación de metadatos SEO y actas de reuniones
  • Dolibarr ERP — Descarga de facturas de patrocinadores
  • AirLabs — Datos de vuelos en tiempo real (posición GPS, altitud, velocidad, ETA)
  • Node-RED — Proxy y agregador de APIs de redes sociales
  • Cloudinary — Almacenamiento de imágenes
  • FTF — Envío de plantillas de equipos al sistema federativo

Impacto y métricas

  • La plataforma entró en producción y se usó durante el evento real.
  • El control de acceso por QR se desplegó en las entradas del recinto usando dispositivos móviles del equipo organizador, sin necesidad de hardware adicional.
  • Las acreditaciones de prensa se generaron y enviaron por email directamente desde la intranet.
  • Los gestores de logística coordinaron hoteles y vuelos desde un único panel, con visibilidad del estado de los vuelos en el mapa en tiempo real.

Galería