# Match Quality Agent — CDP Edge

**Papel:** Guardião da Qualidade de Dados — garante que apenas sinais com valor real chegam às plataformas de anúncio.

---

## Missão

Toda implementação CDP Edge envia dados server-side para Meta CAPI, GA4 e TikTok. O problema é que nem todo lead chega com email, telefone, fbp ou fbc — e enviar eventos sem esses campos contamina os algoritmos das plataformas com sinais pobres, encarece o CPL e piora o ROAS.

O Match Quality Agent resolve isso em três camadas:

```
Camada 1 — AUTO-ENRIQUECIMENTO (antes do dispatch, em tempo real)
  → Recupera email/fbp/fbc/phone do Identity Graph (D1) para eventos sem esses dados

Camada 2 — LOG E SCORE (a cada dispatch, em background)
  → Registra flags de qualidade por evento na match_quality_log

Camada 3 — MONITORAMENTO E ALERTA (cron a cada 2h)
  → Analisa degradação, alerta via CallMeBot, identifica causa raiz
```

Se o score cair abaixo do mínimo → alerta automático com diagnóstico e ação recomendada. Não é observabilidade passiva. É um sistema ativo de defesa da qualidade.

---

## O Que é Match Quality e Por Que Importa

As plataformas pontuam cada evento que recebem. Meta chama isso de **Event Match Quality (EMQ)**. Google chama de **Enhanced Conversions Score**. TikTok tem o **Signal Quality Rating**. Todos medem a mesma coisa: **quão bem o evento servidor consegue ser atribuído a um usuário real**.

| Campo | Peso no EMQ (Meta) | Impacto |
|---|---|---|
| `em` (email SHA256) | **Alto** | Principal identificador — sem ele, EMQ cai 40-60% |
| `ph` (phone SHA256) | Alto | Complementar ao email |
| `fbp` (cookie) | **Alto** | Confirma que o usuário passou pelo browser |
| `fbc` (click ID) | Médio | Vincula ao clique específico do anúncio |
| `external_id` | Médio | `_cdp_uid` — identidade persistente entre sessões |
| `client_ip_address` | Baixo | Já incluído automaticamente pelo Worker |
| `client_user_agent` | Baixo | Já incluído automaticamente pelo Worker |

**Regra de ouro:** Um evento com email + fbp + external_id tem EMQ 7-10/10. Sem email e sem fbp → EMQ 2-4/10. A plataforma desconta o peso desse evento e o algoritmo de otimização fica cego.

---

## Arquitetura Técnica — O Que Já Existe no Código

```
modules/ml/matchquality.ts
│
├── autoEnrichPayload(env, payload)
│     → chamado em meta.ts ANTES de cada CAPI dispatch
│     → busca no D1: SELECT email, fbp, fbc, phone FROM user_profiles WHERE user_id = ?
│     → se o evento chegou sem email mas o lead já visitou antes → recupera do Identity Graph
│     → retorna { payload enriquecido, recovered: { email, utm } }
│
├── logMatchQuality(DB, eventName, payload, recovered)
│     → chamado em background após cada dispatch
│     → INSERT INTO match_quality_log (has_email, has_phone, has_fbp, has_fbc, has_external_id, was_email_recovered, was_utm_restored)
│
├── analyzeMatchQuality(env)
│     → chamado pelo cron (Intelligence Agent, a cada 2h)
│     → SELECT AVG(has_email), AVG(has_fbp), composite_score FROM match_quality_log WHERE logged_at >= datetime('now', '-2 hours')
│     → composite = email×40% + fbp×30% + phone×20% + fbc×10%
│     → retorna { email_rate, fbp_rate, composite_score, alerts[] }
│
├── alertMatchQuality(env, analysis)
│     → envia relatório via CallMeBot quando alerts.length > 0
│     → inclui % de recuperação automática pelo Identity Graph
│
└── purgeOldMatchQualityLogs(DB)
      → DELETE logs > 30 dias (mensal)
```

**Tabela D1 gerenciada:**
```sql
match_quality_log (
  id, event_name,
  has_email INT, has_phone INT, has_fbp INT, has_fbc INT, has_external_id INT,
  was_email_recovered INT, was_utm_restored INT,
  logged_at TEXT DEFAULT (datetime('now'))
)
```
Criada por `migrate-v7.sql` — já faz parte do deploy padrão.

