cdp-edge 1.17.0 β†’ 1.18.1

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 (42) hide show
  1. package/contracts/api-versions.json +12 -8
  2. package/dist/commands/install.js +186 -0
  3. package/dist/commands/setup.js +18 -1
  4. package/extracted-skill/tracking-events-generator/agents/attribution-agent.md +23 -23
  5. package/extracted-skill/tracking-events-generator/agents/bing-agent.md +8 -0
  6. package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +172 -72
  7. package/extracted-skill/tracking-events-generator/agents/compliance-agent.md +20 -0
  8. package/extracted-skill/tracking-events-generator/agents/crm-integration-agent.md +56 -16
  9. package/extracted-skill/tracking-events-generator/agents/dashboard-agent.md +7 -7
  10. package/extracted-skill/tracking-events-generator/agents/database-agent.md +16 -8
  11. package/extracted-skill/tracking-events-generator/agents/debug-agent.md +13 -13
  12. package/extracted-skill/tracking-events-generator/agents/devops-agent.md +32 -7
  13. package/extracted-skill/tracking-events-generator/agents/domain-setup-agent.md +8 -0
  14. package/extracted-skill/tracking-events-generator/agents/email-agent.md +27 -0
  15. package/extracted-skill/tracking-events-generator/agents/fingerprint-agent.md +205 -0
  16. package/extracted-skill/tracking-events-generator/agents/google-agent.md +126 -0
  17. package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +90 -4
  18. package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +8 -641
  19. package/extracted-skill/tracking-events-generator/agents/linkedin-agent.md +116 -0
  20. package/extracted-skill/tracking-events-generator/agents/ltv-predictor-agent.md +1 -1
  21. package/extracted-skill/tracking-events-generator/agents/master-feedback-loop.md +68 -8
  22. package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +71 -34
  23. package/extracted-skill/tracking-events-generator/agents/memory-agent.md +127 -2
  24. package/extracted-skill/tracking-events-generator/agents/meta-agent.md +8 -0
  25. package/extracted-skill/tracking-events-generator/agents/performance-agent.md +29 -19
  26. package/extracted-skill/tracking-events-generator/agents/performance-optimization-agent.md +11 -1
  27. package/extracted-skill/tracking-events-generator/agents/pinterest-agent.md +8 -0
  28. package/extracted-skill/tracking-events-generator/agents/r2-setup-agent.md +8 -0
  29. package/extracted-skill/tracking-events-generator/agents/reddit-agent.md +8 -0
  30. package/extracted-skill/tracking-events-generator/agents/security-enterprise-agent.md +137 -28
  31. package/extracted-skill/tracking-events-generator/agents/server-tracking.md +8 -8
  32. package/extracted-skill/tracking-events-generator/agents/spotify-agent.md +8 -0
  33. package/extracted-skill/tracking-events-generator/agents/tiktok-agent.md +71 -0
  34. package/extracted-skill/tracking-events-generator/agents/tracking-plan-agent.md +100 -5
  35. package/extracted-skill/tracking-events-generator/agents/validator-agent.md +4 -0
  36. package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +108 -0
  37. package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +58 -5
  38. package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +23 -15
  39. package/extracted-skill/tracking-events-generator/agents/youtube-agent.md +140 -25
  40. package/extracted-skill/tracking-events-generator/contracts/api-versions.json +12 -8
  41. package/package.json +2 -2
  42. package/server-edge-tracker/worker.js +53 -8
@@ -109,99 +109,199 @@ Implementado via `anti-blocking.js`:
109
109
 
110
110
  ## πŸ’» EXEMPLO DE CΓ“DIGO GERADO
111
111
 
112
- ### `cdpTrack.js` (SDK Principal)
112
+ ### `cdpTrack.js` (SDK Principal β€” PadrΓ£o Multi-Plataforma)
113
+
114
+ > Este Γ© o padrΓ£o canΓ΄nico do cdpTrack SDK para Meta, TikTok e GA4.
115
+ > Cada agente de plataforma injeta seus eventos neste SDK via Browser Tracking Agent.
113
116
 
