@happyvertical/smrt-marketing 0.39.16

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 (67) hide show
  1. package/AGENTS.md +79 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +67 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/collections/CampaignChannelCollection.d.ts +9 -0
  8. package/dist/collections/CampaignChannelCollection.d.ts.map +1 -0
  9. package/dist/collections/CampaignCollection.d.ts +10 -0
  10. package/dist/collections/CampaignCollection.d.ts.map +1 -0
  11. package/dist/collections/CampaignMetricSnapshotCollection.d.ts +15 -0
  12. package/dist/collections/CampaignMetricSnapshotCollection.d.ts.map +1 -0
  13. package/dist/collections/index.d.ts +4 -0
  14. package/dist/collections/index.d.ts.map +1 -0
  15. package/dist/index.d.ts +5 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +625 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/manifest.json +1173 -0
  20. package/dist/models/Campaign.d.ts +31 -0
  21. package/dist/models/Campaign.d.ts.map +1 -0
  22. package/dist/models/CampaignChannel.d.ts +22 -0
  23. package/dist/models/CampaignChannel.d.ts.map +1 -0
  24. package/dist/models/CampaignMetricSnapshot.d.ts +29 -0
  25. package/dist/models/CampaignMetricSnapshot.d.ts.map +1 -0
  26. package/dist/models/index.d.ts +4 -0
  27. package/dist/models/index.d.ts.map +1 -0
  28. package/dist/services/BudgetPacingService.d.ts +25 -0
  29. package/dist/services/BudgetPacingService.d.ts.map +1 -0
  30. package/dist/services/CampaignLifecycleService.d.ts +19 -0
  31. package/dist/services/CampaignLifecycleService.d.ts.map +1 -0
  32. package/dist/services/MetricIngestionService.d.ts +16 -0
  33. package/dist/services/MetricIngestionService.d.ts.map +1 -0
  34. package/dist/services/index.d.ts +4 -0
  35. package/dist/services/index.d.ts.map +1 -0
  36. package/dist/smrt-knowledge.json +875 -0
  37. package/dist/svelte/__tests__/components.test.js +115 -0
  38. package/dist/svelte/__tests__/helpers.test.js +94 -0
  39. package/dist/svelte/components/BudgetPacing.svelte +129 -0
  40. package/dist/svelte/components/BudgetPacing.svelte.d.ts +10 -0
  41. package/dist/svelte/components/BudgetPacing.svelte.d.ts.map +1 -0
  42. package/dist/svelte/components/CampaignDetail.svelte +208 -0
  43. package/dist/svelte/components/CampaignDetail.svelte.d.ts +14 -0
  44. package/dist/svelte/components/CampaignDetail.svelte.d.ts.map +1 -0
  45. package/dist/svelte/components/CampaignList.svelte +140 -0
  46. package/dist/svelte/components/CampaignList.svelte.d.ts +11 -0
  47. package/dist/svelte/components/CampaignList.svelte.d.ts.map +1 -0
  48. package/dist/svelte/components/ChannelMix.svelte +138 -0
  49. package/dist/svelte/components/ChannelMix.svelte.d.ts +10 -0
  50. package/dist/svelte/components/ChannelMix.svelte.d.ts.map +1 -0
  51. package/dist/svelte/components/MarketingDashboard.svelte +129 -0
  52. package/dist/svelte/components/MarketingDashboard.svelte.d.ts +13 -0
  53. package/dist/svelte/components/MarketingDashboard.svelte.d.ts.map +1 -0
  54. package/dist/svelte/format.d.ts +8 -0
  55. package/dist/svelte/format.d.ts.map +1 -0
  56. package/dist/svelte/format.js +42 -0
  57. package/dist/svelte/index.d.ts +8 -0
  58. package/dist/svelte/index.d.ts.map +1 -0
  59. package/dist/svelte/index.js +7 -0
  60. package/dist/svelte/types.d.ts +73 -0
  61. package/dist/svelte/types.d.ts.map +1 -0
  62. package/dist/svelte/types.js +80 -0
  63. package/dist/types.d.ts +61 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +29 -0
  66. package/dist/types.js.map +1 -0
  67. package/package.json +79 -0
