diff --git a/README(20260807-134416).md b/README(20260807-134416).md new file mode 100644 index 0000000..bfec3d1 --- /dev/null +++ b/README(20260807-134416).md @@ -0,0 +1,674 @@ +# 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 | +| **Estado** | Operativo · mantenimiento evolutivo | +| **Developer Principal** | Isaac Aracena | +| **IT Manager** | Luis Matos | +| **Fecha de Inicio** | No documentada en el repositorio | +| **Fecha de Cierre Estimada** | N/A · producto interno en evolución | +| **Ciclo Shape Up** | No documentado | +| **Repositorio Gitea** | `Isaac_Aracena/cdc-project-management` | +| **Board de Ejecución** | Pendiente de enlazar | +| **PRD del Proyecto** | Pendiente de enlazar | +| **Ruta de despliegue** | `/tablero-cdc/` | + +--- + +## 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 + +```text +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 + +```text +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 | +| Hosting | Servidor web GLM | Publicación del `dist` | + +### 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 + +1. **El acceso no depende solamente del dominio del correo.** El usuario debe autenticarse con Google y existir activo en `public.tablero_cdc_allowed_users`. + +2. **Los permisos especiales se controlan desde Supabase**, principalmente mediante: + - `can_delete_projects` + - `can_manage_internal_pricing` + - `can_control_pricing_summary` + - `can_manage_tariff_catalog` + +3. **No se deben hardcodear administradores nuevos en el frontend.** Los accesos y permisos se administran en Supabase. + +4. **Los tarifarios generales** están disponibles para los clientes que no dependen de un tarifario especial. + +5. **Los tarifarios por cliente** solo aparecen al seleccionar el cliente asociado a esa sección. + +6. **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. + +7. **Las tarifas administradas desde la app** quedan marcadas con `managed_by = 'app'`. El sincronizador del Sheet no debe sobrescribirlas. + +8. **Las tarifas históricas no deben eliminarse como operación normal.** Se deben desactivar para conservar integridad histórica. + +9. **Los costos seleccionados en un proyecto** se guardan en `tablero_cdc_project_pricing_items` y alimentan el total interno del proyecto. + +10. **El Total Tarifado Global** se calcula mediante la RPC `tablero_cdc_get_pricing_summary` y respeta los filtros activos. Los proyectos creados con tarifarios actuales o futuros siguen formando parte del total al guardar su costo interno. + +11. **La visibilidad del Total Tarifado** se controla mediante configuración y permisos de Supabase. + +12. **La estructura del Google Sheet original debe mantenerse estable**, especialmente cuando es consumida por Power BI. Cualquier cambio estructural debe validarse previamente. + +13. **Paginación actual:** + - proyectos: `24` por página; + - secciones del módulo de tarifario: `6` por página; + - tarifas / piezas del módulo: `10` por página. + +14. 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: + +```env +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: + +```text +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: + +```text +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: + +```text +can_manage_tariff_catalog = true +``` + +### Instalación local + +```bash +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: + +```bash +npm run dev +``` + +La configuración actual de Vite usa: + +```text +http://localhost:3000/tablero-cdc/ +``` + +### Build + +```bash +npm run build +``` + +El script ejecuta: + +```text +tsc && vite build +``` + +Por lo tanto, un error de TypeScript detiene el build y debe corregirse antes de publicar. + +### Preview + +```bash +npm run preview +``` + +--- + +## INSTALACIÓN / DEPLOY + +La aplicación está compilada para funcionar debajo de: + +```text +/tablero-cdc/ +``` + +Configuración en `vite.config.ts`: + +```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: + +```text +dist/ +├── assets/ +├── index.html +├── favicon.ico +└── demás archivos públicos generados +``` + +> `dist/assets/` es obligatorio. Sin esa carpeta, `index.html` no podrá cargar correctamente el JavaScript y CSS compilados. + +Flujo recomendado: + +1. Probar la aplicación con `npm run dev`. +2. Generar el build con `npm run build`. +3. Probar **ese mismo `dist`** en XAMPP bajo `/tablero-cdc/`. +4. No regenerar el build después de la validación si se desea desplegar exactamente la versión probada. +5. Subir a Gitea el mismo `dist`, incluyendo `dist/assets/`. +6. Copiar ese `dist` validado al servidor. +7. Probar login, tablero, tarifario y una apertura directa sin recargar la página. + +--- + +## CÓMO FUNCIONA + +### Flujo paso a paso + +1. El usuario entra a la aplicación. +2. Supabase Auth inicia o recupera la sesión Google. +3. La app consulta `tablero_cdc_allowed_users`. +4. Si el usuario no está activo/autorizado, la sesión se rechaza. +5. Si está autorizado, la app carga sus permisos. +6. El tablero consulta los proyectos desde Supabase mediante RPC paginada. +7. Los filtros se aplican desde la consulta y no requieren descargar toda la base. +8. Realtime mantiene sincronizadas las ventanas activas. +9. Al crear o editar un proyecto, la información se persiste en Supabase. +10. Si `VITE_WEBHOOK_URL` está configurado, la aplicación dispara la sincronización correspondiente hacia n8n. +11. Los costos internos se guardan como líneas de pricing por proyecto. +12. El total tarifado se calcula en Supabase mediante RPC. +13. 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: + +```text +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: + +- `Uniformes` +- `Photobooth` +- `Arco de entrada` + +Subtotal esperado: + +```text +$480.00 +``` + +Agregando manualmente: + +```text +Propuesta general Walmart Connect = $900.00 +``` + +Total esperado: + +```text +$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 `Console` y `Network` ante errores de frontend o `404`. +- **Gitea:** confirmar que el commit de despliegue contiene `dist/index.html` y `dist/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 + +```text +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 + +```text +.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 + +```text +.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. +- `dist` validado 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_by` para 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 = false` como 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 `dist` en 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 | +|---|---|---| +| Director Creativo / Owner funcional | Gerardo Marrero | `gmarrero@gomezleemarketing.com` | +| 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 build` termina sin errores cuando se genera un nuevo build. +- [ ] El `dist` resultante contiene `index.html` y `assets/`. +- [ ] El mismo `dist` que 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**.