114
117
  ```javascript
115
118
  /**
116
119
  * cdpTrack SDK - CDP Edge Quantum Tier
117
120
  * Browser Tracking SDK Principal
121
+ * Suporta: Meta Pixel, TikTok Pixel, GA4, Pinterest Tag, Reddit Pixel, Spotify Pixel
118
122
  */
119
123
 
120
- (function(w, d, s, l) {
121
- w._pbq = w._pbq || [];
122
- w._pbq.push = w._pbq.push || [];
123
- w._spotify = w._spotify || {};
124
-
125
- // Carregar configuraΓ§Γ£o
126
- const config = window.cdpTrack?.config || {};
124
+ (function(w) {
125
+ 'use strict';
127
126
 
128
- // Inicializar Spotify Pixel (se configurado)
129
- if (config.spotifyPixelId) {
130
- w._spotify.pixelId = config.spotifyPixelId;
131
- w._spotify.currency = config.currency || 'USD';
127
+ // ──────────────────────────────────────────────
128
+ // CORE: GeraΓ§Γ£o de event_id ΓΊnico (deduplicaΓ§Γ£o)
129
+ // O mesmo event_id deve ser usado no browser E no servidor (CAPI)
130
+ // ──────────────────────────────────────────────
131
+ function generateEventId() {
132
+ return 'evt_' + Date.now() + '_' + Math.random().toString(36).substring(2, 11);
132
133
  }
133
134
 
134
- // FunΓ§Γ£o principal de envio
135
- w._spotify.trackEvent = function(eventName, params) {
136
- const eventId = cdpTrack.generateEventId();
137
-
138
- // Track localmente
139
- w._spq.push({
140
- e: eventName,
141
- params: params,
142
- eventId: eventId,
143
- platform: 'spotify'
144
- });
145
-
146
- // Enviar para servidor (via cdpTrack)
147
- if (window.cdpTrack && window.cdpTrack.submit) {
148
- window.cdpTrack.submit('spotify', {
149
- event: eventName,
150
- event_id: eventId,
151
- ...params
135
+ // ──────────────────────────────────────────────
136
+ // CORE: Envio para Cloudflare Worker (same-domain)
137
+ // Usa /track no mesmo domΓ­nio β€” imune a ad-blockers
138
+ // ──────────────────────────────────────────────
139
+ async function sendToWorker(eventName, payload) {
140
+ const eventId = generateEventId();
141
+
142
+ const body = {
143
+ event: eventName,
144
+ event_id: eventId, // CRÍTICO: mesmo ID usado nas CAPIs
145
+ url: window.location.href,
146
+ referrer: document.referrer,
147
+ timestamp: Date.now(),
148
+ ...payload
149
+ };
150
+
151
+ try {
152
+ // Tentativa primΓ‘ria: fetch
153
+ await fetch('/track', {
154
+ method: 'POST',
155
+ headers: { 'Content-Type': 'application/json' },
156
+ body: JSON.stringify(body),
157
+ keepalive: true
152
158
  });
159
+ } catch (_) {
160
+ // Fallback: Beacon API (funciona mesmo no unload da pΓ‘gina)
161
+ navigator.sendBeacon('/track', JSON.stringify(body));
153
162
  }
154
- };
155
163
 
156
- // Eventos PadrΓ£o Spotify
157
- w._spotify.Content = function(contentName, contentId, params) {
158
- w._spotify.trackEvent('ViewContent', {
159
- content_name: contentName,
160
- content_id: contentId,
161
- ...params
162
- });
163
- };
164
+ return eventId;
165
+ }
164
166
 
165
- w._spotify.AddToCart = function(contentName, contentId, cartId, params) {
166
- w._spotify.trackEvent('AddToCart', {
167
- content_name: contentName,
168
- content_id: contentId,
169
- cart_id: cartId,
170
- ...params
171
- });
172
- };
167
+ // ──────────────────────────────────────────────
168
+ // CORE: Captura de cookies first-party
169
+ // ──────────────────────────────────────────────
170
+ function getCookie(name) {
171
+ const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
172
+ return match ? decodeURIComponent(match[2]) : null;
173
+ }
173
174
 
174
- w._spotify.Purchase = function(contentName, contentId, value, currency, params) {
175
- w._spotify.trackEvent('Purchase', {
176
- content_name: contentName,
177
- content_id: contentId,
178
- value: value,
179
- currency: currency,
180
- ...params
181
- });
182
- };
175
+ // ──────────────────────────────────────────────
176
+ // CORE: Captura de click IDs da URL (Meta, TikTok, Google)
177
+ // ──────────────────────────────────────────────
178
+ function getClickIds() {
179
+ const params = new URLSearchParams(window.location.search);
180
+ return {
181
+ fbclid: params.get('fbclid') || getCookie('fbclid') || null,
182
+ ttclid: params.get('ttclid') || getCookie('ttclid') || null,
183
+ gclid: params.get('gclid') || null,
184
+ gbraid: params.get('gbraid') || null,
185
+ wbraid: params.get('wbraid') || null,
186
+ fbp: getCookie('_fbp') || null,
187
+ fbc: getCookie('_fbc') || null,
188
+ ttp: getCookie('_ttp') || null,
189
+ uid: getCookie('_cdp_uid') || null // Identity Graph first-party cookie
190
+ };
191
+ }
183
192
 
184
- w._spotify.Lead = function(contentName, contentId, leadType, params) {
185
- w._spotify.trackEvent('Lead', {
186
- content_name: contentName,
187
- content_id: contentId,
188
- lead_type: leadType,
189
- ...params
190
- });
191
- };
193
+ // ──────────────────────────────────────────────
194
+ // API PÚBLICA
195
+ // ──────────────────────────────────────────────
196
+ const cdpTrack = {
197
+ generateEventId,
198
+
199
+ /**
200
+ * Rastrear evento genΓ©rico β€” enviado para o Worker
201
+ * O Worker despacha para Meta CAPI, GA4 MP, TikTok Events API etc.
202
+ *
203
+ * @param {string} eventName - Nome do evento (ex: 'Lead', 'Purchase', 'PageView')
204
+ * @param {Object} params - ParΓ’metros adicionais do evento
205
+ */
206
+ track(eventName, params = {}) {
207
+ const clickIds = getClickIds();
208
+ return sendToWorker(eventName, { ...clickIds, ...params });
209
+ },
210
+
211
+ /**
212
+ * Rastrear Lead (captura de formulΓ‘rio)
213
+ * Enviar dados PII crus β€” o Worker faz SHA-256 no servidor
214
+ */
215
+ trackLead(userData = {}) {
216
+ const clickIds = getClickIds();
217
+ return sendToWorker('Lead', {
218
+ ...clickIds,
219
+ email: userData.email || null, // Worker aplica SHA-256
220
+ phone: userData.phone || null, // Worker aplica E.164 + SHA-256
221
+ first_name: userData.first_name || null,
222
+ last_name: userData.last_name || null,
223
+ city: userData.city || null,
224
+ state: userData.state || null,
225
+ zip: userData.zip || null,
226
+ country: userData.country || 'BR'
227
+ });
228
+ },
192
229
 
193
- w._spotify.Signup = function(contentName, contentId, signupType, params) {
194
- w._spotify.trackEvent('Signup', {
195
- content_name: contentName,
196
- content_id: contentId,
197
- signup_type: signupType,
198
- ...params
199
- });
230
+ /**
231
+ * Rastrear Purchase (confirmaΓ§Γ£o de compra)
232
+ */
233
+ trackPurchase(orderData = {}) {
234
+ const clickIds = getClickIds();
235
+ return sendToWorker('Purchase', {
236
+ ...clickIds,
237
+ value: orderData.value || 0,
238
+ currency: orderData.currency || 'BRL',
239
+ order_id: orderData.order_id || null,
240
+ content_name: orderData.product || null
241
+ });
242
+ },
243
+
244
+ /**
245
+ * Rastrear PageView β€” chamar no load da pΓ‘gina
246
+ */
247
+ trackPageView() {
248
+ const clickIds = getClickIds();
249
+ return sendToWorker('PageView', { ...clickIds });
250
+ },
251
+
252
+ /**
253
+ * Rastrear InitiateCheckout
254
+ */
255
+ trackInitiateCheckout(checkoutData = {}) {
256
+ const clickIds = getClickIds();
257
+ return sendToWorker('InitiateCheckout', {
258
+ ...clickIds,
259
+ value: checkoutData.value || 0,
260
+ currency: checkoutData.currency || 'BRL'
261
+ });
262
+ }
200
263
  };
201
264
 
202
- })(window, document, 'script', 'location');
265
+ // Expor no window
266
+ w.cdpTrack = cdpTrack;
267
+
268
+ // Auto page_view no load
269
+ if (document.readyState === 'loading') {
270
+ document.addEventListener('DOMContentLoaded', () => cdpTrack.trackPageView());
271
+ } else {
272
+ cdpTrack.trackPageView();
273
+ }
274
+
275
+ })(window);
203
276
  ```
