cdp-edge 1.2.0 → 1.3.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.
Files changed (142) hide show
  1. package/README.md +153 -306
  2. package/bin/cdp-edge.js +71 -61
  3. package/contracts/agent-versions.json +682 -0
  4. package/contracts/api-versions.json +372 -368
  5. package/contracts/types.ts +81 -0
  6. package/dist/commands/analyze.js +52 -52
  7. package/dist/commands/infra.js +54 -54
  8. package/dist/commands/install.js +26 -3
  9. package/dist/commands/server.js +174 -174
  10. package/dist/commands/setup.js +332 -100
  11. package/dist/commands/validate.js +248 -84
  12. package/dist/index.js +12 -12
  13. package/dist/sdk/cdpTrack.js +2095 -0
  14. package/dist/sdk/cdpTrack.min.js +64 -0
  15. package/dist/sdk/install-snippet.html +10 -0
  16. package/docs/whatsapp-ctwa.md +5 -4
  17. package/extracted-skill/tracking-events-generator/INTEGRACAO-COMPLETA.md +89 -0
  18. package/extracted-skill/tracking-events-generator/MELHORIAS-IMPLEMENTADAS.md +101 -0
  19. package/extracted-skill/tracking-events-generator/advanced-matching.js +364 -364
  20. package/extracted-skill/tracking-events-generator/agents/ab-ltv-agent.md +196 -0
  21. package/extracted-skill/tracking-events-generator/agents/ab-testing-agent.md +1 -1
  22. package/extracted-skill/tracking-events-generator/agents/attribution-agent.md +41 -41
  23. package/extracted-skill/tracking-events-generator/agents/bidding-agent.md +347 -0
  24. package/extracted-skill/tracking-events-generator/agents/bing-agent.md +40 -50
  25. package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +174 -74
  26. package/extracted-skill/tracking-events-generator/agents/code-guardian-agent.md +1 -1
  27. package/extracted-skill/tracking-events-generator/agents/compliance-agent.md +25 -5
  28. package/extracted-skill/tracking-events-generator/agents/dashboard-agent.md +10 -10
  29. package/extracted-skill/tracking-events-generator/agents/database-agent.md +43 -42
  30. package/extracted-skill/tracking-events-generator/agents/debug-agent.md +22 -22
  31. package/extracted-skill/tracking-events-generator/agents/devops-agent.md +232 -0
  32. package/extracted-skill/tracking-events-generator/agents/domain-setup-agent.md +23 -9
  33. package/extracted-skill/tracking-events-generator/agents/email-agent.md +28 -1
  34. package/extracted-skill/tracking-events-generator/agents/evo-crm-agent.md +244 -0
  35. package/extracted-skill/tracking-events-generator/agents/fingerprint-agent.md +206 -1
  36. package/extracted-skill/tracking-events-generator/agents/fraud-detection-agent.md +143 -0
  37. package/extracted-skill/tracking-events-generator/agents/google-agent.md +128 -2
  38. package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +191 -31
  39. package/extracted-skill/tracking-events-generator/agents/lead-scoring-agent.md +282 -0
  40. package/extracted-skill/tracking-events-generator/agents/linkedin-agent.md +145 -34
  41. package/extracted-skill/tracking-events-generator/agents/localization-agent.md +1 -1
  42. package/extracted-skill/tracking-events-generator/agents/ltv-predictor-agent.md +5 -5
  43. package/extracted-skill/tracking-events-generator/agents/master-feedback-loop.md +81 -21
  44. package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +428 -190
  45. package/extracted-skill/tracking-events-generator/agents/match-quality-agent.md +304 -0
  46. package/extracted-skill/tracking-events-generator/agents/memory-agent.json +25 -109
  47. package/extracted-skill/tracking-events-generator/agents/memory-agent.md +190 -15
  48. package/extracted-skill/tracking-events-generator/agents/meta-agent.md +10 -2
  49. package/extracted-skill/tracking-events-generator/agents/ml-clustering-agent.md +749 -0
  50. package/extracted-skill/tracking-events-generator/agents/page-analyzer.md +21 -4
  51. package/extracted-skill/tracking-events-generator/agents/performance-agent.md +41 -31
  52. package/extracted-skill/tracking-events-generator/agents/performance-optimization-agent.md +18 -8
  53. package/extracted-skill/tracking-events-generator/agents/pinterest-agent.md +14 -6
  54. package/extracted-skill/tracking-events-generator/agents/premium-tracking-intelligence-agent.md +7 -7
  55. package/extracted-skill/tracking-events-generator/agents/r2-setup-agent.md +16 -8
  56. package/extracted-skill/tracking-events-generator/agents/reddit-agent.md +15 -7
  57. package/extracted-skill/tracking-events-generator/agents/security-enterprise-agent.md +157 -48
  58. package/extracted-skill/tracking-events-generator/agents/server-tracking.md +35 -35
  59. package/extracted-skill/tracking-events-generator/agents/spotify-agent.md +15 -7
  60. package/extracted-skill/tracking-events-generator/agents/tiktok-agent.md +73 -2
  61. package/extracted-skill/tracking-events-generator/agents/tracking-plan-agent.md +104 -9
  62. package/extracted-skill/tracking-events-generator/agents/utm-agent.md +322 -0
  63. package/extracted-skill/tracking-events-generator/agents/validator-agent.md +13 -9
  64. package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +112 -4
  65. package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +58 -5
  66. package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +26 -18
  67. package/extracted-skill/tracking-events-generator/agents/youtube-agent.md +152 -37
  68. package/extracted-skill/tracking-events-generator/anti-blocking.js +285 -285
  69. package/extracted-skill/tracking-events-generator/cdpTrack.js +642 -641
  70. package/extracted-skill/tracking-events-generator/contracts/api-versions.json +14 -10
  71. package/extracted-skill/tracking-events-generator/engagement-scoring.js +226 -226
  72. package/extracted-skill/tracking-events-generator/evals/evals.json +235 -235
  73. package/extracted-skill/tracking-events-generator/integration-test.js +497 -497
  74. package/extracted-skill/tracking-events-generator/knowledge-base.md +172 -0
  75. package/extracted-skill/tracking-events-generator/micro-events.js +992 -992
  76. package/extracted-skill/tracking-events-generator/models/lancamento-imobiliario.md +344 -0
  77. package/extracted-skill/tracking-events-generator/models/pinterest/conversions-api-template.js +144 -144
  78. package/extracted-skill/tracking-events-generator/models/pinterest/event-mappings.json +48 -48
  79. package/extracted-skill/tracking-events-generator/models/pinterest/tag-template.js +28 -28
  80. package/extracted-skill/tracking-events-generator/models/quiz-funnel.md +83 -19
  81. package/extracted-skill/tracking-events-generator/models/reddit/conversions-api-template.js +205 -205
  82. package/extracted-skill/tracking-events-generator/models/reddit/event-mappings.json +56 -56
  83. package/extracted-skill/tracking-events-generator/models/reddit/pixel-template.js +19 -19
  84. package/extracted-skill/tracking-events-generator/models/scenarios/behavior-engine.js +425 -425
  85. package/extracted-skill/tracking-events-generator/route-intent-capture.js +222 -0
  86. package/extracted-skill/tracking-events-generator/tracking.config.js +3 -3
  87. package/package.json +89 -75
  88. package/scripts/build-sdk.js +106 -0
  89. package/server-edge-tracker/.client.env.example +14 -0
  90. package/server-edge-tracker/INSTALAR.md +222 -23
  91. package/server-edge-tracker/SEGMENTATION-DOCS.md +513 -0
  92. package/server-edge-tracker/config/utm-mapping.json +64 -0
  93. package/server-edge-tracker/deploy-client.cjs +76 -0
  94. package/server-edge-tracker/index.ts +1230 -0
  95. package/server-edge-tracker/migrate-v7.sql +64 -0
  96. package/server-edge-tracker/modules/db.ts +710 -0
  97. package/server-edge-tracker/modules/dispatch/crm.ts +382 -0
  98. package/server-edge-tracker/modules/dispatch/ga4.ts +72 -0
  99. package/server-edge-tracker/modules/dispatch/meta.ts +143 -0
  100. package/server-edge-tracker/modules/dispatch/platforms.ts +255 -0
  101. package/server-edge-tracker/modules/dispatch/tiktok.ts +107 -0
  102. package/server-edge-tracker/modules/dispatch/whatsapp.ts +296 -0
  103. package/server-edge-tracker/modules/intelligence.ts +589 -0
  104. package/server-edge-tracker/modules/ml/bidding.ts +247 -0
  105. package/server-edge-tracker/modules/ml/fraud.ts +302 -0
  106. package/server-edge-tracker/modules/ml/logistic.ts +226 -0
  107. package/server-edge-tracker/modules/ml/ltv.ts +531 -0
  108. package/server-edge-tracker/modules/ml/matchquality.ts +232 -0
  109. package/server-edge-tracker/modules/ml/quiz.ts +343 -0
  110. package/server-edge-tracker/modules/ml/roas.ts +255 -0
  111. package/server-edge-tracker/modules/ml/segmentation.ts +407 -0
  112. package/server-edge-tracker/modules/nurture.ts +257 -0
  113. package/server-edge-tracker/modules/utils.ts +311 -0
  114. package/server-edge-tracker/modules/utm/utm-enricher.ts +231 -0
  115. package/server-edge-tracker/schema-ab-ltv.sql +97 -0
  116. package/server-edge-tracker/schema-bidding.sql +86 -0
  117. package/server-edge-tracker/schema-fraud.sql +90 -0
  118. package/server-edge-tracker/schema-indexes.sql +67 -0
  119. package/server-edge-tracker/schema-ltv-feedback.sql +11 -0
  120. package/server-edge-tracker/schema-quiz.sql +52 -0
  121. package/server-edge-tracker/schema-sales-engine.sql +113 -0
  122. package/server-edge-tracker/schema-segmentation.sql +219 -0
  123. package/server-edge-tracker/schema-utm.sql +82 -0
  124. package/server-edge-tracker/schema.sql +281 -265
  125. package/server-edge-tracker/types.ts +275 -0
  126. package/server-edge-tracker/wrangler.toml +140 -85
  127. package/templates/lancamento-imobiliario.md +344 -0
  128. package/templates/multi-step-checkout.md +3 -4
  129. package/templates/pinterest/conversions-api-template.js +144 -144
  130. package/templates/pinterest/event-mappings.json +48 -48
  131. package/templates/pinterest/tag-template.js +28 -28
  132. package/templates/quiz-funnel.md +83 -19
  133. package/templates/reddit/conversions-api-template.js +205 -205
  134. package/templates/reddit/event-mappings.json +56 -56
  135. package/templates/reddit/pixel-template.js +12 -39
  136. package/templates/scenarios/behavior-engine.js +45 -22
  137. package/docs/PixelBuilder-Documentacao-Completa (2).docx +0 -0
  138. package/docs/installation.md +0 -155
  139. package/docs/quick-start.md +0 -185
  140. package/extracted-skill/tracking-events-generator/agents/crm-integration-agent.md +0 -1419
  141. package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +0 -643
  142. package/server-edge-tracker/worker.js +0 -2574