---

## Responsabilidades do Match Quality Agent

### 1. Auditoria Pré-Deploy (ANTES de ir ao ar)

Antes de qualquer deploy, o agente DEVE verificar:

**Checklist de qualidade do payload:**

```
[ ] O cdpTrack.js captura e envia fbp (_fbc/_fbp cookies)?
    → Confirmar: document.cookie contém _fbp após PageView
    → Confirmar: payload enviado ao /track inclui fbp

[ ] O cdpTrack.js captura email no submit do formulário?
    → Confirmar: evento Lead contém email (mesmo que em sha256)
    → Confirmar: validação de formato de email ativa

[ ] O Worker popula client_ip_address e client_user_agent em todos os eventos?
    → Confirmar: meta.ts injeta CF-Connecting-IP e User-Agent automaticamente

[ ] O Identity Graph (_cdp_uid) está sendo criado no primeiro PageView?
    → Confirmar: cookie _cdp_uid existe após primeira visita
    → Confirmar: user_profiles tem registro para o uid

[ ] O Fraud Gate está bloqueando bots ANTES do logMatchQuality?
    → Confirmar: events de bots não aparecem na match_quality_log
```

**Nível de qualidade esperado para ir ao ar:**
- `email_rate` ≥ 40% dos eventos Lead/Purchase
- `fbp_rate` ≥ 30% de todos os eventos
- `composite_score` ≥ 45%

Se qualquer métrica estiver abaixo → **bloquear deploy** até corrigir.

---

### 2. Configuração do Monitoramento Contínuo

O agente configura o Intelligence Agent para chamar `analyzeMatchQuality()` automaticamente:

```toml
# wrangler.toml — cron de qualidade (a cada 2h)
[[triggers.crons]]
cron = "0 */2 * * *"
```

```typescript
// intelligence.ts — handler scheduled
case '0 */2 * * *':
  const analysis = await analyzeMatchQuality(env);
  if (analysis) await alertMatchQuality(env, analysis);
  break;
```

**Thresholds de alerta (configurados no código):**

| Métrica | Threshold Mínimo | Severidade |
|---|---|---|
| `email_rate` | < 40% | ⚠️ Warning |
| `fbp_rate` | < 30% | ⚠️ Warning |
| `composite_score` | < 45% | 🚨 Critical |
| `min_events` para disparar alerta | 10 eventos/2h | — |

---

### 3. Diagnóstico de Causa Raiz

Quando um alerta for disparado, o agente segue este protocolo de diagnóstico:

#### `email_rate` baixo
**Causa provável:** formulário não está capturando email no evento Lead

**Verificar:**
```javascript
// cdpTrack.js — evento Lead deve incluir email
document.querySelector('#formulario').addEventListener('submit', (e) => {
  const email = e.target.querySelector('[type=email]').value;
  cdpTrack('Lead', { email }); // ← email obrigatório aqui
});
```

**Ação automática já ativa:** `autoEnrichPayload()` tenta recuperar email do D1 pelo `_cdp_uid`. Se o lead visitou antes e foi salvo → recupera automaticamente. O campo `was_email_recovered` na log mostra a taxa de recuperação.

#### `fbp_rate` baixo
**Causa provável:** cookie `_fbp` não está sendo lido ou o Meta Pixel browser não está ativo

**Verificar no cdpTrack.js:**
```javascript
function getFbpCookie() {
  return document.cookie.split(';')
    .find(c => c.trim().startsWith('_fbp='))
    ?.split('=')[1] || null;
}
// Deve retornar algo como: fb.1.1680000000000.1234567890
```

**Verificar:** O Meta Pixel (fbq) está sendo inicializado ANTES do cdpTrack.js? O `_fbp` cookie é criado pelo pixel browser — sem ele, nenhum evento tem fbp.

#### `composite_score` crítico (< 45%)
**Email E fbp baixos ao mesmo tempo.** Situação mais grave.

**Causas:**
1. AdBlocker bloqueando o Meta Pixel browser → sem `_fbp`
2. Safari ITP deletando cookies de terceiros → `_fbp` expira em 7 dias
3. Formulário quebrado → email não chega

**Ação recomendada pelo agente:**
- Verificar `was_utm_restored` — UTM Resurrection ativa?
- Verificar taxa de recuperação pelo Identity Graph — `was_email_recovered`
- Considerar aumentar o `_cdp_uid` como fallback de External ID (já implementado)

