# Manual de Integración Técnica: Sistema VIC (SmartTable)

**Versión del Protocolo:** 1.0  
**Ámbito:** Integración Front-End (Iframe)  
**Mecanismo:** `window.postMessage` (Unidireccional Host $\to$ Client)

## 1. Introducción y Propósito

Un **VIC (Visualizador Interactivo Conectado)** es una aplicación web externa que se ejecuta dentro de un `iframe` en el entorno de SmartTable.

SmartTable actúa como el **Host**: se encarga de la autenticación, la navegación por carpetas, el filtrado de datos y la gestión del estado global. Cuando el usuario visualiza un conjunto de datos, el Host inyecta esos datos filtrados y el contexto de seguridad al VIC para que este ejecute su propósito (visualización, gestión, formularios, etc.).

**Nota de Diseño:** Un VIC puede ser tan simple como una página dedicada a una sola regla específica ("Formulario de Bitácora") o tan complejo como una suite multifuncional ("Gestor de Incidentes Genérico"). La implementación depende enteramente del caso de uso.

---

## 2. El Protocolo de Comunicación

El Host envía actualizaciones de datos en tiempo real mediante eventos `message`. El VIC debe estar "escuchando" estos eventos desde el momento en que se monta.

### 2.1 El Evento (Trigger)

El evento se dispara en los siguientes casos:

1. **Carga Inicial:** Al terminar de cargar el iframe.
2. **Navegación:** El usuario profundiza en el árbol de carpetas del Host.
3. **Filtrado:** El usuario aplica un filtro de color o busca texto.
4. **Polling:** El Host detecta cambios en el backend y actualiza la vista.

### 2.2 Estructura del Payload (Contrato de Datos)

El objeto `event.data` recibido tendrá siempre la siguiente estructura JSON:

```typescript
{
  type: "DATA_SYNC",      // Identificador fijo del evento
  
  // Array de objetos. Contiene las filas visibles en el Host.
  // La estructura de las filas es dinámica (depende de la regla visualizada).
  data: Array<Record<string, any>>, 

  // Metadatos de contexto, seguridad y estado
  meta: {
    ruleId: string,       // UUID único de la regla activa en el Host
    ruleName: string,     // Nombre legible (ej: "Incidentes Críticos")
    
    // Métricas
    totalRows: number,    // Total de registros sin filtrar
    filteredCount: number,// Cantidad de registros enviados en 'data'
    
    // Tiempos (Epoch ms)
    timestamp: number,    // Momento del envío del mensaje
    dataTimestamp: number,// Momento de generación de datos en backend (Para consistencia)

    // Seguridad
    token: string,        // JWT Access Token activo. Permite al VIC consumir APIs del ecosistema sin relogin.

    // Filtros aplicados por el usuario (Contexto visual)
    activeFilters: Record<string, string>, // Ej: { "Estado": "Abierto" }
    
    activeColor: {        // Filtro de semáforo (si aplica)
        groupId: string,
        groupName: string,
        conditionId: string | null,
        conditionName: string
    } | null
  }
}
```

---

## 3. Ejemplos de Data Transmitida

El desarrollador debe tener en cuenta que el contenido de `data` cambia según la regla que el usuario esté mirando en el Host.

#### Ejemplo A: Regla de Negocio (Incidentes)

```json
{
    "type": "DATA_SYNC",
    "data": [
        {
            "Incident Number": "INC000008641380",
            "Status": "Resuelto",
            "Encargada": "Carolina",
            "AlertResult": "Atencion Inmediata..."
        }
        // ... más filas
    ],
    "meta": {
        "ruleName": "Monitoreo Incidentes",
        "filteredCount": 7,
        "token": "eyJhbGciOi...",
        "activeFilters": { "Encargada": "Carolina" }
    }
}
```

#### Ejemplo B: Infraestructura (Servidores)

```json
{
    "type": "DATA_SYNC",
    "data": [
        {
            "Servidor": "AWS Ubuntu (eva)",
            "Archivo": "/etc/hosts",
            "Ultima_Modificacion_Epoch": 1766949252000
        }
    ],
    "meta": {
        "ruleName": "Archivos Críticos",
        "activeFilters": {}
    }
}
```

---

## 4. Guía de Implementación

Para integrar un VIC, se deben seguir estos pasos técnicos mínimos.

### Paso 1: Configurar el Listener

El VIC debe ser capaz de recibir y procesar el mensaje.

