cdp-edge 1.2.2 → 1.4.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 +153 -306
- package/bin/cdp-edge.js +71 -61
- package/contracts/agent-versions.json +682 -0
- package/contracts/api-versions.json +372 -368
- package/contracts/types.ts +81 -0
- package/dist/commands/analyze.js +52 -52
- package/dist/commands/infra.js +54 -54
- package/dist/commands/install.js +26 -3
- package/dist/commands/server.js +174 -174
- package/dist/commands/setup.js +332 -100
- package/dist/commands/validate.js +248 -84
- package/dist/index.js +12 -12
- package/dist/sdk/cdpTrack.js +2095 -0
- package/dist/sdk/cdpTrack.min.js +64 -0
- package/dist/sdk/install-snippet.html +10 -0
- package/docs/whatsapp-ctwa.md +5 -4
- package/extracted-skill/tracking-events-generator/INTEGRACAO-COMPLETA.md +89 -0
- package/extracted-skill/tracking-events-generator/MELHORIAS-IMPLEMENTADAS.md +101 -0
- package/extracted-skill/tracking-events-generator/advanced-matching.js +364 -364
- package/extracted-skill/tracking-events-generator/agents/ab-ltv-agent.md +196 -0
- package/extracted-skill/tracking-events-generator/agents/ab-testing-agent.md +1 -1
- package/extracted-skill/tracking-events-generator/agents/attribution-agent.md +41 -41
- package/extracted-skill/tracking-events-generator/agents/bidding-agent.md +347 -0
- package/extracted-skill/tracking-events-generator/agents/bing-agent.md +40 -50
- package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +174 -74
- package/extracted-skill/tracking-events-generator/agents/code-guardian-agent.md +1 -1
- package/extracted-skill/tracking-events-generator/agents/compliance-agent.md +25 -5
- package/extracted-skill/tracking-events-generator/agents/dashboard-agent.md +10 -10
- package/extracted-skill/tracking-events-generator/agents/database-agent.md +43 -42
- package/extracted-skill/tracking-events-generator/agents/debug-agent.md +22 -22
- package/extracted-skill/tracking-events-generator/agents/devops-agent.md +232 -0
- package/extracted-skill/tracking-events-generator/agents/domain-setup-agent.md +23 -9
- package/extracted-skill/tracking-events-generator/agents/email-agent.md +28 -1
- package/extracted-skill/tracking-events-generator/agents/evo-crm-agent.md +253 -0
- package/extracted-skill/tracking-events-generator/agents/fingerprint-agent.md +206 -1
- package/extracted-skill/tracking-events-generator/agents/fraud-detection-agent.md +143 -0
- package/extracted-skill/tracking-events-generator/agents/google-agent.md +128 -2
- package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +191 -31
- package/extracted-skill/tracking-events-generator/agents/lead-scoring-agent.md +282 -0
- package/extracted-skill/tracking-events-generator/agents/linkedin-agent.md +145 -34
- package/extracted-skill/tracking-events-generator/agents/localization-agent.md +1 -1
- package/extracted-skill/tracking-events-generator/agents/ltv-predictor-agent.md +24 -5
- package/extracted-skill/tracking-events-generator/agents/master-feedback-loop.md +81 -21
- package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +588 -93
- package/extracted-skill/tracking-events-generator/agents/match-quality-agent.md +304 -0
- package/extracted-skill/tracking-events-generator/agents/memory-agent.md +190 -15
- package/extracted-skill/tracking-events-generator/agents/meta-agent.md +10 -2
- package/extracted-skill/tracking-events-generator/agents/ml-clustering-agent.md +769 -0
- package/extracted-skill/tracking-events-generator/agents/page-analyzer.md +21 -4
- package/extracted-skill/tracking-events-generator/agents/performance-agent.md +41 -31
- package/extracted-skill/tracking-events-generator/agents/performance-optimization-agent.md +18 -8
- package/extracted-skill/tracking-events-generator/agents/pinterest-agent.md +14 -6
- package/extracted-skill/tracking-events-generator/agents/premium-tracking-intelligence-agent.md +7 -7
- package/extracted-skill/tracking-events-generator/agents/r2-setup-agent.md +16 -8
- package/extracted-skill/tracking-events-generator/agents/reddit-agent.md +15 -7
- package/extracted-skill/tracking-events-generator/agents/security-enterprise-agent.md +157 -48
- package/extracted-skill/tracking-events-generator/agents/server-tracking.md +35 -35
- package/extracted-skill/tracking-events-generator/agents/spotify-agent.md +15 -7
- package/extracted-skill/tracking-events-generator/agents/tiktok-agent.md +73 -2
- package/extracted-skill/tracking-events-generator/agents/tracking-plan-agent.md +104 -9
- package/extracted-skill/tracking-events-generator/agents/utm-agent.md +322 -0
- package/extracted-skill/tracking-events-generator/agents/validator-agent.md +13 -9
- package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +112 -4
- package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +58 -5
- package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +26 -18
- package/extracted-skill/tracking-events-generator/agents/youtube-agent.md +152 -37
- package/extracted-skill/tracking-events-generator/anti-blocking.js +285 -285
- package/extracted-skill/tracking-events-generator/cdpTrack.js +642 -641
- package/extracted-skill/tracking-events-generator/contracts/api-versions.json +14 -10
- package/extracted-skill/tracking-events-generator/engagement-scoring.js +226 -226
- package/extracted-skill/tracking-events-generator/evals/evals.json +235 -235
- package/extracted-skill/tracking-events-generator/integration-test.js +497 -497
- package/extracted-skill/tracking-events-generator/knowledge-base.md +172 -0
- package/extracted-skill/tracking-events-generator/micro-events.js +992 -992
- package/extracted-skill/tracking-events-generator/models/lancamento-imobiliario.md +344 -0
- package/extracted-skill/tracking-events-generator/models/pinterest/conversions-api-template.js +144 -144
- package/extracted-skill/tracking-events-generator/models/pinterest/event-mappings.json +48 -48
- package/extracted-skill/tracking-events-generator/models/pinterest/tag-template.js +28 -28
- package/extracted-skill/tracking-events-generator/models/quiz-funnel.md +83 -19
- package/extracted-skill/tracking-events-generator/models/reddit/conversions-api-template.js +205 -205
- package/extracted-skill/tracking-events-generator/models/reddit/event-mappings.json +56 -56
- package/extracted-skill/tracking-events-generator/models/reddit/pixel-template.js +19 -19
- package/extracted-skill/tracking-events-generator/models/scenarios/behavior-engine.js +425 -425
- package/extracted-skill/tracking-events-generator/route-intent-capture.js +222 -0
- package/extracted-skill/tracking-events-generator/tracking.config.js +3 -3
- package/package.json +89 -75
- package/scripts/build-sdk.js +106 -0
- package/server-edge-tracker/.client.env.example +14 -0
- package/server-edge-tracker/INSTALAR.md +222 -23
- package/server-edge-tracker/SEGMENTATION-DOCS.md +513 -0
- package/server-edge-tracker/config/utm-mapping.json +64 -0
- package/server-edge-tracker/deploy-client.cjs +76 -0
- package/server-edge-tracker/index.ts +1230 -0
- package/server-edge-tracker/migrate-v7.sql +64 -0
- package/server-edge-tracker/modules/db.ts +710 -0
- package/server-edge-tracker/modules/dispatch/crm.ts +382 -0
- package/server-edge-tracker/modules/dispatch/ga4.ts +72 -0
- package/server-edge-tracker/modules/dispatch/meta.ts +143 -0
- package/server-edge-tracker/modules/dispatch/platforms.ts +255 -0
- package/server-edge-tracker/modules/dispatch/tiktok.ts +107 -0
- package/server-edge-tracker/modules/dispatch/whatsapp.ts +296 -0
- package/server-edge-tracker/modules/intelligence.ts +589 -0
- package/server-edge-tracker/modules/ml/bidding.ts +247 -0
- package/server-edge-tracker/modules/ml/fraud.ts +302 -0
- package/server-edge-tracker/modules/ml/logistic.ts +226 -0
- package/server-edge-tracker/modules/ml/ltv.ts +531 -0
- package/server-edge-tracker/modules/ml/matchquality.ts +232 -0
- package/server-edge-tracker/modules/ml/quiz.ts +343 -0
- package/server-edge-tracker/modules/ml/roas.ts +255 -0
- package/server-edge-tracker/modules/ml/segmentation.ts +407 -0
- package/server-edge-tracker/modules/nurture.ts +257 -0
- package/server-edge-tracker/modules/utils.ts +311 -0
- package/server-edge-tracker/modules/utm/utm-enricher.ts +231 -0
- package/server-edge-tracker/schema-ab-ltv.sql +97 -0
- package/server-edge-tracker/schema-bidding.sql +86 -0
- package/server-edge-tracker/schema-fraud.sql +90 -0
- package/server-edge-tracker/schema-indexes.sql +67 -0
- package/server-edge-tracker/schema-ltv-feedback.sql +11 -0
- package/server-edge-tracker/schema-quiz.sql +52 -0
- package/server-edge-tracker/schema-sales-engine.sql +113 -0
- package/server-edge-tracker/schema-segmentation.sql +219 -0
- package/server-edge-tracker/schema-utm.sql +82 -0
- package/server-edge-tracker/schema.sql +281 -265
- package/server-edge-tracker/types.ts +275 -0
- package/server-edge-tracker/wrangler.toml +140 -85
- package/templates/lancamento-imobiliario.md +344 -0
- package/templates/multi-step-checkout.md +3 -4
- package/templates/pinterest/conversions-api-template.js +144 -144
- package/templates/pinterest/event-mappings.json +48 -48
- package/templates/pinterest/tag-template.js +28 -28
- package/templates/quiz-funnel.md +83 -19
- package/templates/reddit/conversions-api-template.js +205 -205
- package/templates/reddit/event-mappings.json +56 -56
- package/templates/reddit/pixel-template.js +12 -39
- package/templates/scenarios/behavior-engine.js +45 -22
- package/docs/PixelBuilder-Documentacao-Completa (2).docx +0 -0
- package/docs/installation.md +0 -155
- package/docs/quick-start.md +0 -185
- package/extracted-skill/tracking-events-generator/agents/crm-integration-agent.md +0 -1419
- package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +0 -643
- package/server-edge-tracker/worker.js +0 -2574
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# A/B LTV Testing Agent — CDP Edge Quantum Tier
|
|
2
|
+
|
|
3
|
+
## Identidade
|
|
4
|
+
|
|
5
|
+
**Agente:** A/B LTV Testing Agent
|
|
6
|
+
**Papel:** Otimização Contínua de Precisão do LTV Preditivo
|
|
7
|
+
**Nível:** Deus (Quantum Tier) — Enterprise-Level Fase 3
|
|
8
|
+
**Versão:** 1.0.0 — 9 de Abril de 2026
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Missão
|
|
13
|
+
|
|
14
|
+
Testar variações do prompt do modelo de LTV de forma automática e estatisticamente controlada,
|
|
15
|
+
identificando qual formulação do sistema prompt para o Workers AI produz as predições mais
|
|
16
|
+
próximas do valor real de compra — **aumentando a precisão do LTV em até +25%**.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Posição no Fluxo do Master Orchestrator
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Browser /track (Lead Event)
|
|
24
|
+
↓
|
|
25
|
+
LTV Prediction Call (predictLtv)
|
|
26
|
+
↓ [se teste ativo]
|
|
27
|
+
getLtvAbVariation() → sorteia variação ponderada do teste ativo
|
|
28
|
+
↓
|
|
29
|
+
Workers AI com system_prompt da variação sorteada
|
|
30
|
+
↓
|
|
31
|
+
D1: ltv_ab_assignments (registra user_id + variation_id + predicted_ltv)
|
|
32
|
+
↓
|
|
33
|
+
[quando compra chega via webhook]
|
|
34
|
+
D1: ltv_ab_assignments.converted = 1 + real_revenue
|
|
35
|
+
↓
|
|
36
|
+
GET /api/ltv/ab-test/results → accuracy_score por variação
|
|
37
|
+
↓
|
|
38
|
+
POST /api/ltv/ab-test/winner → aplica vencedor ao LTV padrão
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Upstream (de onde recebe dados):**
|
|
42
|
+
- `index.ts → predictLtv()` — ponto de interceptação do teste
|
|
43
|
+
- `webhook events` — fonte verdade do revenue real para scoring
|
|
44
|
+
|
|
45
|
+
**Downstream (quem consome outputs):**
|
|
46
|
+
- `ltv-predictor-agent.md` → recebe o prompt vencedor para aplicar como novo default
|
|
47
|
+
- `bidding-agent.md` → LTV mais preciso → bids mais precisos
|
|
48
|
+
- `dashboard-agent.md` → exibe resultados dos testes no painel
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Como o A/B Test Funciona
|
|
53
|
+
|
|
54
|
+
### 1. Criação do Experimento
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
POST /api/ltv/ab-test/create
|
|
58
|
+
{
|
|
59
|
+
"name": "Teste: Foco Engajamento vs Intenção",
|
|
60
|
+
"min_sample": 200,
|
|
61
|
+
"variations": [
|
|
62
|
+
{
|
|
63
|
+
"name": "Controle — Prompt Original",
|
|
64
|
+
"is_control": true,
|
|
65
|
+
"weight": 0.5,
|
|
66
|
+
"system_prompt": "You are a conversion rate expert. Reply ONLY with JSON {\"adjustment\": <-10 to 10>} based on lead data. No explanation."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "Variação B — Foco em Intenção de Compra",
|
|
70
|
+
"weight": 0.5,
|
|
71
|
+
"system_prompt": "You are a Brazilian digital marketing expert specializing in course sales. Focus on purchase intention signals. Reply ONLY with JSON {\"adjustment\": <-10 to 10>}."
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2. Distribuição Automática
|
|
78
|
+
|
|
79
|
+
A cada chamada de `predictLtv()` para um evento Lead, o sistema:
|
|
80
|
+
1. Busca o teste ativo no D1 (com cache de 5 min no KV para evitar latência)
|
|
81
|
+
2. Sorteia uma variação usando distribuição ponderada pelos `weight`
|
|
82
|
+
3. Usa o `system_prompt` da variação sorteada no Workers AI
|
|
83
|
+
4. Registra o assignment em `ltv_ab_assignments`
|
|
84
|
+
|
|
85
|
+
### 3. Scoring Automático via Webhook
|
|
86
|
+
|
|
87
|
+
Quando chega um webhook de compra (`Purchase`), o sistema:
|
|
88
|
+
1. Busca o email do comprador em `ltv_ab_assignments` (por hash)
|
|
89
|
+
2. Atualiza `converted = 1` e `real_revenue = valor_da_compra`
|
|
90
|
+
3. Incrementa `total_purchases` e `sum_real_revenue` na variação
|
|
91
|
+
|
|
92
|
+
### 4. Cálculo de Accuracy Score
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
accuracy_score =
|
|
96
|
+
1 - (ABS(avg_predicted_ltv - avg_real_revenue) / avg_real_revenue)
|
|
97
|
+
→ 1.0 = predição perfeita
|
|
98
|
+
→ 0.0 = predição completamente errada
|
|
99
|
+
→ Valores negativos = predição muito errada
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 5. Declaração de Vencedor
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
POST /api/ltv/ab-test/winner
|
|
106
|
+
{ "test_id": 1, "variation_id": 2 }
|
|
107
|
+
→ marca variation como winner
|
|
108
|
+
→ retorna o system_prompt vencedor para aplicar como novo default
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Endpoints Expostos
|
|
114
|
+
|
|
115
|
+
| Método | Rota | Função |
|
|
116
|
+
|--------|------|--------|
|
|
117
|
+
| `POST` | `/api/ltv/ab-test/create` | Cria novo experimento com variações |
|
|
118
|
+
| `GET` | `/api/ltv/ab-test/list` | Lista todos os experimentos |
|
|
119
|
+
| `GET` | `/api/ltv/ab-test/results` | Resultados de accuracy por variação |
|
|
120
|
+
| `POST` | `/api/ltv/ab-test/winner` | Declara vencedor e retorna prompt |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Variações de Prompt Predefinidas (use nos seus testes)
|
|
125
|
+
|
|
126
|
+
### Variação A — Controle (atual)
|
|
127
|
+
```text
|
|
128
|
+
You are a conversion rate expert. Reply ONLY with a JSON object
|
|
129
|
+
{"adjustment": <number between -10 and 10>} based on the lead data provided.
|
|
130
|
+
No explanation.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Variação B — Foco em Intenção
|
|
134
|
+
```text
|
|
135
|
+
You are a Brazilian infoproduct marketing expert. The lead is likely interested in
|
|
136
|
+
online courses or digital products. Focus heavily on purchase_intention and
|
|
137
|
+
engagement signals. Reply ONLY with JSON {"adjustment": <-10 to 10>}.
|
|
138
|
+
Higher adjustment = higher purchase probability.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Variação C — Foco em Dados Comportamentais
|
|
142
|
+
```text
|
|
143
|
+
You are a behavioral economics expert. Analyze recency, frequency, and monetary
|
|
144
|
+
signals from the lead data. Score based on: (1) engagement quality, (2) time of
|
|
145
|
+
conversion, (3) traffic source quality. Reply ONLY with JSON {"adjustment": <-10 to 10>}.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Variação D — Foco em Geo + Canal
|
|
149
|
+
```text
|
|
150
|
+
You are a CRM specialist for Brazilian digital products. Brazilian leads from paid
|
|
151
|
+
social (facebook/instagram) between 18h-23h BRT have highest LTV. Organic traffic
|
|
152
|
+
and direct access indicate research phase. Reply ONLY with JSON {"adjustment": <-10 to 10>}.
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Regras de Negócio
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
✅ SEMPRE manter o controle ativo (is_control = 1) — baseline para comparação
|
|
161
|
+
✅ SEMPRE aguardar min_sample assignments antes de recomendar vencedor
|
|
162
|
+
✅ SEMPRE registrar assignments mesmo quando Workers AI está indisponível
|
|
163
|
+
✅ SEMPRE usar cache KV (5 min TTL) para buscar o teste ativo — evitar latência D1
|
|
164
|
+
✅ SEMPRE atualizar assignments quando purchase webhook chegar
|
|
165
|
+
|
|
166
|
+
❌ NUNCA declarar vencedor com < 50 conversões por variação
|
|
167
|
+
❌ NUNCA rodar dois testes simultâneos (status = 'running' deve ser único)
|
|
168
|
+
❌ NUNCA alterar o prompt default automaticamente — sempre exigir aprovação manual via POST /winner
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Schema D1 — Tabelas
|
|
174
|
+
|
|
175
|
+
```sql
|
|
176
|
+
ltv_ab_tests -- Experimentos (id, name, status, winner_id, min_sample)
|
|
177
|
+
ltv_ab_variations -- Variações de prompt por experimento
|
|
178
|
+
ltv_ab_assignments -- Registro de qual variação foi usada por lead
|
|
179
|
+
v_ab_test_performance -- VIEW: accuracy por variação com métricas consolidadas
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Variáveis de Ambiente Requeridas
|
|
185
|
+
|
|
186
|
+
| Variável | Binding | Descrição |
|
|
187
|
+
|----------|---------|-----------|
|
|
188
|
+
| `DB` | D1 | Tabelas ltv_ab_tests, ltv_ab_variations, ltv_ab_assignments |
|
|
189
|
+
| `AI` | Workers AI | Executa as variações de prompt |
|
|
190
|
+
| `GEO_CACHE` | KV | Cache do teste ativo (TTL: 5 min) |
|
|
191
|
+
|
|
192
|
+
*(Nenhum secret externo necessário)*
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
*Agente criado em conformidade com a arquitetura Quantum Tier CDP Edge — 9 de Abril de 2026*
|
|
@@ -44,7 +44,7 @@ Browser (Cliente) Worker (Server-Side) APIs (Meta/Google/TikT
|
|
|
44
44
|
|
|
45
45
|
**Uso:** Campanhas de última milha, conversão rápida.
|
|
46
46
|
|
|
47
|
-
```
|
|
47
|
+
```typescript
|
|
48
48
|
function lastClickAttribution(touchpoints) {
|
|
49
49
|
if (!touchpoints || touchpoints.length === 0) return [];
|
|
50
50
|
|
|
@@ -69,7 +69,7 @@ function lastClickAttribution(touchpoints) {
|
|
|
69
69
|
|
|
70
70
|
**Uso:** Brand awareness, campanhas de descoberta.
|
|
71
71
|
|
|
72
|
-
```
|
|
72
|
+
```typescript
|
|
73
73
|
function firstClickAttribution(touchpoints) {
|
|
74
74
|
if (!touchpoints || touchpoints.length === 0) return [];
|
|
75
75
|
|
|
@@ -94,7 +94,7 @@ function firstClickAttribution(touchpoints) {
|
|
|
94
94
|
|
|
95
95
|
**Uso:** Jornadas longas, múltiplos touchpoints importantes.
|
|
96
96
|
|
|
97
|
-
```
|
|
97
|
+
```typescript
|
|
98
98
|
function linearAttribution(touchpoints) {
|
|
99
99
|
if (!touchpoints || touchpoints.length === 0) return [];
|
|
100
100
|
|
|
@@ -122,7 +122,7 @@ function linearAttribution(touchpoints) {
|
|
|
122
122
|
|
|
123
123
|
**Fórmula:** `Credit = 0.9^dias_desde_touchpoint`
|
|
124
124
|
|
|
125
|
-
```
|
|
125
|
+
```typescript
|
|
126
126
|
function timeDecayAttribution(touchpoints, decayFactor = 0.9) {
|
|
127
127
|
if (!touchpoints || touchpoints.length === 0) return [];
|
|
128
128
|
|
|
@@ -165,7 +165,7 @@ function timeDecayAttribution(touchpoints, decayFactor = 0.9) {
|
|
|
165
165
|
|
|
166
166
|
**Uso:** Funis com pesquisa (awareness) + conversão direta.
|
|
167
167
|
|
|
168
|
-
```
|
|
168
|
+
```typescript
|
|
169
169
|
function uShapeAttribution(touchpoints) {
|
|
170
170
|
if (!touchpoints || touchpoints.length === 0) return [];
|
|
171
171
|
|
|
@@ -207,7 +207,7 @@ function uShapeAttribution(touchpoints) {
|
|
|
207
207
|
|
|
208
208
|
**Uso:** Funis muito longos, jornada complexa.
|
|
209
209
|
|
|
210
|
-
```
|
|
210
|
+
```typescript
|
|
211
211
|
function wShapeAttribution(touchpoints) {
|
|
212
212
|
if (!touchpoints || touchpoints.length === 0) return [];
|
|
213
213
|
|
|
@@ -262,9 +262,9 @@ function wShapeAttribution(touchpoints) {
|
|
|
262
262
|
|
|
263
263
|
**Fórmula:** `Credit = BaseScore * CanalWeight * PositionWeight * ConversionRateWeight`
|
|
264
264
|
|
|
265
|
-
```
|
|
265
|
+
```typescript
|
|
266
266
|
// Modelo Data-Driven simplificado
|
|
267
|
-
async function dataDrivenAttribution(touchpoints, userJourneyHistory) {
|
|
267
|
+
async function dataDrivenAttribution(touchpoints, userJourneyHistory, env) {
|
|
268
268
|
if (!touchpoints || touchpoints.length === 0) return [];
|
|
269
269
|
|
|
270
270
|
// 1. Calcular pesos baseados em dados históricos
|
|
@@ -297,14 +297,14 @@ async function dataDrivenAttribution(touchpoints, userJourneyHistory) {
|
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
// Calcular peso de canal baseado em conversão histórica
|
|
300
|
-
async function calculateChannelWeights(touchpoints, history) {
|
|
300
|
+
async function calculateChannelWeights(touchpoints, history, env) {
|
|
301
301
|
const weights = {};
|
|
302
302
|
|
|
303
303
|
for (const tp of touchpoints) {
|
|
304
304
|
const channel = tp.utm_source;
|
|
305
305
|
|
|
306
306
|
// Buscar conversões históricas deste canal
|
|
307
|
-
const historicalConversions = await DB.prepare(`
|
|
307
|
+
const historicalConversions = await env.DB.prepare(`
|
|
308
308
|
SELECT
|
|
309
309
|
COUNT(*) as total_conversions,
|
|
310
310
|
AVG(value) as avg_value
|
|
@@ -325,14 +325,14 @@ async function calculateChannelWeights(touchpoints, history) {
|
|
|
325
325
|
}
|
|
326
326
|
|
|
327
327
|
// Calcular peso de posição baseado em conversão histórica
|
|
328
|
-
async function calculatePositionWeights(touchpoints, history) {
|
|
328
|
+
async function calculatePositionWeights(touchpoints, history, env) {
|
|
329
329
|
const weights = {};
|
|
330
330
|
|
|
331
331
|
for (const tp of touchpoints) {
|
|
332
332
|
const position = tp.position; // 0 = first, 1 = second, etc.
|
|
333
333
|
|
|
334
334
|
// Buscar conversões históricas nesta posição
|
|
335
|
-
const historicalConversions = await DB.prepare(`
|
|
335
|
+
const historicalConversions = await env.DB.prepare(`
|
|
336
336
|
SELECT
|
|
337
337
|
COUNT(*) as total_conversions
|
|
338
338
|
FROM multi_touch_attribution
|
|
@@ -456,9 +456,9 @@ CREATE INDEX IF NOT EXISTS idx_channel_model ON channel_performance(attribution_
|
|
|
456
456
|
|
|
457
457
|
### 2.1 Captura de Jornada Completa
|
|
458
458
|
|
|
459
|
-
```
|
|
459
|
+
```typescript
|
|
460
460
|
// Capturar touchpoint da jornada
|
|
461
|
-
export async function captureTouchpoint(eventData, request) {
|
|
461
|
+
export async function captureTouchpoint(eventData, request, env) {
|
|
462
462
|
const {
|
|
463
463
|
user_id,
|
|
464
464
|
session_id,
|
|
@@ -485,7 +485,7 @@ export async function captureTouchpoint(eventData, request) {
|
|
|
485
485
|
const position = await calculateJourneyPosition(user_id, event_timestamp);
|
|
486
486
|
|
|
487
487
|
// Persistir touchpoint no D1
|
|
488
|
-
await DB.prepare(`
|
|
488
|
+
await env.DB.prepare(`
|
|
489
489
|
INSERT INTO user_journeys
|
|
490
490
|
(user_id, session_id, email, event_id, event_name,
|
|
491
491
|
utm_source, utm_medium, utm_campaign, utm_content, utm_term,
|
|
@@ -512,8 +512,8 @@ export async function captureTouchpoint(eventData, request) {
|
|
|
512
512
|
}
|
|
513
513
|
|
|
514
514
|
// Calcular posição na jornada
|
|
515
|
-
async function calculateJourneyPosition(userId, eventTimestamp) {
|
|
516
|
-
const result = await DB.prepare(`
|
|
515
|
+
async function calculateJourneyPosition(userId, eventTimestamp, env) {
|
|
516
|
+
const result = await env.DB.prepare(`
|
|
517
517
|
SELECT COUNT(*) as position
|
|
518
518
|
FROM user_journeys
|
|
519
519
|
WHERE user_id = ? AND event_timestamp < ?
|
|
@@ -523,7 +523,7 @@ async function calculateJourneyPosition(userId, eventTimestamp) {
|
|
|
523
523
|
}
|
|
524
524
|
|
|
525
525
|
// Agendar cálculo de atribuição (via Cloudflare Queue)
|
|
526
|
-
async function scheduleAttributionCalculation(email, conversionId, eventName) {
|
|
526
|
+
async function scheduleAttributionCalculation(email, conversionId, eventName, env) {
|
|
527
527
|
await QUEUE.send('cdp-edge-attribution', {
|
|
528
528
|
type: 'CALCULATE_ATTRIBUTION',
|
|
529
529
|
email,
|
|
@@ -536,9 +536,9 @@ async function scheduleAttributionCalculation(email, conversionId, eventName) {
|
|
|
536
536
|
|
|
537
537
|
### 2.2 Cálculo de Atribuição Multi-Touch
|
|
538
538
|
|
|
539
|
-
```
|
|
539
|
+
```typescript
|
|
540
540
|
// Calcular atribuição multi-touch
|
|
541
|
-
export async function calculateMultiTouchAttribution(conversionData) {
|
|
541
|
+
export async function calculateMultiTouchAttribution(conversionData, env) {
|
|
542
542
|
const {
|
|
543
543
|
email,
|
|
544
544
|
conversion_id,
|
|
@@ -548,7 +548,7 @@ export async function calculateMultiTouchAttribution(conversionData) {
|
|
|
548
548
|
} = conversionData;
|
|
549
549
|
|
|
550
550
|
// 1. Buscar jornada completa do usuário
|
|
551
|
-
const journey = await DB.prepare(`
|
|
551
|
+
const journey = await env.DB.prepare(`
|
|
552
552
|
SELECT
|
|
553
553
|
user_id,
|
|
554
554
|
session_id,
|
|
@@ -594,7 +594,7 @@ export async function calculateMultiTouchAttribution(conversionData) {
|
|
|
594
594
|
// 3. Persistir atribuição para cada modelo
|
|
595
595
|
for (const [modelName, attribution] of Object.entries(attributionModels)) {
|
|
596
596
|
for (const touchpoint of attribution) {
|
|
597
|
-
await DB.prepare(`
|
|
597
|
+
await env.DB.prepare(`
|
|
598
598
|
INSERT OR REPLACE INTO multi_touch_attribution
|
|
599
599
|
(conversion_id, user_id, email, attribution_model, touchpoint_index,
|
|
600
600
|
utm_source, utm_medium, utm_campaign, event_name, event_timestamp,
|
|
@@ -628,7 +628,7 @@ export async function calculateMultiTouchAttribution(conversionData) {
|
|
|
628
628
|
}
|
|
629
629
|
|
|
630
630
|
// Atualizar performance de canal
|
|
631
|
-
async function updateChannelPerformance(attributionModels, value, currency) {
|
|
631
|
+
async function updateChannelPerformance(attributionModels, value, currency, env) {
|
|
632
632
|
const today = new Date().toISOString().split('T')[0];
|
|
633
633
|
|
|
634
634
|
for (const [modelName, attribution] of Object.entries(attributionModels)) {
|
|
@@ -660,7 +660,7 @@ async function updateChannelPerformance(attributionModels, value, currency) {
|
|
|
660
660
|
|
|
661
661
|
// Atualizar tabela de performance
|
|
662
662
|
for (const perf of Object.values(channelPerformance)) {
|
|
663
|
-
await DB.prepare(`
|
|
663
|
+
await env.DB.prepare(`
|
|
664
664
|
INSERT OR REPLACE INTO channel_performance
|
|
665
665
|
(utm_source, utm_medium, utm_campaign, attribution_model,
|
|
666
666
|
total_attribution, total_conversions, total_value, avg_conversion_value, date)
|
|
@@ -683,9 +683,9 @@ async function updateChannelPerformance(attributionModels, value, currency) {
|
|
|
683
683
|
|
|
684
684
|
### 2.3 Enviar Atribuição para Plataformas
|
|
685
685
|
|
|
686
|
-
```
|
|
686
|
+
```typescript
|
|
687
687
|
// Enviar Purchase com atribuição calculada
|
|
688
|
-
export async function sendPurchaseWithAttribution(conversionData, attributionModel = 'U_SHAPE') {
|
|
688
|
+
export async function sendPurchaseWithAttribution(conversionData, env, attributionModel = 'U_SHAPE') {
|
|
689
689
|
const {
|
|
690
690
|
email,
|
|
691
691
|
conversion_id,
|
|
@@ -695,7 +695,7 @@ export async function sendPurchaseWithAttribution(conversionData, attributionMod
|
|
|
695
695
|
} = conversionData;
|
|
696
696
|
|
|
697
697
|
// 1. Buscar atribuição calculada
|
|
698
|
-
const attribution = await DB.prepare(`
|
|
698
|
+
const attribution = await env.DB.prepare(`
|
|
699
699
|
SELECT
|
|
700
700
|
utm_source,
|
|
701
701
|
utm_medium,
|
|
@@ -773,7 +773,7 @@ async function sendMetaPurchaseWithAttribution(purchaseData, attribution) {
|
|
|
773
773
|
const response = await fetch('https://graph.facebook.com/v22.0/events', {
|
|
774
774
|
method: 'POST',
|
|
775
775
|
headers: {
|
|
776
|
-
'Authorization': `Bearer ${META_ACCESS_TOKEN}`,
|
|
776
|
+
'Authorization': `Bearer ${env.META_ACCESS_TOKEN}`,
|
|
777
777
|
'Content-Type': 'application/json'
|
|
778
778
|
},
|
|
779
779
|
body: JSON.stringify({ data: [payload] })
|
|
@@ -829,7 +829,7 @@ async function sendTikTokPurchaseWithAttribution(purchaseData, attribution) {
|
|
|
829
829
|
const response = await fetch('https://business-api.tiktok.com/open_api/v1.3/pixel/conversion/', {
|
|
830
830
|
method: 'POST',
|
|
831
831
|
headers: {
|
|
832
|
-
'Authorization': `Bearer ${TIKTOK_ACCESS_TOKEN}`,
|
|
832
|
+
'Authorization': `Bearer ${env.TIKTOK_ACCESS_TOKEN}`,
|
|
833
833
|
'Content-Type': 'application/json'
|
|
834
834
|
},
|
|
835
835
|
body: JSON.stringify(payload)
|
|
@@ -914,7 +914,7 @@ async function sendGA4PurchaseWithAttribution(purchaseData, channelValues) {
|
|
|
914
914
|
|
|
915
915
|
### 3.1 Configuração via Arquivo
|
|
916
916
|
|
|
917
|
-
```
|
|
917
|
+
```typescript
|
|
918
918
|
// attribution.config.js
|
|
919
919
|
export const ATTRIBUTION_CONFIG = {
|
|
920
920
|
// Modelo padrão para cálculo de atribuição
|
|
@@ -1024,7 +1024,7 @@ export default ATTRIBUTION_CONFIG;
|
|
|
1024
1024
|
|
|
1025
1025
|
### 4.1 Endpoint de Atribuição
|
|
1026
1026
|
|
|
1027
|
-
```
|
|
1027
|
+
```typescript
|
|
1028
1028
|
// Endpoint para consultar atribuição de conversão
|
|
1029
1029
|
export async function getAttributionForConversion(request, env) {
|
|
1030
1030
|
const url = new URL(request.url);
|
|
@@ -1036,7 +1036,7 @@ export async function getAttributionForConversion(request, env) {
|
|
|
1036
1036
|
}
|
|
1037
1037
|
|
|
1038
1038
|
// Buscar atribuição calculada
|
|
1039
|
-
const attribution = await DB.prepare(`
|
|
1039
|
+
const attribution = await env.DB.prepare(`
|
|
1040
1040
|
SELECT
|
|
1041
1041
|
utm_source,
|
|
1042
1042
|
utm_medium,
|
|
@@ -1052,7 +1052,7 @@ export async function getAttributionForConversion(request, env) {
|
|
|
1052
1052
|
`).bind(conversionId, model).all();
|
|
1053
1053
|
|
|
1054
1054
|
// Buscar dados da conversão
|
|
1055
|
-
const conversion = await DB.prepare(`
|
|
1055
|
+
const conversion = await env.DB.prepare(`
|
|
1056
1056
|
SELECT
|
|
1057
1057
|
value,
|
|
1058
1058
|
currency,
|
|
@@ -1096,7 +1096,7 @@ export async function compareAttributionModels(request, env) {
|
|
|
1096
1096
|
const comparison = {};
|
|
1097
1097
|
|
|
1098
1098
|
for (const model of ATTRIBUTION_CONFIG.available_models) {
|
|
1099
|
-
const attribution = await DB.prepare(`
|
|
1099
|
+
const attribution = await env.DB.prepare(`
|
|
1100
1100
|
SELECT
|
|
1101
1101
|
utm_source,
|
|
1102
1102
|
credit_percentage
|
|
@@ -1136,7 +1136,7 @@ export async function getChannelPerformance(request, env) {
|
|
|
1136
1136
|
const days = parseInt(url.searchParams.get('days') || '30');
|
|
1137
1137
|
const groupBy = url.searchParams.get('group_by') || 'source'; // 'source' ou 'campaign'
|
|
1138
1138
|
|
|
1139
|
-
const performance = await DB.prepare(`
|
|
1139
|
+
const performance = await env.DB.prepare(`
|
|
1140
1140
|
SELECT
|
|
1141
1141
|
${groupBy === 'source' ? 'utm_source' : 'utm_campaign'} as group_by,
|
|
1142
1142
|
SUM(total_attribution) as total_attribution,
|
|
@@ -1167,10 +1167,10 @@ export async function getChannelPerformance(request, env) {
|
|
|
1167
1167
|
|
|
1168
1168
|
## 🎯 FORMATO DE SAÍDA
|
|
1169
1169
|
|
|
1170
|
-
### DELIVERABLE 1: `attribution-engine.
|
|
1170
|
+
### DELIVERABLE 1: `modules/attribution-engine.ts`
|
|
1171
1171
|
|
|
1172
|
-
```
|
|
1173
|
-
// attribution-engine.
|
|
1172
|
+
```typescript
|
|
1173
|
+
// modules/attribution-engine.ts - Engine de atribuição multi-touch
|
|
1174
1174
|
export {
|
|
1175
1175
|
captureTouchpoint,
|
|
1176
1176
|
calculateMultiTouchAttribution,
|
|
@@ -1207,10 +1207,10 @@ CREATE INDEX IF NOT EXISTS idx_channel_source ON channel_performance(utm_source)
|
|
|
1207
1207
|
CREATE INDEX IF NOT EXISTS idx_channel_campaign ON channel_performance(utm_campaign);
|
|
1208
1208
|
```
|
|
1209
1209
|
|
|
1210
|
-
### DELIVERABLE 3: `attribution-config.
|
|
1210
|
+
### DELIVERABLE 3: `modules/attribution-config.ts`
|
|
1211
1211
|
|
|
1212
|
-
```
|
|
1213
|
-
// attribution-config.
|
|
1212
|
+
```typescript
|
|
1213
|
+
// modules/attribution-config.ts - Configuração de modelos de atribuição
|
|
1214
1214
|
export const ATTRIBUTION_CONFIG = {
|
|
1215
1215
|
default_model: 'U_SHAPE',
|
|
1216
1216
|
available_models: [
|