Tablero CDC — Project Management
Aplicación interna de GomezLee Marketing para centralizar la gestión de proyectos creativos del CDC, sus aprobaciones, enlaces, estimación interna y tarifarios en una sola interfaz web.
INFORMACIÓN GENERAL
| Campo | Detalle |
|---|---|
| Proyecto | Tablero CDC / CDC Project Management |
| Área | Creatividad y Diseño — CDC |
| Developer Principal | Isaac Aracena |
| IT Manager | Luis Matos |
OBJETIVO
Problema que resuelve
La gestión de proyectos del CDC requiere centralizar información que de otro modo queda distribuida entre hojas de cálculo, enlaces, comunicaciones y seguimientos manuales. Esto dificulta consultar rápidamente el estado de un proyecto, sus responsables, propuestas, artes finales, costos internos y actividad reciente.
Solución implementada
El Tablero CDC ofrece una aplicación web donde los usuarios autorizados pueden:
- crear, consultar, editar y cerrar proyectos;
- filtrar y buscar proyectos;
- manejar links de brief, propuestas y artes finales;
- visualizar actividad e información clave de cada proyecto;
- calcular y guardar el costo interno mediante tarifarios;
- usar tarifarios generales o tarifarios especiales por cliente;
- administrar el catálogo de tarifarios cuando el usuario tiene permiso;
- consultar el total tarifado global o filtrado según permisos;
- trabajar con datos persistidos en Supabase y sincronizados entre usuarios.
Usuarios / Beneficiarios
- Equipo de Creatividad y Diseño / CDC.
- Director Creativo.
- Usuarios internos autorizados de GomezLee Marketing.
- IT, para soporte, mantenimiento y administración técnica.
- Áreas que consumen la información consolidada posteriormente mediante Google Sheets / Power BI.
ARQUITECTURA
Diagrama de flujo principal
Usuario autorizado
|
v
React + TypeScript + Vite
|
+--> Supabase Auth (Google OAuth)
|
+--> tablero_cdc_allowed_users
| |
| +--> permisos funcionales
|
+--> Supabase Postgres
| |
| +--> Proyectos
| +--> Links
| +--> Actividad
| +--> Costos internos
| +--> Listas dinámicas
| +--> Tarifarios
| +--> RPCs de paginación y totales
|
+--> Supabase Realtime
|
+--> n8n Webhook
|
v
Google Sheets
|
v
Power BI
Flujo del tarifario
Google Sheet del tarifario
|
v
n8n
|
v
Supabase tariff catalog
|
+--> Secciones generales
|
+--> Tarifarios por cliente
|
v
Estimador interno del proyecto
|
v
tablero_cdc_project_pricing_items
Las tarifas administradas directamente desde la aplicación se identifican con managed_by = 'app' para protegerlas frente al sincronizador del Sheet.
Stack tecnológico
| Componente | Tecnología | Propósito |
|---|---|---|
| Frontend | React 19 + TypeScript | Interfaz y lógica de la aplicación |
| Build / Dev Server | Vite 6 | Desarrollo y compilación |
| UI | Tailwind CSS 4 + Radix UI | Diseño y componentes |
| Base de datos | Supabase / PostgreSQL | Persistencia, RLS, RPCs y configuración |
| Autenticación | Supabase Auth + Google OAuth | Inicio de sesión corporativo |
| Tiempo real | Supabase Realtime | Sincronización multiusuario |
| Automatización | n8n | Integración con Google Sheets |
| Fuente / salida operativa | Google Sheets | Sincronización con procesos existentes |
| Reporting | Power BI | Consumo posterior de la información |
| Repositorio | Gitea | Control de versiones |
Integraciones externas
| Sistema | Tipo de integración | Datos que fluyen |
|---|---|---|
| Supabase | SDK / REST / RPC / Realtime | Usuarios, proyectos, permisos, listas, links, actividad, tarifas y costos |
| Google OAuth | OAuth 2.0 vía Supabase | Identidad del usuario |
| n8n | Webhook HTTPS | Sincronización de proyectos y catálogo |
| Google Sheets | n8n | Datos operativos y catálogo de tarifarios |
| Power BI | Fuente existente basada en Sheets | Reporting / visualización |
REGLAS DE NEGOCIO
-
El acceso no depende solamente del dominio del correo. El usuario debe autenticarse con Google y existir activo en
public.tablero_cdc_allowed_users. -
Los permisos especiales se controlan desde Supabase, principalmente mediante:
can_delete_projectscan_manage_internal_pricingcan_control_pricing_summarycan_manage_tariff_catalog
-
No se deben hardcodear administradores nuevos en el frontend. Los accesos y permisos se administran en Supabase.
-
Los tarifarios generales están disponibles para los clientes que no dependen de un tarifario especial.
-
Los tarifarios por cliente solo aparecen al seleccionar el cliente asociado a esa sección.
-
Walmart Connect WMC utiliza un tarifario especial con 12 piezas de precio fijo y mantiene la posibilidad de agregar un costo manual para propuestas o conceptos no contemplados.
-
Las tarifas administradas desde la app quedan marcadas con
managed_by = 'app'. El sincronizador del Sheet no debe sobrescribirlas. -
Las tarifas históricas no deben eliminarse como operación normal. Se deben desactivar para conservar integridad histórica.
-
Los costos seleccionados en un proyecto se guardan en
tablero_cdc_project_pricing_itemsy alimentan el total interno del proyecto. -
El Total Tarifado Global se calcula mediante la RPC
tablero_cdc_get_pricing_summaryy respeta los filtros activos. Los proyectos creados con tarifarios actuales o futuros siguen formando parte del total al guardar su costo interno. -
La visibilidad del Total Tarifado se controla mediante configuración y permisos de Supabase.
-
La estructura del Google Sheet original debe mantenerse estable, especialmente cuando es consumida por Power BI. Cualquier cambio estructural debe validarse previamente.
-
Paginación actual:
- proyectos:
24por página; - secciones del módulo de tarifario:
6por página; - tarifas / piezas del módulo:
10por página.
- proyectos:
-
Al cambiar de sección, buscar, cambiar entre Generales / Por cliente o activar Mostrar inactivas, el módulo de tarifario reajusta la página automáticamente.
CONFIGURACIÓN Y SETUP
Prerrequisitos
- Git.
- Node.js + npm.
- Acceso al repositorio interno en Gitea.
- Proyecto Supabase configurado.
- Google OAuth configurado en Supabase Auth.
- Acceso a SQL Editor de Supabase para instalaciones o migraciones.
- Acceso al workflow n8n correspondiente si se requiere sincronización con Google Sheets.
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 / infraestructura GLM |
VITE_SUPABASE_ANON_KEY |
Anon/Public Key usada por el frontend | Supabase |
VITE_WEBHOOK_URL |
Webhook de sincronización de proyectos | n8n |
Ejemplo:
VITE_SUPABASE_URL="https://dbit.digitalcompass.agency"
VITE_SUPABASE_ANON_KEY="TU_ANON_PUBLIC_KEY"
VITE_WEBHOOK_URL="https://agenteit.digitalcompass.agency/webhook/tablero-cdc-sync-proyecto"
Nunca commitear
.env,service_role, secretos OAuth, contraseñas, tokens privados ni credenciales administrativas.
La anon key del frontend no debe sustituirse por una service_role.
Esquema de base de datos / SQL incluidos
El repositorio mantiene scripts SQL separados para las distintas capacidades:
supabase_tablero_cdc_access_control.sql
supabase_tablero_cdc_alicia_permissions.sql
supabase_project_activity.sql
supabase_project_pricing_items.sql
supabase_realtime_projects.sql
supabase_rpc_projects_paginated.sql
supabase_pricing_summary_visibility.sql
supabase_tariff_catalog_and_safe_links.sql
supabase_walmart_connect_tariff.sql
supabase_tariff_admin_module.sql
Script principal del módulo de tarifario
Para una instalación que ya tenga la base anterior del Tablero CDC, el archivo:
supabase_tariff_admin_module.sql
incorpora de forma idempotente el tarifario Walmart Connect y el módulo de administración del catálogo, incluyendo can_manage_tariff_catalog, las secciones dinámicas y sus políticas RLS.
Después de ejecutarlo, verificar que los usuarios administradores esperados tengan:
can_manage_tariff_catalog = true
Instalación local
git clone https://git.digitalcompass.agency/Isaac_Aracena/cdc-project-management.git
cd cdc-project-management
npm install
cp .env.example .env
Editar .env con los valores correctos.
Ejecutar en desarrollo:
npm run dev
La configuración actual de Vite usa:
http://localhost:3000/tablero-cdc/
Build
npm run build
El script ejecuta:
tsc && vite build
Por lo tanto, un error de TypeScript detiene el build y debe corregirse antes de publicar.
Preview
npm run preview
INSTALACIÓN / DEPLOY
La aplicación está compilada para funcionar debajo de:
/tablero-cdc/
Configuración en vite.config.ts:
base: "/tablero-cdc/";
Deploy manual mediante dist
Este repositorio sí mantiene el dist validado porque el flujo actual de despliegue utiliza esa carpeta directamente en el servidor.
El dist debe contener como mínimo:
dist/
├── assets/
├── index.html
├── favicon.ico
└── demás archivos públicos generados
dist/assets/es obligatorio. Sin esa carpeta,index.htmlno podrá cargar correctamente el JavaScript y CSS compilados.
Flujo recomendado:
- Probar la aplicación con
npm run dev. - Generar el build con
npm run build. - Probar ese mismo
disten XAMPP bajo/tablero-cdc/. - No regenerar el build después de la validación si se desea desplegar exactamente la versión probada.
- Subir a Gitea el mismo
dist, incluyendodist/assets/. - Copiar ese
distvalidado al servidor. - Probar login, tablero, tarifario y una apertura directa sin recargar la página.
CÓMO FUNCIONA
Flujo paso a paso
- El usuario entra a la aplicación.
- Supabase Auth inicia o recupera la sesión Google.
- La app consulta
tablero_cdc_allowed_users. - Si el usuario no está activo/autorizado, la sesión se rechaza.
- Si está autorizado, la app carga sus permisos.
- El tablero consulta los proyectos desde Supabase mediante RPC paginada.
- Los filtros se aplican desde la consulta y no requieren descargar toda la base.
- Realtime mantiene sincronizadas las ventanas activas.
- Al crear o editar un proyecto, la información se persiste en Supabase.
- Si
VITE_WEBHOOK_URLestá configurado, la aplicación dispara la sincronización correspondiente hacia n8n. - Los costos internos se guardan como líneas de pricing por proyecto.
- El total tarifado se calcula en Supabase mediante RPC.
- El tarifario administrativo solo aparece a usuarios con
can_manage_tariff_catalog = true.
Tarifario general
El estimador puede utilizar secciones generales como:
- Tarifario Gráfico CDC
- Estrategia y Creatividad
Cada tarifa puede incluir categoría, servicio, tipo de trabajo, nivel, rango de referencia, notas y orden.
Tarifario por cliente
Las secciones con scope = 'client' se muestran únicamente cuando el proyecto tiene seleccionado el cliente asociado.
Ejemplo actual:
Walmart Connect WMC
El usuario puede seleccionar varias piezas y el subtotal se calcula automáticamente.
Administración del tarifario
Los usuarios autorizados pueden:
- crear secciones generales;
- crear tarifarios por cliente;
- crear tarifas / piezas;
- editar secciones y tarifas;
- desactivar y reactivar;
- buscar;
- mostrar inactivas;
- paginar listas extensas.
La administración no debe borrar costos ya guardados en proyectos históricos.
Schedules / Triggers
| Trigger | Frecuencia | Descripción |
|---|---|---|
| Interacción del usuario | On demand | Crear, editar, filtrar o cotizar proyectos |
| Webhook de proyecto | On demand | La app envía cambios a n8n cuando VITE_WEBHOOK_URL está configurado |
| Realtime Supabase | Evento | Actualiza la app cuando cambian tablas suscritas |
| Sync de tarifario Sheet → Supabase | Según workflow n8n | Mantiene actualizado el catálogo administrado desde Sheet |
La frecuencia exacta del sincronizador n8n debe consultarse en el workflow activo; no está definida por el frontend.
TESTING
Casos de prueba mínimos
| Caso | Input / Acción | Output esperado | Estado |
|---|---|---|---|
| Login autorizado | Usuario activo en tablero_cdc_allowed_users |
Entra al tablero | Revalidar tras deploy |
| Login no autorizado | Usuario sin fila activa | Acceso rechazado | Revalidar tras cambios de acceso |
| Carga del tablero | Abrir Todos / Activos / Cerrados | Proyectos paginados correctamente | Revalidar tras deploy |
| Filtros | País, marca, cliente o CM | Resultado y total corresponden al filtro | Revalidar tras cambios SQL |
| Realtime | Dos ventanas abiertas | Cambios visibles sin recarga manual | Revalidar tras cambios de Realtime |
| Links | Editar propuestas / artes finales | Persisten al reabrir el proyecto | Revalidar tras cambios en store/RPC |
| Tarifario general | Cliente normal | Secciones generales disponibles | Revalidar tras cambios de catálogo |
| Walmart Connect | Cliente Walmart Connect WMC |
Solo tarifario especial correspondiente + costo manual | Validado funcionalmente |
| WMC multiselección | Elegir varias piezas | Subtotal correcto | Validado funcionalmente |
| Administrar tarifario | Usuario con can_manage_tariff_catalog = true |
Botón Tarifario visible y módulo accesible | Validado funcionalmente |
| Usuario sin permiso | can_manage_tariff_catalog = false |
No ve módulo administrativo | Revalidar al modificar permisos |
| Paginación secciones | Más de 6 secciones | Controles de página sin perder selección | Implementado |
| Paginación tarifas | Más de 10 tarifas | Controles de página correctos | Implementado |
| Mostrar inactivas | Activar switch | Se muestran registros desactivados cuando existan | Implementado |
| Total tarifado | Crear/editar costos | Total global/filtrado se actualiza | Revalidar tras cambios de pricing |
| Build | npm run build |
tsc && vite build sin errores |
Requerido antes de generar nuevo dist |
| XAMPP | Abrir dist en /tablero-cdc/ |
App y módulo Tarifario abren sin recarga | Validado en la versión actual |
Prueba de referencia Walmart Connect
La documentación técnica incluida define este caso:
UniformesPhotoboothArco de entrada
Subtotal esperado:
$480.00
Agregando manualmente:
Propuesta general Walmart Connect = $900.00
Total esperado:
$1,380.00
Al guardar, cerrar y volver a abrir el proyecto, las líneas y el total deben persistir.
ERRORES CONOCIDOS Y TROUBLESHOOTING
| Error / Síntoma | Causa probable | Solución |
|---|---|---|
| Pantalla en blanco al publicar | Falta dist/assets o las rutas del build no coinciden |
Confirmar dist/assets/ y base: "/tablero-cdc/" |
| Tarifario abre como modal blanco hasta recargar | Build antiguo / híbrido o assets desactualizados | Generar un build limpio desde el código fuente actual y desplegar exactamente el dist probado |
npm run build falla en TypeScript |
Error de tipos antes de ejecutar Vite | Corregir el error de tsc; no publicar un dist nuevo hasta que el build termine correctamente |
| Botón Tarifario no aparece | Falta permiso o SQL del módulo | Verificar can_manage_tariff_catalog = true y recargar sesión |
| Usuario válido no puede entrar | No existe como activo en tablero_cdc_allowed_users |
Revisar fila, correo normalizado e is_active |
| Error / ausencia de RPC paginada | SQL no aplicado o schema cache desactualizado | Ejecutar supabase_rpc_projects_paginated.sql y revisar Supabase |
| Total tarifado no responde como esperado | RPC/configuración de visibilidad no aplicada | Revisar supabase_pricing_summary_visibility.sql y tablero_cdc_get_pricing_summary |
| Tarifario no carga desde Supabase | Tabla / SQL no aplicado | Revisar tablero_cdc_tariff_catalog y tablero_cdc_tariff_sections |
| Sync a Sheet no ocurre | VITE_WEBHOOK_URL vacío o workflow n8n inactivo |
Revisar .env, webhook y ejecución de n8n |
| Cambios no aparecen en otra ventana | Realtime no habilitado | Ejecutar / revisar supabase_realtime_projects.sql |
| OAuth vuelve a una ruta incorrecta | Redirect URL no autorizada o base incorrecta | Revisar configuración OAuth y /tablero-cdc/ |
MONITOREO
- Supabase: revisar errores de Auth, RLS, RPC y consultas.
- n8n Executions: revisar ejecuciones fallidas del webhook y sincronizadores.
- Browser DevTools: revisar
ConsoleyNetworkante errores de frontend o404. - Gitea: confirmar que el commit de despliegue contiene
dist/index.htmlydist/assets/. - Prueba funcional: abrir la app en una sesión limpia después de cada despliegue.
Output esperado en operación normal
- usuarios autorizados ingresan con Google;
- usuarios no autorizados quedan fuera;
- proyectos cargan paginados;
- cambios persisten en Supabase;
- Realtime mantiene sincronización multiusuario;
- tarifarios muestran únicamente las secciones aplicables;
- costos guardados alimentan el total interno y el resumen global;
- el módulo administrativo solo aparece a quienes tienen permiso;
- el build publicado funciona directamente sin requerir recargar la página.
ESTRUCTURA DEL REPOSITORIO
cdc-project-management/
├── dist/ # Build probado para despliegue
│ ├── assets/ # JS/CSS compilado — obligatorio
│ └── index.html
├── public/ # Favicons y assets públicos
├── src/
│ ├── components/
│ │ ├── board/ # Tarjetas, diálogo y pricing
│ │ ├── tariff/ # Administración del tarifario
│ │ └── ui/ # Componentes de interfaz
│ ├── context/
│ │ └── AuthContext.tsx # Sesión y permisos
│ ├── data/ # Datos de respaldo
│ ├── hooks/
│ ├── lib/
│ │ ├── accessControl.ts
│ │ ├── appLists.ts
│ │ ├── pricingSummaryVisibility.ts
│ │ ├── store.ts
│ │ ├── supabase.ts
│ │ ├── tariffCatalog.ts
│ │ └── tariffSections.ts
│ ├── pages/
│ │ └── BoardPage.tsx
│ ├── App.tsx
│ ├── main.tsx
│ └── styles.css
├── .env.example
├── package.json
├── package-lock.json
├── vite.config.ts
├── tsconfig.json
├── supabase_*.sql # Migraciones / configuración
├── MODULO_TARIFARIO_ADMIN_IMPLEMENTACION.md
├── PAGINACION_MODULO_TARIFARIO.md
├── WMC_TARIFARIO_IMPLEMENTACION.md
├── VALIDACION_MODULO_TARIFARIO.md
├── CORRECCION_BUILD_Y_MODAL_TARIFARIO.md
└── README.md
SEGURIDAD
No commitear
.env
.env.local
.env.production
service_role keys
tokens privados
secretos OAuth
contraseñas
node_modules/
logs con información sensible
Sí se mantiene en este repositorio
.env.example
dist/
dist/assets/
scripts SQL versionados
documentación técnica
La inclusión de dist/ es intencional mientras el procedimiento de producción dependa de desplegar exactamente el build probado en XAMPP.
CHANGELOG
2026-08-07 — Documentación
- README actualizado al estándar GLM IT.
- Se documenta arquitectura, permisos, setup, deploy, testing y troubleshooting.
- Se deja explícito que
dist/assets/forma parte obligatoria del build desplegable.
2026-07-28 — Módulo de tarifario administrativo
- Incorporación del tarifario especial Walmart Connect.
- Administración de secciones generales y por cliente.
- Permiso
can_manage_tariff_catalog. - Creación, edición, desactivación y reactivación de tarifas.
- Compatibilidad con tarifas gestionadas por Sheet y por app.
- Corrección del build / renderizado del modal del tarifario.
- Paginación de secciones y tarifas:
- 6 secciones por página.
- 10 tarifas por página.
distvalidado mediante XAMPP bajo/tablero-cdc/.
DECISIONS LOG
DEC-001 — Acceso administrado desde Supabase
- Contexto: evitar listas rígidas de usuarios dentro del frontend.
- Decisión: utilizar
tablero_cdc_allowed_users. - Razón: permite habilitar, deshabilitar y asignar permisos sin recompilar la aplicación.
DEC-002 — Permisos granulares
- Contexto: no todos los usuarios deben administrar costos, eliminar proyectos, controlar el resumen o editar tarifarios.
- Decisión: usar flags independientes en Supabase.
- Razón: mantener privilegio mínimo y separar responsabilidades.
DEC-003 — Tarifario híbrido Sheet + App
- Contexto: las tarifas generales existentes se mantienen desde el proceso operativo, mientras nuevos tarifarios especiales pueden administrarse desde la app.
- Decisión: utilizar
managed_bypara distinguir origen y proteger registros administrados en la aplicación. - Razón: evitar que el sincronizador del Sheet sobrescriba cambios creados desde el módulo administrativo.
DEC-004 — Desactivar en lugar de eliminar tarifas históricas
- Contexto: una tarifa puede estar referenciada por proyectos anteriores.
- Decisión: usar
is_active = falsecomo operación habitual. - Razón: conservar trazabilidad e integridad histórica.
DEC-005 — Base de Vite fija en /tablero-cdc/
- Contexto: la aplicación se publica dentro de una subcarpeta.
- Decisión: configurar
base: "/tablero-cdc/". - Razón: generar rutas correctas para JS, CSS y assets en producción.
DEC-006 — Publicar exactamente el dist validado
- Contexto: el build de producción debe comportarse igual que la versión probada antes del despliegue.
- Decisión: validar el
disten XAMPP y subir ese mismo build al repositorio / servidor. - Razón: evitar diferencias entre el artefacto probado y el artefacto publicado.
CONTACTOS DEL PROYECTO
| Rol | Nombre | Contacto |
|---|---|---|
| IT Manager | Luis Matos | lmatos@gomezleemarketing.com |
| Developer Principal | Isaac Aracena | iaracena@gomezleemarketing.com |
DEFINITION OF DONE
Para considerar una versión lista para producción:
- Criterios funcionales de la versión verificados.
- Código relevante commiteado y pusheado a Gitea.
- README actualizado cuando cambie arquitectura, setup o comportamiento.
- Variables requeridas documentadas en
.env.example. - No existen secretos privados en el repositorio.
- SQL nuevo / modificado aplicado y validado en Supabase cuando corresponda.
npm run buildtermina sin errores cuando se genera un nuevo build.- El
distresultante contieneindex.htmlyassets/. - El mismo
distque se publicará fue probado en XAMPP bajo/tablero-cdc/. - Login y control de acceso validados.
- Crear / editar / consultar proyectos funciona.
- Links persisten correctamente.
- Realtime funciona cuando la versión toca sincronización.
- Tarifario general funciona.
- Tarifarios por cliente funcionan.
- Permisos del módulo de tarifario validados.
- Total tarifado global / filtrado se actualiza correctamente.
- Aplicación probada en ambiente real después del despliegue.
- Output final validado por el responsable funcional correspondiente.
Documento mantenido por el equipo GLM IT.