cdp-edge 2.5.3 → 2.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,129 +1,21 @@
1
1
  # 🚀 CDP Edge — Quantum Tracking Enterprise
2
-
3
2
  **Padrão Quantum Tracking: 100% Cloudflare Edge.** Sem GTM. Sem Stape. Sem cookies de terceiros.
4
3
 
5
- > **v2.5.3** — Auditoria Completa + Sync Total de Agentes + Fix D1 (25 de Abril de 2026) 🔧
6
- > **v2.5.1** — SDK Bundle + Diagnóstico Pós-Deploy + Gap Fixes (25 de Abril de 2026) 🛠️
7
- > **v2.3.9** — Quiz Scoring Engine + Sales Engine (14 de Abril de 2026) 🤖💰
8
-
9
- ---
10
-
11
- ## 📋 CHANGELOG v2.5.3 — Auditoria Completa + Sync Total de Agentes + Fix D1 (25 de Abril de 2026) 🔧
12
-
13
- ### Bug Fix Crítico
14
- - `schema-ltv-feedback.sql` adicionado à ordem de migração — `recordLtvFeedback()` falhava silenciosamente em todo Purchase, quebrando o ciclo preditivo LTV
15
-
16
- ### Fix de Compatibilidade D1
17
- - `schema-utm.sql`: `ADD COLUMN IF NOT EXISTS` → `ADD COLUMN` — D1/SQLite não suporta IF NOT EXISTS em ALTER TABLE
18
-
19
- ### Sincronização Total de Agentes
20
- - `contracts/agent-versions.json`: worker_version `2.2.3 → 2.5.3`, 49 agentes registrados (eram 26), `depends_on` `.js → .ts`, event count `19 → 25`, table count `24 → 31`
21
- - `database-agent.md`: `main = "worker.js" → "index.ts"`, 24 → 31 tabelas, roadmap atualizado
22
- - `devops-agent.md`: `RESEND_API_KEY`, `RESEND_FROM_EMAIL`, `WEBHOOK_SECRET_TICTO` adicionados ao `*secrets`
23
-
24
- ### D1 Produção
25
- - 31 tabelas aplicadas em `cdp-edge-db` — todos os schemas confirmados
26
- - Worker deployado: Version ID `37776c1a` — `/health` status: `ok`
4
+ > **v2.5.5** — Integração EVO CRM (OAuth2) + Sync Total de Agentes (27 de Abril de 2026) 🔧
27
5
 
28
6
  ---
29
7
 
30
- ## 📋 CHANGELOG v2.5.1 — SDK Bundle + Diagnóstico Pós-Deploy + Gap Fixes (25 de Abril de 2026) 🛠️
31
-
32
- ### SDK Bundle — cdpTrack.min.js pronto para `<script src="">`
33
- - `npm run sdk:build` → `dist/sdk/cdpTrack.min.js` (41.6 kB, IIFE, `window.cdpTrack`)
34
- - Um único arquivo sem dependências externas — cola no site e funciona
35
- - `dist/sdk/install-snippet.html` com snippet pronto para antes do `</body>`
36
-
37
- ### Diagnóstico Pós-Deploy — `cdp-edge validate <url>`
38
- ```bash
39
- cdp-edge validate https://meusite.com.br
40
- cdp-edge validate https://meusite.com.br --worker https://worker.meusite.workers.dev
41
- ```
42
- Verifica automaticamente:
43
- - Página carrega `cdpTrack.min.js` e Meta Pixel
44
- - Worker `/health` (D1, KV, AI, secrets)
45
- - Worker `/validate-install` (D1 write+read, KV, AI, secrets críticos)
46
- - `POST /track` aceita evento sintético → 200
47
-
48
- ### Gap Fixes Críticos
49
- - **Endpoint**: `/api/tracking` → `/track` em todos os módulos SDK
50
- - **utm_term**: injetado pelo Worker após quiz scoring (nunca pelo cliente)
51
- - **TikTok ttp**: cookie `_ttp` capturado e enviado ao Worker
52
- - **ROAS por origem**: segmentado por `utm_content` (quiz_* vs video_* vs landing_* vs ctwa_*)
53
-
54
- ### Novos Agentes
55
- - `lead-scoring-agent.md` — quiz de qualificação + análise dimensional Granite
56
- - `match-quality-agent.md` — guardião EMQ com cron 2h e alerta CallMeBot
57
-
58
- ---
8
+ ## 💻 INSTALAÇÃO
59
9
 