@@ -0,0 +1,231 @@
1
+ /**
2
+ * UTM Enricher Module
3
+ * Obfusca/desobfusca UTMs sensíveis (valores de produto)
4
+ * Integração com Agente UTM
5
+ */
6
+
7
+ // ============================================================================
8
+ // Constants & Config
9
+ // ============================================================================
10
+
11
+ const UTM_SALT = 'CDP_EDGE_UTM_SALT';
12
+ const HASH_TRUNCATE_LENGTH = 8;
13
+
14
+ // Obfuscação: SHA256(original + salt) → truncate(8)
15
+ // Isso garante: mesmo valor → mesmo hash, mas irreversível sem o mapeamento
16
+
17
+ // ============================================================================
18
+ // Types
19
+ // ============================================================================
20
+
21
+ export interface UTMMapping {
22
+ obfuscated: string; // Hash truncado (ex: "8a3f1d2b")
23
+ original: string; // Valor real (ex: "700k-1M")
24
+ category: string; // "imovel", "automotivo", etc
25
+ pixel_audience?: string; // ID da custom audience Meta
26
+ platform_specific?: {
27
+ meta?: { custom_audience_id?: string };
28
+ tiktok?: { pixel_id?: string };
29
+ ga4?: { event_parameter?: string };
30
+ };
31
+ }
32
+
33
+ export interface UTMMappingConfig {
34
+ method: 'sha256';
35
+ salt: string;
36
+ truncated_length: number;
37
+ mappings: UTMMapping[];
38
+ }
39
+
40
+ export interface EnrichedUTM {
41
+ source?: string;
42
+ medium?: string;
43
+ campaign?: string;
44
+ content?: string;
45
+ faixa_obfuscada?: string; // Hash da faixa de valor
46
+ faixa_real?: string; // Valor real (de-obfuscado)
47
+ faixa_category?: string; // Categoria do produto
48
+ product_id_obfuscated?: string;
49
+ product_id_real?: string;
50
+ }
51
+
52
+ // ============================================================================
53
+ // Core Functions
54
+ // ============================================================================
55
+
56
+ /**
57
+ * Obfusca um valor sensível usando SHA256 + truncate
58
+ * @param value - Valor a ser obfuscado (ex: "700k-1M")
59
+ * @returns Hash truncado de 8 caracteres
60
+ */
61
+ export function obfuscateValue(value: string): string {
62
+ // sha256(value + salt) → truncate(8)
63
+ const hash = sha256(`${value}${UTM_SALT}`);
64
+ return hash.substring(0, HASH_TRUNCATE_LENGTH);
65
+ }
66
+
67
+ /**
68
+ * Verifica se um hash é válido (8 chars hex)
69
+ */
70
+ export function isValidObfuscatedHash(hash: string): boolean {
71
+ return /^[a-f0-9]{8}$/.test(hash);
72
+ }
73
+
74
+ /**
75
+ * Desobfusca um valor usando o mapeamento
76
+ * @param obfuscated - Hash obfuscado
77
+ * @param mappings - Mapeamento de UTM (do config/utm-mapping.json)
78
+ * @returns UTM com valor real ou undefined se não encontrado
79
+ */
80
+ export function deobfuscateValue(
81
+ obfuscated: string,
82
+ mappings: UTMMapping[]
83
+ ): UTMMapping | undefined {
84
+ return mappings.find(m => m.obfuscated === obfuscated);
85
+ }
86
+
87
+ /**
88
+ * Enrich payload com UTMs, desobfuscando valores sensíveis
89
+ */
90
+ export function enrichPayloadWithUTM(
91
+ payload: any,
92
+ utms: Record<string, string>,
93
+ mappings: UTMMapping[]
94
+ ): { enriched: any; faixa?: UTMMapping } {
95
+ const enriched = { ...payload };
96
+ let faixa: UTMMapping | undefined;
97
+
98
+ // Desobfuscar faixa de valor
99
+ if (utms.faixa_obfuscada || utms.utm_faixa) {
100
+ const faixaHash = utms.faixa_obfuscada || utms.utm_faixa;
101
+ if (isValidObfuscatedHash(faixaHash)) {
102
+ faixa = deobfuscateValue(faixaHash, mappings);
103
+ if (faixa) {
104
+ enriched.faixa_real = faixa.original;
105
+ enriched.faixa_category = faixa.category;
106
+ enriched.pixel_audience = faixa.pixel_audience;
107
+ }
108
+ }
109
+ }
110
+
111
+ // Extrair UTMs padrão
112
+ enriched.utm_source = utms.utm_source || utms.source;
113
+ enriched.utm_medium = utms.utm_medium || utms.medium;
114
+ enriched.utm_campaign = utms.utm_campaign || utms.campaign;
115
+ enriched.utm_content = utms.utm_content || utms.content;
116
+
117
+ return { enriched, faixa };
118
+ }
119
+
120
+ /**
121
+ * Gera UTM obfuscada para uma faixa de valor
122
+ * @param range - Faixa real (ex: "700k-1M")
123
+ * @param category - Categoria (ex: "imovel")
124
+ * @returns Object com hash obfuscado
125
+ */
126
+ export function generateObfuscatedUTM(range: string, category: string) {
127
+ const obfuscated = obfuscateValue(range);
128
+ return {
129
+ utm_faixa: obfuscated,
130
+ utm_campaign: `${category}_${obfuscated}`,
131
+ original_range: range,
132
+ hash: obfuscated
133
+ };
134
+ }
135
+
136
+ /**
137
+ * Cria um novo mapeamento de UTM
138
+ */
139
+ export function createUTMMapping(
140
+ original: string,
141
+ category: string,
142
+ platform_specific?: any
143
+ ): UTMMapping {
144
+ return {
145
+ obfuscated: obfuscateValue(original),
146
+ original,
147
+ category,
148
+ platform_specific
149
+ };
150
+ }
151
+
152
+ // ============================================================================
153
+ // Integration Functions (para uso no Worker)
154
+ // ============================================================================
155
+
156
+ /**
157
+ * Verifica se payload tem UTMs de segmentação
158
+ */
159
+ export function hasSegmentationUTM(utms: Record<string, string>): boolean {
160
+ return !!(
161
+ utms.faixa_obfuscada ||
162
+ utms.utm_faixa ||
163
+ (utms.utm_campaign && isValidObfuscatedHash(
164
+ utms.utm_campaign.split('_').pop() || ''
165
+ ))
166
+ );
167
+ }
168
+
169
+ /**
170
+ * Extrai faixa de valor do utm_campaign (pattern: category_hash)
171
+ */
172
+ export function extractFaixaFromCampaign(
173
+ campaign: string
174
+ ): string | null {
175
+ const parts = campaign.split('_');
176
+ const hash = parts.pop();
177
+ if (hash && isValidObfuscatedHash(hash)) {
178
+ return hash;
179
+ }
180
+ return null;
181
+ }
182
+
183
+ /**
184
+ * Para Meta CAPI: adiciona segmentação ao external_id
185
+ */
186
+ export function addSegmentationToExternalId(
187
+ cdp_uid: string,
188
+ faixa: UTMMapping
189
+ ): string {
190
+ return `${cdp_uid}_${faixa.obfuscated}`;
191
+ }
192
+
193
+ /**
194
+ * Para GA4: cria custom parameter segmentado
195
+ */
196
+ export function createSegmentationCustomParameter(faixa: UTMMapping) {
197
+ return {
198
+ 'custom_faixa_categoria': faixa.category,
199
+ 'custom_faixa_obfuscada': faixa.obfuscated,
200
+ 'custom_faixa_audience': faixa.pixel_audience || 'UNKNOWN'
201
+ };
202
+ }
203
+
204
+ // ============================================================================
205
+ // Import de sha256 (reutilizar de utils.ts)
206
+ // ============================================================================
207
+
208
+ function sha256(message: string): string {
209
+ // Importado de utils.ts - implementação real do SHA256
210
+ // Aqui simulamos para o exemplo:
211
+ const crypto = require('crypto');
212
+ return crypto.createHash('sha256').update(message).digest('hex');
213
+ }
214
+
215
+ // ============================================================================
216
+ // Export
217
+ // ============================================================================
218
+
219
+ export const UTM_ENRICHER_VERSION = '1.0.0';
220
+
221
+ export default {
222
+ obfuscateValue,
223
+ deobfuscateValue,
224
+ enrichPayloadWithUTM,
225
+ generateObfuscatedUTM,
226
+ createUTMMapping,
227
+ hasSegmentationUTM,
228
+ extractFaixaFromCampaign,
229
+ addSegmentationToExternalId,
230
+ createSegmentationCustomParameter
231
+ };
@@ -0,0 +1,97 @@
1
+ -- Schema A/B Testing de Prompts LTV — CDP Edge Quantum Tier
2
+ -- Versão: 1.0
3
+ -- Data: 9 de Abril de 2026
4
+ -- Fase 3 Enterprise-Level
5
+
6
+ -- TABELA: Experimentos A/B
7
+ CREATE TABLE IF NOT EXISTS ltv_ab_tests (
8
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
9
+ name TEXT NOT NULL,
10
+ description TEXT,
11
+ status TEXT NOT NULL DEFAULT 'draft', -- 'draft', 'running', 'paused', 'completed'
12
+ winner_id INTEGER, -- FK para ltv_ab_variations.id
13
+ started_at TEXT,
14
+ completed_at TEXT,
15
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
16
+ min_sample INTEGER NOT NULL DEFAULT 100, -- Mínimo de assignments para declarar vencedor
17
+ confidence_threshold REAL NOT NULL DEFAULT 0.90 -- Nível de confiança estatística (90%)
18
+ );
19
+
20
+ -- TABELA: Variações de Prompt por Experimento
21
+ CREATE TABLE IF NOT EXISTS ltv_ab_variations (
22
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ test_id INTEGER NOT NULL REFERENCES ltv_ab_tests(id),
24
+ name TEXT NOT NULL, -- Ex: 'Variação A — Foco em Engajamento'
25
+ system_prompt TEXT NOT NULL, -- O prompt system enviado ao Workers AI
26
+ weight REAL NOT NULL DEFAULT 0.5, -- Peso de distribuição (0-1, soma deve = 1)
27
+ is_control INTEGER NOT NULL DEFAULT 0, -- 1 = variação controle (baseline)
28
+
29
+ -- Métricas acumuladas
30
+ total_assigned INTEGER NOT NULL DEFAULT 0,
31
+ total_purchases INTEGER NOT NULL DEFAULT 0,
32
+ sum_predicted_ltv REAL NOT NULL DEFAULT 0,
33
+ sum_real_revenue REAL NOT NULL DEFAULT 0,
34
+
35
+ -- Métricas calculadas (atualizadas por trigger ou batch)
36
+ avg_predicted_ltv REAL,
37
+ avg_real_revenue REAL,
38
+ conversion_rate REAL,
39
+ accuracy_score REAL, -- Quão próximo do valor real (1 - |predicted-real|/real)
40
+
41
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
42
+ );
43
+
44
+ -- TABELA: Assignments — qual variação foi usada para qual lead
45
+ CREATE TABLE IF NOT EXISTS ltv_ab_assignments (
46
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
47
+ test_id INTEGER NOT NULL REFERENCES ltv_ab_tests(id),
48
+ variation_id INTEGER NOT NULL REFERENCES ltv_ab_variations(id),
49
+ user_id TEXT NOT NULL,
50
+ email_hash TEXT, -- SHA256 do email (indexação sem PII)
51
+ predicted_ltv REAL,
52
+ predicted_class TEXT,
53
+ assigned_at TEXT NOT NULL DEFAULT (datetime('now')),
54
+
55
+ -- Preenchido quando purchase chega via webhook
56
+ converted INTEGER NOT NULL DEFAULT 0,
57
+ real_revenue REAL,
58
+ converted_at TEXT
59
+ );
60
+
61
+ -- Índices
62
+ CREATE INDEX IF NOT EXISTS idx_ab_tests_status ON ltv_ab_tests(status);
63
+ CREATE INDEX IF NOT EXISTS idx_ab_variations_test ON ltv_ab_variations(test_id);
64
+ CREATE INDEX IF NOT EXISTS idx_ab_assignments_test ON ltv_ab_assignments(test_id);
65
+ CREATE INDEX IF NOT EXISTS idx_ab_assignments_user ON ltv_ab_assignments(user_id);
66
+ CREATE INDEX IF NOT EXISTS idx_ab_assignments_email ON ltv_ab_assignments(email_hash);
67
+ CREATE INDEX IF NOT EXISTS idx_ab_assignments_conv ON ltv_ab_assignments(converted);
68
+
69
+ -- VIEW: Resumo de performance por variação
70
+ CREATE VIEW IF NOT EXISTS v_ab_test_performance AS
71
+ SELECT
72
+ t.id AS test_id,
73
+ t.name AS test_name,
74
+ t.status,
75
+ v.id AS variation_id,
76
+ v.name AS variation_name,
77
+ v.is_control,
78
+ v.weight,
79
+ v.total_assigned,
80
+ v.total_purchases,
81
+ CASE WHEN v.total_assigned > 0
82
+ THEN ROUND(CAST(v.total_purchases AS REAL) / v.total_assigned * 100, 2)
83
+ ELSE 0
84
+ END AS conversion_rate_pct,
85
+ CASE WHEN v.total_assigned > 0
86
+ THEN ROUND(v.sum_predicted_ltv / v.total_assigned, 2)
87
+ ELSE 0
88
+ END AS avg_predicted_ltv,
89
+ CASE WHEN v.total_purchases > 0
90
+ THEN ROUND(v.sum_real_revenue / v.total_purchases, 2)
91
+ ELSE 0
92
+ END AS avg_real_revenue,
93
+ v.accuracy_score,
94
+ t.winner_id = v.id AS is_winner
95
+ FROM ltv_ab_tests t
96
+ JOIN ltv_ab_variations v ON v.test_id = t.id
97
+ ORDER BY t.id, v.id;
@@ -0,0 +1,86 @@
1
+ -- Schema de Recomendações de Bids Automáticas — CDP Edge Quantum Tier
2
+ -- Versão: 1.0
3
+ -- Data: 9 de Abril de 2026
4
+ -- Complementa: schema-segmentation.sql
5
+
6
+ -- TABELA PRINCIPAL: Recomendações de Bids
7
+ CREATE TABLE IF NOT EXISTS bid_recommendations (
8
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
9
+ generated_at TEXT NOT NULL DEFAULT (datetime('now')),
10
+ vertical TEXT NOT NULL, -- 'infoproduto', 'ecommerce', 'saas'
11
+ platform TEXT NOT NULL, -- 'meta', 'google', 'tiktok', 'all'
12
+ period_days INTEGER NOT NULL DEFAULT 30, -- Janela de análise
13
+ target_roi REAL NOT NULL DEFAULT 3.5, -- ROI alvo
14
+
15
+ -- Segmento ML de origem (FK para ml_segments)
16
+ segment_id INTEGER,
17
+ segment_name TEXT,
18
+
19
+ -- Dados analisados
20
+ leads_analyzed INTEGER NOT NULL DEFAULT 0,
21
+ conversions_found INTEGER NOT NULL DEFAULT 0,
22
+ avg_ltv REAL, -- LTV médio do segmento
23
+ cpa_target REAL, -- CPA alvo calculado: avg_ltv / target_roi
24
+
25
+ -- Output: O Bid em si
26
+ recommended_bid REAL, -- Bid recomendado em BRL
27
+ bid_currency TEXT NOT NULL DEFAULT 'BRL',
28
+ confidence REAL NOT NULL DEFAULT 0, -- 0-1 (base: conversions / 100)
29
+ expected_roi REAL, -- ROI esperado com este bid
30
+
31
+ -- Rastreabilidade
32
+ reasoning TEXT, -- Explicação detalhada da lógica
33
+ ai_used INTEGER DEFAULT 0, -- 1 = Workers AI usado
34
+ alert_message TEXT, -- Ex: "Dados insuficientes (< 30 conversões)"
35
+
36
+ -- Fatores internos de cálculo (para auditoria)
37
+ platform_factor REAL, -- 0.75–0.90 por plataforma
38
+ confidence_adjustment REAL, -- 0.70–1.00 por nível de confiança
39
+ segment_multiplier REAL, -- 0.60–1.40 por tipo de segmento
40
+
41
+ -- Ciclo de vida
42
+ is_active INTEGER NOT NULL DEFAULT 1,
43
+ applied_at TEXT, -- Quando o usuário aplicou o bid
44
+ applied_campaign TEXT, -- ID da campanha onde foi aplicado
45
+ applied_result TEXT -- JSON: {clicks, conversions, real_roi}
46
+ );
47
+
48
+ -- Índices
49
+ CREATE INDEX IF NOT EXISTS idx_bid_recs_vertical ON bid_recommendations(vertical);
50
+ CREATE INDEX IF NOT EXISTS idx_bid_recs_platform ON bid_recommendations(platform);
51
+ CREATE INDEX IF NOT EXISTS idx_bid_recs_generated ON bid_recommendations(generated_at);
52
+ CREATE INDEX IF NOT EXISTS idx_bid_recs_active ON bid_recommendations(is_active);
53
+ CREATE INDEX IF NOT EXISTS idx_bid_recs_segment ON bid_recommendations(segment_id);
54
+ CREATE INDEX IF NOT EXISTS idx_bid_recs_confidence ON bid_recommendations(confidence);
55
+
56
+ -- VIEW: Recomendações Ativas (com dados dos segmentos)
57
+ CREATE VIEW IF NOT EXISTS v_active_bid_recommendations AS
58
+ SELECT
59
+ br.id,
60
+ br.generated_at,
61
+ br.vertical,
62
+ br.platform,
63
+ br.period_days,
64
+ br.target_roi,
65
+ br.segment_name,
66
+ br.leads_analyzed,
67
+ br.conversions_found,
68
+ br.avg_ltv,
69
+ br.cpa_target,
70
+ br.recommended_bid,
71
+ br.bid_currency,
72
+ br.confidence,
73
+ br.expected_roi,
74
+ br.reasoning,
75
+ br.alert_message,
76
+ br.ai_used,
77
+ -- Dados do segmento ML relacionado
78
+ ms.cluster_name AS ml_cluster_name,
79
+ ms.avg_behavior_score,
80
+ ms.avg_engagement_score,
81
+ ms.silhouette_score,
82
+ ms.size AS segment_size
83
+ FROM bid_recommendations br
84
+ LEFT JOIN ml_segments ms ON br.segment_id = ms.id
85
+ WHERE br.is_active = 1
86
+ ORDER BY br.generated_at DESC;
@@ -0,0 +1,90 @@
1
+ -- Schema Fraud Detection — CDP Edge Quantum Tier
2
+ -- Versão: 1.0
3
+ -- Data: 9 de Abril de 2026
4
+ -- Fase 4 Enterprise-Level
5
+
6
+ -- TABELA: Sinais de Fraude por Evento
7
+ CREATE TABLE IF NOT EXISTS fraud_signals (
8
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
9
+ detected_at TEXT NOT NULL DEFAULT (datetime('now')),
10
+
11
+ -- Identificadores do evento
12
+ ip_address TEXT,
13
+ fingerprint TEXT,
14
+ user_id TEXT,
15
+ email_hash TEXT, -- SHA256, sem PII
16
+ event_name TEXT,
17
+ event_id TEXT,
18
+
19
+ -- Score e decisão
20
+ fraud_score INTEGER NOT NULL, -- 0-100
21
+ action_taken TEXT NOT NULL, -- 'allowed', 'flagged', 'dropped'
22
+ reasons TEXT NOT NULL, -- JSON array: ["ip_velocity_high", "datacenter_ip", ...]
23
+
24
+ -- Contexto
25
+ ip_country TEXT,
26
+ ip_asn TEXT,
27
+ user_agent TEXT,
28
+ bot_score INTEGER,
29
+ velocity_1h INTEGER, -- Eventos deste IP na última 1h
30
+ velocity_1m INTEGER, -- Eventos deste IP no último 1min
31
+
32
+ -- Resultado (preenchido depois se lead converter)
33
+ was_real_user INTEGER -- 1 = comprou depois (falso positivo), 0 = fraude confirmada
34
+ );
35
+
36
+ -- TABELA: Alertas Agregados (quando IP/fingerprint atinge threshold repetidamente)
37
+ CREATE TABLE IF NOT EXISTS fraud_alerts (
38
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
39
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
40
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
41
+
42
+ alert_type TEXT NOT NULL, -- 'ip_attack', 'fingerprint_abuse', 'bot_network'
43
+ entity_type TEXT NOT NULL, -- 'ip', 'fingerprint', 'asn'
44
+ entity_value TEXT NOT NULL, -- O IP, fingerprint ou ASN em questão
45
+
46
+ -- Métricas do ataque
47
+ events_total INTEGER NOT NULL DEFAULT 0,
48
+ events_dropped INTEGER NOT NULL DEFAULT 0,
49
+ peak_score INTEGER NOT NULL DEFAULT 0,
50
+ first_seen TEXT NOT NULL DEFAULT (datetime('now')),
51
+ last_seen TEXT NOT NULL DEFAULT (datetime('now')),
52
+
53
+ -- Status
54
+ is_blocked INTEGER NOT NULL DEFAULT 0, -- 1 = está no KV blocklist
55
+ blocked_at TEXT,
56
+ block_expires TEXT, -- NULL = permanente
57
+ resolved_at TEXT,
58
+ resolved_by TEXT, -- 'auto', 'manual'
59
+
60
+ -- Contexto
61
+ top_reasons TEXT, -- JSON: razões mais comuns
62
+ sample_ips TEXT -- JSON: amostra de IPs relacionados (para redes de bots)
63
+ );
64
+
65
+ -- Índices
66
+ CREATE INDEX IF NOT EXISTS idx_fraud_signals_ip ON fraud_signals(ip_address);
67
+ CREATE INDEX IF NOT EXISTS idx_fraud_signals_fp ON fraud_signals(fingerprint);
68
+ CREATE INDEX IF NOT EXISTS idx_fraud_signals_score ON fraud_signals(fraud_score);
69
+ CREATE INDEX IF NOT EXISTS idx_fraud_signals_action ON fraud_signals(action_taken);
70
+ CREATE INDEX IF NOT EXISTS idx_fraud_signals_date ON fraud_signals(detected_at);
71
+ CREATE INDEX IF NOT EXISTS idx_fraud_alerts_entity ON fraud_alerts(entity_type, entity_value);
72
+ CREATE INDEX IF NOT EXISTS idx_fraud_alerts_blocked ON fraud_alerts(is_blocked);
73
+ CREATE INDEX IF NOT EXISTS idx_fraud_alerts_date ON fraud_alerts(created_at);
74
+
75
+ -- VIEW: Dashboard de fraude (últimas 24h)
76
+ CREATE VIEW IF NOT EXISTS v_fraud_dashboard AS
77
+ SELECT
78
+ COUNT(*) AS total_events_checked,
79
+ SUM(CASE WHEN action_taken = 'dropped' THEN 1 ELSE 0 END) AS events_dropped,
80
+ SUM(CASE WHEN action_taken = 'flagged' THEN 1 ELSE 0 END) AS events_flagged,
81
+ SUM(CASE WHEN action_taken = 'allowed' THEN 1 ELSE 0 END) AS events_allowed,
82
+ ROUND(
83
+ CAST(SUM(CASE WHEN action_taken = 'dropped' THEN 1 ELSE 0 END) AS REAL) /
84
+ NULLIF(COUNT(*), 0) * 100
85
+ , 2) AS fraud_rate_pct,
86
+ AVG(fraud_score) AS avg_fraud_score,
87
+ MAX(fraud_score) AS peak_fraud_score,
88
+ COUNT(DISTINCT ip_address) AS unique_ips_flagged
89
+ FROM fraud_signals
90
+ WHERE detected_at >= datetime('now', '-24 hours');
@@ -0,0 +1,67 @@
1
+ -- CDP Edge — Composite Indexes para Performance
2
+ -- Executar após todos os outros schemas:
3
+ -- wrangler d1 execute cdp-edge-db --file=schema-indexes.sql --remote
4
+ --
5
+ -- Todos os índices usam IF NOT EXISTS — idempotente, seguro para re-executar.
6
+
7
+ -- ── leads: queries mais comuns ────────────────────────────────────────────────
8
+
9
+ -- Deduplicação por email + janela temporal (upsertProfile, saveLead)
10
+ CREATE INDEX IF NOT EXISTS idx_leads_email_created
11
+ ON leads(email, created_at DESC);
12
+
13
+ -- Relatórios por plataforma + período (Intelligence Agent, Dashboard)
14
+ CREATE INDEX IF NOT EXISTS idx_leads_platform_created
15
+ ON leads(platform, created_at DESC);
16
+
17
+ -- Lookup de conversão por evento + período (auditErrorRates, generateDailyReport)
18
+ CREATE INDEX IF NOT EXISTS idx_leads_event_created
19
+ ON leads(event_name, created_at DESC);
20
+
21
+ -- Identity resolution: user_id + evento para evitar duplicatas
22
+ CREATE INDEX IF NOT EXISTS idx_leads_userid_event
23
+ ON leads(user_id, event_name);
24
+
25
+ -- Exportação Customer Match: event_name + email filtrado por data
26
+ CREATE INDEX IF NOT EXISTS idx_leads_event_email
27
+ ON leads(event_name, email);
28
+
29
+ -- CRM Dashboard: ordenação por status + criação
30
+ CREATE INDEX IF NOT EXISTS idx_leads_crm_created
31
+ ON leads(crm_status, created_at DESC);
32
+
33
+ -- ── user_profiles: enrichment e Advanced Matching ────────────────────────────
34
+
35
+ -- Busca por LTV class + atualização (Bidding ML consome isso)
36
+ CREATE INDEX IF NOT EXISTS idx_profiles_ltv_updated
37
+ ON user_profiles(predicted_ltv_class, updated_at DESC);
38
+
39
+ -- Score + cohort para segmentação ML (handleSegmentationCluster)
40
+ CREATE INDEX IF NOT EXISTS idx_profiles_score_cohort
41
+ ON user_profiles(score DESC, cohort_label);
42
+
43
+ -- Lookup email + updated_at (resolveDeviceGraph, getProfileByEmail)
44
+ CREATE INDEX IF NOT EXISTS idx_profiles_email_updated
45
+ ON user_profiles(email, updated_at DESC);
46
+
47
+ -- ── fraud_signals: dashboard e alertas ───────────────────────────────────────
48
+
49
+ -- handleFraudAlerts: filtra por ip + período (coluna: detected_at)
50
+ CREATE INDEX IF NOT EXISTS idx_fraud_ip_detected
51
+ ON fraud_signals(ip_address, detected_at DESC);
52
+
53
+ -- handleFraudStats: fraud_score >= threshold ordenado por data
54
+ CREATE INDEX IF NOT EXISTS idx_fraud_score_detected
55
+ ON fraud_signals(fraud_score DESC, detected_at DESC);
56
+
57
+ -- ── ltv_ab_assignments: resultados de A/B test ───────────────────────────────
58
+
59
+ -- handleLtvAbTestResults: test_id + predicted_class para análise
60
+ CREATE INDEX IF NOT EXISTS idx_ab_testid_class
61
+ ON ltv_ab_assignments(test_id, predicted_class);
62
+
63
+ -- ── ml_segment_members: join com leads para bidding ─────────────────────────
64
+
65
+ -- handleBiddingRecommend: segment_id lookup (coluna: assigned_at)
66
+ CREATE INDEX IF NOT EXISTS idx_seg_members_segid
67
+ ON ml_segment_members(cluster_id, assigned_at DESC);
@@ -0,0 +1,11 @@
1
+ -- CDP Edge — Schema LTV Feedback Loop
2
+ -- Fecha o ciclo preditivo: Purchase real → corrige predicted_ltv_value
3
+ -- Execução: wrangler d1 execute cdp-edge-db --file=schema-ltv-feedback.sql --remote
4
+ --
5
+ -- Idempotência: ALTER TABLE não suporta IF NOT EXISTS no SQLite.
6
+ -- Se a coluna já existir, o comando gera erro mas não afeta dados existentes.
7
+ -- Seguro executar mais de uma vez.
8
+
9
+ ALTER TABLE user_profiles ADD COLUMN real_ltv_value REAL;
10
+ ALTER TABLE user_profiles ADD COLUMN ltv_accuracy REAL; -- 1 - |pred-real|/real (0–1, maior = melhor)
11
+ ALTER TABLE user_profiles ADD COLUMN ltv_feedback_at TEXT; -- timestamp do último feedback
@@ -0,0 +1,52 @@
1
+ -- CDP Edge — Schema Quiz Sessions (Fase 6 v2)
2
+ -- Análise Dimensional Automática por Workers AI
3
+ -- Executar: wrangler d1 execute cdp-edge-db --file=schema-quiz.sql --remote
4
+
5
+ CREATE TABLE IF NOT EXISTS quiz_sessions (
6
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
7
+ user_id TEXT, -- _cdp_uid (FK lógica → user_profiles)
8
+ quiz_name TEXT, -- nome do quiz (ex: "Diagnóstico Imóvel")
9
+ answers_json TEXT NOT NULL, -- JSON: [{question, answer, step}]
10
+ qualification TEXT NOT NULL, -- comprador | interessado | curioso | perdido
11
+ intent_score REAL NOT NULL, -- 0.0–1.0 (propagado ao pipeline CDP)
12
+ weighted_score REAL NOT NULL, -- score ponderado bruto Σ(score×weight)/Σ(weight)
13
+ confidence REAL NOT NULL DEFAULT 0.7,
14
+ reason TEXT, -- frase explicativa em português (audit)
15
+ dominant_dimension TEXT, -- dimensão com maior impacto: budget|urgency|etc.
16
+ dimensions_json TEXT, -- JSON: [{step, dimension, score, weight, signal}]
17
+ source TEXT DEFAULT 'ai', -- ai | heuristic
18
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
19
+ );
20
+
21
+ CREATE INDEX IF NOT EXISTS idx_quiz_user_id ON quiz_sessions(user_id);
22
+ CREATE INDEX IF NOT EXISTS idx_quiz_qualification ON quiz_sessions(qualification);
23
+ CREATE INDEX IF NOT EXISTS idx_quiz_created_at ON quiz_sessions(created_at);
24
+ CREATE INDEX IF NOT EXISTS idx_quiz_dominant_dim ON quiz_sessions(dominant_dimension);
25
+
26
+ -- VIEW: distribuição de qualificações por quiz + score médio
27
+ CREATE VIEW IF NOT EXISTS v_quiz_qualification_summary AS
28
+ SELECT
29
+ quiz_name,
30
+ qualification,
31
+ COUNT(*) AS total,
32
+ ROUND(AVG(intent_score) * 100, 1) AS avg_intent_pct,
33
+ ROUND(AVG(weighted_score) * 100, 1) AS avg_weighted_pct,
34
+ ROUND(AVG(confidence) * 100, 1) AS avg_confidence_pct,
35
+ COUNT(CASE WHEN source = 'ai' THEN 1 END) AS ai_scored,
36
+ COUNT(CASE WHEN source = 'heuristic' THEN 1 END) AS heuristic_scored
37
+ FROM quiz_sessions
38
+ GROUP BY quiz_name, qualification
39
+ ORDER BY quiz_name, avg_intent_pct DESC;
40
+
41
+ -- VIEW: qual dimensão mais penaliza/beneficia cada quiz
42
+ CREATE VIEW IF NOT EXISTS v_quiz_dimension_impact AS
43
+ SELECT
44
+ quiz_name,
45
+ dominant_dimension,
46
+ COUNT(*) AS total_sessions,
47
+ ROUND(AVG(weighted_score) * 100, 1) AS avg_weighted_pct,
48
+ qualification
49
+ FROM quiz_sessions
50
+ WHERE dominant_dimension IS NOT NULL
51
+ GROUP BY quiz_name, dominant_dimension, qualification
52
+ ORDER BY quiz_name, total_sessions DESC;