204
277
 
278
+ ### Uso tΓ­pico no HTML do cliente
279
+
280
+ ```html
281
+ <!-- 1. Carregar o SDK -->
282
+ <script src="/tracking/cdpTrack.js"></script>
283
+
284
+ <!-- 2. Rastrear lead ao submeter formulΓ‘rio -->
285
+ <script>
286
+ document.getElementById('lead-form').addEventListener('submit', function(e) {
287
+ cdpTrack.trackLead({
288
+ email: document.getElementById('email').value,
289
+ phone: document.getElementById('phone').value,
290
+ first_name: document.getElementById('name').value
291
+ });
292
+ });
293
+ </script>
294
+
295
+ <!-- 3. Rastrear checkout (botΓ£o de compra) -->
296
+ <script>
297
+ document.getElementById('buy-btn').addEventListener('click', function() {
298
+ cdpTrack.trackInitiateCheckout({ value: 97.00, currency: 'BRL' });
299
+ });
300
+ </script>
301
+ ```
302
+
303
+ > **Nota:** O Worker recebe os dados crus, aplica SHA-256, e despacha para Meta CAPI v22.0, GA4 MP, TikTok Events API v1.3 e demais plataformas configuradas β€” tudo em paralelo via `Promise.allSettled`.
304
+
205
305
  ---
206
306
 
207
307
  ## πŸ”§ INTEGRAÇÃO COM OUTROS AGENTES
