Eliminar README.md
This commit is contained in:
@@ -1,958 +0,0 @@
|
|||||||
GLM Hub
|
|
||||||
|
|
||||||
Portal interno de GomezLee Marketing para centralizar las aplicaciones corporativas, administrar el catálogo compartido y gestionar solicitudes de acceso mediante Supabase, n8n y autenticación con Google.
|
|
||||||
|
|
||||||
INFORMACIÓN GENERAL
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
Ciclo Shape Up
|
|
||||||
|
|
||||||
No definido en el repositorio
|
|
||||||
|
|
||||||
Board de ejecución
|
|
||||||
|
|
||||||
Pendiente de enlazar
|
|
||||||
|
|
||||||
PRD del proyecto
|
|
||||||
|
|
||||||
Pendiente de enlazar
|
|
||||||
|
|
||||||
Repositorio
|
|
||||||
|
|
||||||
https://git.digitalcompass.agency/Isaac_Aracena/glm-hub
|
|
||||||
|
|
||||||
URL de producción
|
|
||||||
|
|
||||||
https://home.digitalcompass.agency/
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
Usuario
|
|
||||||
|
|
|
||||||
v
|
|
||||||
Frontend React + Vite
|
|
||||||
|
|
|
||||||
+--> Supabase Auth (Google OAuth)
|
|
||||||
|
|
|
||||||
+--> Supabase Postgres + RLS + Realtime
|
|
||||||
| |-- Usuarios autorizados y roles
|
|
||||||
| |-- Catálogo compartido
|
|
||||||
| |-- Favoritos y recientes por usuario
|
|
||||||
| `-- Solicitudes y decisiones de acceso
|
|
||||||
|
|
|
||||||
+--> Supabase Storage
|
|
||||||
| `-- Íconos del catálogo
|
|
||||||
|
|
|
||||||
+--> Webhook n8n: generación de ícono
|
|
||||||
| `-- Validación de administrador -> Gemini -> imagen
|
|
||||||
|
|
|
||||||
`--> Webhook n8n: solicitud de acceso
|
|
||||||
`-- Supabase -> Gmail -> aprobación/rechazo -> 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
|
|
||||||
|
|
||||||
Solo pueden iniciar sesión usuarios activos registrados en glm_hub_authorized_users y con correo del dominio @gomezleemarketing.com.
|
|
||||||
|
|
||||||
Los roles válidos son admin y member.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
Solo los administradores pueden abrir el apartado Administrar, crear, editar, publicar, ocultar o eliminar aplicaciones.
|
|
||||||
|
|
||||||
Todos los usuarios autorizados ven el mismo catálogo de aplicaciones publicadas.
|
|
||||||
|
|
||||||
El Hub no controla el acceso interno de cada aplicación; ese permiso se administra desde el login o backend de cada portal.
|
|
||||||
|
|
||||||
Las categorías disponibles son Administración, Recursos Humanos y CDC.
|
|
||||||
|
|
||||||
No se puede publicar una aplicación sin ícono.
|
|
||||||
|
|
||||||
El nombre debe tener entre 2 y 60 caracteres y la descripción un máximo de 180 caracteres.
|
|
||||||
|
|
||||||
Los íconos admitidos son PNG, JPG o WebP y no pueden superar 1 MB.
|
|
||||||
|
|
||||||
Los favoritos y accesos recientes son personales y no afectan la vista de otros usuarios.
|
|
||||||
|
|
||||||
Los favoritos se ordenan antes que las demás aplicaciones antes de aplicar la paginación.
|
|
||||||
|
|
||||||
Los usuarios normales pueden solicitar acceso a cualquier aplicación publicada.
|
|
||||||
|
|
||||||
No se permite una segunda solicitud pendiente del mismo usuario para la misma aplicación.
|
|
||||||
|
|
||||||
Las solicitudes se envían individualmente a Isaac Aracena, José Leopoldo Gómez y Máximo Gómez.
|
|
||||||
|
|
||||||
La primera decisión registrada gana; cualquier intento posterior queda bloqueado y no cambia el resultado.
|
|
||||||
|
|
||||||
Después de aprobar o rechazar, IT Support recibe un correo con el solicitante, la aplicación, el resultado y la persona que decidió.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
El usuario entra al Hub y selecciona Continuar con Google.
|
|
||||||
|
|
||||||
Supabase Auth valida la cuenta de Google.
|
|
||||||
|
|
||||||
El frontend consulta glm_hub_authorized_users para confirmar que el usuario esté activo y conocer su rol.
|
|
||||||
|
|
||||||
El catálogo compartido se carga desde glm_hub_apps.
|
|
||||||
|
|
||||||
Los favoritos y recientes se cargan para el usuario autenticado.
|
|
||||||
|
|
||||||
Supabase Realtime mantiene el catálogo actualizado en sesiones abiertas.
|
|
||||||
|
|
||||||
Los administradores pueden crear, editar, ocultar o eliminar aplicaciones.
|
|
||||||
|
|
||||||
Los usuarios normales pueden solicitar acceso a una aplicación publicada.
|
|
||||||
|
|
||||||
Generación de íconos
|
|
||||||
|
|
||||||
El administrador completa nombre y descripción.
|
|
||||||
|
|
||||||
El frontend llama el webhook glm-hub-generar-icono.
|
|
||||||
|
|
||||||
n8n valida el JWT y confirma el rol de administrador.
|
|
||||||
|
|
||||||
Gemini genera una imagen cuadrada sin texto.
|
|
||||||
|
|
||||||
n8n devuelve el archivo binario al frontend.
|
|
||||||
|
|
||||||
El ícono se previsualiza y se guarda en Supabase Storage al publicar.
|
|
||||||
|
|
||||||
Solicitud de acceso
|
|
||||||
|
|
||||||
El usuario selecciona un área y una aplicación publicada.
|
|
||||||
|
|
||||||
n8n registra la solicitud en Supabase.
|
|
||||||
|
|
||||||
Supabase emite un token único para cada aprobador.
|
|
||||||
|
|
||||||
Gmail envía un correo individual a cada aprobador.
|
|
||||||
|
|
||||||
El aprobador confirma Aceptar o Rechazar.
|
|
||||||
|
|
||||||
Supabase registra atómicamente la primera decisión.
|
|
||||||
|
|
||||||
n8n envía el resultado a itsupport@gomezleemarketing.com.
|
|
||||||
|
|
||||||
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.
|
|
||||||
Reference in New Issue
Block a user