Files
glm-hub/README.md
T
2026-07-29 16:36:10 +00:00

22 KiB

GomezLee Marketing

GLM Hub

El punto de entrada a las aplicaciones internas de GomezLee Marketing

Estado Versión Frontend Backend

Portal interno para centralizar aplicaciones corporativas, administrar un catálogo compartido y gestionar solicitudes de acceso mediante Supabase, n8n y autenticación con Google.

Producción · Repositorio


Navegación rápida

Información general Objetivo Arquitectura
Reglas de negocio Configuración Cómo funciona
Testing Troubleshooting Monitoreo
Estructura Changelog Definition of Done

📌 Información general

Estado
🟢 Listo para producción
Versión
v1.0.0
Producción
home.digitalcompass.agency
Responsable
Isaac Aracena
Campo Detalle
Proyecto GLM Hub
Área IT / Corporativo
Estado Listo para producción
Developer principal Isaac Aracena
IT Manager Luis Matos
Product Owner Máximo Gómez
Fecha de inicio 2026-07-22
Fecha de cierre 2026-07-29
Repositorio https://git.digitalcompass.agency/Isaac_Aracena/glm-hub
URL de producción https://home.digitalcompass.agency/

Capacidades principales

Catálogo compartido Experiencia personalizada Automatización
Aplicaciones publicadas visibles para todos los usuarios autorizados Favoritos y accesos recientes por usuario Generación de íconos con Gemini
Administración sin modificar código Rol Administrador o Usuario Solicitudes y decisiones por correo
Actualización en tiempo real Paginación y búsqueda Primera decisión protegida en Supabase

🎯 Objetivo

Problema que resuelve

Las aplicaciones internas de GomezLee Marketing estaban distribuidas en diferentes enlaces y dependían de comunicación manual para que los colaboradores pudieran encontrarlas, identificar cuál necesitaban y solicitar acceso. Además, no existía un catálogo central compartido que pudiera ser mantenido por administradores sin modificar el código.

Solución implementada

GLM Hub centraliza los portales corporativos en una sola interfaz, permite que los administradores creen y mantengan el catálogo desde la aplicación, muestra a todos los usuarios autorizados las mismas aplicaciones publicadas, conserva favoritos y accesos recientes por usuario, genera íconos con IA y gestiona solicitudes de acceso mediante aprobaciones por correo.

Usuarios / Beneficiarios

  • Colaboradores autorizados de GomezLee Marketing.
  • Administradores del catálogo de aplicaciones.
  • Equipo de IT Support que recibe las decisiones de acceso.
  • Desarrolladores responsables de administrar los permisos dentro de cada aplicación individual.

🏗️ Arquitectura

Diagrama de flujo

flowchart LR
    U[Usuario] --> F[GLM Hub<br/>React + Vite]
    F --> A[Supabase Auth<br/>Google OAuth]
    F --> D[(Supabase Postgres)]
    F --> S[Supabase Storage]
    F --> N1[n8n<br/>Generar ícono]
    F --> N2[n8n<br/>Solicitar acceso]
    N1 --> G[Google Gemini]
    N2 --> M[Gmail]
    D --> R[Roles · Catálogo · Favoritos · Solicitudes]
    M --> AP[Aprobadores]
    AP --> IT[IT Support]
Ver flujo técnico en formato texto
Usuario
  └── Frontend React + Vite
      ├── Supabase Auth (Google OAuth)
      ├── Supabase Postgres + RLS + Realtime
      ├── Supabase Storage (íconos)
      ├── n8n → Gemini (generación de íconos)
      └── n8n → Gmail → aprobadores → IT Support

Stack tecnológico

Componente Tecnología Propósito
Frontend React 19 + TypeScript Interfaz del Hub
Build Vite 6 Desarrollo, validación y compilación
UI CSS + Lucide React Estilos e iconografía
Autenticación Supabase Auth + Google OAuth Inicio de sesión corporativo
Base de datos Supabase / PostgreSQL Catálogo, usuarios, favoritos, recientes y solicitudes
Seguridad Row Level Security Control de lectura y escritura según usuario y rol
Archivos Supabase Storage Almacenamiento de íconos
Sincronización Supabase Realtime Actualización del catálogo en sesiones abiertas
Automatización n8n Orquestación de generación de íconos y solicitudes
IA Google Gemini Generación de íconos para nuevas aplicaciones
Notificaciones Gmail OAuth Envío de solicitudes y decisiones por correo
Repositorio Gitea Control de versiones
Hosting Servidor web GLM Publicación del contenido de dist/