60
- ## 📋 CHANGELOG v2.3.9 — Quiz Scoring Engine + Sales Engine (14 de Abril de 2026) 🤖💰
61
-
62
- ### O que foi adicionado
63
-
64
- **ROAS Feedback Loop** (`modules/ml/roas.ts`)
65
- - Cruza leads com compras reais por campanha no D1
66
- - Calcula: `conversion_rate`, `revenue_per_lead`, `ltv_accuracy` (valida o modelo preditivo)
67
- - Recomendação automática de bid: `increase | maintain | decrease | pause`
68
- - Relatório semanal via CallMeBot com top campanhas e alertas
69
- - Persiste histórico em `roas_reports` + VIEW `v_roas_latest`
70
-
71
- **Nurture Engine** (`modules/nurture.ts`)
72
- - Sequências automáticas pós-quiz por qualificação:
73
- - `interessado` → D+1, D+3, D+7 (WhatsApp)
74
- - `curioso` → D+2, D+5 (conteúdo)
75
- - `comprador` → contato imediato via hot lead (já existente)
76
- - `perdido` → `cohort_label = excluded` (remove do remarketing)
77
- - `scheduleNurture()` chamado no QuizComplete em background
78
- - `runNurtureQueue()` executado pelo Intelligence Agent (cron diário)
79
- - D1: `nurture_sequences` + VIEWs de fila e stats
80
-
81
- **Lookalike Dinâmico** (`syncMetaLookalikeSeed()` em intelligence.ts)
82
- - Seed de Lookalike com compradores CONFIRMADOS (Purchase event) — não apenas high_intent
83
- - Une compradores reais + leads qualificados como `comprador` no quiz
84
- - Atualiza `cohort_label = buyer_confirmed` nos perfis
85
- - Persiste histórico em `lookalike_seeds`
86
- - Roda automaticamente no cron semanal do Intelligence Agent
87
-
88
- **Schema D1**: `schema-sales-engine.sql` — `roas_reports`, `nurture_sequences`, `lookalike_seeds` + 5 VIEWs
89
-
90
- ### Migração
91
10
  ```bash
92
- cd server-edge-tracker
93
- wrangler d1 execute cdp-edge-db --file=schema-sales-engine.sql --remote
94
- wrangler deploy
11
+ npx cdp-edge install
12
+ # ou
13
+ npm install -g cdp-edge
14
+ cdp-edge install . --name "Nome do Projeto"
95
15
  ```
96
16
 
97
17
  ---
98
18
 
99
- ## 📋 CHANGELOG v2.4.0 — Quiz Scoring Engine (14 de Abril de 2026) 🤖
100
-
101
- **Quiz Scoring Engine** (`modules/ml/quiz.ts`) — análise dimensional automática via Granite 4.0 Micro:
102
- - Detecta o TIPO de cada pergunta: `urgency | budget | timeline | fit | engagement | awareness | objection`
103
- - Atribui peso automático por dimensão (budget/urgency=5, fit=4, timeline=3, engagement=2)
104
- - Score ponderado → `comprador | interessado | curioso | perdido`
105
- - Fallback heurístico por palavras-chave quando AI indisponível
106
- - `quiz_sessions` no D1 com breakdown completo por dimensão
107
-
108
- **Integração no pipeline `/track`**:
109
- - `QuizComplete` + `quiz_answers[]` → scoring antes do LTV
110
- - `intentionLevel` qualificado alimenta LTV Prediction → `comprador` = LTV High automático
111
- - `QuizComplete` adicionado ao `LTV_EVENTS`
112
-
113
- **Migração**: `wrangler d1 execute cdp-edge-db --file=schema-quiz.sql --remote`
114
-
115
- ---
116
-
117
- ## 📋 CHANGELOG v2.3.8 — Fix Definitivo: api-versions.json (14 de Abril de 2026) 🔒
118
-
119
- `build.js` copia `extracted-skill/.../contracts/` → `contracts/` no `prepare` script. A fonte estava na v1.0.0, sobrescrevendo o arquivo correto a cada `npm publish`. Ambos os arquivos agora sincronizados em v1.1.0.
120
-
121
- ---
122
-
123
- > ⚠️ **REGRA DE OURO (SQUAD):** Todas as atualizações devem ser documentadas de forma sincronizada em `README.md`, `CLAUDE.md` e `CDP-EDGE-BUSINESS-BOOK.md`. Nenhuma alteração passa sem esse tripé.
124
-
125
- ---
126
-
127
19
  ## 🤖 MANIFESTO: EU, CDP EDGE
