cdp-edge 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdp-edge",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "CDP Edge - Quantum Tracking - Sistema multi-agente para tracking digital Cloudflare Native (Workers + D1)",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -371,9 +371,12 @@ export default {
371
371
  'utmSource','utmMedium','utmCampaign','utmContent','utmTerm',
372
372
  'fbclid','ttclid','gclid','transactionId','productName','currency'];
373
373
 
374
- const { eventName, behavioral_data, ...payload } = body as { eventName?: string; behavioral_data?: BehavioralData; [key: string]: any };
374
+ const { eventName: _bodyEventName, behavioral_data, ...payload } = body as { eventName?: string; behavioral_data?: BehavioralData; [key: string]: any };
375
375
  const trackPayload: TrackPayload = payload;
376
376
 
377
+ // Aceita eventName (camelCase) ou event_name (snake_case — formato cdpTrack.js SDK)
378
+ const eventName = _bodyEventName || (payload.event_name as string | undefined);
379
+
377
380
  // ── Extrair click_ids e utms de sub-objetos (formato cdpTrack.js) ────────
378
381
  // cdpTrack.js envia fbp/fbc/fbclid dentro de click_ids{} e UTMs dentro de utms{}
379
382
  // O Worker trabalha com campos no nível raiz — esta extração resolve o mismatch.
@@ -383,8 +386,10 @@ export default {
383
386
  if (!trackPayload.fbc && c.fbc) trackPayload.fbc = c.fbc;
384
387
  if (!trackPayload.fbclid && c.fbclid) trackPayload.fbclid = c.fbclid;
385
388
  if (!trackPayload.gclid && c.gclid) trackPayload.gclid = c.gclid;
389
+ if (!trackPayload.wbraid && c.wbraid) trackPayload.wbraid = c.wbraid;
390
+ if (!trackPayload.gbraid && c.gbraid) trackPayload.gbraid = c.gbraid;
386
391
  if (!trackPayload.ttclid && c.ttclid) trackPayload.ttclid = c.ttclid;
387
- if (!trackPayload.ttp && c.ttp) trackPayload.ttp = c.ttp; // TikTok Pixel cookie
392
+ if (!trackPayload.ttp && c.ttp) trackPayload.ttp = c.ttp;
388
393
  }
389
394
  if (payload.utms && typeof payload.utms === 'object') {
390
395
  const u = payload.utms as Record<string, string>;
@@ -395,6 +400,12 @@ export default {
395
400
  if (!trackPayload.utmTerm && u.utm_term) trackPayload.utmTerm = u.utm_term;
396
401
  }
397
402
 
403
+ // ── Normalizar campos snake_case → camelCase (formato cdpTrack.js SDK) ──
404
+ if (!trackPayload.userId && payload.user_id) trackPayload.userId = payload.user_id;
405
+ if (!trackPayload.eventId && payload.event_id) trackPayload.eventId = payload.event_id;
406
+ if (!trackPayload.pageUrl && payload.page_url) trackPayload.pageUrl = payload.page_url;
407
+ if (!trackPayload.sessionId && payload.session_id) trackPayload.sessionId = payload.session_id;
408
+
398
409
  // ── Validação de eventName ────────────────────────────────────────
399
410
  if (!eventName) {
400
411
  return new Response(JSON.stringify({ error: 'eventName é obrigatório' }), { status: 400, headers });
@@ -750,6 +761,17 @@ export default {
750
761
  ctx.waitUntil(resolveDeviceGraph(env.DB, payload.userId, payload.email, payload.phone));
751
762
  }
752
763
 
764
+ // Registrar em events — deduplicação + label ML (INSERT OR IGNORE descarta duplicatas)
765
+ if (env.DB && payload.eventId) {
766
+ ctx.waitUntil(
767
+ env.DB.prepare(
768
+ `INSERT OR IGNORE INTO events (event_id, event_name, user_id, created_at)
769
+ VALUES (?, ?, ?, datetime('now'))`
770
+ ).bind(payload.eventId, eventName, payload.userId || null).run()
771
+ .catch(() => { /* silencioso — não bloqueia o pipeline */ })
772
+ );
773
+ }
774
+
753
775
  // R2 Audit Log — background
754
776
  ctx.waitUntil(writeAuditLog(env, eventName, payload, geoData));
755
777
 
@@ -79,6 +79,22 @@ CREATE INDEX IF NOT EXISTS idx_profiles_fbp ON user_profiles(fbp);
79
79
  CREATE INDEX IF NOT EXISTS idx_profiles_msclkid ON user_profiles(msclkid);
80
80
  CREATE INDEX IF NOT EXISTS idx_profiles_li_fat ON user_profiles(li_fat_id);
81
81
 
82
+ -- ── Tabela de Eventos (Deduplicação + Label ML) ──────────────────────────────
83
+ -- Registra cada evento processado com sucesso.
84
+ -- Duplo uso: (1) deduplicação server-side via event_id UNIQUE;
85
+ -- (2) label de LTV para treinamento ML (lead comprou depois?)
86
+ CREATE TABLE IF NOT EXISTS events (
87
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
88
+ event_id TEXT UNIQUE, -- deduplicação: INSERT OR IGNORE descarta duplicatas
89
+ event_name TEXT NOT NULL,
90
+ user_id TEXT,
91
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
92
+ );
93
+
94
+ CREATE INDEX IF NOT EXISTS idx_events_user_id ON events(user_id);
95
+ CREATE INDEX IF NOT EXISTS idx_events_event_name ON events(event_name);
96
+ CREATE INDEX IF NOT EXISTS idx_events_created ON events(created_at);
97
+
82
98
  -- ── Tabela de LOG de Webhooks Offline ─────────────────────────────────────────
83
99
  CREATE TABLE IF NOT EXISTS webhook_events (
84
100
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -85,8 +85,17 @@ export interface TrackPayload {
85
85
  // Identifiers
86
86
  fbp?: string | null;
87
87
  fbc?: string | null;
88
+ fbclid?: string | null;
88
89
  ttp?: string | null;
90
+ gclid?: string | null;
91
+ wbraid?: string | null;
92
+ gbraid?: string | null;
93
+ ttclid?: string | null;
94
+ rclid?: string | null;
95
+ msclkid?: string | null;
96
+ li_fat_id?: string | null;
89
97
  gaClientId?: string | null;
98
+ sessionId?: string | null;
90
99
 
91
100
  // Parameters
92
101
  value?: number | null;