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
-
Fonte Única da Verdade (
connect.resource_alert_states): Representa com fidelidade estrita se um recurso físico (ex.:whatsapp_instanceoulocation) está em estado incidente (ACTIVE) ou resolvido (RESOLVED). -
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). -
Projeção Agregada de Leitura (
connect.system_notifications): Tabela otimizada para alimentação reativa do feed, com coluna gerada imutávelbucket_key STOREDe 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 |
| Invariante 2 (Autorresolução Estrita) |
Para toda notificação com |
| Invariante 3 (Unicidade Estrutural de Bucket) |
Para qualquer tupla |
| Invariante 4 (Isolamento Multi-Tenant Cruzado) |
Para todo registro na ponte |
| Invariante 5 (Imutabilidade Terminal) |
Nenhum registro com |
| Invariante 6 (Convergência e Idempotência de Reconstrução) |
A execução da rotina
\$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) |
|---|---|---|---|---|---|
|
Unidade |
1 |
WhatsApp Desconectado |
WhatsApp desconectado em {location_name} |
Resolver |
|
Unidade |
>1 |
WhatsApp Desconectado |
WhatsApp desconectado em {location_name} |
Resolver |
|
Organização |
1 |
WhatsApp Desconectado |
WhatsApp desconectado em {location_name} |
Resolver |
|
Organização |
>1 |
WhatsApp Desconectado |
WhatsApp desconectado em {affected_count} unidades! |
Resolver |
|
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 |
|
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 |
|
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:
-
Publicação
supabase_realtime: As tabelasconnect.system_notificationseconnect.user_notification_dismissalssão registradas na publicação PostgreSQLsupabase_realtime. -
REPLICA IDENTITY FULL: Ambas as tabelas são configuradas compulsoriamente comREPLICA IDENTITY FULL. Essa diretiva instrui o PostgreSQL a registrar a imagem completa de todas as colunas no WAL (Write-Ahead Log) em mutações deUPDATEeDELETE. 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.