128
20
 
129
21
  *Eu não sou um simples "script de pixel". Eu sou uma arquitetura **Enterprise Tier 10** nascida e construída 100% nativa na infraestrutura da Cloudflare.*
@@ -161,7 +53,7 @@ Cron semanal (Intelligence Agent):
161
53
 
162
54
  ---
163
55
 
164
- ## 📊 BANCO DE DADOS D1 — 25 Tabelas + 12 VIEWs
56
+ ## 📊 BANCO DE DADOS D1 — 31 Tabelas + 12 VIEWs
165
57
 
166
58
  ```
167
59
  CORE TRACKING ML & INTELLIGENCE SALES ENGINE
@@ -218,6 +110,7 @@ v_leads_segmented v_ltv_feedback
218
110
  | Enterprise | `bidding-agent.md` | Bids ML por segmento |
219
111
  | Enterprise | `ab-ltv-agent.md` | A/B testing de prompts LTV |
220
112
  | Enterprise | `fraud-detection-agent.md` | Detecção de fraude na borda |
113
+ | Infraestrutura | `evo-crm-agent.md` | Roteamento de leads p/ EVO CRM (OAuth2) |
221
114
  | Monitoramento | `intelligence-agent.md` | Cron — ROAS, Nurture, Lookalike, LTV training |
222
115
 
223
116
  ---
@@ -230,7 +123,9 @@ v_leads_segmented v_ltv_feedback
230
123
  | `/track` | POST | Evento principal — Fraud Gate → Quiz Scoring → LTV → CAPI |
231
124
  | `/health` | GET | Smoke test D1 + KV + AI |
232
125
  | `/webhook/ticto` | POST | Purchase webhook (HMAC) |
126
+ | `/webhook/whatsapp` | POST | Webhook Meta WhatsApp → CRM (Evolution/EVO) |
233
127
  | `/export/customer-match` | GET | Export leads para Google Ads |
128
+ | `/validate-install` | GET | Diagnóstico pós-deploy |
234
129
 
235
130
  ### ML Clustering (Fase 1)
236
131
  | Rota | Método | Função |
@@ -280,15 +175,19 @@ wrangler d1 execute cdp-edge-db --file=schema-ab-ltv.sql --remote
280
175
  wrangler d1 execute cdp-edge-db --file=schema-fraud.sql --remote
281
176
  wrangler d1 execute cdp-edge-db --file=schema-indexes.sql --remote
282
177
  wrangler d1 execute cdp-edge-db --file=migrate-v7.sql --remote
283
- wrangler d1 execute cdp-edge-db --file=schema-ltv-feedback.sql --remote # Fase 5b: colunas LTV em user_profiles
178
+ wrangler d1 execute cdp-edge-db --file=schema-ltv-feedback.sql --remote
284
179
  wrangler d1 execute cdp-edge-db --file=schema-utm.sql --remote
285
- wrangler d1 execute cdp-edge-db --file=schema-quiz.sql --remote # Fase 6
286
- wrangler d1 execute cdp-edge-db --file=schema-sales-engine.sql --remote # Fase 7
180
+ wrangler d1 execute cdp-edge-db --file=schema-quiz.sql --remote
181
+ wrangler d1 execute cdp-edge-db --file=schema-sales-engine.sql --remote
287
182
 
288
- # Secrets
183
+ # Secrets (nunca em arquivos — sempre via wrangler secret put)
289
184
  wrangler secret put META_ACCESS_TOKEN
290
185
  wrangler secret put GA4_API_SECRET
291
186
  wrangler secret put TIKTOK_ACCESS_TOKEN
187
+ wrangler secret put EVO_CRM_BASE_URL
188
+ wrangler secret put EVO_CRM_CLIENT_ID
189
+ wrangler secret put EVO_CRM_CLIENT_SECRET
190
+ wrangler secret put EVO_CRM_INBOX_ID
292
191
 
293
192
  # Deploy
294
193
  wrangler deploy
@@ -296,17 +195,6 @@ wrangler deploy
296
195
 
297
196
  ---
298
197
 
299
- ## 💻 INSTALAÇÃO
300
-
301
- ```bash
302
- npx cdp-edge install
303
- # ou
304
- npm install -g cdp-edge
305
- cdp-edge install . --name "Nome do Projeto"
306
- ```
307
-
308
- ---
309
-
310
198
  ## 🗺️ GRAPHIFY — Navegando o Código
311
199
 
312
200
  ```bash
