Files
cdc-project-management/README.md
T
2026-08-07 13:50:02 +00:00

675 lines
24 KiB
Markdown

# 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**.