```javascript
// Ejemplo genérico en JS
function initListener() {
    window.addEventListener('message', (event) => {
        // 1. Validar estructura básica
        const payload = event.data;
        if (!payload || payload.type !== 'DATA_SYNC') return;

        console.log(`[VIC] Datos recibidos: ${payload.data.length} filas`);

        // 2. Procesar datos (Renderizar UI, guardar en Store, etc.)
        updateApplicationState(payload.data, payload.meta);
    });
}
```

### Paso 2: Autenticación (Uso del Token)

El VIC **no debe implementar pantalla de login**. Debe utilizar el `meta.token` proporcionado para realizar peticiones HTTP a las APIs del ecosistema (si su funcionalidad lo requiere).

```javascript
async function fetchAdditionalDetails(id) {
    // Asumimos que el token se guardó en un estado global al recibir el mensaje
    const token = globalState.token; 

    const response = await fetch(`https://api.dominio.com/recurso/${id}`, {
        headers: {
            'Authorization': `Bearer ${token}`, // Inyección del token
            'Content-Type': 'application/json'
        }
    });
    return response.json();
}
```

### Paso 3: Validación de Contexto (Opcional pero Recomendado)

Dependiendo de la naturaleza del VIC, puede ser necesario validar si los datos recibidos son "compatibles" con la funcionalidad que ofrece.

* **VIC Ad-Hoc (Dedicado):** Si el VIC fue construido exclusivamente para la regla "Vacaciones", puede verificar `meta.ruleId` o `meta.ruleName`. Si no coinciden, muestra un mensaje "Configuración incorrecta" o pantalla en blanco.
* **VIC Genérico/Dinámico:** Si el VIC es una herramienta multipropósito (ej. un graficador), debe inspeccionar las columnas dentro de `data` para decidir si puede graficar la información o qué tipo de gráfico mostrar.

---

## 5. Recomendaciones y Best Practices

1. **Reactividad Total:** El Host puede enviar actualizaciones frecuentes (el usuario filtra, busca o cambia de carpeta). El VIC debe estar preparado para reemplazar completamente su dataset visualizado en cualquier momento, no solo al cargar la página.
2. **Consistencia de Datos:** Si el VIC necesita consultar más detalles al backend para un registro específico (patrón *Double Fetch*), se recomienda enviar el `meta.dataTimestamp` en la petición. Esto asegura que el backend devuelva la versión del dato coherente con lo que el usuario está viendo en ese instante.
3. **Idempotencia:** Si el VIC permite ejecutar acciones (ej. botones de "Aprobar", "Reintentar"), genere claves de idempotencia locales. Los usuarios pueden hacer doble clic accidentalmente o el Host puede reenviar datos.
4. **Manejo de Estados Vacíos:** Si `meta.filteredCount` es 0 o el array `data` está vacío, el VIC debe mostrar un estado amigable ("Sin registros seleccionados") en lugar de una pantalla en blanco o error.

## 6. Ejemplos Adicionales y Variantes de Filtrado

A continuación, se presentan cuatro trazas reales de comunicación. Estos ejemplos ilustran cómo varía el payload `DATA_SYNC` dependiendo de la interacción del usuario en el Host (navegación, selección de alertas, cambio de regla, etc.). El VIC debe ser capaz de interpretar estos estados.

### Caso A: Filtrado por Navegación (Drill-down)

**Escenario:** El usuario ha navegado a través de las carpetas del árbol de la regla (ej. Seleccionó "Encargada: Carolina" y luego el sub-grupo "StatusFinal: Op - Sin Contacto").
**Nota para el VIC:** `activeFilters` contiene la ruta de navegación. `activeColor` es nulo porque no se ha seleccionado un estado específico del dashboard.

```json
{
    "type": "DATA_SYNC",
    "data": [
        {
            "Incident Number": "INC000008641380",
            "StatusFinal": "Op - Sin Contacto con Cliente",
            "Encargada": "Carolina",
            "Status": "Resuelto",
            "AlertResult": "Monitores: Atencion Inmediata..."
        },
        {
            "Incident Number": "INC000008642177",
            "StatusFinal": "Op - Sin Contacto con Cliente",
            "Encargada": "Carolina",
            "Status": "Resuelto",
            "AlertResult": "Monitores: Atencion Inmediata..."
        }
        // ... 5 items más
    ],
    "meta": {
        "ruleId": "2a25e2d3-f272-45ac-a12e-1dc4fa537c61",
        "ruleName": "Monitoreo (ESTE SI)",
        "totalRows": 59,
        "filteredCount": 7,
        "timestamp": 1767021924174,
        "activeFilters": {
            "Encargada": "Carolina",
            "StatusFinal": "Op - Sin Contacto con Cliente"
        },
        "activeColor": null
    }
}
```

### Caso B: Cambio de Contexto (Estructura de Datos Diferente)

**Escenario:** El usuario cambió de la regla de "Incidentes" a una regla de "Auditoría de Archivos".
**Nota para el VIC:** El esquema de `data` ha cambiado radicalmente (nuevas columnas). Si el VIC es genérico, debe redibujar la tabla/gráfico. Si el VIC es específico para Incidentes, debería mostrar un estado de "Esperando datos compatibles" o desactivarse.

```json
{
    "type": "DATA_SYNC",
    "data": [
        {
            "Alias del Servidor": "AWS Ubuntu (eva)",
            "Archivo": "/home/ubuntu/dev/headers.json",
            "Ultima_Modificacion_Epoch": 1766949252000,
            "Servidor": "localhost"
        },
        {
            "Alias del Servidor": "minimobs",
            "Archivo": "/var/opt/helix-sql/cookies.json",
            "Ultima_Modificacion_Epoch": 1766950507000,
            "Servidor": "143...."
        }
        // ... más items
    ],
    "meta": {
        "ruleId": "d6b773eb-b3fe-461b-a9e0-eccf76df72c6",
        "ruleName": "Archivos Críticos",
        "totalRows": 6,
        "filteredCount": 6,
        "timestamp": 1767021985551,
        "activeFilters": {},
        "activeColor": null
    }
}
```

### Caso C: Filtrado Global por Estado/Color

**Escenario:** El usuario hizo clic en una "burbuja" o KPI de color en el dashboard (ej. Alerta "Crítica") sin haber navegado por carpetas.
**Nota para el VIC:** `activeFilters` está vacío (estamos en la raíz), pero `activeColor` está poblado. El array `data` contiene solo los registros que cumplen con esa condición de color.

```json
{
    "type": "DATA_SYNC",
    "data": [
        {
            "Incident Number": "INC000008644404",
            "StatusFinal": "Op - Sin Contacto con Cliente",
            "AlertResult": "Monitores: Critico Resuelto...",
            "Status": "Resuelto"
        },
        {
            "Incident Number": "INC000008637472",
            "StatusFinal": "Op - En Observacion con Client",
            "AlertResult": "Monitores: Critico Resuelto...",
            "Status": "Resuelto"
        }
        // ... 1 item más
    ],
    "meta": {
        "ruleId": "2a25e2d3-f272-45ac-a12e-1dc4fa537c61",
        "ruleName": "Monitoreo (ESTE SI)",
        "totalRows": 59,
        "filteredCount": 3,
        "timestamp": 1767022118878,
        "activeFilters": {},
        "activeColor": {
            "groupId": "e90dd8ea-1446-4e08-8878-07986db27b26",
            "groupName": "Alertas",
            "conditionId": "ef68c7da-2b96-436d-a812-720942e1d73e",
            "conditionName": "Critica"
        }
    }
}
```

### Caso D: Selección Específica y Filtros Combinados

**Escenario:** El usuario navegó profundamente hasta seleccionar un registro específico (o grupo muy pequeño) Y ADEMÁS tiene activo un filtro de color ("Urgente").
**Nota para el VIC:** `filteredCount` es muy bajo (1). `activeFilters` incluye identificadores únicos (como el número de incidente). `activeColor` también está aplicando restricción. Esta es la vista más específica posible.

```json
{
    "type": "DATA_SYNC",
    "data": [
        {
            "Incident Number": "INC000008638921",
            "StatusFinal": "Op - En Observacion con Client",
            "AlertResult": "Monitores: Urgente Resuelto...",
            "Encargada": "Carolina",
            "Status": "Resuelto"
        }
    ],
    "meta": {
        "ruleId": "2a25e2d3-f272-45ac-a12e-1dc4fa537c61",
        "ruleName": "Monitoreo (ESTE SI)",
        "totalRows": 59,
        "filteredCount": 1,
        "timestamp": 1767022207936,
        "activeFilters": {
            "Encargada": "Carolina",
            "StatusFinal": "Op - En Observacion con Client",
            "Incident Number": "INC000008638921"
        },
        "activeColor": {
            "groupId": "e90dd8ea-1446-4e08-8878-07986db27b26",
            "groupName": "Alertas",
            "conditionId": "533fe54b-6fb0-4a45-be74-c82c3a532379",
            "conditionName": "Urgente"
        }
    }
}
```
