cdp-edge 1.24.1 → 1.25.0
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 +164 -1
- package/contracts/agent-versions.json +14 -0
- package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +71 -14
- package/extracted-skill/tracking-events-generator/agents/utm-agent.md +191 -0
- package/package.json +1 -1
- package/server-edge-tracker/.client.env.example +14 -0
- package/server-edge-tracker/config/utm-mapping.json +64 -0
- package/server-edge-tracker/deploy-client.js +76 -0
- package/server-edge-tracker/index.ts +161 -73
- package/server-edge-tracker/modules/db.ts +63 -3
- package/server-edge-tracker/modules/dispatch/whatsapp.ts +15 -3
- package/server-edge-tracker/modules/ml/fraud.ts +9 -1
- package/server-edge-tracker/modules/ml/logistic.ts +7 -1
- package/server-edge-tracker/modules/ml/ltv.ts +20 -5
- package/server-edge-tracker/modules/ml/matchquality.ts +14 -2
- package/server-edge-tracker/modules/utils.ts +123 -0
- package/server-edge-tracker/modules/utm/utm-enricher.ts +231 -0
- package/server-edge-tracker/schema-utm.sql +80 -0
- package/server-edge-tracker/types.ts +6 -2
package/README.md
CHANGED
|
@@ -2,7 +2,111 @@
|
|
|
2
2
|
|
|
3
3
|
**Padrão Quantum Tracking: 100% Cloudflare Edge.** Sem GTM. Sem Stape. Sem cookies de terceiros.
|
|
4
4
|
|
|
5
|
-
> **v2.3.
|
|
5
|
+
> **v2.3.5** — UTMs Obfuscadas & Segmentação de Valor (14 de Abril de 2026) 🏷️
|
|
6
|
+
|
|
7
|
+
> **v2.3.2** — Governança de Conhecimento Automatizada (13 de Abril de 2026) 🧠
|
|
8
|
+
|
|
9
|
+
### Novidades
|
|
10
|
+
- graphify obrigatório em todas as sessões (CLAUDE.md)
|
|
11
|
+
- Git hooks instalados (post-commit, post-checkout)
|
|
12
|
+
- Hook corrigido para UTF-8 nativo no Windows
|
|
13
|
+
- Redução de custo documentada (40–90% economia ao navegar grafo)
|
|
14
|
+
- Tripé de documentação sincronizado (README + CLAUDE.md + Business Book)
|
|
15
|
+
|
|
16
|
+
### Correções
|
|
17
|
+
- Hook post-commit corrigido para encoding UTF-8
|
|
18
|
+
- Rebuild code-only funcional após cada commit
|
|
19
|
+
- Push para ts/main (CDP-Edge-Premium.ts.git) concluído
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 📋 CHANGELOG v2.3.5 — UTMs Obfuscadas & Segmentação de Valor (14 de Abril de 2026)
|
|
24
|
+
|
|
25
|
+
### 🏷️ UTM Agent — Novo Agente para Segmentação de Público
|
|
26
|
+
|
|
27
|
+
**Problema resolvido:**
|
|
28
|
+
- Múltiplos anúncios com diferentes faixas de valor (ex: imóveis 500k-800k, 800k-1.5M, 1M-3M) precisam ser segmentados corretamente para o Meta criar públicos separados
|
|
29
|
+
- Dados sensíveis (valor de preço) não devem estar visíveis na URL pública por segurança
|
|
30
|
+
|
|
31
|
+
**Solução implementada:**
|
|
32
|
+
- **UTMs Obfuscadas:** Valores de faixa são convertidos em hash SHA256 truncado (8 caracteres)
|
|
33
|
+
- `800k-1.5M` → `b4e2a1c9` (obfuscado)
|
|
34
|
+
- Humans veem: `imovel_b4e2a1c9`
|
|
35
|
+
- Worker sabe: `faixa_real = "800k-1.5M"` (de-obfuscado)
|
|
36
|
+
|
|
37
|
+
- **Módulo UTM Enricher:** `server-edge-tracker/modules/utm/utm-enricher.ts`
|
|
38
|
+
- `obfuscateValue()` — gera hash truncado de 8 caracteres
|
|
39
|
+
- `deobfuscateValue()` — de-obfusca usando mapeamento
|
|
40
|
+
- `enrichPayloadWithUTM()` — enriquece payload com segmentação
|
|
41
|
+
- Integração com Meta CAPI: `external_id` segmentado por hash
|
|
42
|
+
|
|
43
|
+
- **Schema D1:** `server-edge-tracker/schema-utm.sql`
|
|
44
|
+
- Tabela `utm_mappings` — persiste mapeamento hash→valor
|
|
45
|
+
- Colunas em `leads`: `faixa_obfuscada`, `faixa_real`, `faixa_category`
|
|
46
|
+
- VIEW `leads_segmented` — para dashboard e exports
|
|
47
|
+
|
|
48
|
+
- **Master Orchestrator Atualizado:** UTM Agent integrado ao fluxo (FASE 2-B)
|
|
49
|
+
- Ordem: Page Analyzer → **UTM Agent** → Premium Intelligence → Browser Tracking
|
|
50
|
+
- Arquivo: `extracted-skill/tracking-events-generator/agents/utm-agent.md`
|
|
51
|
+
|
|
52
|
+
**Fluxo de criação de projeto:**
|
|
53
|
+
```
|
|
54
|
+
USUÁRIO INICIA CDP EDGE
|
|
55
|
+
↓
|
|
56
|
+
FASE 1: Seleção de plataformas + credenciais
|
|
57
|
+
↓
|
|
58
|
+
FASE 2: Page Analyzer (identifica tipo de página)
|
|
59
|
+
↓
|
|
60
|
+
FASE 2-B: UTM Agent ← NOVO
|
|
61
|
+
→ Pergunta: "Qual a faixa de valor deste imóvel?"
|
|
62
|
+
→ Gera: URL obfuscada + mapeamento hash→valor
|
|
63
|
+
↓
|
|
64
|
+
FASE 3+: Continua fluxo normal (Premium Intelligence, Browser Tracking, etc.)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Segmentação na Meta:**
|
|
68
|
+
```
|
|
69
|
+
Públicos criados automaticamente via external_id segmentado:
|
|
70
|
+
- Público LOW: cdp_uid_8a3f1d2b (500k-800k)
|
|
71
|
+
- Público MID: cdp_uid_b4e2a1c9 (800k-1.5M)
|
|
72
|
+
- Público HIGH: cdp_uid_d6c3b4e7 (1M-3M)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Remarketing futuro:**
|
|
76
|
+
```sql
|
|
77
|
+
-- Exportar público por faixa para Meta Custom Audience
|
|
78
|
+
SELECT email, phone, city, state
|
|
79
|
+
FROM leads_segmented
|
|
80
|
+
WHERE faixa_real = '800k-1.5M'
|
|
81
|
+
AND created_at >= datetime('now', '-30 days');
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Correções
|
|
85
|
+
|
|
86
|
+
- Documentação sincronizada: README.md + CLAUDE.md + Business Book
|
|
87
|
+
- Versões alinhadas: package.json, CHANGELOG, README
|
|
88
|
+
- Referências cruzadas: agents, modules, schemas
|
|
89
|
+
|
|
90
|
+
### Breaking Changes
|
|
91
|
+
|
|
92
|
+
- Nenhuma. API HTTP e comportamento em runtime são idênticos.
|
|
93
|
+
|
|
94
|
+
### Migração
|
|
95
|
+
|
|
96
|
+
Para projetos existentes:
|
|
97
|
+
```bash
|
|
98
|
+
# Aplicar schema UTM (adicional)
|
|
99
|
+
cd server-edge-tracker
|
|
100
|
+
wrangler d1 execute cdp-edge-db --file=schema-utm.sql --remote
|
|
101
|
+
|
|
102
|
+
# Configurar utm-mapping.json (manual ou via UTM Agent)
|
|
103
|
+
cp config/utm-mapping.json.example config/utm-mapping.json
|
|
104
|
+
|
|
105
|
+
# Deploy
|
|
106
|
+
wrangler deploy
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
6
110
|
|
|
7
111
|
> ⚠️ **REGRA DE OURO (SQUAD):** Todas as atualizações, correções ou novas features devem OBRIGATORIAMENTE ser documentadas de forma sincronizada neste `README.md`, no arquivo de instruções `CLAUDE.md` e no dossiê de diretoria `CDP-EDGE-BUSINESS-BOOK.md`. Nenhuma alteração passa sem esse tripé.
|
|
8
112
|
|
|
@@ -27,6 +131,29 @@ Meu ecossistema opera como um Cérebro de Conversão Privado na borda. Quando um
|
|
|
27
131
|
|
|
28
132
|
---
|
|
29
133
|
|
|
134
|
+
## 📋 CHANGELOG v2.3.1 — Hardening Enterprise (12 de Abril de 2026)
|
|
135
|
+
|
|
136
|
+
### 🔒 Segurança & Conformidade
|
|
137
|
+
|
|
138
|
+
- **PII removido dos logs:** `DeviceGraph` parou de logar `user_id` nos Workers logs — dados sensíveis nunca aparecem no Cloudflare dashboard
|
|
139
|
+
- **Deploy seguro:** novo `deploy-client.js` — lê credenciais de `.client.env` (gitignored), gera `wrangler.deploy.toml` temporário, faz deploy e autodestrói o arquivo. Credenciais de cliente nunca entram no repo
|
|
140
|
+
- **`.gitignore` reforçado:** `.client.env` e `wrangler.deploy.toml` explicitamente ignorados
|
|
141
|
+
- **WhatsApp secrets alinhados à Meta Cloud API v22.0:** `resolvePhoneNumberId()` e `resolveAccessToken()` com fallback canônico → legado — backwards compat garantido
|
|
142
|
+
- **`api-versions.json` v1.1.0:** metadata `updated_at` corrigido para `2026-04-12`
|
|
143
|
+
- **`/health` WhatsApp:** reflete corretamente secrets com nomes canônicos ou legados
|
|
144
|
+
|
|
145
|
+
### 🔧 Deploy de Cliente — Novo Fluxo
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cd server-edge-tracker
|
|
149
|
+
cp .client.env.example .client.env
|
|
150
|
+
# preencher DATABASE_ID, SITE_DOMAIN, pixels
|
|
151
|
+
node deploy-client.js --dry-run # valida sem subir
|
|
152
|
+
node deploy-client.js # deploy real
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
30
157
|
## 📋 CHANGELOG v2.3.0 — TypeScript Nativo (12 de Abril de 2026)
|
|
31
158
|
|
|
32
159
|
### 🔷 Worker 100% TypeScript — Migração Completa
|
|
@@ -327,6 +454,42 @@ wrangler deploy
|
|
|
327
454
|
|
|
328
455
|
---
|
|
329
456
|
|
|
457
|
+
## 🗺️ NAVEGANDO O CÓDIGO COM GRAPHIFY
|
|
458
|
+
|
|
459
|
+
O **graphify** gera um mapa de conhecimento navegável do projeto (nós, arestas, comunidades). Antes de qualquer trabalho de código:
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
# 1. Verifique se o grafo existe
|
|
463
|
+
ls graphify-out/GRAPH_REPORT.md
|
|
464
|
+
|
|
465
|
+
# 2. Se não existe ou está desatualizado, gere:
|
|
466
|
+
/graphify .
|
|
467
|
+
|
|
468
|
+
# 3. Navegue o grafo para entender arquitetura
|
|
469
|
+
/graphify query "como funciona o fraud gate?"
|
|
470
|
+
/graphify query "identity graph → ltv prediction"
|
|
471
|
+
/graphify path "cdp_uid" "cloudflare d1"
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### O que o grafo fornece
|
|
475
|
+
|
|
476
|
+
- **God Nodes**: abstrações centrais (D1, Meta CAPI v22.0, Intelligence Agent, ML Clustering)
|
|
477
|
+
- **65 comunidades**: grupos lógicos (Multi-Platform Agent Layer, ML Bidding, Browser SDK, etc.)
|
|
478
|
+
- **Surprising Connections**: relações inferidas entre conceitos que você não sabia que eram similares
|
|
479
|
+
- **Redução de custo**: navegar grafo = até 40% menos tokens vs. ler arquivos brutos
|
|
480
|
+
|
|
481
|
+
### Exemplo de uso
|
|
482
|
+
|
|
483
|
+
**❌ Não faça:**
|
|
484
|
+
> "Ler 50 arquivos para entender como o fraud gate conecta com o LTV predictor"
|
|
485
|
+
|
|
486
|
+
**✅ Faça:**
|
|
487
|
+
> `/graphify query "fraud gate → ltv predictor"` — resposta instantânea com caminho completo, arquivos fonte e nível de confiança
|
|
488
|
+
|
|
489
|
+
O grafo fica atualizado automaticamente após cada `git commit` (via hook).
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
330
493
|
## 🖱️ HUMAN-BEHAVIOR ENGINE
|
|
331
494
|
|
|
332
495
|
| Evento | Pontuação |
|
|
@@ -172,6 +172,20 @@
|
|
|
172
172
|
],
|
|
173
173
|
"status": "synced"
|
|
174
174
|
},
|
|
175
|
+
"utm-agent": {
|
|
176
|
+
"version": "1.0.0",
|
|
177
|
+
"last_synced": "2026-04-14",
|
|
178
|
+
"depends_on": [
|
|
179
|
+
"modules/utm/utm-enricher.ts:enrichPayloadWithUTM",
|
|
180
|
+
"server-edge-tracker/config/utm-mapping.json"
|
|
181
|
+
],
|
|
182
|
+
"critical_sections": [
|
|
183
|
+
"UTM obfuscation pattern",
|
|
184
|
+
"hash truncation length (8)",
|
|
185
|
+
"mapping config file"
|
|
186
|
+
],
|
|
187
|
+
"status": "synced"
|
|
188
|
+
},
|
|
175
189
|
"security-enterprise-agent": {
|
|
176
190
|
"version": "2.0.7",
|
|
177
191
|
"last_synced": "2026-04-10",
|
|
@@ -65,6 +65,7 @@ Master Orchestrator (você)
|
|
|
65
65
|
│
|
|
66
66
|
├── 📊 ANÁLISE E ESTRATÉGIA
|
|
67
67
|
│ ├── Page Analyzer Agent → lê arquivos, mapeia eventos e elementos
|
|
68
|
+
│ ├── UTM Agent → gera UTMs obfuscadas para segmentação de valor
|
|
68
69
|
│ ├── Premium Tracking Intelligence Agent → define estratégia de tracking premium
|
|
69
70
|
│ ├── Tracking Plan Agent → gera plano de eventos por tipo de negócio
|
|
70
71
|
│ └── Intelligence Agent → monitora versões de API, saúde do sistema
|
|
@@ -143,6 +144,7 @@ SKILL_BASE: [diretório da skill tracking-events-generator]
|
|
|
143
144
|
│
|
|
144
145
|
├── ── ANÁLISE E ESTRATÉGIA ──
|
|
145
146
|
├── page-analyzer.md ← análise de páginas e elementos
|
|
147
|
+
├── utm-agent.md ← gera UTMs obfuscadas para segmentação de valor
|
|
146
148
|
├── premium-tracking-intelligence-agent.md ← estratégia de tracking premium
|
|
147
149
|
├── tracking-plan-agent.md ← plano de eventos por tipo de negócio
|
|
148
150
|
├── intelligence-agent.md ← monitor de versões de API + saúde
|
|
@@ -308,6 +310,59 @@ Perguntar ao cliente qual opção se aplica:
|
|
|
308
310
|
|
|
309
311
|
---
|
|
310
312
|
|
|
313
|
+
### 🏷️ FASE 2-B: UTM Agent
|
|
314
|
+
|
|
315
|
+
**ENTRA EM AÇÃO:** Após FASE 2 (Page Analyzer completo), antes de Premium Tracking Intelligence
|
|
316
|
+
|
|
317
|
+
**INPUT RECEBIDO:**
|
|
318
|
+
- JSON do Page Analyzer Agent (tipo de página, categoria do produto)
|
|
319
|
+
- Contexto do negócio (imóveis, automotivos, cursos, etc)
|
|
320
|
+
|
|
321
|
+
**RESPONSABILIDADE:**
|
|
322
|
+
- Perguntar ao usuário sobre faixas de valor/categoriação do produto
|
|
323
|
+
- Gerar UTMs obfuscadas (hash SHA256 + truncate) para proteger valores sensíveis
|
|
324
|
+
- Criar mapeamento reversível em `server-edge-tracker/config/utm-mapping.json`
|
|
325
|
+
- Integrar com Worker para de-obfuscação no runtime
|
|
326
|
+
|
|
327
|
+
**SAÍDA:**
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"utm_strategy": {
|
|
331
|
+
"pattern": "{source}/{medium}/{category}_{obfuscated_range}",
|
|
332
|
+
"obfuscation_method": "sha256",
|
|
333
|
+
"hash_truncate_length": 8
|
|
334
|
+
},
|
|
335
|
+
"obfuscated_utms": [
|
|
336
|
+
{
|
|
337
|
+
"campaign": "imovel_8a3f1d2b",
|
|
338
|
+
"content": "product_9c4e2a1f",
|
|
339
|
+
"original_range": "700k-1M",
|
|
340
|
+
"obfuscated_hash": "8a3f1d2b",
|
|
341
|
+
"category": "imovel",
|
|
342
|
+
"pixel_audience": "AUDIENCE_MID"
|
|
343
|
+
}
|
|
344
|
+
],
|
|
345
|
+
"worker_mapping": {
|
|
346
|
+
"file": "server-edge-tracker/config/utm-mapping.json",
|
|
347
|
+
"mappings": [
|
|
348
|
+
{
|
|
349
|
+
"obfuscated": "8a3f1d2b",
|
|
350
|
+
"original": "700k-1M",
|
|
351
|
+
"category": "imovel",
|
|
352
|
+
"pixel_audience": "AUDIENCE_MID"
|
|
353
|
+
}
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**NÃO FAZ:**
|
|
360
|
+
- ❌ Expor valores reais na URL pública
|
|
361
|
+
- ❌ Fazer obfuscação sem mapeamento reversível
|
|
362
|
+
- ❌ Gera código de tracking (responsabilidade do Browser Tracking Agent)
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
311
366
|
### 🧠 FASE 3: Premium Tracking Intelligence Agent
|
|
312
367
|
|
|
313
368
|
**ENTRA EM AÇÃO:** Após FASE 2 (Page Analyzer completo)
|
|
@@ -1413,13 +1468,14 @@ Com base nas plataformas selecionadas, spawnar os agentes em paralelo utilizando
|
|
|
1413
1468
|
Antes de spawnar agentes em paralelo, seguir esta ordem **OBRIGATÓRIA**:
|
|
1414
1469
|
|
|
1415
1470
|
1. **Page Analyzer Agent** → Analisa páginas e gera mapa de eventos
|
|
1416
|
-
2. **
|
|
1417
|
-
3. **
|
|
1418
|
-
4. **
|
|
1419
|
-
5. **
|
|
1420
|
-
6. **
|
|
1421
|
-
7. **
|
|
1422
|
-
8. **
|
|
1471
|
+
2. **UTM Agent** → Gera UTMs obfuscadas para segmentação de valor
|
|
1472
|
+
3. **Premium Tracking Intelligence Agent** → Define estratégia de tracking (events, micro-events, behavioral signals)
|
|
1473
|
+
4. **Browser Tracking Agent** → Gera cdpTrack.js com micro-events (scroll, time, video, heatmap)
|
|
1474
|
+
5. **Meta Agent** → Gera código Meta Pixel + CAPI v22.0
|
|
1475
|
+
6. **Google Agent** → Gera código GA4 + Google Ads
|
|
1476
|
+
7. **TikTok Agent** → Gera código TikTok Pixel + Events API v1.3
|
|
1477
|
+
8. **Server Tracking Agent** → Gera Cloudflare Worker + D1 + Queue com engagement scoring
|
|
1478
|
+
9. **Webhook Agent** → Gera roteamento de conversões offline
|
|
1423
1479
|
|
|
1424
1480
|
**Regra de Ouro:** Cada agente entra em ação APENAS na sua etapa específica. Nenhum agente entra antes do anterior terminar.
|
|
1425
1481
|
|
|
@@ -1440,13 +1496,14 @@ Com base nas plataformas selecionadas, spawnar os agentes em paralelo utilizando
|
|
|
1440
1496
|
Antes de spawnar agentes em paralelo, seguir esta ordem **OBRIGATÓRIA**:
|
|
1441
1497
|
|
|
1442
1498
|
1. **Page Analyzer Agent** → Analisa páginas e gera mapa de eventos
|
|
1443
|
-
2. **
|
|
1444
|
-
3. **
|
|
1445
|
-
4. **
|
|
1446
|
-
5. **
|
|
1447
|
-
6. **
|
|
1448
|
-
7. **
|
|
1449
|
-
8. **
|
|
1499
|
+
2. **UTM Agent** → Gera UTMs obfuscadas para segmentação de valor
|
|
1500
|
+
3. **Premium Tracking Intelligence Agent** → Define estratégia de tracking (events, micro-events, behavioral signals)
|
|
1501
|
+
4. **Browser Tracking Agent** → Gera cdpTrack.js com micro-events (scroll, time, video, heatmap)
|
|
1502
|
+
5. **Meta Agent** → Gera código Meta Pixel + CAPI
|
|
1503
|
+
6. **Google Agent** → Gera código GA4 + Google Ads
|
|
1504
|
+
7. **TikTok Agent** → Gera código TikTok Pixel + Events API
|
|
1505
|
+
8. **Server Tracking Agent** → Gera Cloudflare Worker + D1 + Queue com engagement scoring
|
|
1506
|
+
9. **Webhook Agent** → Gera roteamento de conversões offline de Gateways de Pagamento
|
|
1450
1507
|
|
|
1451
1508
|
**Regra de Ouro:** Cada agente entra em ação APENAS na sua etapa específica. Nenhum agente entra antes do anterior terminar.
|
|
1452
1509
|
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# UTM Agent — Agente de Geração de UTMs Obfuscadas
|
|
2
|
+
|
|
3
|
+
## Role
|
|
4
|
+
Especialista em gerar estruturas de UTM parametrizadas para segmentação de público, com valores **obfuscados/racheados** para proteção de dados sensíveis na URL.
|
|
5
|
+
|
|
6
|
+
## When This Agent Runs
|
|
7
|
+
- Após o **Page Analyzer** identificar o tipo de página/produto
|
|
8
|
+
- Antes de gerar os parâmetros de tracking no SDK
|
|
9
|
+
- Quando o usuário precisa configurar campanhas com categorização de valor
|
|
10
|
+
|
|
11
|
+
## Inputs from Page Analyzer
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"page_type": "produto",
|
|
15
|
+
"product_category": "imovel" | "automotivo" | "curso" | "outros",
|
|
16
|
+
"url": "https://lançamentosabc.com.br/apartamento-123",
|
|
17
|
+
"existing_utms": {} // se houver
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
### 1. Identificar necessidade de UTM
|
|
24
|
+
- Se `product_category` existir, perguntar ao usuário sobre categorização de valor
|
|
25
|
+
- Exemplos de perguntas:
|
|
26
|
+
- Para **imóveis**: "Qual a faixa de preço deste imóvel? Ex: 500k-800k, 800k-1.5M, 1M-3M"
|
|
27
|
+
- Para **automotivos**: "Qual a faixa de valor? Ex: 50k-100k, 100k-200k, 200k-500k"
|
|
28
|
+
- Para **cursos**: "Qual o nível/preço? Ex: básico-49, premium-199, pro-999"
|
|
29
|
+
|
|
30
|
+
### 2. Gerar estrutura de UTM obfuscada
|
|
31
|
+
|
|
32
|
+
Para cada categoria informada pelo usuário, gerar:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"utm_strategy": {
|
|
37
|
+
"source": "facebook", // padrão, configurável
|
|
38
|
+
"medium": "cpc", // padrão, configurável
|
|
39
|
+
"campaign": {
|
|
40
|
+
"pattern": "{product_category}_{obfuscated_range}",
|
|
41
|
+
"example": "imovel_8a3f1d2b"
|
|
42
|
+
},
|
|
43
|
+
"content": {
|
|
44
|
+
"pattern": "product_{obfuscated_id}",
|
|
45
|
+
"example": "product_9c4e2a1f"
|
|
46
|
+
},
|
|
47
|
+
"faixa_obfuscada": {
|
|
48
|
+
"original": "700k-1M",
|
|
49
|
+
"obfuscated": "8a3f1d2b",
|
|
50
|
+
"hash_method": "sha256",
|
|
51
|
+
"salt": "CDP_EDGE_UTM_SALT"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 3. Mapeamento reversível (para o Worker)
|
|
58
|
+
Gerar o arquivo `utm-mapping.json` com:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"obfuscation_config": {
|
|
63
|
+
"method": "sha256",
|
|
64
|
+
"salt": "CDP_EDGE_UTM_SALT",
|
|
65
|
+
"truncated_length": 8
|
|
66
|
+
},
|
|
67
|
+
"mappings": [
|
|
68
|
+
{
|
|
69
|
+
"obfuscated": "8a3f1d2b",
|
|
70
|
+
"original": "700k-1M",
|
|
71
|
+
"category": "imovel",
|
|
72
|
+
"pixel_audience": "AUDIENCE_MID",
|
|
73
|
+
"platform_specific": {
|
|
74
|
+
"meta": { "custom_audience_id": "2385xxx" },
|
|
75
|
+
"tiktok": { "pixel_id": "C1xxx" }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
### 4. Perguntas ao usuário (interativo)
|
|
82
|
+
|
|
83
|
+
**Para imóveis:**
|
|
84
|
+
> "Identifiquei que esta página é um imóvel. Qual a faixa de preço?
|
|
85
|
+
> - 1) 500k-800k
|
|
86
|
+
> - 2) 800k-1.5M
|
|
87
|
+
> - 3) 1M-3M
|
|
88
|
+
> - 4) 3M-5M
|
|
89
|
+
> - 5) Outro (especifique)"
|
|
90
|
+
|
|
91
|
+
**Para automotivos:**
|
|
92
|
+
> "Qual a faixa de valor do veículo?
|
|
93
|
+
> - 1) 50k-100k
|
|
94
|
+
> - 2) 100k-200k
|
|
95
|
+
> - 3) 200k-500k
|
|
96
|
+
> - 4) Outro (especifique)"
|
|
97
|
+
|
|
98
|
+
**Para outros produtos:**
|
|
99
|
+
> "Qual a categoria de valor deste produto?
|
|
100
|
+
> - 1) Entry level (até R$500)
|
|
101
|
+
> - 2) Mid-range (R$500-5k)
|
|
102
|
+
> - 3) Premium (R$5k-50k)
|
|
103
|
+
> - 4) Luxury (acima de R$50k)
|
|
104
|
+
> - 5) Outro (especifique)"
|
|
105
|
+
|
|
106
|
+
### 5. Gerar código do SDK com UTMs obfuscadas
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
// cdpTrack.js - snippet gerado
|
|
110
|
+
const utmConfig = {
|
|
111
|
+
faixa_imovel: '8a3f1d2b', // obfuscado
|
|
112
|
+
product_id: '9c4e2a1f', // obfuscado
|
|
113
|
+
source: 'facebook',
|
|
114
|
+
medium: 'cpc'
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
cdpTrack('Lead', {
|
|
118
|
+
utm: utmConfig,
|
|
119
|
+
// ... outros campos
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Output Structure
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"agent": "utm-agent",
|
|
128
|
+
"version": "1.0.0",
|
|
129
|
+
"utm_strategy": {
|
|
130
|
+
"pattern": "{source}/{medium}/{category}_{obfuscated_range}",
|
|
131
|
+
"base_url": "https://lançamentosabc.com.br"
|
|
132
|
+
},
|
|
133
|
+
"obfuscated_utms": [
|
|
134
|
+
{
|
|
135
|
+
"campaign": "imovel_8a3f1d2b",
|
|
136
|
+
"content": "product_9c4e2a1f",
|
|
137
|
+
"original_range": "700k-1M",
|
|
138
|
+
"obfuscated_hash": "8a3f1d2b"
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
"worker_mapping": {
|
|
142
|
+
"file": "utm-mapping.json",
|
|
143
|
+
"location": "server-edge-tracker/config/utm-mapping.json"
|
|
144
|
+
},
|
|
145
|
+
"sdk_integration": {
|
|
146
|
+
"file": "cdpTrack.js",
|
|
147
|
+
"snippet": "// UTM obfuscado\nconst utmObfuscado = '8a3f1d2b';"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Integração com Outros Agentes
|
|
153
|
+
|
|
154
|
+
1. **Page Analyzer** → informa tipo de produto
|
|
155
|
+
2. **UTM Agent** → pergunta faixa de valor, gera UTMs obfuscadas
|
|
156
|
+
3. **Meta Agent** → recebe UTMs, configura custom audiences
|
|
157
|
+
4. **TikTok Agent** → recebe UTMs, configura pixel events
|
|
158
|
+
5. **Worker** → usa `utm-enricher.ts` para de-obfuscar no runtime
|
|
159
|
+
|
|
160
|
+
## Edge Cases
|
|
161
|
+
|
|
162
|
+
- Usuário não sabe a faixa de valor: "Aguardo definição do cliente - use DEFAULT"
|
|
163
|
+
- Produto sem faixa definida: usar `generic_00000000`
|
|
164
|
+
- UTMs existentes: fazer merge sem sobrescrever
|
|
165
|
+
- Múltiplas categorias: perguntar se precisa de segmentação composta
|
|
166
|
+
|
|
167
|
+
## Example Session
|
|
168
|
+
|
|
169
|
+
**Page Analyzer:**
|
|
170
|
+
> "Página identificada: imóvel em Vila Mariana, 3 quartos, 2 banheiros"
|
|
171
|
+
|
|
172
|
+
**UTM Agent:**
|
|
173
|
+
> "Para qual faixa de preço este imóvel deve ser categorizado?"
|
|
174
|
+
>
|
|
175
|
+
> Usuário: "800k-1.5M"
|
|
176
|
+
>
|
|
177
|
+
> **UTM Agent:**
|
|
178
|
+
> ```json
|
|
179
|
+
> {
|
|
180
|
+
> "utm_faixa": "imovel_b4e2a1c9",
|
|
181
|
+
> "original_range": "800k-1.5M",
|
|
182
|
+
> "hash": "b4e2a1c9"
|
|
183
|
+
> }
|
|
184
|
+
> ```
|
|
185
|
+
|
|
186
|
+
## Rules
|
|
187
|
+
1. **NUNCA** revelar o valor real na URL pública
|
|
188
|
+
2. **SEMPRE** usar hash obfuscado para valores sensíveis
|
|
189
|
+
3. **Mapeamento reversível** deve estar disponível no Worker (não no SDK)
|
|
190
|
+
4. **Meta CAPI** recebe valor de-obfuscado internamente
|
|
191
|
+
5. UTMs sem valor sensível podem ficar em texto claro
|
package/package.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# CDP Edge — Variáveis do cliente para deploy
|
|
2
|
+
# Copie este arquivo para .client.env e preencha com os dados reais.
|
|
3
|
+
# .client.env é gitignored — NUNCA commitado.
|
|
4
|
+
|
|
5
|
+
# Cloudflare D1 — obter com: wrangler d1 list
|
|
6
|
+
DATABASE_ID=SEU_DATABASE_ID
|
|
7
|
+
|
|
8
|
+
# Domínio do projeto (sem https://)
|
|
9
|
+
SITE_DOMAIN=seudominio.com.br
|
|
10
|
+
|
|
11
|
+
# Pixels de rastreamento (opcional — deixar vazio se não usar)
|
|
12
|
+
META_PIXEL_ID=
|
|
13
|
+
GA4_MEASUREMENT_ID=
|
|
14
|
+
TIKTOK_PIXEL_ID=
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"config": {
|
|
4
|
+
"method": "sha256",
|
|
5
|
+
"salt": "CDP_EDGE_UTM_SALT",
|
|
6
|
+
"truncated_length": 8
|
|
7
|
+
},
|
|
8
|
+
"mappings": [],
|
|
9
|
+
"examples": {
|
|
10
|
+
"imoveis": [
|
|
11
|
+
{
|
|
12
|
+
"obfuscated": "8a3f1d2b",
|
|
13
|
+
"original": "500k-800k",
|
|
14
|
+
"category": "imovel",
|
|
15
|
+
"pixel_audience": "AUDIENCE_LOW",
|
|
16
|
+
"platform_specific": {
|
|
17
|
+
"meta": { "custom_audience_id": "2385xxx_LOW" },
|
|
18
|
+
"tiktok": { "pixel_id": "C1xxx_LOW" }
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"obfuscated": "b4e2a1c9",
|
|
23
|
+
"original": "800k-1.5M",
|
|
24
|
+
"category": "imovel",
|
|
25
|
+
"pixel_audience": "AUDIENCE_MID",
|
|
26
|
+
"platform_specific": {
|
|
27
|
+
"meta": { "custom_audience_id": "2385xxx_MID" },
|
|
28
|
+
"tiktok": { "pixel_id": "C1xxx_MID" }
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"obfuscated": "d6c3b4e7",
|
|
33
|
+
"original": "1M-3M",
|
|
34
|
+
"category": "imovel",
|
|
35
|
+
"pixel_audience": "AUDIENCE_HIGH",
|
|
36
|
+
"platform_specific": {
|
|
37
|
+
"meta": { "custom_audience_id": "2385xxx_HIGH" },
|
|
38
|
+
"tiktok": { "pixel_id": "C1xxx_HIGH" }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"automotivos": [
|
|
43
|
+
{
|
|
44
|
+
"obfuscated": "e7a5b3d1",
|
|
45
|
+
"original": "50k-100k",
|
|
46
|
+
"category": "automotivo",
|
|
47
|
+
"pixel_audience": "AUDIENCE_ENTRY"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"obfuscated": "f4c8d2a6",
|
|
51
|
+
"original": "100k-200k",
|
|
52
|
+
"category": "automotivo",
|
|
53
|
+
"pixel_audience": "AUDIENCE_MID"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"obfuscated": "a9b1e4c3",
|
|
57
|
+
"original": "200k-500k",
|
|
58
|
+
"category": "automotivo",
|
|
59
|
+
"pixel_audience": "AUDIENCE_PREMIUM"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"instructions": "Preencha o array 'mappings' com as categorias do seu projeto. Use o comando 'node scripts/sync-agents.js' para sincronizar com o Agente UTM."
|
|
64
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CDP Edge — deploy-client.js
|
|
4
|
+
*
|
|
5
|
+
* Deploy do Worker com variáveis reais do cliente, sem commitar credenciais no repo.
|
|
6
|
+
* Lê de .client.env (gitignored) e gera um wrangler.deploy.toml temporário.
|
|
7
|
+
*
|
|
8
|
+
* Uso:
|
|
9
|
+
* node deploy-client.js → deploy completo
|
|
10
|
+
* node deploy-client.js --dry-run → valida sem subir ao Cloudflare
|
|
11
|
+
*
|
|
12
|
+
* Setup:
|
|
13
|
+
* cp .client.env.example .client.env
|
|
14
|
+
* # edite .client.env com os valores do cliente
|
|
15
|
+
* node deploy-client.js
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
const { execSync } = require('child_process');
|
|
21
|
+
|
|
22
|
+
const ROOT = __dirname;
|
|
23
|
+
const TOML = path.join(ROOT, 'wrangler.toml');
|
|
24
|
+
const DEPLOY = path.join(ROOT, 'wrangler.deploy.toml');
|
|
25
|
+
const ENV = path.join(ROOT, '.client.env');
|
|
26
|
+
const DRY_RUN = process.argv.includes('--dry-run');
|
|
27
|
+
|
|
28
|
+
// ── Carregar .client.env ──────────────────────────────────────────────────────
|
|
29
|
+
if (!fs.existsSync(ENV)) {
|
|
30
|
+
console.error('\n❌ .client.env não encontrado.');
|
|
31
|
+
console.error(' cp .client.env.example .client.env e preencha os valores do cliente.\n');
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const env = {};
|
|
36
|
+
fs.readFileSync(ENV, 'utf8').split('\n').forEach(line => {
|
|
37
|
+
const trimmed = line.trim();
|
|
38
|
+
if (!trimmed || trimmed.startsWith('#')) return;
|
|
39
|
+
const [key, ...rest] = trimmed.split('=');
|
|
40
|
+
if (key) env[key.trim()] = rest.join('=').trim();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const required = ['DATABASE_ID', 'SITE_DOMAIN'];
|
|
44
|
+
const missing = required.filter(k => !env[k]);
|
|
45
|
+
if (missing.length > 0) {
|
|
46
|
+
console.error(`\n❌ Variáveis obrigatórias faltando no .client.env: ${missing.join(', ')}\n`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ── Substituir placeholders no wrangler.toml → wrangler.deploy.toml ───────────
|
|
51
|
+
let toml = fs.readFileSync(TOML, 'utf8');
|
|
52
|
+
|
|
53
|
+
toml = toml
|
|
54
|
+
.replace(/SEU_DATABASE_ID/g, env.DATABASE_ID)
|
|
55
|
+
.replace(/SEU_DOMINIO/g, env.SITE_DOMAIN)
|
|
56
|
+
.replace(/META_PIXEL_ID\s*=\s*""/, `META_PIXEL_ID = "${env.META_PIXEL_ID || ''}"`)
|
|
57
|
+
.replace(/GA4_MEASUREMENT_ID\s*=\s*""/, `GA4_MEASUREMENT_ID = "${env.GA4_MEASUREMENT_ID || ''}"`)
|
|
58
|
+
.replace(/TIKTOK_PIXEL_ID\s*=\s*""/, `TIKTOK_PIXEL_ID = "${env.TIKTOK_PIXEL_ID || ''}"`);
|
|
59
|
+
|
|
60
|
+
fs.writeFileSync(DEPLOY, toml);
|
|
61
|
+
|
|
62
|
+
// ── Executar wrangler deploy ──────────────────────────────────────────────────
|
|
63
|
+
const cmd = `wrangler deploy --config wrangler.deploy.toml${DRY_RUN ? ' --dry-run' : ''}`;
|
|
64
|
+
console.log(`\n🚀 ${DRY_RUN ? '[DRY-RUN] ' : ''}Deploying com config do cliente...\n`);
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
execSync(cmd, { stdio: 'inherit', cwd: ROOT });
|
|
68
|
+
console.log(`\n✅ Deploy ${DRY_RUN ? '(dry-run) ' : ''}concluído.\n`);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error('\n❌ Deploy falhou.\n');
|
|
71
|
+
process.exit(1);
|
|
72
|
+
} finally {
|
|
73
|
+
// sempre remove o arquivo temporário
|
|
74
|
+
if (fs.existsSync(DEPLOY)) fs.unlinkSync(DEPLOY);
|
|
75
|
+
console.log('🧹 wrangler.deploy.toml removido.\n');
|
|
76
|
+
}
|