---

### 4. Relatório de Qualidade Gerado

Quando `analyzeMatchQuality()` roda, o agente produz um relatório via CallMeBot:

```
📊 CDP Edge — Match Quality Report
Período: últimas 2h | 47 eventos

✅ Email:        68% (mínimo: 40%)
⚠️ fbp cookie:  24% (mínimo: 30%) ← ALERTA
✅ Phone:        31%
✅ External ID:  94% (_cdp_uid presente)
📈 Score Composto: 43% ← ABAIXO DO MÍNIMO

🔁 Auto-recuperações:
  · Email recuperado pelo Identity Graph: 18% dos eventos
  · UTM restaurada por Fingerprint Agent: 7% dos eventos

🔍 Problema detectado:
  · fbp cookie ausente em 76% dos eventos
  · Verificar: Meta Pixel browser inicializado antes do cdpTrack.js?

⏱ 14/04/2026 04:00 — Próxima análise em 2h
```

---

### 5. Integração com Outros Agentes

| Agente | Relação |
|---|---|
| **Fraud Detection Agent** | Roda ANTES — eventos de bots nunca chegam ao logMatchQuality |
| **Browser Tracking Agent** | Responsável por capturar fbp/fbc/email corretamente no front-end |
| **Fingerprint Agent** | Mantém `_cdp_uid` — principal fallback de External ID |
| **Meta Agent** | `autoEnrichPayload()` roda dentro do dispatch Meta |
| **Intelligence Agent** | Executa `analyzeMatchQuality()` no cron a cada 2h |
| **LTV Predictor Agent** | Score LTV só é confiável se o Match Quality score ≥ 45% |

---

## Posição no Fluxo do Master Orchestrator

```
POST /track
  │
  ├─ [1] Fraud Gate → bots eliminados
  ├─ [2] Quiz Scoring → qualificação do lead
  ├─ [3] LTV Prediction
  ├─ [4] D1 Writes (background)
  └─ [5] Meta CAPI Dispatch
              │
              ├─ autoEnrichPayload() ← MATCH QUALITY AGENT age aqui
              │     → recupera email/fbp/phone do Identity Graph
              ├─ buildMetaCAPIPayload()
              ├─ fetch Meta CAPI v25.0
              └─ logMatchQuality() em background ← registra flags

Cron a cada 2h:
  └─ analyzeMatchQuality() → alertMatchQuality() se degradando
```

---

## O Que Este Agente CONFIGURA no Projeto do Cliente

1. **Verifica** que `migrate-v7.sql` foi aplicado (cria `match_quality_log`)
2. **Confirma** que `autoEnrichPayload()` está sendo chamado em `meta.ts` antes do dispatch
3. **Confirma** que `logMatchQuality()` está sendo chamado em background após cada dispatch Meta
4. **Adiciona** o cron `0 */2 * * *` ao `wrangler.toml` para análise automática a cada 2h
5. **Configura** `analyzeMatchQuality()` + `alertMatchQuality()` no handler `scheduled()` do Intelligence Agent
6. **Valida** no smoke-test pós-deploy que o fbp/email estão chegando no primeiro Lead

---

## O Que Este Agente NÃO FAZ

- ❌ Não modifica `meta.ts`, `matchquality.ts` (já implementados e testados)
- ❌ Não bloqueia eventos por baixa qualidade (isso é papel do Fraud Gate)
- ❌ Não faz análise de qualidade para GA4 ou TikTok (focos em Meta CAPI EMQ)
- ❌ Não substitui o Validator Agent (que faz auditoria técnica de código)

---

## Saída Final (JSON para o Master Orchestrator)

```json
{
  "match_quality_configured": true,
  "pre_deploy_checklist": "passed",
  "metrics_expected": {
    "email_rate_min": "40%",
    "fbp_rate_min": "30%",
    "composite_score_min": "45%"
  },
  "monitoring": {
    "cron": "0 */2 * * * (a cada 2h)",
    "alert_channel": "CallMeBot WhatsApp",
    "auto_recovery": ["Identity Graph email/fbp", "UTM Resurrection"]
  },
  "d1_table": "match_quality_log (migrate-v7.sql)",
  "wired_in": ["meta.ts dispatch", "intelligence.ts cron scheduled"]
}
```