Integraciones externas

Sistema Tipo de integración Datos que fluyen
Google OAuth OAuth 2.0 mediante Supabase Identidad, correo, nombre y foto del usuario
Supabase SDK, REST, RPC, Storage y Realtime Usuarios, roles, catálogo, íconos, favoritos, recientes y solicitudes
n8n Webhooks HTTPS Solicitudes del frontend y respuestas procesadas
Google Gemini Credencial nativa de n8n Nombre y descripción de la app; devuelve una imagen
Gmail OAuth mediante n8n Correos de aprobación y notificación a IT Support

📐 Reglas de negocio

  1. Solo pueden iniciar sesión usuarios activos registrados en glm_hub_authorized_users y con correo del dominio @gomezleemarketing.com.
  2. Los roles válidos son admin y member.
  3. Los administradores autorizados son:
    • José Leopoldo Gómez — jgomez@gomezleemarketing.com
    • Isaac Aracena — iaracena@gomezleemarketing.com
    • Eidan Then — ethen@gomezleemarketing.com
    • Máximo Gómez — mgomez@gomezleemarketing.com
    • Luis Matos — lmatos@gomezleemarketing.com
  4. Solo los administradores pueden abrir el apartado Administrar, crear, editar, publicar, ocultar o eliminar aplicaciones.
  5. Todos los usuarios autorizados ven el mismo catálogo de aplicaciones publicadas.
  6. El Hub no controla el acceso interno de cada aplicación; ese permiso se administra desde el login o backend de cada portal.
  7. Las categorías disponibles son Administración, Recursos Humanos y CDC.
  8. No se puede publicar una aplicación sin ícono.
  9. El nombre debe tener entre 2 y 60 caracteres y la descripción un máximo de 180 caracteres.
  10. Los íconos admitidos son PNG, JPG o WebP y no pueden superar 1 MB.
  11. Los favoritos y accesos recientes son personales y no afectan la vista de otros usuarios.
  12. Los favoritos se ordenan antes que las demás aplicaciones antes de aplicar la paginación.
  13. Los usuarios normales pueden solicitar acceso a cualquier aplicación publicada.
  14. No se permite una segunda solicitud pendiente del mismo usuario para la misma aplicación.
  15. Las solicitudes se envían individualmente a Isaac Aracena, José Leopoldo Gómez y Máximo Gómez.
  16. La primera decisión registrada gana; cualquier intento posterior queda bloqueado y no cambia el resultado.
  17. Después de aprobar o rechazar, IT Support recibe un correo con el solicitante, la aplicación, el resultado y la persona que decidió.
  18. La generación de íconos con IA solo está disponible para administradores y requiere nombre y descripción.

⚙️ Configuración y setup

Prerrequisitos

  • Node.js y npm instalados.
  • Acceso al proyecto Supabase de GLM.
  • Proveedor Google habilitado en Supabase Auth.
  • Instancia de n8n operativa.
  • Credencial de Google Gemini configurada en n8n.
  • Credencial Gmail OAuth configurada en n8n.
  • Acceso al servidor o subdominio de producción.

Variables de entorno

Crear .env a partir de .env.example:

Variable Descripción Dónde se obtiene
VITE_SUPABASE_URL URL pública del proyecto Supabase Supabase / configuración del proyecto
VITE_SUPABASE_ANON_KEY Clave pública anon para el frontend Supabase / API Keys
VITE_ICON_GENERATOR_WEBHOOK_URL Webhook de n8n para generar íconos Workflow de generación de íconos
VITE_ACCESS_REQUEST_WEBHOOK_URL Webhook de n8n para solicitudes de acceso Workflow de solicitudes y aprobación

Caution

Nunca commitear credenciales reales. El archivo .env, las claves service_role, los tokens y las credenciales de Gmail o Gemini deben mantenerse fuera del repositorio.

Esquema de base de datos

Ejecutar en Supabase SQL Editor:

SUPABASE-GLM-HUB-COMPLETO.sql

El script crea o actualiza:

  • glm_hub_authorized_users
  • glm_hub_apps
  • glm_hub_favorites
  • glm_hub_recent_apps
  • glm_hub_access_requests
  • glm_hub_access_request_approvers
  • Funciones RPC para validación, solicitudes y decisiones.
  • Bucket público glm-hub-icons.
  • Políticas RLS.
  • Publicación Realtime del catálogo.