@@ -0,0 +1,875 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "generatedAt": "2026-07-14T21:46:27.372Z",
4
+ "packageName": "@happyvertical/smrt-marketing",
5
+ "packageVersion": "0.39.16",
6
+ "sourceManifestPath": "dist/manifest.json",
7
+ "agentDocPath": "AGENTS.md",
8
+ "sourceHashes": {
9
+ "manifest": "2a69e8f8f28600bad04b6bea25b7b8d1944688098c51878d675ac200a57e3de9",
10
+ "packageJson": "f7d6e48ab768607668aed961676c1fb8b0cf7cd879843647c829bf3b2bca129d",
11
+ "agents": "d3fd7ea9606b3bf1918cfbc2bbb67cd2d9889012915470fd95f16e61495c5556"
12
+ },
13
+ "exports": [
14
+ ".",
15
+ "./manifest",
16
+ "./manifest.json",
17
+ "./svelte"
18
+ ],
19
+ "dependencies": {
20
+ "@happyvertical/smrt-core": "workspace:*",
21
+ "@happyvertical/smrt-tenancy": "workspace:*",
22
+ "@happyvertical/smrt-ui": "workspace:*",
23
+ "@happyvertical/smrt-vitest": "workspace:*",
24
+ "@happyvertical/sql": "catalog:",
25
+ "@sveltejs/package": "^2.5.8",
26
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
27
+ "@testing-library/svelte": "^5.4.2",
28
+ "@types/node": "24.13.2",
29
+ "jsdom": "^26.1.0",
30
+ "svelte": "^5.56.4",
31
+ "svelte-check": "^4.7.1",
32
+ "typescript": "^5.9.3",
33
+ "vite": "^8.1.3",
34
+ "vitest": "^4.1.9"
35
+ },
36
+ "smrtDependencies": [
37
+ "@happyvertical/smrt-core",
38
+ "@happyvertical/smrt-tenancy",
39
+ "@happyvertical/smrt-ui",
40
+ "@happyvertical/smrt-vitest"
41
+ ],
42
+ "sdkDependencies": [
43
+ "@happyvertical/sql"
44
+ ],
45
+ "tags": [],
46
+ "risks": [],
47
+ "objects": [
48
+ {
49
+ "name": "CampaignChannelCollection",
50
+ "qualifiedName": "@happyvertical/smrt-marketing:CampaignChannelCollection",
51
+ "collection": "campaignchannels",
52
+ "tableName": "campaign_channels",
53
+ "packageName": "@happyvertical/smrt-marketing",
54
+ "extends": "SmrtCollection",
55
+ "fields": [],
56
+ "relationships": [],
57
+ "methods": [
58
+ "findByCampaign",
59
+ "findByExecutionRef"
60
+ ],
61
+ "surfaces": [],
62
+ "relationshipFeatures": [
63
+ "uuidColumns"
64
+ ],
65
+ "tags": [],
66
+ "risks": []
67
+ },
68
+ {
69
+ "name": "CampaignCollection",
70
+ "qualifiedName": "@happyvertical/smrt-marketing:CampaignCollection",
71
+ "collection": "campaigns",
72
+ "tableName": "campaigns",
73
+ "packageName": "@happyvertical/smrt-marketing",
74
+ "extends": "SmrtCollection",
75
+ "fields": [],
76
+ "relationships": [],
77
+ "methods": [
78
+ "findByCampaignKey",
79
+ "findByStatus"
80
+ ],
81
+ "surfaces": [],
82
+ "relationshipFeatures": [
83
+ "uuidColumns"
84
+ ],
85
+ "tags": [],
86
+ "risks": []
87
+ },
88
+ {
89
+ "name": "CampaignMetricSnapshotCollection",
90
+ "qualifiedName": "@happyvertical/smrt-marketing:CampaignMetricSnapshotCollection",
91
+ "collection": "campaignmetricsnapshots",
92
+ "tableName": "campaign_metric_snapshots",
93
+ "packageName": "@happyvertical/smrt-marketing",
94
+ "extends": "SmrtCollection",
95
+ "fields": [],
96
+ "relationships": [],
97
+ "methods": [
98
+ "findByCampaign",
99
+ "findByChannel",
100
+ "findByDedupeKey",
101
+ "getOrCreateByDedupeKey"
102
+ ],
103
+ "surfaces": [],
104
+ "relationshipFeatures": [
105
+ "uuidColumns"
106
+ ],
107
+ "tags": [],
108
+ "risks": []
109
+ },
110
+ {
111
+ "name": "Campaign",
112
+ "qualifiedName": "@happyvertical/smrt-marketing:Campaign",
113
+ "collection": "campaigns",
114
+ "tableName": "campaigns",
115
+ "packageName": "@happyvertical/smrt-marketing",
116
+ "extends": "SmrtObject",
117
+ "fields": [
118
+ {
119
+ "name": "tenantId",
120
+ "type": "text",
121
+ "required": false,
122
+ "columnType": "UUID"
123
+ },
124
+ {
125
+ "name": "campaignKey",
126
+ "type": "text",
127
+ "required": true,
128
+ "columnType": "TEXT"
129
+ },
130
+ {
131
+ "name": "name",
132
+ "type": "text",
133
+ "required": true,
134
+ "columnType": "TEXT"
135
+ },
136
+ {
137
+ "name": "objective",
138
+ "type": "text",
139
+ "required": false,
140
+ "columnType": "TEXT"
141
+ },
142
+ {
143
+ "name": "status",
144
+ "type": "text",
145
+ "required": false,
146
+ "columnType": "TEXT"
147
+ },
148
+ {
149
+ "name": "startAt",
150
+ "type": "datetime",
151
+ "required": false,
152
+ "columnType": "TIMESTAMP"
153
+ },
154
+ {
155
+ "name": "endAt",
156
+ "type": "datetime",
157
+ "required": false,
158
+ "columnType": "TIMESTAMP"
159
+ },
160
+ {
161
+ "name": "budgetCents",
162
+ "type": "integer",
163
+ "required": false,
164
+ "columnType": "INTEGER"
165
+ },
166
+ {
167
+ "name": "currency",
168
+ "type": "text",
169
+ "required": false,
170
+ "columnType": "TEXT"
171
+ },
172
+ {
173
+ "name": "metadata",
174
+ "type": "text",
175
+ "required": false,
176
+ "columnType": "TEXT"
177
+ }
178
+ ],
179
+ "relationships": [],
180
+ "methods": [
181
+ "getMetadata",
182
+ "initialize",
183
+ "save",
184
+ "setMetadata",
185
+ "transitionTo"
186
+ ],
187
+ "surfaces": [
188
+ {
189
+ "kind": "api",
190
+ "name": "campaigns.list",
191
+ "operation": "list",
192
+ "objectName": "@happyvertical/smrt-marketing:Campaign",
193
+ "path": "/campaigns",
194
+ "method": "GET"
195
+ },
196
+ {
197
+ "kind": "api",
198
+ "name": "campaigns.get",
199
+ "operation": "get",
200
+ "objectName": "@happyvertical/smrt-marketing:Campaign",
201
+ "path": "/campaigns/[id]",
202
+ "method": "GET"
203
+ },
204
+ {
205
+ "kind": "api",
206
+ "name": "campaigns.create",
207
+ "operation": "create",
208
+ "objectName": "@happyvertical/smrt-marketing:Campaign",
209
+ "path": "/campaigns",
210
+ "method": "POST"
211
+ },
212
+ {
213
+ "kind": "api",
214
+ "name": "campaigns.update",
215
+ "operation": "update",
216
+ "objectName": "@happyvertical/smrt-marketing:Campaign",
217
+ "path": "/campaigns/[id]",
218
+ "method": "PATCH"
219
+ },
220
+ {
221
+ "kind": "cli",
222
+ "name": "campaign_list",
223
+ "operation": "list",
224
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
225
+ },
226
+ {
227
+ "kind": "cli",
228
+ "name": "campaign_get",
229
+ "operation": "get",
230
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
231
+ },
232
+ {
233
+ "kind": "cli",
234
+ "name": "campaign_create",
235
+ "operation": "create",
236
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
237
+ },
238
+ {
239
+ "kind": "cli",
240
+ "name": "campaign_update",
241
+ "operation": "update",
242
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
243
+ },
244
+ {
245
+ "kind": "mcp",
246
+ "name": "campaign_list",
247
+ "operation": "list",
248
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
249
+ },
250
+ {
251
+ "kind": "mcp",
252
+ "name": "campaign_get",
253
+ "operation": "get",
254
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
255
+ },
256
+ {
257
+ "kind": "mcp",
258
+ "name": "campaign_create",
259
+ "operation": "create",
260
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
261
+ },
262
+ {
263
+ "kind": "mcp",
264
+ "name": "campaign_update",
265
+ "operation": "update",
266
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
267
+ }
268
+ ],
269
+ "relationshipFeatures": [
270
+ "uuidColumns"
271
+ ],
272
+ "tags": [],
273
+ "risks": []
274
+ },
275
+ {
276
+ "name": "CampaignChannel",
277
+ "qualifiedName": "@happyvertical/smrt-marketing:CampaignChannel",
278
+ "collection": "campaignchannels",
279
+ "tableName": "campaign_channels",
280
+ "packageName": "@happyvertical/smrt-marketing",
281
+ "extends": "SmrtObject",
282
+ "fields": [
283
+ {
284
+ "name": "tenantId",
285
+ "type": "text",
286
+ "required": false,
287
+ "columnType": "UUID"
288
+ },
289
+ {
290
+ "name": "campaignId",
291
+ "type": "foreignKey",
292
+ "required": true,
293
+ "related": "Campaign",
294
+ "columnType": "UUID"
295
+ },
296
+ {
297
+ "name": "channelKind",
298
+ "type": "text",
299
+ "required": true,
300
+ "columnType": "TEXT"
301
+ },
302
+ {
303
+ "name": "channelRef",
304
+ "type": "text",
305
+ "required": true,
306
+ "columnType": "TEXT"
307
+ },
308
+ {
309
+ "name": "allocatedBudgetCents",
310
+ "type": "integer",
311
+ "required": false,
312
+ "columnType": "INTEGER"
313
+ },
314
+ {
315
+ "name": "startAt",
316
+ "type": "datetime",
317
+ "required": false,
318
+ "columnType": "TIMESTAMP"
319
+ },
320
+ {
321
+ "name": "endAt",
322
+ "type": "datetime",
323
+ "required": false,
324
+ "columnType": "TIMESTAMP"
325
+ },
326
+ {
327
+ "name": "status",
328
+ "type": "text",
329
+ "required": false,
330
+ "columnType": "TEXT"
331
+ }
332
+ ],
333
+ "relationships": [
334
+ {
335
+ "name": "campaignId",
336
+ "type": "foreignKey",
337
+ "required": true,
338
+ "related": "Campaign",
339
+ "columnType": "UUID"
340
+ }
341
+ ],
342
+ "methods": [
343
+ "initialize",
344
+ "save"
345
+ ],
346
+ "surfaces": [
347
+ {
348
+ "kind": "api",
349
+ "name": "campaignchannels.list",
350
+ "operation": "list",
351
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
352
+ "path": "/campaignchannels",
353
+ "method": "GET"
354
+ },
355
+ {
356
+ "kind": "api",
357
+ "name": "campaignchannels.get",
358
+ "operation": "get",
359
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
360
+ "path": "/campaignchannels/[id]",
361
+ "method": "GET"
362
+ },
363
+ {
364
+ "kind": "api",
365
+ "name": "campaignchannels.create",
366
+ "operation": "create",
367
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
368
+ "path": "/campaignchannels",
369
+ "method": "POST"
370
+ },
371
+ {
372
+ "kind": "api",
373
+ "name": "campaignchannels.update",
374
+ "operation": "update",
375
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
376
+ "path": "/campaignchannels/[id]",
377
+ "method": "PATCH"
378
+ },
379
+ {
380
+ "kind": "api",
381
+ "name": "campaignchannels.delete",
382
+ "operation": "delete",
383
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
384
+ "path": "/campaignchannels/[id]",
385
+ "method": "DELETE"
386
+ },
387
+ {
388
+ "kind": "cli",
389
+ "name": "campaignchannel_list",
390
+ "operation": "list",
391
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
392
+ },
393
+ {
394
+ "kind": "cli",
395
+ "name": "campaignchannel_get",
396
+ "operation": "get",
397
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
398
+ },
399
+ {
400
+ "kind": "cli",
401
+ "name": "campaignchannel_create",
402
+ "operation": "create",
403
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
404
+ },
405
+ {
406
+ "kind": "cli",
407
+ "name": "campaignchannel_update",
408
+ "operation": "update",
409
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
410
+ },
411
+ {
412
+ "kind": "cli",
413
+ "name": "campaignchannel_delete",
414
+ "operation": "delete",
415
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
416
+ },
417
+ {
418
+ "kind": "mcp",
419
+ "name": "campaignchannel_list",
420
+ "operation": "list",
421
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
422
+ },
423
+ {
424
+ "kind": "mcp",
425
+ "name": "campaignchannel_get",
426
+ "operation": "get",
427
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
428
+ },
429
+ {
430
+ "kind": "mcp",
431
+ "name": "campaignchannel_create",
432
+ "operation": "create",
433
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
434
+ },
435
+ {
436
+ "kind": "mcp",
437
+ "name": "campaignchannel_update",
438
+ "operation": "update",
439
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
440
+ }
441
+ ],
442
+ "relationshipFeatures": [
443
+ "foreignKey",
444
+ "uuidColumns"
445
+ ],
446
+ "tags": [],
447
+ "risks": []
448
+ },
449
+ {
450
+ "name": "CampaignMetricSnapshot",
451
+ "qualifiedName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot",
452
+ "collection": "campaignmetricsnapshots",
453
+ "tableName": "campaign_metric_snapshots",
454
+ "packageName": "@happyvertical/smrt-marketing",
455
+ "extends": "SmrtObject",
456
+ "fields": [
457
+ {
458
+ "name": "tenantId",
459
+ "type": "text",
460
+ "required": false,
461
+ "columnType": "UUID"
462
+ },
463
+ {
464
+ "name": "campaignId",
465
+ "type": "foreignKey",
466
+ "required": true,
467
+ "related": "Campaign",
468
+ "columnType": "UUID"
469
+ },
470
+ {
471
+ "name": "campaignChannelId",
472
+ "type": "foreignKey",
473
+ "required": false,
474
+ "related": "CampaignChannel",
475
+ "columnType": "UUID"
476
+ },
477
+ {
478
+ "name": "periodStart",
479
+ "type": "datetime",
480
+ "required": true,
481
+ "columnType": "TIMESTAMP"
482
+ },
483
+ {
484
+ "name": "periodEnd",
485
+ "type": "datetime",
486
+ "required": true,
487
+ "columnType": "TIMESTAMP"
488
+ },
489
+ {
490
+ "name": "spendCents",
491
+ "type": "integer",
492
+ "required": false,
493
+ "columnType": "INTEGER"
494
+ },
495
+ {
496
+ "name": "impressions",
497
+ "type": "integer",
498
+ "required": false,
499
+ "columnType": "INTEGER"
500
+ },
501
+ {
502
+ "name": "clicks",
503
+ "type": "integer",
504
+ "required": false,
505
+ "columnType": "INTEGER"
506
+ },
507
+ {
508
+ "name": "conversions",
509
+ "type": "integer",
510
+ "required": false,
511
+ "columnType": "INTEGER"
512
+ },
513
+ {
514
+ "name": "leads",
515
+ "type": "integer",
516
+ "required": false,
517
+ "columnType": "INTEGER"
518
+ },
519
+ {
520
+ "name": "revenueCents",
521
+ "type": "integer",
522
+ "required": false,
523
+ "columnType": "INTEGER"
524
+ },
525
+ {
526
+ "name": "source",
527
+ "type": "text",
528
+ "required": true,
529
+ "columnType": "TEXT"
530
+ },
531
+ {
532
+ "name": "dedupeKey",
533
+ "type": "text",
534
+ "required": true,
535
+ "columnType": "TEXT"
536
+ }
537
+ ],
538
+ "relationships": [
539
+ {
540
+ "name": "campaignId",
541
+ "type": "foreignKey",
542
+ "required": true,
543
+ "related": "Campaign",
544
+ "columnType": "UUID"
545
+ },
546
+ {
547
+ "name": "campaignChannelId",
548
+ "type": "foreignKey",
549
+ "required": false,
550
+ "related": "CampaignChannel",
551
+ "columnType": "UUID"
552
+ }
553
+ ],
554
+ "methods": [
555
+ "delete",
556
+ "initialize",
557
+ "save"
558
+ ],
559
+ "surfaces": [
560
+ {
561
+ "kind": "api",
562
+ "name": "campaignmetricsnapshots.list",
563
+ "operation": "list",
564
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot",
565
+ "path": "/campaignmetricsnapshots",
566
+ "method": "GET"
567
+ },
568
+ {
569
+ "kind": "api",
570
+ "name": "campaignmetricsnapshots.get",
571
+ "operation": "get",
572
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot",
573
+ "path": "/campaignmetricsnapshots/[id]",
574
+ "method": "GET"
575
+ },
576
+ {
577
+ "kind": "api",
578
+ "name": "campaignmetricsnapshots.create",
579
+ "operation": "create",
580
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot",
581
+ "path": "/campaignmetricsnapshots",
582
+ "method": "POST"
583
+ },
584
+ {
585
+ "kind": "cli",
586
+ "name": "campaignmetricsnapshot_list",
587
+ "operation": "list",
588
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
589
+ },
590
+ {
591
+ "kind": "cli",
592
+ "name": "campaignmetricsnapshot_get",
593
+ "operation": "get",
594
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
595
+ },
596
+ {
597
+ "kind": "cli",
598
+ "name": "campaignmetricsnapshot_create",
599
+ "operation": "create",
600
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
601
+ },
602
+ {
603
+ "kind": "mcp",
604
+ "name": "campaignmetricsnapshot_list",
605
+ "operation": "list",
606
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
607
+ },
608
+ {
609
+ "kind": "mcp",
610
+ "name": "campaignmetricsnapshot_get",
611
+ "operation": "get",
612
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
613
+ },
614
+ {
615
+ "kind": "mcp",
616
+ "name": "campaignmetricsnapshot_create",
617
+ "operation": "create",
618
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
619
+ }
620
+ ],
621
+ "relationshipFeatures": [
622
+ "foreignKey",
623
+ "uuidColumns"
624
+ ],
625
+ "tags": [],
626
+ "risks": []
627
+ }
628
+ ],
629
+ "surfaces": [
630
+ {
631
+ "kind": "api",
632
+ "name": "campaigns.list",
633
+ "operation": "list",
634
+ "objectName": "@happyvertical/smrt-marketing:Campaign",
635
+ "path": "/campaigns",
636
+ "method": "GET"
637
+ },
638
+ {
639
+ "kind": "api",
640
+ "name": "campaigns.get",
641
+ "operation": "get",
642
+ "objectName": "@happyvertical/smrt-marketing:Campaign",
643
+ "path": "/campaigns/[id]",
644
+ "method": "GET"
645
+ },
646
+ {
647
+ "kind": "api",
648
+ "name": "campaigns.create",
649
+ "operation": "create",
650
+ "objectName": "@happyvertical/smrt-marketing:Campaign",
651
+ "path": "/campaigns",
652
+ "method": "POST"
653
+ },
654
+ {
655
+ "kind": "api",
656
+ "name": "campaigns.update",
657
+ "operation": "update",
658
+ "objectName": "@happyvertical/smrt-marketing:Campaign",
659
+ "path": "/campaigns/[id]",
660
+ "method": "PATCH"
661
+ },
662
+ {
663
+ "kind": "cli",
664
+ "name": "campaign_list",
665
+ "operation": "list",
666
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
667
+ },
668
+ {
669
+ "kind": "cli",
670
+ "name": "campaign_get",
671
+ "operation": "get",
672
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
673
+ },
674
+ {
675
+ "kind": "cli",
676
+ "name": "campaign_create",
677
+ "operation": "create",
678
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
679
+ },
680
+ {
681
+ "kind": "cli",
682
+ "name": "campaign_update",
683
+ "operation": "update",
684
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
685
+ },
686
+ {
687
+ "kind": "mcp",
688
+ "name": "campaign_list",
689
+ "operation": "list",
690
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
691
+ },
692
+ {
693
+ "kind": "mcp",
694
+ "name": "campaign_get",
695
+ "operation": "get",
696
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
697
+ },
698
+ {
699
+ "kind": "mcp",
700
+ "name": "campaign_create",
701
+ "operation": "create",
702
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
703
+ },
704
+ {
705
+ "kind": "mcp",
706
+ "name": "campaign_update",
707
+ "operation": "update",
708
+ "objectName": "@happyvertical/smrt-marketing:Campaign"
709
+ },
710
+ {
711
+ "kind": "api",
712
+ "name": "campaignchannels.list",
713
+ "operation": "list",
714
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
715
+ "path": "/campaignchannels",
716
+ "method": "GET"
717
+ },
718
+ {
719
+ "kind": "api",
720
+ "name": "campaignchannels.get",
721
+ "operation": "get",
722
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
723
+ "path": "/campaignchannels/[id]",
724
+ "method": "GET"
725
+ },
726
+ {
727
+ "kind": "api",
728
+ "name": "campaignchannels.create",
729
+ "operation": "create",
730
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
731
+ "path": "/campaignchannels",
732
+ "method": "POST"
733
+ },
734
+ {
735
+ "kind": "api",
736
+ "name": "campaignchannels.update",
737
+ "operation": "update",
738
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
739
+ "path": "/campaignchannels/[id]",
740
+ "method": "PATCH"
741
+ },
742
+ {
743
+ "kind": "api",
744
+ "name": "campaignchannels.delete",
745
+ "operation": "delete",
746
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel",
747
+ "path": "/campaignchannels/[id]",
748
+ "method": "DELETE"
749
+ },
750
+ {
751
+ "kind": "cli",
752
+ "name": "campaignchannel_list",
753
+ "operation": "list",
754
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
755
+ },
756
+ {
757
+ "kind": "cli",
758
+ "name": "campaignchannel_get",
759
+ "operation": "get",
760
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
761
+ },
762
+ {
763
+ "kind": "cli",
764
+ "name": "campaignchannel_create",
765
+ "operation": "create",
766
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
767
+ },
768
+ {
769
+ "kind": "cli",
770
+ "name": "campaignchannel_update",
771
+ "operation": "update",
772
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
773
+ },
774
+ {
775
+ "kind": "cli",
776
+ "name": "campaignchannel_delete",
777
+ "operation": "delete",
778
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
779
+ },
780
+ {
781
+ "kind": "mcp",
782
+ "name": "campaignchannel_list",
783
+ "operation": "list",
784
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
785
+ },
786
+ {
787
+ "kind": "mcp",
788
+ "name": "campaignchannel_get",
789
+ "operation": "get",
790
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
791
+ },
792
+ {
793
+ "kind": "mcp",
794
+ "name": "campaignchannel_create",
795
+ "operation": "create",
796
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
797
+ },
798
+ {
799
+ "kind": "mcp",
800
+ "name": "campaignchannel_update",
801
+ "operation": "update",
802
+ "objectName": "@happyvertical/smrt-marketing:CampaignChannel"
803
+ },
804
+ {
805
+ "kind": "api",
806
+ "name": "campaignmetricsnapshots.list",
807
+ "operation": "list",
808
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot",
809
+ "path": "/campaignmetricsnapshots",
810
+ "method": "GET"
811
+ },
812
+ {
813
+ "kind": "api",
814
+ "name": "campaignmetricsnapshots.get",
815
+ "operation": "get",
816
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot",
817
+ "path": "/campaignmetricsnapshots/[id]",
818
+ "method": "GET"
819
+ },
820
+ {
821
+ "kind": "api",
822
+ "name": "campaignmetricsnapshots.create",
823
+ "operation": "create",
824
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot",
825
+ "path": "/campaignmetricsnapshots",
826
+ "method": "POST"
827
+ },
828
+ {
829
+ "kind": "cli",
830
+ "name": "campaignmetricsnapshot_list",
831
+ "operation": "list",
832
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
833
+ },
834
+ {
835
+ "kind": "cli",
836
+ "name": "campaignmetricsnapshot_get",
837
+ "operation": "get",
838
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
839
+ },
840
+ {
841
+ "kind": "cli",
842
+ "name": "campaignmetricsnapshot_create",
843
+ "operation": "create",
844
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
845
+ },
846
+ {
847
+ "kind": "mcp",
848
+ "name": "campaignmetricsnapshot_list",
849
+ "operation": "list",
850
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
851
+ },
852
+ {
853
+ "kind": "mcp",
854
+ "name": "campaignmetricsnapshot_get",
855
+ "operation": "get",
856
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
857
+ },
858
+ {
859
+ "kind": "mcp",
860
+ "name": "campaignmetricsnapshot_create",
861
+ "operation": "create",
862
+ "objectName": "@happyvertical/smrt-marketing:CampaignMetricSnapshot"
863
+ }
864
+ ],
865
+ "prompts": [],
866
+ "relationshipsV2": {
867
+ "foreignKeyFields": 3,
868
+ "crossPackageRefFields": 0,
869
+ "junctionCollections": 0,
870
+ "hierarchicalObjects": 0,
871
+ "polymorphicAssociations": 0,
872
+ "uuidColumns": 12
873
+ },
874
+ "agentDoc": "# @happyvertical/smrt-marketing\n\nCross-channel campaign coordination for SMRT. This package owns Campaign\nidentity, budgets, lifecycle, execution links, immutable performance evidence,\ncomputed pacing, and props-driven Svelte surfaces. It does not execute ads,\npublish social posts, send messages, or own sales attribution.\n\n## Validation\n\nRun `pnpm --filter @happyvertical/smrt-marketing test` and\n`pnpm --filter @happyvertical/smrt-marketing typecheck`; use `test:coverage`\nto exercise the model/service and component coverage configurations.\nNatural-key changes must also run\n`pnpm --filter @happyvertical/smrt-marketing test:postgres` when\nthe disposable PostgreSQL harness is available. Use\n`pnpm --filter @happyvertical/smrt-marketing build` and `verify:pack` for\npublish-surface changes.\n\n## Models\n\n- **Campaign**: optional-tenant umbrella with stable natural key\n `(tenant_id, campaign_key)`, open objective, integer-cent budget, currency,\n schedule, guarded metadata helpers, and lifecycle\n `draft → scheduled → active ↔ paused → completed → archived`. Raw saves are\n protected by an authoritative prior-status re-read; use\n `CampaignLifecycleService` for lifecycle writes.\n- **CampaignChannel**: one generic execution link per\n `(campaign_id, channel_kind, channel_ref)`. `channelKind`/`channelRef` are\n intentionally plain strings so ads, social, messages, content, events, and\n referral programs remain peer packages. Allocation and schedule overrides\n use integer cents and dates.\n- **CampaignMetricSnapshot**: immutable period evidence with a global\n `dedupe_key` natural key. A snapshot always carries `campaignId`; a null\n `campaignChannelId` means campaign-level rollup evidence; when present, the\n channel must belong to that same campaign. API/MCP/CLI expose create/list/get\n only, and the save guard rejects hydrated edits, blind-id overwrites, and\n natural-key overwrites. Programmatic deletion is rejected.\n\nEvery model is `@TenantScoped({ mode: 'optional' })` with nullable `tenantId`.\nAll generated surfaces are explicit; never omit `api`, `mcp`, or `cli` config.\n\n## Services\n\n- **CampaignLifecycleService** loads the current row before applying one legal\n transition. Paused campaigns may resume; completed campaigns may only be\n archived; archived campaigns are terminal.\n- **MetricIngestionService** validates required scope/source/period fields and\n delegates to `getOrCreateByDedupeKey()`. A replay returns the original row\n unchanged even if the replay payload differs.\n- **BudgetPacingService** computes campaign/channel pacing from snapshots and\n never persists derived balances. For each exact reporting period, campaign\n pacing prefers campaign rollups and otherwise sums channel snapshots,\n preventing double counting without dropping channel-only periods. Status\n uses a five-percent budget tolerance around schedule-derived expected spend.\n\n## Svelte\n\n`@happyvertical/smrt-marketing/svelte` exports `MarketingDashboard`,\n`CampaignList`, `CampaignDetail`, `ChannelMix`, and `BudgetPacing`, plus view\ninterfaces and pure helpers. Components are props-only: no fetching, no model\nimports, no providers. Use Provider-free `smrt-ui` primitives, `--smrt-*`\ntokens, named `$props()` interfaces, and integer-cent inputs formatted only at\nrender time.\n\n## Boundaries and gotchas\n\n- Runtime dependencies stay limited to `smrt-core`, `smrt-tenancy`, and\n `smrt-ui`. Never statically import sibling domain packages.\n- Lead loop-closing is conventional: CRM stores `sourceKind: 'campaign'` and a\n campaign key in `sourceId`; marketing does not import or mutate Lead.\n- Attribution math remains in sales/referrals. Marketing stores performance\n evidence only.\n- Campaign rollups and channel snapshots may describe the same period. The\n pacing service deliberately chooses one evidence level instead of summing\n both.\n- Corrections append a new metric snapshot with a new dedupe key; never edit\n persisted evidence.\n- Table names are global: `campaigns`, `campaign_channels`, and\n `campaign_metric_snapshots`.\n"
875
+ }