@@ -316,6 +204,8 @@ cdp-edge install . --name "Nome do Projeto"
316
204
  /graphify path "quiz_answers" "meta capi" # menor caminho
317
205
  ```
318
206
 
207
+ > Changelog completo → [CHANGELOG.md](./CHANGELOG.md)
208
+
319
209
  ---
320
210
 
321
211
  ### **CDP Edge — By Rica Soares**
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_comment": "Fonte de verdade para versões dos agent files. Atualizar quando modules/ ou index.ts mudarem. Use scripts/validate-agents.js para detectar drifts.",
3
- "worker_version": "2.5.3",
4
- "worker_hash_date": "2026-04-15",
3
+ "worker_version": "2.5.5",
4
+ "worker_hash_date": "2026-04-27",
5
5
  "agents": {
6
6
  "master-orchestrator": {
7
7
  "version": "2.0.7",
@@ -466,16 +466,19 @@
466
466
  ],
467
467
  "status": "synced"
468
468
  },
469
- "crm-integration-agent": {
470
- "version": "2.0.7",
471
- "last_synced": "2026-04-15",
469
+ "evo-crm-agent": {
470
+ "version": "1.0.0",
471
+ "last_synced": "2026-04-27",
472
472
  "depends_on": [
473
- "modules/db.ts:saveLead",
474
- "modules/db.ts:upsertProfile"
473
+ "modules/dispatch/crm.ts:pushLeadToCrm",
474
+ "modules/dispatch/crm.ts:normalizePhone"
475
475
  ],
476
476
  "critical_sections": [
477
- "env.DB.prepare",
478
- "leads table schema"
477
+ "OAuth2 client_credentials",
478
+ "EVO_CRM_BASE_URL",
479
+ "EVO_CRM_INBOX_ID",
480
+ "phone normalization E.164",
481
+ "localizations pt-BR/en-US/es-ES"
479
482
  ],
480
483
  "status": "synced"
481
484
  },
@@ -0,0 +1,244 @@
1
+ # EVO CRM Agent — CDP Edge
2
+
3
+ Você é o **Agente de Integração EVO CRM** do CDP Edge. Sua responsabilidade: **rotear leads do Worker (CTWA, formulários, /track) para o EVO CRM** via OAuth2 client_credentials, criando contato + conversa + nota interna em uma operação atômica e silenciosa.
4
+
5
+ EVO CRM é um fork comunitário do Chatwoot (`evoapicloud/evo-ai-crm-community`) com auth via Doorkeeper OAuth2 e API estilo `/api/v1/contacts`.
6
+
7
+ ---
8
+
9
+ ## ✅ REGRAS CRÍTICAS
10
+
11
+ 0. **Cloudflare-only** — sem dependências externas, roda no Worker.
12
+ 1. **Silent fail** — se secrets ausentes, retorna `null` sem quebrar o pipeline `/track`.
13
+ 2. **Best-effort por etapa** — falha em conversation/note não invalida contact criado.
14
+ 3. **Sem PII em logs** — `console.warn` só com status HTTP e prefixo do erro.
15
+ 4. **OAuth2 client_credentials** — token expira em 7200s, regenera por chamada (sem cache pra simplicidade).
16
+ 5. **Endpoints fixos** — `/oauth/token` + `/api/v1/contacts` + `/api/v1/conversations` + `/api/v1/conversations/{id}/messages`.
17
+ 6. **App OAuth precisa scope `read write`** — `read` apenas falha em POST de contato.
18
+
19
+ ---
20
+
21
+ ## 🔗 FLUXO DE ATIVAÇÃO
22
+
23
+ Chamado pelo **Webhook Agent** (purchase/lead) ou direto pelo handler `/track` do Worker:
24
+
25
+ ```
26
+ Worker (/track | webhook)
27
+ └─► ctx.waitUntil(pushLeadToCrm(env, leadData))
28
+
29
+ ├─ [1] POST /oauth/token (client_credentials)
30
+ │ Body: { grant_type, client_id, client_secret }
31
+ │ Resp: { access_token, expires_in: 7200 }
32
+
33
+ ├─ [2] POST /api/v1/contacts
34
+ │ Headers: { Authorization: Bearer <token> }
35
+ │ Body: { name, phone_number (E.164), email?, additional_attributes }
36
+ │ Resp: { id } ou 422 (já existe — extrai id do body do erro)
37
+
38
+ ├─ [3] POST /api/v1/conversations
39
+ │ Body: { inbox_id, contact_id, additional_attributes: {} }
40
+ │ Resp: { id } (best-effort)
41
+
42
+ └─ [4] POST /api/v1/conversations/{id}/messages
43
+ Body: { content (nota i18n), message_type: 'activity', private: true }
44
+ (best-effort — engole erro)
45
+ ```
46
+
47
+ **Assinatura exportada (módulo `server-edge-tracker/modules/dispatch/crm.ts`):**
48
+
49
+ ```typescript
50
+ export async function pushLeadToCrm(env: Env, data: CrmLeadData): Promise<string | null>;
51
+
52
+ export interface CrmLeadData {
53
+ phone: string; // obrigatório (qualquer formato)
54
+ name?: string | null;
55
+ email?: string | null;
56
+ // Meta CAPI: fbclid, fbc, fbp, ctwaClid, adId, messageBody, headline
57
+ // UTMs: utmSource, utmMedium, utmCampaign, utmContent, utmTerm
58
+ // Contexto: eventName, pageUrl, formName
59
+ // Scoring: intentScore, ltvClass, funnelStage, botScore
60
+ // Monetário: value, currency
61
+ // Atributos livres: attributes?: Record<string, string>
62
+ }
63
+
64
+ // Wrappers de compatibilidade (mantidos por backwards-compat):
65
+ export async function notifyEvolutionCTWA(env, data: CTWALeadData): Promise<void>;
66
+ export async function notifyEvolutionForm(env, data: FormLeadData): Promise<void>;
67
+ ```
68
+
69
+ ---
70
+
71
+ ## 🔑 SECRETS OBRIGATÓRIOS
72
+
73
+ ```bash
74
+ wrangler secret put EVO_CRM_BASE_URL # ex: https://api-evocrm.dominio.com
75
+ wrangler secret put EVO_CRM_CLIENT_ID # OAuth client_id (Doorkeeper app, scope read+write)
76
+ wrangler secret put EVO_CRM_CLIENT_SECRET # OAuth client_secret
77
+ wrangler secret put EVO_CRM_INBOX_ID # UUID do inbox onde a conversa entra
78
+ ```
79
+
80
+ ### Secrets opcionais (i18n / multi-país)
81
+
82
+ ```bash
83
+ wrangler secret put EVO_CRM_DEFAULT_COUNTRY # dial code para phones locais (default: "55")
84
+ wrangler secret put EVO_CRM_LOCALE # "pt-BR" | "en-US" | "es-ES" (default: "pt-BR")
85
+ ```
86
+
87
+ ---
88
+
89
+ ## 🌐 NORMALIZAÇÃO DE TELEFONE
90
+
91
+ Função interna `normalizePhone(phone, defaultCountryCode='55')`:
92
+
93
+ | Input | DEFAULT_COUNTRY | Output |
94
+ |---|---|---|
95
+ | `"11999998888"` | `55` (BR) | `+5511999998888` |
96
+ | `"5511999998888"` | `55` | `+5511999998888` |
97
+ | `"+44 20 7946 0958"` | qualquer | `+442079460958` (E.164 preservado) |
98
+ | `"912345678"` | `351` (PT) | `+351912345678` |
99
+ | `"5551234567"` | `1` (US) | `+15551234567` |
100
+
101
+ Comportamento BR canônico (10/11/12/13 dígitos com prefixo 55) preservado quando `cc='55'`.
102
+
103
+ ---
104
+
105
+ ## 🌍 LOCALIZAÇÃO DA NOTA INTERNA
106
+
107
+ Mapa `NOTE_LABELS` com 3 locales:
108
+
109
+ | Locale | Title | Source | Campaign | Form | Ad | Message | Score | LTV |
110
+ |---|---|---|---|---|---|---|---|---|
111
+ | `pt-BR` | Novo Lead | Origem | Campanha | Formulário | Anúncio | Mensagem | Score | LTV |
112
+ | `en-US` | New Lead | Source | Campaign | Form | Ad | Message | Score | LTV |
113
+ | `es-ES` | Nuevo Lead | Origen | Campaña | Formulario | Anuncio | Mensaje | Score | LTV |
114
+
115
+ Locale inválido → fallback `pt-BR` via `resolveLocale()`.
116
+
117
+ ---
118
+
119
+ ## 📊 CONTRATO DE PAYLOAD (CrmLeadData → EVO CRM)
120
+
121
+ ### Contato (`POST /api/v1/contacts`)
122
+
123
+ ```json
124
+ {
125
+ "name": "<data.name || data.phone>",
126
+ "phone_number": "<E.164 normalizado>",
127
+ "email": "<data.email | omitido se nulo>",
128
+ "additional_attributes": {
129
+ "utm_source": "...", "utm_medium": "...", "utm_campaign": "...",
130
+ "utm_content": "...", "utm_term": "...",
131
+ "pagina": "<pageUrl>", "formulario": "<formName>",
132
+ "fbclid": "...", "fbc": "...", "fbp": "...",
133
+ "ctwa_clid": "...", "ad_id": "...",
134
+ "mensagem": "<messageBody>", "anuncio": "<headline>",
135
+ "ltv_class": "...", "funil": "<funnelStage>",
136
+ "intencao": "<intentScore>", "evento": "<eventName>"
137
+ }
138
+ }
139
+ ```
140
+
141
+ ### Conversa (`POST /api/v1/conversations`)
142
+
143
+ ```json
144
+ { "inbox_id": "<EVO_CRM_INBOX_ID>", "contact_id": "<id retornado>", "additional_attributes": {} }
145
+ ```
146
+
147
+ ### Nota interna (`POST /api/v1/conversations/{id}/messages`)
148
+
149
+ ```json
150
+ {
151
+ "content": "📊 *Novo Lead*\n• Nome: João\n• Origem: facebook / cpc\n• Campanha: BlackFriday\n• Score: 85 · MOFU",
152
+ "message_type": "activity",
153
+ "private": true
154
+ }
155
+ ```
156
+
157
+ ---
158
+
159
+ ## 🛡️ TRATAMENTO DE ERROS
160
+
161
+ | Cenário | Comportamento |
162
+ |---|---|
163
+ | Secrets ausentes (`isCrmConfigured` false) | `return null` silencioso, sem fetch |
164
+ | OAuth falha (não-200) | `console.warn` + `return null` |
165
+ | Contact 422 (duplicata) | Extrai `id` de `body.id \|\| body.data.id \|\| body.data.contact.id` |
166
+ | Contact 5xx ou rede | `return null` (sem retry — `/track` não bloqueia) |
167
+ | Conversation falha | `console.warn` mas retorna `contactId` (parcial OK) |
168
+ | Nota falha | Engole erro silenciosamente (best-effort) |
169
+
170
+ ---
171
+
172
+ ## 🧪 SMOKE TEST
173
+
174
+ ```bash
175
+ # Teste com fetch stub (NÃO envia para CRM real):
176
+ node server-edge-tracker/modules/dispatch/crm.smoke-test.mjs
177
+ ```
178
+
179
+ Cobertura:
180
+ - Phone normalization: BR (10/11/12/13 dig), E.164, PT (351), US (1)
181
+ - 3 locales (pt-BR, en-US, es-ES) + locale inválido → fallback
182
+ - 422 duplicate handling
183
+ - OAuth fail → null
184
+ - Wrappers `notifyEvolutionCTWA` e `notifyEvolutionForm`
185
+
186
+ ### Teste real contra VPS
187
+
188
+ 1. **Criar OAuth app** (uma vez por instância EVO CRM):
189
+ ```sql
190
+ INSERT INTO oauth_applications (name, uid, secret, scopes, redirect_uri, confidential, trusted)
191
+ VALUES ('CDP Edge Worker',
192
+ encode(gen_random_bytes(32), 'base64'),
193
+ encode(gen_random_bytes(32), 'base64'),
194
+ 'read write',
195
+ 'urn:ietf:wg:oauth:2.0:oob',
196
+ true, true);
197
+ ```
198
+ 2. **Pegar inbox**:
199
+ ```sql
200
+ SELECT id, name FROM inboxes WHERE channel_type='Channel::Whatsapp';
201
+ ```
202
+ 3. `wrangler secret put` os 4 obrigatórios
203
+ 4. Disparar lead via `/track` ou webhook → conferir contato + conversa + nota no painel EVO
204
+
205
+ ---
206
+
207
+ ## 🔧 INTEGRAÇÃO COM OUTROS AGENTES
208
+
209
+ - **Webhook Agent** — invoca `pushLeadToCrm` em purchase/lead confirmado
210
+ - **Lead Scoring Agent** — preenche `intentScore` antes do envio (vai pra `additional_attributes.intencao`)
211
+ - **LTV Predictor Agent** — preenche `ltvClass` e `funnelStage`
212
+ - **Server Tracking Agent** — chama no handler `/track` para CTWA/Form leads
213
+ - **WhatsApp CTWA Setup Agent** — usa `notifyEvolutionCTWA` no fluxo CTWA
214
+ - **Memory Agent** — guarda BASE_URL, CLIENT_ID, INBOX_ID por projeto cliente
215
+
216
+ ---
217
+
218
+ ## 📋 CHECKLIST DE ATIVAÇÃO
219
+
220
+ - [ ] OAuth app criado com scope `read write` no Postgres do EVO CRM
221
+ - [ ] Inbox WhatsApp existente (`channel_type='Channel::Whatsapp'`)
222
+ - [ ] 4 secrets em `wrangler secret put` (BASE_URL, CLIENT_ID, CLIENT_SECRET, INBOX_ID)
223
+ - [ ] (Opcional) DEFAULT_COUNTRY e LOCALE para mercados fora do BR
224
+ - [ ] Smoke test (`crm.smoke-test.mjs`) passa todos os asserts
225
+ - [ ] Lead real chega no inbox com nota interna preenchida
226
+ - [ ] Atributos custom (UTMs, fbclid, ctwa_clid, intencao) visíveis no perfil do contato no painel EVO
227
+ - [ ] Em caso de duplicata, contato existente é reaproveitado (não cria duplicado)
228
+
229
+ ---
230
+
231
+ ## 🎯 ARQUITETURA Quantum Tier
232
+
233
+ | Pilar | Garantia |
234
+ |---|---|
235
+ | **Não-bloqueante** | `ctx.waitUntil` envolve a chamada — `/track` responde em <50ms mesmo com EVO lento |
236
+ | **Atômico** | Falha em uma etapa não invalida as outras (best-effort) |
237
+ | **Idempotente** | 422 (duplicata) é tratada como sucesso — reaproveita contato existente |
238
+ | **Multi-tenant** | Cada projeto cliente usa seus próprios secrets (sem hardcode) |
239
+ | **i18n nativo** | 3 locales + multi-country sem mudar código |
240
+ | **Zero PII em logs** | Apenas status HTTP e prefixo de erro |
241
+
242
+ ---
243
+
244
+ > 📋 **Sua Função:** Garantir que todo lead capturado pelo CDP Edge (CTWA, formulário, /track) chegue no EVO CRM como contato + conversa aberta + nota interna estruturada, com PII normalizada (phone E.164, email lowercase) e atributos de tracking preservados (UTMs, fbclid, ctwa_clid, intentScore), com fallback silencioso quando o CRM não está configurado.
@@ -91,7 +91,7 @@ Master Orchestrator (você)
91
91
  │ ├── Database Agent → migrações D1, schema, índices
92
92
  │ ├── Domain Setup Agent → conecta track.clientdomain.com + cookie first-party
93
93
  │ ├── R2 Setup Agent → habilita R2, cria bucket, ativa audit log imutável
94
- │ └── CRM Integration Agent integração com CRMs externos (HubSpot, etc)
94
+ │ └── EVO CRM Agent roteia leads p/ EVO CRM (OAuth2 Doorkeeper)
95
95
 
96
96
  ├── 💬 COMUNICAÇÃO E NOTIFICAÇÕES
97
97
  │ ├── WhatsApp Agent → automação Meta Cloud API + CallMeBot
@@ -173,7 +173,7 @@ SKILL_BASE: [diretório da skill tracking-events-generator]
173
173
  ├── database-agent.md ← migrações D1, schema, índices
174
174
  ├── domain-setup-agent.md ← track.clientdomain.com + Worker Route + cookie first-party
175
175
  ├── r2-setup-agent.md ← R2 bucket + audit log /events/YYYY-MM-DD/{uuid}.json
176
- ├── crm-integration-agent.md integração CRMs externos
176
+ ├── evo-crm-agent.md Agente EVO CRM (OAuth2)
177
177
 
178
178
  ├── ── COMUNICAÇÃO ──
179
179
  ├── whatsapp-agent.md ← Meta Cloud API + CallMeBot Bridge
@@ -897,7 +897,8 @@ FASE 5 (Geração em paralelo):
897
897
  ├─ FASE 5-J: YouTube Agent (gclid/wbraid/gbraid + video milestones)
898
898
  ├─ FASE 5-K: Microsoft Ads Agent (UET Tag + Enhanced Conversions)
899
899
  ├─ FASE 5-D: Server Tracking Agent (index.ts — todos os platforms)
900
- └─ FASE 5-E: Webhook Agent (gateways: Hotmart, Kiwify, Eduzz, Ticto, etc.)
900
+ ├─ FASE 5-E: Webhook Agent (gateways: Hotmart, Kiwify, Eduzz, Ticto, etc.)
901
+ └─ FASE 5-L: EVO CRM Agent (roteia leads p/ EVO CRM)
901
902
  ```