Workflows de n8n

Importar y configurar:

n8n/GLM-Hub-Generar-Icono-Gemini-Nodo-Nativo.json
n8n/GLM-Hub-Solicitudes-Acceso-Aprobacion.json

Configuración necesaria:

  • Seleccionar una credencial de Gemini en Generate an image.
  • Seleccionar una credencial Gmail válida en los dos nodos de envío.
  • Usar la clave anon donde la llamada representa al usuario autenticado.
  • Usar service_role únicamente en los nodos internos que emiten tokens o registran decisiones.
  • Mantener las claves únicamente en n8n; nunca enviarlas al navegador.
  • En producción, Enviar solicitud a aprobadores debe usar ={{ $json.sendTo }}.
  • En producción, Enviar decisión a IT Support debe enviar a itsupport@gomezleemarketing.com.

Instalación local

git clone https://git.digitalcompass.agency/Isaac_Aracena/glm-hub.git
cd glm-hub
npm install
cp .env.example .env
# Editar .env con los valores reales
npm run typecheck
npm run dev

En PowerShell, puede usarse:

Copy-Item .env.example .env

Build

npm run build

La compilación se genera en:

dist/

Deploy

El proyecto se publica en la raíz de un subdominio, por lo que vite.config.ts debe permanecer sin una propiedad base personalizada.

export default defineConfig({
  plugins: [react()],
});

Copiar el contenido de dist/ directamente al Document Root del subdominio:

