cdp-edge 2.0.0 → 2.0.2

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 (34) hide show
  1. package/contracts/api-versions.json +12 -8
  2. package/dist/commands/install.js +1 -2
  3. package/dist/commands/setup.js +1 -2
  4. package/extracted-skill/tracking-events-generator/agents/attribution-agent.md +23 -23
  5. package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +172 -72
  6. package/extracted-skill/tracking-events-generator/agents/compliance-agent.md +20 -0
  7. package/extracted-skill/tracking-events-generator/agents/crm-integration-agent.md +48 -16
  8. package/extracted-skill/tracking-events-generator/agents/dashboard-agent.md +7 -7
  9. package/extracted-skill/tracking-events-generator/agents/database-agent.md +8 -8
  10. package/extracted-skill/tracking-events-generator/agents/debug-agent.md +13 -13
  11. package/extracted-skill/tracking-events-generator/agents/devops-agent.md +31 -7
  12. package/extracted-skill/tracking-events-generator/agents/email-agent.md +27 -0
  13. package/extracted-skill/tracking-events-generator/agents/fingerprint-agent.md +205 -0
  14. package/extracted-skill/tracking-events-generator/agents/google-agent.md +118 -0
  15. package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +90 -4
  16. package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +8 -641
  17. package/extracted-skill/tracking-events-generator/agents/linkedin-agent.md +108 -0
  18. package/extracted-skill/tracking-events-generator/agents/ltv-predictor-agent.md +1 -1
  19. package/extracted-skill/tracking-events-generator/agents/master-feedback-loop.md +68 -8
  20. package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +61 -18
  21. package/extracted-skill/tracking-events-generator/agents/memory-agent.md +98 -0
  22. package/extracted-skill/tracking-events-generator/agents/performance-agent.md +29 -19
  23. package/extracted-skill/tracking-events-generator/agents/performance-optimization-agent.md +11 -1
  24. package/extracted-skill/tracking-events-generator/agents/security-enterprise-agent.md +137 -28
  25. package/extracted-skill/tracking-events-generator/agents/server-tracking.md +7 -8
  26. package/extracted-skill/tracking-events-generator/agents/tiktok-agent.md +63 -0
  27. package/extracted-skill/tracking-events-generator/agents/tracking-plan-agent.md +100 -5
  28. package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +100 -0
  29. package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +58 -5
  30. package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +16 -16
  31. package/extracted-skill/tracking-events-generator/agents/youtube-agent.md +140 -25
  32. package/extracted-skill/tracking-events-generator/contracts/api-versions.json +12 -8
  33. package/package.json +2 -2
  34. package/server-edge-tracker/worker.js +53 -8
@@ -212,10 +212,14 @@
212
212
  ]
213
213
  },
214
214
  "conversions_api": {
215
- "current": "v2",
216
- "minimum_supported": "v1",
217
- "recommended": "v2",
218
- "endpoint_pattern": "https://api.linkedin.com/rest/attributionConversions/{VERSION}",
215
+ "current": "202401",
216
+ "minimum_supported": "202401",
217
+ "recommended": "202401",
218
+ "endpoint_pattern": "https://api.linkedin.com/rest/conversionEvents",
219
+ "required_headers": {
220
+ "LinkedIn-Version": "202401",
221
+ "X-Restli-Protocol-Version": "2.0.0"
222
+ },
219
223
  "authentication": "Bearer token (LINKEDIN_ACCESS_TOKEN)",
220
224
  "rate_limits": {
221
225
  "requests_per_second": 10,
@@ -359,10 +363,10 @@
359
363
  },
360
364
 
361
365
  "last_updated_by": {
362
- "agent": "Intelligence Agent",
363
- "session_id": "CDP_2026-03-28_sync",
364
- "timestamp": "2026-03-28T00:00:00.000Z"
366
+ "agent": "Audit — CDP Edge v2.0",
367
+ "session_id": "CDP_2026-04-10_audit",
368
+ "timestamp": "2026-04-10T00:00:00.000Z"
365
369
  },
366
370
 
367
- "next_review_date": "2026-04-27T00:00:00.000Z"
371
+ "next_review_date": "2026-05-10T00:00:00.000Z"
368
372
  }
@@ -32,8 +32,7 @@ function printBanner() {
32
32
  console.log(chalk.cyan('╚██████╗██████╔╝██║ ███████╗██████╔╝╚██████╔╝███████╗'));
33
33
  console.log(chalk.cyan(' ╚═════╝╚═════╝ ╚═╝ ╚══════╝╚═════╝ ╚═════╝╚══════╝'));
34
34
  console.log('');
35
- console.log(chalk.gray(' Customer Data Platform on the Edge · Quantum Tracking · Cloudflare Native'));
36
- console.log(chalk.gray(` Installer v2.0.0`));
35
+ console.log(chalk.gray(' Customer Data Platform on the Edge · Global Edge Tracking · v2.0.2'));
37
36
  console.log('');
38
37
  console.log(chalk.gray('═'.repeat(68)));
39
38
  console.log('');
@@ -19,8 +19,7 @@ function printBanner() {
19
19
  console.log(chalk.cyan('╚██████╗██████╔╝██║ ███████╗██████╔╝╚██████╔╝███████╗'));
20
20
  console.log(chalk.cyan(' ╚═════╝╚═════╝ ╚═╝ ╚══════╝╚═════╝ ╚═════╝╚══════╝'));
21
21
  console.log('');
22
- console.log(chalk.gray(' Customer Data Platform on the Edge · Quantum Tracking · Cloudflare Native'));
23
- console.log(chalk.gray(' Setup Wizard v2.0.0'));
22
+ console.log(chalk.gray(' Customer Data Platform on the Edge · Global Edge Tracking · v2.0.2'));
24
23
  console.log('');
25
24
  console.log(chalk.gray('═'.repeat(68)));
26
25
  console.log('');
@@ -264,7 +264,7 @@ function wShapeAttribution(touchpoints) {
264
264
 
265
265
  ```javascript
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
@@ -458,7 +458,7 @@ CREATE INDEX IF NOT EXISTS idx_channel_model ON channel_performance(attribution_
458
458
 
459
459
  ```javascript
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,
@@ -538,7 +538,7 @@ async function scheduleAttributionCalculation(email, conversionId, eventName) {
538
538
 
539
539
  ```javascript
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)
@@ -685,7 +685,7 @@ async function updateChannelPerformance(attributionModels, value, currency) {
685
685
 
686
686
  ```javascript
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)
@@ -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,
@@ -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