cdp-edge 1.5.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.
@@ -0,0 +1,368 @@
1
+ {
2
+ "metadata": {
3
+ "version": "1.0.0",
4
+ "created_at": "2026-03-28T14:00:00.000Z",
5
+ "updated_at": "2026-03-28T14:00:00.000Z",
6
+ "maintained_by": "Intelligence Agent (CDP Edge Quantum Tier)",
7
+ "purpose": "Fonte única da verdade para versões de API em todo o ecossistema CDP Edge"
8
+ },
9
+
10
+ "meta": {
11
+ "platform": "meta",
12
+ "name": "Meta (Facebook)",
13
+ "documentation": "https://developers.facebook.com/docs/marketing-api/conversions-api/",
14
+ "changelog": "https://developers.facebook.com/docs/graph-changelog/",
15
+
16
+ "versions": {
17
+ "pixel": {
18
+ "current": "v22.0",
19
+ "minimum_supported": "v21.0",
20
+ "recommended": "v22.0",
21
+ "deprecated": ["v20.0", "v21.0"],
22
+ "deprecated_cutoff": {
23
+ "v20.0": "2024-01-01T00:00:00.000Z",
24
+ "v21.0": "2024-06-01T00:00:00.000Z"
25
+ }
26
+ },
27
+
28
+ "capi": {
29
+ "current": "v22.0",
30
+ "minimum_supported": "v21.0",
31
+ "recommended": "v22.0",
32
+ "endpoint_pattern": "https://graph.facebook.com/{VERSION}/{PIXEL_ID}/events",
33
+ "authentication": "Bearer token (META_ACCESS_TOKEN)",
34
+ "rate_limits": {
35
+ "requests_per_hour": 200,
36
+ "events_per_batch": 10,
37
+ "batches_per_hour": 20
38
+ }
39
+ },
40
+
41
+ "messenger": {
42
+ "current": "v22.0",
43
+ "minimum_supported": "v21.0",
44
+ "recommended": "v22.0",
45
+ "whatsapp_cloud_api": "v22.0"
46
+ }
47
+ }
48
+ },
49
+
50
+ "google": {
51
+ "platform": "google",
52
+ "name": "Google (GA4 + Google Ads)",
53
+ "versions": {
54
+ "ga4": {
55
+ "current": "latest",
56
+ "minimum_supported": "v2",
57
+ "recommended": "latest",
58
+ "endpoint_pattern": "https://www.google-analytics.com/mp/collect?measurement_id={MEASUREMENT_ID}&api_secret={SECRET}",
59
+ "authentication": "API Secret (GA4_API_SECRET)"
60
+ },
61
+ "google_ads": {
62
+ "current": "latest",
63
+ "minimum_supported": "v2",
64
+ "recommended": "latest",
65
+ "uet_tag": "latest"
66
+ },
67
+ "consent_mode": {
68
+ "current": "v2",
69
+ "minimum_supported": "v2",
70
+ "required_parameters": [
71
+ "ad_storage",
72
+ "analytics_storage",
73
+ "ad_user_data",
74
+ "ad_personalization"
75
+ ],
76
+ "default_values": {
77
+ "ad_storage": "denied",
78
+ "analytics_storage": "denied",
79
+ "ad_user_data": "denied",
80
+ "ad_personalization": "denied"
81
+ },
82
+ "flags": {
83
+ "url_passthrough": true,
84
+ "wait_for_update": 500
85
+ }
86
+ }
87
+ }
88
+ },
89
+
90
+ "tiktok": {
91
+ "platform": "tiktok",
92
+ "name": "TikTok (Pixel + Events API)",
93
+ "documentation": "https://ads.tiktok.com/marketing_api/docs?id=1740465605569281",
94
+ "versions": {
95
+ "pixel": {
96
+ "current": "v1.3",
97
+ "minimum_supported": "v1.2",
98
+ "recommended": "v1.3",
99
+ "deprecated": [
100
+ "v1.2"
101
+ ],
102
+ "deprecated_cutoff": {
103
+ "v1.2": "2024-03-01T00:00:00.000Z"
104
+ },
105
+ "endpoint_pattern": "https://analytics.tiktok.com/v1/pixel"
106
+ },
107
+ "events_api": {
108
+ "current": "v1.3",
109
+ "minimum_supported": "v1.2",
110
+ "recommended": "v1.3",
111
+ "endpoint_pattern": "https://business-api.tiktok.com/open_api/{VERSION}/event/track/",
112
+ "authentication": "Bearer token (TIKTOK_ACCESS_TOKEN)",
113
+ "rate_limits": {
114
+ "requests_per_minute": 10,
115
+ "events_per_batch": 5,
116
+ "batches_per_minute": 2
117
+ }
118
+ }
119
+ }
120
+ },
121
+
122
+ "pinterest": {
123
+ "platform": "pinterest",
124
+ "name": "Pinterest (Tag + Conversions API)",
125
+ "documentation": "https://developers.pinterest.com/docs/conversions/",
126
+ "versions": {
127
+ "tag": {
128
+ "current": "3.0",
129
+ "minimum_supported": "2.0",
130
+ "recommended": "3.0",
131
+ "endpoint_pattern": "https://s.pinimg.com/ct/core.js",
132
+ "enhanced_match": {
133
+ "supports_email_hashing": true,
134
+ "supports_phone_hashing": true,
135
+ "auto_hash_by_pixel": true
136
+ }
137
+ },
138
+ "conversions_api": {
139
+ "current": "v5",
140
+ "minimum_supported": "v4.0",
141
+ "recommended": "v5",
142
+ "deprecated": [
143
+ "v4"
144
+ ],
145
+ "deprecated_cutoff": {
146
+ "v4": "2024-01-01T00:00:00.000Z"
147
+ },
148
+ "endpoint_pattern": "https://api.pinterest.com/v5/ad_accounts/{AD_ACCOUNT_ID}/events",
149
+ "authentication": "Bearer token (PINTEREST_ACCESS_TOKEN)",
150
+ "rate_limits": {
151
+ "requests_per_hour": 100,
152
+ "events_per_batch": 10,
153
+ "batches_per_hour": 10
154
+ }
155
+ }
156
+ }
157
+ },
158
+
159
+ "reddit": {
160
+ "platform": "reddit",
161
+ "name": "Reddit (Pixel + Conversions API)",
162
+ "documentation": "https://ads.reddit.com/help/article/reddit-pixel",
163
+ "versions": {
164
+ "pixel": {
165
+ "current": "v2",
166
+ "minimum_supported": "v1.0",
167
+ "recommended": "v2",
168
+ "endpoint_pattern": "https://www.redditstatic.com/ads/v2.js",
169
+ "advanced_matching": {
170
+ "supports_email_hashing": true,
171
+ "auto_hash_by_pixel": true,
172
+ "supports_external_id": true
173
+ }
174
+ },
175
+ "conversions_api": {
176
+ "current": "v2.0",
177
+ "minimum_supported": "v1.0",
178
+ "recommended": "v2.0",
179
+ "deprecated": [
180
+ "v1.0"
181
+ ],
182
+ "deprecated_cutoff": {
183
+ "v1.0": "2024-06-01T00:00:00.000Z"
184
+ },
185
+ "endpoint_pattern": "https://ads-api.reddit.com/api/{VERSION}/conversions/events/{AD_ACCOUNT_ID}",
186
+ "authentication": "Bearer token (REDDIT_ACCESS_TOKEN)",
187
+ "rate_limits": {
188
+ "requests_per_minute": 5,
189
+ "events_per_batch": 10,
190
+ "batches_per_minute": 1
191
+ }
192
+ }
193
+ }
194
+ },
195
+
196
+ "linkedin": {
197
+ "platform": "linkedin",
198
+ "name": "LinkedIn (Insight Tag + Conversions API)",
199
+ "documentation": "https://learn.microsoft.com/en-us/linkedin/marketing/conversions-api/",
200
+ "versions": {
201
+ "insight_tag": {
202
+ "current": "v2",
203
+ "minimum_supported": "v1",
204
+ "recommended": "v2",
205
+ "endpoint_pattern": "https://snap.licdn.com/li.lms-analytics/insight.beta.min.js",
206
+ "consent_mode_required": true,
207
+ "data_attributes": [
208
+ "conversion_id",
209
+ "text",
210
+ "currency",
211
+ "value"
212
+ ]
213
+ },
214
+ "conversions_api": {
215
+ "current": "v2",
216
+ "minimum_supported": "v1",
217
+ "recommended": "v2",
218
+ "endpoint_pattern": "https://api.linkedin.com/rest/attributionConversions/{VERSION}",
219
+ "authentication": "Bearer token (LINKEDIN_ACCESS_TOKEN)",
220
+ "rate_limits": {
221
+ "requests_per_second": 10,
222
+ "events_per_batch": 100
223
+ }
224
+ }
225
+ }
226
+ },
227
+
228
+ "bing": {
229
+ "platform": "bing",
230
+ "name": "Microsoft Advertising (UET Tag + Clarity)",
231
+ "documentation": "https://learn.microsoft.com/en-us/advertising/guides/event-tracking",
232
+ "versions": {
233
+ "uet_tag": {
234
+ "current": "latest",
235
+ "minimum_supported": "v1",
236
+ "recommended": "latest",
237
+ "endpoint_pattern": "https://bat.bing.com/bat.js",
238
+ "enhanced_conversions": {
239
+ "supports_email_hashing": true,
240
+ "supports_phone_hashing": true,
241
+ "requires_sha256": true
242
+ }
243
+ },
244
+ "clarity": {
245
+ "current": "latest",
246
+ "minimum_supported": "v1",
247
+ "recommended": "latest",
248
+ "endpoint_pattern": "https://clarity.ms/tag/s/{CLARITY_PROJECT_ID}/clarity.js"
249
+ }
250
+ }
251
+ },
252
+
253
+ "youtube": {
254
+ "platform": "youtube",
255
+ "name": "YouTube Ads (Video Campaigns)",
256
+ "documentation": "https://developers.google.com/youtube/v3/guides/auth/server-side-web-apps",
257
+ "versions": {
258
+ "video_campaigns": {
259
+ "current": "latest",
260
+ "minimum_supported": "v1",
261
+ "recommended": "latest",
262
+ "campaign_types": ["TrueView In-Stream", "Bumper Ads", "Non-skip In-Stream", "Video Discovery"],
263
+ "click_ids": ["gclid", "wbraid", "gbraid"],
264
+ "conversion_window_vtc_days": 7
265
+ },
266
+ "iframe_api": {
267
+ "current": "latest",
268
+ "endpoint_pattern": "https://www.youtube.com/embed/{VIDEO_ID}?enablejsapi=1",
269
+ "events": ["video_start", "video_progress", "video_complete"],
270
+ "milestones_percent": [25, 50, 75, 100]
271
+ },
272
+ "customer_match": {
273
+ "current": "latest",
274
+ "hash_required": true,
275
+ "hash_algorithm": "SHA-256",
276
+ "accepted_fields": ["email", "phone", "first_name", "last_name"]
277
+ }
278
+ }
279
+ },
280
+
281
+ "spotify": {
282
+ "platform": "spotify",
283
+ "name": "Spotify Ads (Pixel + Conversions API)",
284
+ "documentation": "https://advertising-api.spotify.com/docs/",
285
+ "versions": {
286
+ "pixel": {
287
+ "current": "v1",
288
+ "minimum_supported": "v1",
289
+ "recommended": "v1",
290
+ "endpoint_pattern": "Spotify Pixel SDK (custom)"
291
+ },
292
+ "conversions_api": {
293
+ "current": "v1",
294
+ "minimum_supported": "v1",
295
+ "recommended": "v1",
296
+ "endpoint_pattern": "https://advertising-api.spotify.com/conversion/v1/accounts/{ACCOUNT_ID}/events",
297
+ "authentication": "Bearer token (SPOTIFY_ACCESS_TOKEN)",
298
+ "rate_limits": {
299
+ "requests_per_minute": 30,
300
+ "events_per_batch": 10
301
+ }
302
+ }
303
+ }
304
+ },
305
+
306
+ "validation_rules": {
307
+ "deprecation_policy": "APIs marcadas como deprecated devem ser atualizadas IMEDIATAMENTE",
308
+ "minimum_version_policy": "Versões abaixo do minimum_supported NÃO são suportadas",
309
+ "recommended_version_policy": "Usar sempre a recommended version para máxima compatibilidade",
310
+ "endpoint_validation": "Endpoints devem seguir exatamente o padrão especificado",
311
+ "authentication_validation": "Tokens devem ser obtidos via wrangler secret (NUNCA hardcoded)",
312
+ "rate_limit_policy": "Respeitar rate_limits para evitar bloqueios"
313
+ },
314
+
315
+ "migration_guidelines": {
316
+ "meta_v20_to_v22": {
317
+ "breaking_changes": [],
318
+ "new_parameters": [],
319
+ "deprecated_parameters": [],
320
+ "migration_steps": [
321
+ "Atualizar endpoint de /v20.0/ para /v22.0/",
322
+ "Verificar novos parâmetros obrigatórios",
323
+ "Testar em ambiente de sandbox"
324
+ ]
325
+ },
326
+
327
+ "tiktok_v1.2_to_v1.3": {
328
+ "breaking_changes": [],
329
+ "new_parameters": [],
330
+ "deprecated_parameters": [],
331
+ "migration_steps": [
332
+ "Atualizar endpoint de /v1.2/ para /v1.3/",
333
+ "Verificar compatibilidade de event names",
334
+ "Atualizar rate limits"
335
+ ]
336
+ },
337
+
338
+ "pinterest_v4_to_v5": {
339
+ "breaking_changes": ["ad_account_id agora obrigatório na URL"],
340
+ "new_parameters": ["external_data", "action_source"],
341
+ "deprecated_parameters": [],
342
+ "migration_steps": [
343
+ "Adicionar ad_account_id ao endpoint",
344
+ "Atualizar estrutura de payload",
345
+ "Verificar novos campos obrigatórios"
346
+ ]
347
+ },
348
+
349
+ "reddit_v1.0_to_v2.0": {
350
+ "breaking_changes": ["URL mudou de /api/v1.0/ para /api/v2.0/"],
351
+ "new_parameters": ["conversion_type", "ip_address", "user_agent"],
352
+ "deprecated_parameters": [],
353
+ "migration_steps": [
354
+ "Atualizar todos os endpoints para v2.0",
355
+ "Adicionar novos campos de user data",
356
+ "Verificar compatibilidade de event names"
357
+ ]
358
+ }
359
+ },
360
+
361
+ "last_updated_by": {
362
+ "agent": "Intelligence Agent",
363
+ "session_id": "CDP_2026-03-28_sync",
364
+ "timestamp": "2026-03-28T00:00:00.000Z"
365
+ },
366
+
367
+ "next_review_date": "2026-04-27T00:00:00.000Z"
368
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Analyze Command - Análise de páginas
3
+ */
4
+
5
+ import inquirer from 'inquirer';
6
+ import chalk from 'chalk';
7
+ import ora from 'ora';
8
+ import { promises as fs } from 'fs';
9
+
10
+ export async function runAnalyze(dir) {
11
+ console.log(chalk.cyan.bold('\n CDP Edge - Page Analyzer\n'));
12
+
13
+ const spinner = ora('Analisando arquivos...').start();
14
+
15
+ try {
16
+ // Busca arquivos HTML/JS no diretório
17
+ const files = await findProjectFiles(dir);
18
+
19
+ spinner.succeed(`Encontrados ${files.length} arquivos`);
20
+
21
+ // Análise dos eventos detectados
22
+ const events = await analyzeEvents(files);
23
+
24
+ console.log('\n' + chalk.yellow('Eventos detectados:'));
25
+ console.log(formatEventAnalysis(events));
26
+
27
+ } catch (error) {
28
+ spinner.fail('Erro na análise');
29
+ console.error(error);
30
+ }
31
+ }
32
+
33
+ async function findProjectFiles(dir) {
34
+ // Em produção, faria glob real dos arquivos
35
+ return ['index.html', 'checkout.html', 'thankyou.html'];
36
+ }
37
+
38
+ async function analyzeEvents(files) {
39
+ // Em produção, analisaria cada arquivo com o Page Analyzer Agent
40
+ return {
41
+ leads: 2,
42
+ purchases: 1,
43
+ views: 3,
44
+ custom: 0
45
+ };
46
+ }
47
+
48
+ function formatEventAnalysis(events) {
49
+ return Object.entries(events)
50
+ .map(([type, count]) => ` ${chalk.cyan(type)}: ${count}`)
51
+ .join('\n');
52
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Infra Command - Guia de setup Cloudflare
3
+ */
4
+
5
+ import chalk from 'chalk';
6
+
7
+ export async function runInfra() {
8
+ console.log(chalk.cyan.bold('\n CDP Edge - Guia de Infraestrutura Cloudflare\n'));
9
+
10
+ const guide = `
11
+
12
+ ${chalk.yellow.bold('🚀 Setup do Zero ao Deploy')}
13
+
14
+ ${chalk.cyan.bold('PASSO 1: Criar Conta Cloudflare')}
15
+ 1. Acesse https://dash.cloudflare.com/sign-up
16
+ 2. Crie uma conta gratuita
17
+ 3. Adicione seu domínio (opcional para testes)
18
+
19
+ ${chalk.cyan.bold('PASSO 2: Instalar Wrangler CLI')}
20
+ npm install -g wrangler
21
+ wrangler login
22
+
23
+ ${chalk.cyan.bold('PASSO 3: Criar D1 Database')}
24
+ wrangler d1 create cdp-edge-db
25
+ # Copie o database_id gerado
26
+
27
+ ${chalk.cyan.bold('PASSO 4: Criar Worker')}
28
+ wrangler init cdp-edge-worker
29
+ # Responda às perguntas do wizard
30
+
31
+ ${chalk.cyan.bold('PASSO 5: Configurar Secrets')}
32
+ wrangler secret put META_ACCESS_TOKEN
33
+ wrangler secret put TIKTOK_ACCESS_TOKEN
34
+ wrangler secret put GA4_MEASUREMENT_ID
35
+
36
+ ${chalk.cyan.bold('PASSO 6: Aplicar Schema D1')}
37
+ wrangler d1 execute cdp-edge-db --file=schema.sql
38
+
39
+ ${chalk.cyan.bold('PASSO 7: Deploy')}
40
+ wrangler deploy
41
+
42
+ ${chalk.cyan.bold('PASSO 8: Configurar Domínio')}
43
+ # No dashboard Cloudflare:
44
+ # 1. Workers & Pages → Routes → Add Route
45
+ # 2. Exemplo: seu-dominio.com/api/tracking/*
46
+ # 3. Aponte para o worker criado
47
+
48
+ ${chalk.green.bold('✅ Pronto! Seu tracking Quantum Tier está ativo.')}
49
+
50
+ ${chalk.gray('Para mais detalhes, consulte docs/guia-cloudflare-iniciante.md')}
51
+ `;
52
+
53
+ console.log(guide);
54
+ }
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Server Command - Infraestrutura Cloudflare Workers
3
+ */
4
+
5
+ import chalk from 'chalk';
6
+ import ora from 'ora';
7
+ import { promises as fs } from 'fs';
8
+ import { join } from 'path';
9
+
10
+ export async function runServer(dir) {
11
+ console.log(chalk.cyan.bold('\n CDP Edge - Server-Side Tracking\n'));
12
+
13
+ const spinner = ora('Gerando infraestrutura...').start();
14
+
15
+ try {
16
+ // Gerar worker.js
17
+ await generateWorker(dir);
18
+
19
+ // Gerar schema.sql
20
+ await generateSchema(dir);
21
+
22
+ // Gerar wrangler.toml
23
+ await generateWranglerConfig(dir);
24
+
25
+ spinner.succeed(chalk.green('Infraestrutura gerada!'));
26
+
27
+ console.log('\n' + chalk.yellow('Arquivos gerados:'));
28
+ console.log(` ${chalk.gray('├─')} worker.js`);
29
+ console.log(` ${chalk.gray('├─')} schema.sql`);
30
+ console.log(` ${chalk.gray('└─')} wrangler.toml`);
31
+
32
+ console.log(chalk.cyan('\nPróximos passos:'));
33
+ console.log(' 1. Configure suas API tokens no Wrangler:');
34
+ console.log(' wrangler secret put META_ACCESS_TOKEN');
35
+ console.log(' 2. Faça o deploy:');
36
+ console.log(' wrangler deploy');
37
+ console.log(' 3. Configure o schema D1:');
38
+ console.log(' wrangler d1 execute db --file=schema.sql');
39
+
40
+ } catch (error) {
41
+ spinner.fail('Erro ao gerar infraestrutura');
42
+ console.error(error);
43
+ }
44
+ }
45
+
46
+ async function generateWorker(dir) {
47
+ const workerPath = join(dir, 'worker.js');
48
+ await fs.writeFile(workerPath, generateWorkerCode());
49
+ }
50
+
51
+ async function generateSchema(dir) {
52
+ const schemaPath = join(dir, 'schema.sql');
53
+ await fs.writeFile(schemaPath, generateSchemaCode());
54
+ }
55
+
56
+ async function generateWranglerConfig(dir) {
57
+ const configPath = join(dir, 'wrangler.toml');
58
+ await fs.writeFile(configPath, generateWranglerCode());
59
+ }
60
+
61
+ function generateWorkerCode() {
62
+ return `// CDP Edge Quantum Tier - Cloudflare Worker
63
+ // Auto-generated by cdp-edge npx
64
+
65
+ export default {
66
+ async fetch(request, env) {
67
+ const url = new URL(request.url);
68
+ const path = url.pathname;
69
+
70
+ // Endpoint de tracking
71
+ if (path === '/api/tracking') {
72
+ return handleTracking(request, env);
73
+ }
74
+
75
+ // Health check
76
+ if (path === '/health') {
77
+ return new Response(JSON.stringify({ status: 'ok' }), {
78
+ headers: { 'Content-Type': 'application/json' }
79
+ });
80
+ }
81
+
82
+ return new Response('Not Found', { status: 404 });
83
+ }
84
+ };
85
+
86
+ async function handleTracking(request, env) {
87
+ try {
88
+ const body = await request.json();
89
+ const { event, data } = body;
90
+
91
+ // Persistir no D1
92
+ await env.DB.prepare(
93
+ 'INSERT INTO events (event_id, event_type, user_id, data, created_at) VALUES (?, ?, ?, ?, ?)'
94
+ ).bind(data.event_id, event, data.user_id, JSON.stringify(data), Date.now()).run();
95
+
96
+ // Enviar para APIs externas (background)
97
+ if (event === 'Purchase' || event === 'Lead') {
98
+ ctx.waitUntil(sendToPlatforms(event, data, env));
99
+ }
100
+
101
+ return new Response(JSON.stringify({ success: true }), {
102
+ headers: { 'Content-Type': 'application/json' }
103
+ });
104
+ } catch (error) {
105
+ return new Response(JSON.stringify({ error: error.message }), {
106
+ status: 500,
107
+ headers: { 'Content-Type': 'application/json' }
108
+ });
109
+ }
110
+ }
111
+
112
+ async function sendToPlatforms(event, data, env) {
113
+ // Implementar envio para Meta, TikTok, etc.
114
+ // Use Promise.allSettled para resiliência
115
+ }
116
+ `;
117
+ }
118
+
119
+ function generateSchemaCode() {
120
+ return `-- CDP Edge Quantum Tier - D1 Schema
121
+ -- Auto-generated by cdp-edge npx
122
+
123
+ -- Tabela de sessões/identidade
124
+ CREATE TABLE IF NOT EXISTS identities (
125
+ id TEXT PRIMARY KEY,
126
+ user_id TEXT NOT NULL,
127
+ email TEXT,
128
+ phone TEXT,
129
+ created_at INTEGER NOT NULL,
130
+ updated_at INTEGER NOT NULL,
131
+ INDEX idx_user_id (user_id)
132
+ );
133
+
134
+ -- Tabela de leads
135
+ CREATE TABLE IF NOT EXISTS leads (
136
+ id TEXT PRIMARY KEY,
137
+ identity_id TEXT NOT NULL,
138
+ email TEXT,
139
+ phone TEXT,
140
+ name TEXT,
141
+ source TEXT,
142
+ created_at INTEGER NOT NULL,
143
+ FOREIGN KEY (identity_id) REFERENCES identities(id)
144
+ );
145
+
146
+ -- Tabela de eventos
147
+ CREATE TABLE IF NOT EXISTS events (
148
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
149
+ event_id TEXT NOT NULL UNIQUE,
150
+ event_type TEXT NOT NULL,
151
+ user_id TEXT,
152
+ data TEXT,
153
+ created_at INTEGER NOT NULL,
154
+ INDEX idx_event_id (event_id),
155
+ INDEX idx_event_type (event_type),
156
+ INDEX idx_user_id (user_id)
157
+ );
158
+ `;
159
+ }
160
+
161
+ function generateWranglerCode() {
162
+ return `# CDP Edge Quantum Tier - Wrangler Config
163
+ # Auto-generated by cdp-edge npx
164
+
165
+ name = "cdp-edge-worker"
166
+ main = "worker.js"
167
+ compatibility_date = "2024-01-01"
168
+
169
+ [[d1_databases]]
170
+ binding = "DB"
171
+ database_name = "cdp-edge-db"
172
+ database_id = "your-database-id"
173
+ `;
174
+ }