DocumentRoot/
|-- index.html
|-- assets/
|-- glm-logo.png
`-- archivos de favicon

No colocar una carpeta dist dentro del Document Root.

Para probar el mismo build con XAMPP, usar un VirtualHost que apunte directamente a la carpeta donde se copió el contenido de dist/. Servirlo como http://localhost/glm-hub/ sin configurar base hará que los assets se busquen desde una ruta incorrecta.

Redirects de autenticación

Registrar en Supabase las URLs permitidas que correspondan al entorno:

https://home.digitalcompass.agency/
http://localhost:4173/

Si se utiliza un VirtualHost local, registrar también su URL completa.


🔄 Cómo funciona

Flujo general

  1. El usuario entra al Hub y selecciona Continuar con Google.
  2. Supabase Auth valida la cuenta de Google.
  3. El frontend consulta glm_hub_authorized_users para confirmar que el usuario esté activo y conocer su rol.
  4. El catálogo compartido se carga desde glm_hub_apps.
  5. Los favoritos y recientes se cargan para el usuario autenticado.
  6. Supabase Realtime mantiene el catálogo actualizado en sesiones abiertas.
  7. Los administradores pueden crear, editar, ocultar o eliminar aplicaciones.
  8. Los usuarios normales pueden solicitar acceso a una aplicación publicada.

Generación de íconos

  1. El administrador completa nombre y descripción.
  2. El frontend llama el webhook glm-hub-generar-icono.
  3. n8n valida el JWT y confirma el rol de administrador.
  4. Gemini genera una imagen cuadrada sin texto.
  5. n8n devuelve el archivo binario al frontend.
  6. El ícono se previsualiza y se guarda en Supabase Storage al publicar.

Solicitud de acceso

  1. El usuario selecciona un área y una aplicación publicada.
  2. n8n registra la solicitud en Supabase.
  3. Supabase emite un token único para cada aprobador.
  4. Gmail envía un correo individual a cada aprobador.
  5. El aprobador confirma Aceptar o Rechazar.
  6. Supabase registra atómicamente la primera decisión.
  7. n8n envía el resultado a itsupport@gomezleemarketing.com.
  8. Cualquier clic posterior muestra que la solicitud ya fue atendida.

Triggers

Trigger Frecuencia Descripción
Google OAuth Bajo demanda Inicio de sesión de un usuario
Realtime de Supabase En tiempo real Actualización del catálogo compartido
POST /webhook/glm-hub-generar-icono Bajo demanda Generación de ícono con Gemini
POST /webhook/glm-hub-solicitar-acceso Bajo demanda Registro y envío de solicitud
GET /webhook/glm-hub-confirmar-solicitud Bajo demanda Pantalla de confirmación de decisión
POST /webhook/glm-hub-resolver-solicitud Bajo demanda Registro de aprobación o rechazo

🧪 Testing

Casos de prueba mínimos

Caso Input Output esperado Estado
Login autorizado Usuario activo del dominio GLM Acceso al Hub Validado
Usuario inactivo Registro con is_active = false Acceso denegado Validado
Rol administrador Cuenta con role = admin Muestra Administrar Validado
Rol usuario Cuenta con role = member No muestra controles administrativos Validado
Catálogo compartido Admin publica una app Todos ven la misma app Validado en Supabase; realizar smoke test final con segundo usuario
Publicación sin ícono Formulario sin archivo Publicación bloqueada Validado
Generar ícono Nombre y descripción válidos Imagen generada y previsualizada Validado
Cambio de pestaña Salir y regresar al navegador Mantiene vista y formulario Validado
Favoritos Marcar una aplicación Se guarda solo para el usuario Validado
Paginación Más de 10 aplicaciones Navegación compacta y usable Implementado
Solicitud de acceso Usuario y app válidos Correos enviados a aprobadores Validado
Primera decisión Un aprobador acepta o rechaza Registra resultado y notifica a IT Validado
Segundo clic Otro aprobador intenta decidir No modifica la primera decisión Validado
Build de producción npm run build Genera dist/ sin errores Validado

🛠️ Errores conocidos y troubleshooting

Error Causa probable Solución
Pantalla en blanco en XAMPP El build de raíz se sirve dentro de /glm-hub/ Usar VirtualHost o npm run preview; no agregar base para producción en subdominio raíz
Assets con 404 index.html apunta a /assets/ pero el servidor usa una subcarpeta Servir el contenido de dist/ desde el Document Root
Google regresa a una URL incorrecta Redirect no autorizado Agregar la URL exacta en Supabase Auth
Usuario no ve Administrar Rol desactualizado o sesión antigua Confirmar role = admin, cerrar sesión y volver a entrar
HTTP 401 en n8n JWT vencido o encabezado incorrecto Usar el token dinámico enviado por el frontend
HTTP 403 en una RPC Clave o permisos incorrectos Verificar si el nodo requiere anon, JWT o service_role
Output vacío de HTTP Request Respuesta configurada como archivo o envuelta con headers Usar Response Format: JSON y revisar la estructura esperada
Solicitud duplicada Ya existe una solicitud pendiente Atender o eliminar la solicitud anterior
No se genera ícono Credencial Gemini no seleccionada Revisar el nodo Generate an image
Ícono rechazado Archivo mayor a 1 MB o MIME no permitido Convertir a PNG/JPG/WebP y reducir tamaño

📊 Monitoreo

  • n8n Executions: revisar ejecuciones fallidas o detenidas en ramas de error.
  • Supabase Logs: revisar errores de Auth, REST, RLS y Storage.
  • Solicitudes pendientes: consultar glm_hub_access_requests filtrando status = 'pending'.
  • Correos: confirmar entregas desde la cuenta Gmail conectada a n8n.
  • Output normal: catálogo cargado, sesión persistente, Realtime activo y webhooks respondiendo correctamente.
  • Alertas automáticas: no configuradas actualmente; el monitoreo se realiza desde n8n y Supabase.

Consulta rápida:

select
  requester_name,
  requester_email,
  app_name,
  status,
  decided_by_name,
  decided_by_email,
  created_at,
  decided_at
from public.glm_hub_access_requests
order by created_at desc;

🗂️ Estructura del repositorio

glm-hub/
|-- README.md
|-- .env.example
|-- index.html
|-- package.json
|-- package-lock.json
|-- tsconfig.json
|-- vite.config.ts
|-- SUPABASE-GLM-HUB-COMPLETO.sql
|-- dist/
|   |-- index.html
|   `-- assets/
|-- n8n/
|   |-- GLM-Hub-Generar-Icono-Gemini-Nodo-Nativo.json
|   `-- GLM-Hub-Solicitudes-Acceso-Aprobacion.json
|-- public/
|   `-- logos y favicons
|-- scripts/
|-- src/
|   |-- components/
|   |-- lib/
|   |-- App.tsx
|   `-- main.tsx
`-- documentación técnica adicional

node_modules/ y .env nunca deben subirse al repositorio. En el flujo actual de despliegue manual, dist/ puede mantenerse versionado para entregar una compilación ya validada.


🧾 Changelog

