@happyvertical/smrt-marketing 0.43.9 → 0.44.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.
Files changed (31) hide show
  1. package/AGENTS.md +5 -3
  2. package/README.md +23 -4
  3. package/dist/collections/CampaignCollection.d.ts +10 -1
  4. package/dist/collections/CampaignCollection.d.ts.map +1 -1
  5. package/dist/index.js +448 -256
  6. package/dist/index.js.map +1 -1
  7. package/dist/manifest.json +25 -1
  8. package/dist/services/BudgetPacingService.d.ts +0 -3
  9. package/dist/services/BudgetPacingService.d.ts.map +1 -1
  10. package/dist/services/pacing-calculation.d.ts +18 -0
  11. package/dist/services/pacing-calculation.d.ts.map +1 -0
  12. package/dist/smrt-knowledge.json +16 -5
  13. package/dist/svelte/components/BudgetPacing.svelte +3 -0
  14. package/dist/svelte/components/BudgetPacing.svelte.d.ts +3 -0
  15. package/dist/svelte/components/BudgetPacing.svelte.d.ts.map +1 -1
  16. package/dist/svelte/components/CampaignDetail.svelte +5 -0
  17. package/dist/svelte/components/CampaignDetail.svelte.d.ts +5 -0
  18. package/dist/svelte/components/CampaignDetail.svelte.d.ts.map +1 -1
  19. package/dist/svelte/components/CampaignList.svelte +4 -0
  20. package/dist/svelte/components/CampaignList.svelte.d.ts +4 -0
  21. package/dist/svelte/components/CampaignList.svelte.d.ts.map +1 -1
  22. package/dist/svelte/components/ChannelMix.svelte +3 -0
  23. package/dist/svelte/components/ChannelMix.svelte.d.ts +3 -0
  24. package/dist/svelte/components/ChannelMix.svelte.d.ts.map +1 -1
  25. package/dist/svelte/components/MarketingDashboard.svelte +4 -0
  26. package/dist/svelte/components/MarketingDashboard.svelte.d.ts +4 -0
  27. package/dist/svelte/components/MarketingDashboard.svelte.d.ts.map +1 -1
  28. package/dist/types.d.ts +28 -0
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/types.js.map +1 -1
  31. package/package.json +7 -6
package/AGENTS.md CHANGED
@@ -55,9 +55,11 @@ All generated surfaces are explicit; never omit `api`, `mcp`, or `cli` config.
55
55
  uses a five-percent budget tolerance around schedule-derived expected spend.
56
56
  - **CampaignCollection** exposes bounded, tenant-and-Customer-scoped cursor
57
57
  pages ordered by `start_at DESC, id DESC` and bounded batch summaries for
58
- total count, active count, and latest start time. Customer scope is validated
59
- through runtime relationship metadata; there is no static commerce import or
60
- tenant-wide campaign materialization.
58
+ total count, active count, and latest start time. Its reporting-page variant
59
+ preserves that order/cursor and adds channel count/mix, immutable metric
60
+ totals, and canonical pacing with two page-wide grouped reads. Customer scope
61
+ is validated through runtime relationship metadata; there is no static
62
+ commerce import, per-campaign callback, or tenant-wide materialization.
61
63
 
62
64
  ## Svelte
63
65
 
package/README.md CHANGED
@@ -83,12 +83,31 @@ const secondPage = firstPage.nextCursor
83
83
 
84
84
  const summaries = await campaigns.summarizeByCustomers(tenantId, customerIds);
85
85
  // [{ customerId, totalCount, activeCount, latestStartAt }]