@@ -2044,6 +2044,26 @@ async function handleGetCurrentPolicy(request, env) {
2044
2044
  - **security-enterprise-agent.md**: Usa encryption de PII para LGPD/GDPR
2045
2045
  - **attribution-agent.md**: Respeita consentimento para analytics e marketing
2046
2046
  - **master-orchestrator.md**: Implementa middleware de consentimento antes de tracking
2047
+ - **validator-agent.md**: O Compliance Agent DEVE ser consultado pelo Validator Agent para verificar conformidade de PII. Fluxo:
2048
+
2049
+ ```
2050
+ validator-agent (auditoria do cΓ³digo gerado)
2051
+ └─► checkComplianceCompliance(generatedCode)
2052
+ β”œβ”€ Verificar: SHA-256 aplicado em todos os campos PII (em, ph, fn, ln)?
2053
+ β”œβ”€ Verificar: Google Consent Mode v2 implementado (ad_storage, analytics_storage)?
2054
+ β”œβ”€ Verificar: url_passthrough: true ativo?
2055
+ β”œβ”€ Verificar: PII nunca logada em plaintext?
2056
+ └─ Verificar: opt-in explΓ­cito antes de tracking de marketing?
2057
+
2058
+ // No validator-agent, chamar:
2059
+ const complianceCheck = await validateComplianceRequirements(generatedBrowserCode, generatedWorkerCode);
2060
+ if (!complianceCheck.passed) {
2061
+ // Bloquear entrega e reportar issues ao Master Orchestrator
2062
+ return { status: 'BLOCKED', issues: complianceCheck.issues };
2063
+ }
2064
+ ```
2065
+
2066
+ - **google-agent.md**: Consent Mode v2 gerado por este agente valida conformidade detectada pelo Compliance Agent
2047
2067
 
2048
2068
  ---
2049
2069
 
@@ -4,6 +4,46 @@ VocΓͺ Γ© o **Agente de IntegraΓ§Γ£o CRM do CDP Edge**. Sua responsabilidade: **c
4
4
 
5
5
  ---
6
6
 
7
+ ## βœ… REGRAS CRÍTICAS
8
+
9
+ 0. **CONSULTA OBRIGATΓ“RIA Γ€ MEMΓ“RIA**: Extraia as Credenciais de APIs CRM e Endpoints de IntegraΓ§Γ£o (`CRM_API_KEY`, `CRM_ENDPOINT`, `CRM_WEBHOOK_SECRET`) consultando ativamente o "memory-agent.json". Solicite ao Orquestrador tudo o que faltar. Execute integraΓ§Γ΅es de CRM exclusivamente com os dados oficiais guardados na MemΓ³ria para garantir alinhamento sistΓͺmico.
10
+ 1. Cloudflare-Only: Sem dependΓͺncias externas.
11
+ 2. Same-Domain: Worker no domΓ­nio do site (anti-adblock).
12
+
13
+ ---
14
+
15
+ ## πŸ”— FLUXO DE ATIVAÇÃO (Como este agente Γ© chamado)
16
+
17
+ O CRM Integration Agent Γ© ativado pelo **Webhook Agent** apΓ³s confirmaΓ§Γ£o de compra ou captura de lead:
18
+
19
+ ```
20
+ Webhook Agent (purchase confirmado)
21
+ └─► ctx.waitUntil(syncToCRM(env, 'purchase', payload))
22
+ β”‚
23
+ β”œβ”€ Criar/atualizar contato no CRM com status 'customer'
24
+ β”œβ”€ Criar negΓ³cio/oportunidade com valor da compra
25
+ └─ Atualizar D1 com CRM_CONTACT_ID para rastreamento futuro
26
+
27
+ Webhook Agent (lead capturado via /track)
28
+ └─► ctx.waitUntil(syncToCRM(env, 'lead', payload))
29
+ β”‚
30
+ β”œβ”€ Criar contato no CRM com status 'lead'
31
+ └─ Registrar no D1 para cruzamento futuro
32
+ ```
33
+
34
+ **Assinatura da funΓ§Γ£o exportada (injetada no Worker):**
35
+
36
+ ```javascript
37
+ // Injetada no worker.js pelo CRM Integration Agent
38
+ export async function syncToCRM(env, eventType, payload) {
39
+ // eventType: 'lead' | 'purchase' | 'checkout_abandoned'
40
+ // payload: { email, name, product, value, order_id, phone }
41
+ // Retorna: { success: boolean, crm_contact_id: string | null }
42
+ }
43
+ ```
44
+
45
+ ---
46
+
7
47
  ## 🎯 OBJETIVO PRINCIPAL
8
48
 
9
49
  Implementar **integraΓ§Γ£o bidirecional** entre CDP Edge D1 e CRMs externos, permitindo que dados de tracking (leads, purchases, user journeys) fluam automaticamente para sistemas de vendas, marketing e atendimento, eliminando importaΓ§Γ΅es manuais e maximizando conversΓ£o.
@@ -604,8 +644,8 @@ export const PURCHASE_FIELD_MAPPINGS = {
604
644
 
605
645
  ```javascript
606
646
  // Sincronizar leads do D1 para CRM em batch
607
- export async function syncLeadsToCRM(hours = 24, batchSize = 50) {
608
- const leads = await DB.prepare(`
647
+ export async function syncLeadsToCRM(env, hours = 24, batchSize = 50) {
648
+ const leads = await env.DB.prepare(`
609
649
  SELECT * FROM leads
610
650
  WHERE created_at > datetime('now', '-${hours} hours')
611
651
  ORDER BY created_at DESC
@@ -691,8 +731,8 @@ async function sendLeadsBatchToCRM(leadsBatch) {
691
731
  };
692
732
  }
693
733
 
694
- async function markLeadAsSynced(leadId) {
695
- await DB.prepare(`
734
+ async function markLeadAsSynced(leadId, env) {
735
+ await env.DB.prepare(`
696
736
  UPDATE leads SET crm_synced = 1, crm_synced_at = datetime('now')
697
737
  WHERE id = ?
698
738
  `).bind(leadId).run();
@@ -703,8 +743,8 @@ async function markLeadAsSynced(leadId) {
703
743
 
704
744
  ```javascript
705
745
  // Sincronizar compras do D1 para CRM em batch
706
- export async function syncPurchasesToCRM(hours = 24, batchSize = 20) {
707
- const purchases = await DB.prepare(`
746
+ export async function syncPurchasesToCRM(env, hours = 24, batchSize = 20) {
747
+ const purchases = await env.DB.prepare(`
708
748
  SELECT p.*, l.email
709
749
  FROM purchases p
710
750
  LEFT JOIN leads l ON p.lead_id = l.id
@@ -792,8 +832,8 @@ async function sendPurchasesBatchToCRM(purchasesBatch) {
792
832
  };
793
833
  }
794
834
 
795
- async function markPurchaseAsSynced(purchaseId) {
796
- await DB.prepare(`
835
+ async function markPurchaseAsSynced(purchaseId, env) {
836
+ await env.DB.prepare(`
797
837
  UPDATE purchases SET crm_synced = 1, crm_synced_at = datetime('now')
798
838
  WHERE id = ?
799
839
  `).bind(purchaseId).run();
@@ -845,8 +885,8 @@ export async function handleCRMWebhook(request, env) {
845
885
  }
846
886
  }
847
887
 
848
- async function updateLeadStageFromCRM(payload) {
849
- await DB.prepare(`
888
+ async function updateLeadStageFromCRM(payload, env) {
889
+ await env.DB.prepare(`
850
890
  UPDATE leads SET crm_stage = ?, crm_stage_updated_at = datetime('now')
851
891
  WHERE email = ?
852
892
  `).bind(payload.stage, payload.email).run();
@@ -854,8 +894,8 @@ async function updateLeadStageFromCRM(payload) {
854
894
  console.log(`Stage do lead ${payload.email} atualizado para: ${payload.stage}`);
855
895
  }
856
896
 
857
- async function updateDealStatusFromCRM(payload) {
858
- await DB.prepare(`
897
+ async function updateDealStatusFromCRM(payload, env) {
898
+ await env.DB.prepare(`
859
899
  UPDATE purchases SET crm_deal_status = ?, crm_deal_status_updated_at = datetime('now')
860
900
  WHERE transaction_id = ?
861
901
  `).bind(payload.status, payload.transaction_id).run();
@@ -863,8 +903,8 @@ async function updateDealStatusFromCRM(payload) {
863
903
  console.log(`Status da compra ${payload.transaction_id} atualizado para: ${payload.status}`);
864
904
  }
865
905
 
866
- async function updateLeadScoreFromCRM(payload) {
867
- await DB.prepare(`
906
+ async function updateLeadScoreFromCRM(payload, env) {
907
+ await env.DB.prepare(`
868
908
  UPDATE leads SET lead_score = ?, lead_score_updated_at = datetime('now')
869
909
  WHERE email = ?
870
910
  `).bind(payload.lead_score, payload.email).run();
@@ -971,7 +1011,7 @@ export async function registerCRMWebhooks(crmType, webhookUrl) {
971
1011
  };
972
1012
 
973
1013
  // Salvar configuraΓ§Γ£o no D1
974
- await DB.prepare(`
1014
+ await env.DB.prepare(`
975
1015
  INSERT INTO crm_webhook_config (webhook_url, crm_type, events, signature_enabled)
976
1016
  VALUES (?, ?, ?, ?)
977
1017
  `).bind(
@@ -986,7 +1026,7 @@ export async function registerCRMWebhooks(crmType, webhookUrl) {
986
1026
 
987
1027
  // Endpoint de saΓΊde da integraΓ§Γ£o
988
1028
  export async function handleCRMHealthCheck(request, env) {
989
- const stats = await DB.prepare(`
1029
+ const stats = await env.DB.prepare(`
990
1030
  SELECT
991
1031
  COUNT(*) as total_leads,
992
1032
  COUNT(CASE WHEN crm_synced = 1 THEN 1 END) as synced_leads,
@@ -96,16 +96,16 @@ Definir o Dashboard como um **Centro de Comando de Dados** que equilibra:
96
96
  **ImplementaΓ§Γ£o:**
97
97
  ```javascript
98
98
  // Carregar dados do cache
99
- const fetchMetrics = async (forceRefresh = false) => {
99
+ const fetchMetrics = async (env, forceRefresh = false) => {
100
100
  const cacheKey = 'dashboard_metrics';
101
- const cached = await KV.get(cacheKey);
101
+ const cached = await env.GEO_CACHE.get(cacheKey);
102
102
 
103
103
  if (cached && !forceRefresh) {
104
104
  return JSON.parse(cached);
105
105
  }
106
106
 
107
107
  // Cache miss ou refresh forΓ§ado β€” consultar D1
108
- const metrics = await DB.prepare(`
108
+ const metrics = await env.DB.prepare(`
109
109
  SELECT
110
110
  AVG(heat_score) as avg_heat,
111
111
  COUNT(DISTINCT fingerprint) as total_users,
@@ -115,7 +115,7 @@ const fetchMetrics = async (forceRefresh = false) => {
115
115
  `).all();
116
116
 
117
117
  // Salvar no KV com TTL de 1 hora
118
- await KV.put(cacheKey, JSON.stringify(metrics), { expirationTtl: 3600 });
118
+ await env.GEO_CACHE.put(cacheKey, JSON.stringify(metrics), { expirationTtl: 3600 });
119
119
 
120
120
  return metrics;
121
121
  };
@@ -217,13 +217,13 @@ export const DASHBOARD_API = {
217
217
  };
218
218
 
219
219
  // HANDLER DE SINCronizaÇÃO (atualizaΓ§Γ£o de cache)
220
- export async function invalidateCache(domain, pattern) {
220
+ export async function invalidateCache(domain, pattern, env) {
221
221
  const deletePattern = `${domain}:${pattern}`;
222
222
 
223
223
  // Deletar do KV
224
- const keys = await KV.list({ prefix: deletePattern });
224
+ const keys = await env.GEO_CACHE.list({ prefix: deletePattern });
225
225
  for (const key of keys.keys) {
226
- await KV.delete(key);
226
+ await env.GEO_CACHE.delete(key);
227
227
  }
228
228
 
229
229
  // Retornar contagem
@@ -6,6 +6,14 @@ Enquanto o `server-tracking-agent` define **o que o Worker FAZ**, vocΓͺ define *
6
6
 
7
7
  ---
8
8
 
9
+ ## βœ… REGRAS CRÍTICAS
10
+
11
+ 0. **CONSULTA OBRIGATΓ“RIA Γ€ MEMΓ“RIA**: Extraia os IDs de Recursos Cloudflare (`D1_DATABASE_ID`, `KV_ID`, `R2_BUCKET_NAME`, `ZONE_ID`) e configuraΓ§Γ΅es de bindings consultando ativamente o "memory-agent.json". Solicite ao Orquestrador tudo o que faltar. Execute configuraΓ§Γ΅es de infraestrutura exclusivamente com os dados oficiais guardados na MemΓ³ria para garantir alinhamento sistΓͺmico.
12
+ 1. Cloudflare-Only: Sem dependΓͺncias externas.
13
+ 2. Same-Domain: Worker no domΓ­nio do site (anti-adblock).
14
+
15
+ ---
16
+
9
17
  ## πŸ›οΈ RESPONSABILIDADES EXCLUSIVAS
10
18
 
11
19
  | DomΓ­nio | VocΓͺ Γ© dono de |
@@ -70,7 +78,7 @@ crons = ["0 2 * * 7", "0 3 1 * *"]
70
78
  - **ID:** `SEU_D1_DATABASE_ID`
71
79
  - **RegiΓ£o:** ENAM (US East)
72
80
  - **Engine:** SQLite (Cloudflare D1)
73
- - **Tabelas ativas:** 8
81
+ - **Tabelas ativas:** 24 (core: 13, migrate-v6: 1, Enterprise Fases 1-4: 10)
74
82
 
75
83
  ### Schema Completo (ProduΓ§Γ£o)
76
84
 
@@ -251,7 +259,7 @@ CREATE INDEX IF NOT EXISTS idx_wa_ctwa_clid ON whatsapp_contacts(ctwa_clid);
251
259
  CREATE INDEX IF NOT EXISTS idx_wa_created_at ON whatsapp_contacts(created_at);
252
260
  ```
253
261
  > **Migration:** `migrate-v6.sql` β€” aplicar com `wrangler d1 execute cdp-edge-db --file=migrate-v6.sql --remote`
254
- > **Tabelas ativas apΓ³s v6:** 9
262
+ > **Tabelas ativas apΓ³s v6:** 14 (core: 13 + whatsapp_contacts)
255
263
 
256
264
  ---
257
265
 
@@ -305,9 +313,9 @@ ctx.waitUntil(
305
313
 
306
314
  ---
307
315
 
308
- ## πŸ“¬ BINDING 2 β€” QUEUES (`env.QUEUE`) β€” *A Adicionar*
316
+ ## πŸ“¬ BINDING 2 β€” QUEUES (`env.RETRY_QUEUE`) β€” βœ… Configurado
309
317
 
310
- > **Status:** Arquitetado, ainda nΓ£o configurado no `wrangler.toml`. Adicionar para habilitar retry assΓ­ncrono robusto.
318
+ > **Status:** Ativo em produΓ§Γ£o β€” `wrangler.toml` com `RETRY_QUEUE` binding e consumer configurados.
311
319
 
312
320
  ### ConfiguraΓ§Γ£o no `wrangler.toml`
313
321
  ```toml
@@ -379,9 +387,9 @@ Queue Consumer (assΓ­ncrono)
379
387
 
380
388
  ---
381
389
 
382
- ## πŸ—‚οΈ BINDING 3 β€” KV NAMESPACE (`env.GEO_CACHE`) β€” *A Adicionar*
390
+ ## πŸ—‚οΈ BINDING 3 β€” KV NAMESPACE (`env.GEO_CACHE`) β€” βœ… Configurado
383
391
 
384
- > **Status:** Arquitetado para cache de geo/IP. Ainda nΓ£o configurado.
392
+ > **Status:** Ativo em produΓ§Γ£o β€” usado para geo cache, fraud blocklist, fraud velocity counters e A/B test cache.
385
393
 
386
394
  ### ConfiguraΓ§Γ£o no `wrangler.toml`
387
395
  ```toml
@@ -540,7 +548,7 @@ async function runIntelligenceAgent(cron, env) {
540
548
  | `META_TEST_CODE` | ⚠️ Reconfigurar | SΓ³ testes | meta-agent |
541
549
  | `META_AD_ACCOUNT_ID` | ⚠️ Reconfigurar | Customer Match | meta-agent |
542
550
  | `META_AUDIENCE_ID` | ⚠️ Reconfigurar | Customer Match | meta-agent |
543
- | `WHATSAPP_TOKEN` | ⚠️ Reconfigurar | WhatsApp | whatsapp-agent |
551
+ | `WHATSAPP_ACCESS_TOKEN` | ⚠️ Reconfigurar | WhatsApp | whatsapp-agent |
544
552
  | `WHATSAPP_PHONE_NUMBER_ID` | ⚠️ Reconfigurar | WhatsApp | whatsapp-agent |
545
553
  | `RESEND_API_KEY` | ⚠️ Reconfigurar | Email | email-agent |
546
554
  | `RESEND_FROM_EMAIL` | ⚠️ Reconfigurar | Email | email-agent |
@@ -552,7 +560,7 @@ async function runIntelligenceAgent(cron, env) {
552
560
  wrangler secret put META_ACCESS_TOKEN
553
561
  wrangler secret put GA4_API_SECRET
554
562
  wrangler secret put TIKTOK_ACCESS_TOKEN
555
- wrangler secret put WHATSAPP_TOKEN
563
+ wrangler secret put WHATSAPP_ACCESS_TOKEN
556
564
  wrangler secret put WHATSAPP_PHONE_NUMBER_ID
557
565
  wrangler secret put RESEND_API_KEY
558
566
  wrangler secret put RESEND_FROM_EMAIL
@@ -56,9 +56,9 @@ export function logWorker(level, category, message, context = {}) {
56
56
  console.log(`[${level}] [${category}] ${message}`, JSON.stringify(context));
57
57
  }
58
58
 
59
- async function persistLogEntry(logEntry) {
59
+ async function persistLogEntry(env, logEntry) {
60
60
  try {
61
- await DB.prepare(`
61
+ await env.DB.prepare(`
62
62
  INSERT INTO worker_logs (timestamp, level, category, message, context, session_id, request_id)
63
63
  VALUES (?, ?, ?, ?, ?, ?, ?)
64
64
  `).bind(
@@ -82,7 +82,7 @@ async function dispatchEventToMeta(event, userContext) {
82
82
  try {
83
83
  const response = await fetch('https://graph.facebook.com/v22.0/events', {
84
84
  method: 'POST',
85
- headers: { 'Authorization': `Bearer ${META_ACCESS_TOKEN}` },
85
+ headers: { 'Authorization': `Bearer ${env.META_ACCESS_TOKEN}` },
86
86
  body: JSON.stringify(event)
87
87
  });
88
88
 
@@ -221,7 +221,7 @@ cdpTrack.track = function(eventName, params) {
221
221
  };
222
222
 
223
223
  // Enviar para Worker
224
- fetch('/api/track', {
224
+ fetch('/track', {
225
225
  method: 'POST',
226
226
  headers: { 'Content-Type': 'application/json' },
227
227
  body: JSON.stringify(eventPayload)
@@ -331,7 +331,7 @@ export async function handleDebugRequest(request, env) {
331
331
  }
332
332
 
333
333
  async function getApiHealth(platform) {
334
- const recentFailures = await DB.prepare(`
334
+ const recentFailures = await env.DB.prepare(`
335
335
  SELECT
336
336
  COUNT(*) as failure_count,
337
337
  MAX(created_at) as last_failure_at
@@ -339,7 +339,7 @@ async function getApiHealth(platform) {
339
339
  WHERE platform = ? AND created_at > datetime('now', '-1 hour')
340
340
  `).bind(platform).get();
341
341
 
342
- const recentSuccesses = await DB.prepare(`
342
+ const recentSuccesses = await env.DB.prepare(`
343
343
  SELECT COUNT(*) as success_count
344
344
  FROM events_log
345
345
  WHERE platform = ? AND status = 'success' AND created_at > datetime('now', '-1 hour')
@@ -394,7 +394,7 @@ export async function handleHealthCheck(request, env) {
394
394
  }
395
395
 
396
396
  async function getSimpleApiHealth(platform) {
397
- const lastSuccess = await DB.prepare(`
397
+ const lastSuccess = await env.DB.prepare(`
398
398
  SELECT created_at
399
399
  FROM events_log
400
400
  WHERE platform = ? AND status = 'success'
@@ -402,7 +402,7 @@ async function getSimpleApiHealth(platform) {
402
402
  LIMIT 1
403
403
  `).bind(platform).get();
404
404
 
405
- const lastFailure = await DB.prepare(`
405
+ const lastFailure = await env.DB.prepare(`
406
406
  SELECT created_at
407
407
  FROM api_failures
408
408
  WHERE platform = ?
@@ -433,7 +433,7 @@ export async function handleEventsLogRequest(request, env) {
433
433
  const limit = parseInt(url.searchParams.get('limit') || '50');
434
434
  const hours = parseInt(url.searchParams.get('hours') || '24');
435
435
 
436
- const events = await DB.prepare(`
436
+ const events = await env.DB.prepare(`
437
437
  SELECT
438
438
  event_name,
439
439
  platform,
@@ -485,7 +485,7 @@ export async function handleEventsLogRequest(request, env) {
485
485
 
486
486
  - [ ] **Envio de eventos para Worker:**
487
487
  - [ ] Verificar Network tab em Developer Tools
488
- - [ ] Confirmar requisiΓ§Γ£o para `/api/track`
488
+ - [ ] Confirmar requisiΓ§Γ£o para `/track`
489
489
  - [ ] Verificar status da resposta (deve ser 200 OK)
490
490
  - [ ] Verificar payload enviado (deve conter event_name, params, timestamp)
491
491
 
@@ -1033,7 +1033,7 @@ export async function handleEventsLogRequest(request, env) {
1033
1033
  const limit = parseInt(url.searchParams.get('limit') || '50');
1034
1034
  const hours = parseInt(url.searchParams.get('hours') || '24');
1035
1035
 
1036
- const events = await DB.prepare(`
1036
+ const events = await env.DB.prepare(`
1037
1037
  SELECT event_name, platform, status, error_message, created_at
1038
1038
  FROM events_log
1039
1039
  WHERE created_at > datetime('now', '-${hours} hours')
@@ -1057,7 +1057,7 @@ export async function handleBrowserLogs(request, env) {
1057
1057
 
1058
1058
  // Persistir logs do browser no D1
1059
1059
  for (const log of logs) {
1060
- await DB.prepare(`
1060
+ await env.DB.prepare(`
1061
1061
  INSERT INTO browser_logs (timestamp, level, category, message, context, session_id, page_url)
1062
1062
  VALUES (?, ?, ?, ?, ?, ?, ?)
1063
1063
  `).bind(
@@ -1182,7 +1182,7 @@ window.pbDebugLogger = logger;
1182
1182
  **PossΓ­veis Causas:**
1183
1183
 
1184
1184
  1. **Evento nΓ£o estΓ‘ sendo enviado para a plataforma**
1185
- - Verificar se `/api/track` estΓ‘ recebendo o evento
1185
+ - Verificar se `/track` estΓ‘ recebendo o evento
1186
1186
  - Consultar `/api/events-log` para ver se evento foi processado
1187
1187
  - Verificar logs do Worker: `wrangler tail`
1188
1188