2026-07-29 — v1.0.0

  • Catálogo compartido en Supabase.
  • Autenticación con Google y control de roles.
  • Favoritos y accesos recientes por usuario.
  • Administración completa del catálogo.
  • Realtime para aplicaciones publicadas.
  • Generación de íconos con Gemini mediante n8n.
  • Solicitudes de acceso con aprobación o rechazo por correo.
  • Primera decisión protegida de forma atómica.
  • Paginación automática en acceso rápido, catálogo y administración.
  • Build preparado para la raíz de un subdominio.

2026-07-28 — v0.9.0

  • Persistencia de pantalla al cambiar de pestaña.
  • Correcciones de CORS y JWT para generación de íconos.
  • Integración con el nodo nativo de Gemini en n8n.

2026-07-22 — v0.1.0

  • Inicio del proyecto y diseño inicial del portal.

🧠 Decisions log

DEC-001 — Catálogo compartido en Supabase

  • Fecha: 2026-07-25
  • Contexto: El catálogo guardado en localStorage solo existía en el navegador del administrador.
  • Opciones consideradas: localStorage vs. base de datos compartida.
  • Decisión: Guardar aplicaciones en Supabase.
  • Razón: Todos los usuarios deben ver el mismo catálogo y los administradores deben actualizarlo sin modificar código.

DEC-002 — Acceso individual fuera del Hub

  • Fecha: 2026-07-29
  • Contexto: Se evaluó controlar permisos por aplicación desde el Hub.
  • Opciones consideradas: Permisos centralizados en el Hub vs. permisos en cada aplicación.
  • Decisión: El Hub muestra todas las aplicaciones publicadas y cada aplicación controla su propio acceso.
  • Razón: Evita duplicar reglas y mantiene la responsabilidad de seguridad en cada portal.

DEC-003 — Favoritos y recientes por usuario

  • Fecha: 2026-07-28
  • Contexto: El catálogo debe ser compartido, pero la personalización no.
  • Decisión: Guardar favoritos y accesos recientes asociados al usuario autenticado.
  • Razón: Cada persona conserva su propia experiencia sin afectar a los demás.

DEC-004 — Generación de íconos desde n8n

  • Fecha: 2026-07-28
  • Contexto: La clave de Gemini no puede exponerse en el frontend.
  • Decisión: Usar un webhook de n8n y el nodo nativo Generate an image.
  • Razón: Mantiene las credenciales fuera del navegador y permite validar el rol administrativo.

DEC-005 — Primera decisión gana

  • Fecha: 2026-07-29
  • Contexto: Tres aprobadores reciben botones para la misma solicitud.
  • Decisión: Registrar atómicamente la primera aprobación o rechazo y bloquear las siguientes.
  • Razón: Evita decisiones contradictorias y correos duplicados a IT Support.

DEC-006 — Build sin base personalizado

  • Fecha: 2026-07-29
  • Contexto: La aplicación se desplegará en la raíz de un subdominio.
  • Decisión: No configurar base: '/glm-hub/' en Vite.
  • Razón: Los assets deben resolverse desde / en producción.

👥 Contactos del proyecto

Rol Nombre Contacto
Product Owner Máximo Gómez mgomez@gomezleemarketing.com
IT Manager Luis Matos lmatos@gomezleemarketing.com
Developer principal Isaac Aracena iaracena@gomezleemarketing.com
Administrador técnico Eidan Then ethen@gomezleemarketing.com
Soporte GLM IT Support itsupport@gomezleemarketing.com

Definition of Done

  • Catálogo compartido en Supabase.
  • Autenticación con Google operativa.
  • Roles de administrador y usuario aplicados.
  • RLS configurado para tablas y Storage.
  • Favoritos y recientes por usuario.
  • Paginación implementada.
  • Generación de íconos con IA operativa.
  • Workflows de n8n exportados en /n8n.
  • SQL completo incluido en el repositorio.
  • Variables documentadas en .env.example.
  • Solicitudes de acceso y primera decisión validadas.
  • Código y build listos para Gitea.
  • Probado localmente y con webhooks reales.
  • Ejecutar smoke test final con un segundo usuario en producción.
  • Enlazar el board y el PRD oficiales.
  • Registrar validación final de Luis Matos.
  • Registrar aprobación final de Máximo Gómez.


Documento mantenido por el equipo GLM IT
GomezLee Marketing · 2026