86
+
87
+ const reporting = await campaigns.listReportingByCustomer(
88
+ tenantId,
89
+ customerId,
90
+ {
91
+ limit: 50,
92
+ after: firstPage.nextCursor ?? undefined,
93
+ at: new Date('2026-08-15T00:00:00Z'),
94
+ },
95
+ );
96
+ // reporting.items keeps the same newest-first page order. Every item contains:
97
+ // { campaign, channelCount, channelMix, metricTotals, pacing }
86
98
  ```
87
99
 
88
- Pages and summary batches are capped at 100 items and reject larger inputs.
89
- Pagination is newest-first by `startAt`, then UUID; campaigns without a start
90
- time follow scheduled campaigns. Summary resolution uses a bounded grouped
91
- query rather than loading tenant campaigns or issuing one query per Customer.
100
+ Pages, reporting pages, and summary batches are capped at 100 items and reject
101
+ larger inputs. Pagination is newest-first by `startAt`, then UUID; campaigns
102
+ without a start time follow scheduled campaigns. `listReportingByCustomer()`
103
+ validates Customer scope and reads the page in one transaction, then performs
104
+ one grouped channel read and one grouped immutable-evidence read regardless of
105
+ page size. `metricTotals` use the same evidence selection as
106
+ `BudgetPacingService`: for each exact period, a campaign rollup replaces its
107
+ channel snapshots while channel-only periods remain. `pacing` is therefore
108
+ equivalent to `getCampaignPacing()` without per-campaign callbacks or lazy
109
+ loads. Summary resolution likewise uses a bounded grouped query rather than
110
+ loading tenant campaigns or issuing one query per Customer.
92
111
 
93
112
  ### Migrating metadata-backed associations
94
113
 
@@ -1,6 +1,6 @@
1
1
  import { CollectionCacheConfig, SmrtCollection, SmrtListOptions, SmrtSelectedRow, SmrtSelectField, SmrtWhereClause } from '@happyvertical/smrt-core';
2
2
  import { Campaign } from '../models/Campaign.js';
3
- import { CampaignCustomerPage, CampaignCustomerSummary, CampaignStatus, ListCampaignsByCustomerOptions } from '../types.js';
3
+ import { CampaignCustomerPage, CampaignCustomerSummary, CampaignReportingPage, CampaignStatus, ListCampaignReportingByCustomerOptions, ListCampaignsByCustomerOptions } from '../types.js';
4
4
  export declare const MAX_CAMPAIGN_CUSTOMER_PAGE_SIZE = 100;
5
5
  export declare const MAX_CAMPAIGN_CUSTOMER_BATCH_SIZE = 100;
6
6
  export declare class CampaignCollection extends SmrtCollection<Campaign> {
@@ -22,6 +22,15 @@ export declare class CampaignCollection extends SmrtCollection<Campaign> {
22
22
  * Null start times follow all scheduled rows on every supported database.
23
23
  */
24
24
  listByCustomer(tenantId: string | null, customerId: string, options?: ListCampaignsByCustomerOptions): Promise<CampaignCustomerPage>;
25
+ /**
26
+ * Return one bounded customer page with its complete read-only reporting
27
+ * projection. Channels and immutable evidence are aggregated in two grouped
28
+ * reads, independent of page size; no campaign callback or lazy load runs.
29
+ */
30
+ listReportingByCustomer(tenantId: string | null, customerId: string, options?: ListCampaignReportingByCustomerOptions): Promise<CampaignReportingPage>;
31
+ private projectReportingPage;
32
+ private loadChannelMixRows;
33
+ private loadMetricRows;
25
34
  private listByCustomerInTransaction;
26
35
  /**
27
36
  * Summarize a bounded customer batch with one scope check and one grouped
@@ -1 +1 @@
1
- {"version":3,"file":"CampaignCollection.d.ts","sourceRoot":"","sources":["../../src/collections/CampaignCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAE1B,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAalC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,EAGV,oBAAoB,EACpB,uBAAuB,EACvB,cAAc,EACd,8BAA8B,EAC/B,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAEpD,qBAAa,kBAAmB,SAAQ,cAAc,CAAC,QAAQ,CAAC;IAC9D,MAAM,CAAC,QAAQ,CAAC,UAAU,kBAAY;IAEvB,GAAG,CAChB,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,EAC1C,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAA;KAAO,GACtD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAMZ,IAAI,CACjB,KAAK,CAAC,MAAM,SAAS,SAAS,eAAe,CAAC,QAAQ,CAAC,EAAE,EAEzD,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAE,GACvE,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;IAChC,IAAI,CACjB,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,GAAG;QACpD,MAAM,CAAC,EAAE,SAAS,CAAC;KACpB,GACA,OAAO,CAAC,QAAQ,EAAE,CAAC;IAYhB,iBAAiB,CACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAQrB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO/D;;;OAGG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,oBAAoB,CAAC;YAgClB,2BAA2B;IA2BzC;;;OAGG;IACG,oBAAoB,CACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,uBAAuB,EAAE,CAAC;YAgCvB,iCAAiC;YAkDjC,yBAAyB;YAoBzB,iBAAiB;YA4BjB,iBAAiB;CAiBhC;AA4JD,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"CampaignCollection.d.ts","sourceRoot":"","sources":["../../src/collections/CampaignCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,qBAAqB,EAE1B,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAalC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,KAAK,EAIV,oBAAoB,EACpB,uBAAuB,EAEvB,qBAAqB,EACrB,cAAc,EACd,sCAAsC,EACtC,8BAA8B,EAC/B,MAAM,aAAa,CAAC;AAIrB,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAEpD,qBAAa,kBAAmB,SAAQ,cAAc,CAAC,QAAQ,CAAC;IAC9D,MAAM,CAAC,QAAQ,CAAC,UAAU,kBAAY;IAEvB,GAAG,CAChB,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,EAC1C,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAA;KAAO,GACtD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAMZ,IAAI,CACjB,KAAK,CAAC,MAAM,SAAS,SAAS,eAAe,CAAC,QAAQ,CAAC,EAAE,EAEzD,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAE,GACvE,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;IAChC,IAAI,CACjB,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,GAAG;QACpD,MAAM,CAAC,EAAE,SAAS,CAAC;KACpB,GACA,OAAO,CAAC,QAAQ,EAAE,CAAC;IAYhB,iBAAiB,CACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAQrB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAO/D;;;OAGG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,oBAAoB,CAAC;IAiChC;;;;OAIG;IACG,uBAAuB,CAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,sCAA2C,GACnD,OAAO,CAAC,qBAAqB,CAAC;YAoCnB,oBAAoB;YAkDpB,kBAAkB;YA2BlB,cAAc;YA6Dd,2BAA2B;IA4BzC;;;OAGG;IACG,oBAAoB,CACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,uBAAuB,EAAE,CAAC;YAgCvB,iCAAiC;YAkDjC,yBAAyB;YAoBzB,iBAAiB;YA4BjB,iBAAiB;CAiBhC;AA4PD,eAAe,kBAAkB,CAAC"}