Motor de Rastreabilidade e Notificações da Home

1. Visão Geral e Modelo de Duas Camadas

O ecossistema yzex-connect adota uma arquitetura rigorosa de Duas Camadas para o hub de avisos operacionais da interface (Home), segregando o Fato Físico do Incidente da Apresentação de Interface (Read Model):

               FONTES DE DETECÇÃO
   ┌────────────────────────────────────────┐
   │  In-Band: PostgreSQL Status Triggers   │
   │  Out-of-Band: Temporal Reconciler      │
   └───────────────────┬────────────────────┘
                       │
                       ▼
   ┌────────────────────────────────────────┐
   │      connect.resource_alert_states     │  <-- FONTE ÚNICA DA VERDADE (SSOT)
   │  (Estado físico ativo por recurso)     │      Um registro por incidente real
   └───────────────────┬────────────────────┘
                       │
                       ▼
   ┌────────────────────────────────────────┐
   │ connect.system_notification_resources  │  <-- PONTE RELACIONAL
   │  (Associação N:N Notificação x Alerta) │      Contagem derivada via COUNT()
   └───────────────────┬────────────────────┘
                       │
                       ▼
   ┌────────────────────────────────────────┐
   │      connect.system_notifications      │  <-- PROJEÇÃO DE LEITURA (READ MODEL)
   │  (Avisos consolidados por bucket_key)  │      Deduplicado e amigável para o feed
   └───────────────────┬────────────────────┘
                       │
                       ▼
            BFF + RBAC + SWR CACHE
                       │
                       ▼
              HomeNotifications.vue
  1. Fonte Única da Verdade (connect.resource_alert_states): Representa com fidelidade estrita se um recurso físico (ex.: whatsapp_instance ou location) está em estado incidente (ACTIVE) ou resolvido (RESOLVED).

  2. Ponte Relacional Associativa (connect.system_notification_resources): Garante a integridade relacional entre avisos agregados e incidentes físicos, prevenindo qualquer anomalia de contagem (count drift).

  3. Projeção Agregada de Leitura (connect.system_notifications): Tabela otimizada para alimentação reativa do feed, com coluna gerada imutável bucket_key STORED e contadores calculados atomicamente.

2. Invariantes Matemáticas de Integridade

O motor satisfaz compulsoriamente seis propriedades formais:

Invariante 1 (Garantia de Existência Ativa)

Para toda notificação com status = 'ACTIVE', existe estritamente $\ge 1$ registro em connect.resource_alert_states com status = 'ACTIVE' associado via connect.system_notification_resources.

Invariante 2 (Autorresolução Estrita)

Para toda notificação com status = 'AUTO_RESOLVED', existem exatamente $0$ registros em connect.resource_alert_states com status = 'ACTIVE' vinculados.

Invariante 3 (Unicidade Estrutural de Bucket)

Para qualquer tupla (organization_id, bucket_key), existe no máximo $1$ registro em connect.system_notifications com status = 'ACTIVE' em qualquer instante de tempo.

Invariante 4 (Isolamento Multi-Tenant Cruzado)

Para todo registro na ponte connect.system_notification_resources, a tupla (organization_id, partner_id) da notificação é estritamente idêntica à do estado de alerta associado.

Invariante 5 (Imutabilidade Terminal)

Nenhum registro com status = 'AUTO_RESOLVED' em system_notifications ou status = 'RESOLVED' em resource_alert_states pode sofrer mutação ou retornar a ACTIVE.

Invariante 6 (Convergência e Idempotência de Reconstrução)

A execução da rotina connect.rebuild_all_system_notifications é estritamente convergente e idempotente:

\$rebuild(rebuild(State)) \equiv rebuild(State)\$

3. Concorrência e Advisory Locks Ordenados

Para neutralizar deadlocks em cenários de alta concorrência (ex.: quedas em massa de instâncias gerando webhooks simultâneos), o orquestrador connect.reconcile_incident_buckets implementa Advisory Locks Transacionais Ordenados Léxica:

-- Ordenação léxica mandatória para eliminação universal de deadlocks
SELECT array_agg(b ORDER BY b ASC) INTO v_buckets FROM unnest(v_buckets) AS b;

-- Aquisição sequencial determinística dos locks
FOREACH v_bucket IN ARRAY v_buckets LOOP
    v_lock_key := hashtextextended('bucket_lock:' || v_bucket, 0);
    PERFORM pg_advisory_xact_lock(v_lock_key);
END LOOP;

4. Catálogo de Mensagens Formais Dinâmicas

A agregação anti-saturação formata os títulos e mensagens conforme a granularidade e contagem ativa:

Evento Escopo Qtd Título Mensagem Ação (CTA)

whatsapp_disconnected

Unidade

1

WhatsApp Desconectado

WhatsApp desconectado em {location_name}

Resolver

whatsapp_disconnected

Unidade

>1

WhatsApp Desconectado

WhatsApp desconectado em {location_name}

Resolver

whatsapp_disconnected

Organização

1

WhatsApp Desconectado

WhatsApp desconectado em {location_name}

Resolver

whatsapp_disconnected

Organização

>1

WhatsApp Desconectado

WhatsApp desconectado em {affected_count} unidades!

Resolver

whatsapp_unlinked_unit

Unidade

1

Canal de Atendimento Pendente

Esta unidade ainda não possui uma linha de WhatsApp vinculada. Para iniciar os atendimentos neste local, vincule uma linha existente ou configure um novo canal.

Vincular Linha

whatsapp_unlinked_unit

Organização

1

Unidade sem Canal de Atendimento

A unidade {location_name} não possui uma linha de WhatsApp vinculada. Associe uma linha para disponibilizar o canal de atendimento nesta filial.

Vincular Linha

whatsapp_unlinked_unit

Organização

>1

Unidades sem Canal de Atendimento

Identificamos {affected_count} unidades da sua organização sem linha de WhatsApp vinculada. Realize a vinculação para habilitar o atendimento nessas filiais.

Configurar Unidades

5. Publicação Realtime CDC e Identidade de Réplica

Para possibilitar a sincronização reativa em tempo real com a camada de frontend Nuxt 3 sem necessidade de polling HTTP periódico:

  1. Publicação supabase_realtime: As tabelas connect.system_notifications e connect.user_notification_dismissals são registradas na publicação PostgreSQL supabase_realtime.

  2. REPLICA IDENTITY FULL: Ambas as tabelas são configuradas compulsoriamente com REPLICA IDENTITY FULL. Essa diretiva instrui o PostgreSQL a registrar a imagem completa de todas as colunas no WAL (Write-Ahead Log) em mutações de UPDATE e DELETE. Dessa forma, o motor do Supabase Realtime tem acesso aos identificadores de isolamento (organization_id, partner_id, location_id, user_id) para avaliar filtros declarativos e políticas de Row-Level Security (RLS) sob o JWT do usuário conectado.