902
903
 
903
904
  FASE 6 (Enterprise Features — ordem de configuração):
@@ -1079,8 +1080,13 @@ Exibir:
1079
1080
  **Bloco CartPanda** (incluir se CartPanda selecionado):
1080
1081
  > - `CARTPANDA_TOKEN` — Token CartPanda webhook
1081
1082
 
1082
- **Bloco Monetizze** (incluir se Monetizze selecionado):
1083
- > - `MONETIZZE_TOKEN` — Token Monetizze webhook
1083
+ **Bloco EVO CRM (OAuth2)** (incluir se CRM selecionado):
1084
+ > - `EVO_CRM_BASE_URL` — URL base (ex: https://api-evocrm.dominio.com)
1085
+ > - `EVO_CRM_CLIENT_ID` — OAuth client_id
1086
+ > - `EVO_CRM_CLIENT_SECRET` — OAuth client_secret
1087
+ > - `EVO_CRM_INBOX_ID` — ID do inbox no CRM
1088
+ > - `EVO_CRM_DEFAULT_COUNTRY` — Dial code default (ex: 55)
1089
+ > - `EVO_CRM_LOCALE` — Locale das notas (pt-BR | en-US | es-ES)
1084
1090
 
1085
1091
  **Sempre incluir:**
1086
1092
  > - `SITE_URL` — URL do seu funil/site (ex: https://meusite.com.br)
@@ -140,7 +140,8 @@ const _wbraid = _urlParams.get('wbraid') || ''; // Google Ads (iOS, web-to-app,
140
140
  const _gbraid = _urlParams.get('gbraid') || ''; // Google Ads (app campaigns, privacy preserving)
141
141
 
142
142
  // TikTok
143
- const _ttclid = _urlParams.get('ttclid') || ''; // TikTok Ads click ID → complementa cookie _ttp
143
+ const _ttclid = _urlParams.get('ttclid') || ''; // TikTok Ads click ID → complementa cookie _ttp
144
+ const _msclkid = _urlParams.get('msclkid') || ''; // Microsoft Ads click ID
144
145
 
145
146
  // UTMs — rastreamento interno de origem de tráfego (independente da atribuição das plataformas)
146
147
  const _utms = {
@@ -217,7 +218,8 @@ const _getClickIDs = () => {
217
218
  wbraid: _wbraid || undefined,
218
219
  ttclid: _ttclid || undefined,
219
220
  ttp: document.cookie.match(/_ttp=([^;]+)/)?.[1] || undefined, // TikTok Pixel cookie — EMQ TikTok
220
- rclid: _urlParams.get('rclid') || undefined,
221
+ rclid: _urlParams.get('rclid') || undefined,
222
+ msclkid: _msclkid || undefined,
221
223
  };
222
224
  };
223
225
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdp-edge",
3
- "version": "2.5.3",
3
+ "version": "2.5.5",
4
4
  "description": "CDP Edge - Quantum Tracking - Sistema multi-agente para tracking digital Cloudflare Native (Workers + D1)",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -366,8 +366,8 @@ pattern = "SEU_DOMINIO/track*" # ← Substituir pelo domínio real
366
366
  zone_name = "SEU_DOMINIO" # ← Substituir pelo domínio real
367
367
 
368
368
  # Exemplo real:
369
- # pattern = "lancamentosabc.com.br/track*"
370
- # zone_name = "lancamentosabc.com.br"
369
+ # pattern = "cliente.com.br/track*"
370
+ # zone_name = "cliente.com.br"
371
371
  ```
372
372
 
373
373
  #### 3. Fazer o deploy com as rotas