@happyvertical/smrt-ads 0.57.36 → 0.57.38

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.
@@ -3,13 +3,13 @@
3
3
  "sensitiveFieldsExcluded": true,
4
4
  "generatedAt": "1970-01-01T00:00:00.000Z",
5
5
  "packageName": "@happyvertical/smrt-ads",
6
- "packageVersion": "0.57.36",
6
+ "packageVersion": "0.57.38",
7
7
  "sourceManifestPath": "dist/manifest.json",
8
8
  "agentDocPath": "AGENTS.md",
9
9
  "sourceHashes": {
10
- "manifest": "4f30b02bd348086a2613781f7ae92b3e4db553338e72ac4817346a4a3f9aa1dc",
11
- "packageJson": "d541791941b2e8a8a0f6942614eeb4d126245289289d4199660ffbeb937710e1",
12
- "agents": "876d4834346e5033011df69c99da0767db466b3855bf03fec787cd44f7290679"
10
+ "manifest": "b45f708391040d3a6b925b2ed785de6c230ede8cae79a602487c74c0bf3731ee",
11
+ "packageJson": "360d40ede9f544e786bde15db22ab274cfcee08610f16628f6694469fae3d2e5",
12
+ "agents": "a74f5ff1aea757073496bcd3fe01802b5a4e2f59b39a04c1bb0d11b81343f660"
13
13
  },
14
14
  "exports": [
15
15
  ".",
@@ -1167,27 +1167,31 @@
1167
1167
  "type": "text",
1168
1168
  "required": false,
1169
1169
  "columnType": "TEXT",
1170
- "default": ""
1170
+ "default": "",
1171
+ "description": "What the tier is called, for example Sponsorship, Standard or House."
1171
1172
  },
1172
1173
  {
1173
1174
  "name": "priority",
1174
1175
  "type": "integer",
1175
1176
  "required": false,
1176
1177
  "columnType": "INTEGER",
1177
- "default": 0
1178
+ "default": 0,
1179
+ "description": "The order tiers are tried in: 1 is tried first, then 2, and so on."
1178
1180
  },
1179
1181
  {
1180
1182
  "name": "pricingModel",
1181
1183
  "type": "text",
1182
1184
  "required": false,
1183
- "columnType": "TEXT"
1185
+ "columnType": "TEXT",
1186
+ "description": "How ads in this tier are charged: a fixed price, per thousand showings, per click, or per sale."
1184
1187
  },
1185
1188
  {
1186
1189
  "name": "description",
1187
1190
  "type": "text",
1188
1191
  "required": false,
1189
1192
  "columnType": "TEXT",
1190
- "default": ""
1193
+ "default": "",
1194
+ "description": "A note about what this tier is for."
1191
1195
  }
1192
1196
  ],
1193
1197
  "relationships": [],
@@ -1547,34 +1551,39 @@
1547
1551
  "type": "text",
1548
1552
  "required": false,
1549
1553
  "columnType": "TEXT",
1550
- "default": ""
1554
+ "default": "",
1555
+ "description": "What the size is called, for example Leaderboard."
1551
1556
  },
1552
1557
  {
1553
1558
  "name": "width",
1554
1559
  "type": "integer",
1555
1560
  "required": false,
1556
1561
  "columnType": "INTEGER",
1557
- "default": 0
1562
+ "default": 0,
1563
+ "description": "How wide the ad is, in pixels."
1558
1564
  },
1559
1565
  {
1560
1566
  "name": "height",
1561
1567
  "type": "integer",
1562
1568
  "required": false,
1563
1569
  "columnType": "INTEGER",
1564
- "default": 0
1570
+ "default": 0,
1571
+ "description": "How tall the ad is, in pixels."
1565
1572
  },
1566
1573
  {
1567
1574
  "name": "formatType",
1568
1575
  "type": "text",
1569
1576
  "required": false,
1570
- "columnType": "TEXT"
1577
+ "columnType": "TEXT",
1578
+ "description": "What kind of ad fits this size: a picture, a piece written to look like your own content, or a video."
1571
1579
  },
1572
1580
  {
1573
1581
  "name": "description",
1574
1582
  "type": "text",
1575
1583
  "required": false,
1576
1584
  "columnType": "TEXT",
1577
- "default": ""
1585
+ "default": "",
1586
+ "description": "A note about where this size is usually used."
1578
1587
  }
1579
1588
  ],
1580
1589
  "relationships": [],
@@ -1739,28 +1748,32 @@
1739
1748
  "type": "crossPackageRef",
1740
1749
  "required": false,
1741
1750
  "related": "@happyvertical/smrt-commerce:SalesContract",
1742
- "columnType": "UUID"
1751
+ "columnType": "UUID",
1752
+ "description": "The sales contract this campaign is sold under, if there is one."
1743
1753
  },
1744
1754
  {
1745
1755
  "name": "tierId",
1746
1756
  "type": "foreignKey",
1747
1757
  "required": false,
1748
1758
  "related": "AdDeliveryTier",
1749
- "columnType": "UUID"
1759
+ "columnType": "UUID",
1760
+ "description": "The priority tier the campaign runs in. Tiers are tried in order when more than one campaign could show."
1750
1761
  },
1751
1762
  {
1752
1763
  "name": "name",
1753
1764
  "type": "text",
1754
1765
  "required": false,
1755
1766
  "columnType": "TEXT",
1756
- "default": ""
1767
+ "default": "",
1768
+ "description": "What you call the campaign, for example Summer sale."
1757
1769
  },
1758
1770
  {
1759
1771
  "name": "verticalSlug",
1760
1772
  "type": "text",
1761
1773
  "required": false,
1762
1774
  "columnType": "TEXT",
1763
- "default": ""
1775
+ "default": "",
1776
+ "description": "The category the campaign belongs to, such as retail."
1764
1777
  },
1765
1778
  {
1766
1779
  "name": "targeting",
@@ -1780,33 +1793,38 @@
1780
1793
  "name": "startDate",
1781
1794
  "type": "datetime",
1782
1795
  "required": false,
1783
- "columnType": "TIMESTAMP"
1796
+ "columnType": "TIMESTAMP",
1797
+ "description": "The first day the campaign can show."
1784
1798
  },
1785
1799
  {
1786
1800
  "name": "endDate",
1787
1801
  "type": "datetime",
1788
1802
  "required": false,
1789
- "columnType": "TIMESTAMP"
1803
+ "columnType": "TIMESTAMP",
1804
+ "description": "The last day the campaign can show."
1790
1805
  },
1791
1806
  {
1792
1807
  "name": "dailyBudget",
1793
1808
  "type": "decimal",
1794
1809
  "required": false,
1795
1810
  "columnType": "REAL",
1796
- "default": 0
1811
+ "default": 0,
1812
+ "description": "The most to spend in one day. The app shows this but does not stop the campaign by itself."
1797
1813
  },
1798
1814
  {
1799
1815
  "name": "totalBudget",
1800
1816
  "type": "decimal",
1801
1817
  "required": false,
1802
1818
  "columnType": "REAL",
1803
- "default": 0
1819
+ "default": 0,
1820
+ "description": "The most to spend over the whole campaign."
1804
1821
  },
1805
1822
  {
1806
1823
  "name": "status",
1807
1824
  "type": "text",
1808
1825
  "required": false,
1809
- "columnType": "TEXT"
1826
+ "columnType": "TEXT",
1827
+ "description": "Where the campaign stands: draft, active, paused or completed. Only active campaigns show ads."
1810
1828
  }
1811
1829
  ],
1812
1830
  "relationships": [
@@ -2215,69 +2233,79 @@
2215
2233
  "type": "foreignKey",
2216
2234
  "required": false,
2217
2235
  "related": "AdGroup",
2218
- "columnType": "UUID"
2236
+ "columnType": "UUID",
2237
+ "description": "The campaign this ad belongs to."
2219
2238
  },
2220
2239
  {
2221
2240
  "name": "formatId",
2222
2241
  "type": "foreignKey",
2223
2242
  "required": false,
2224
2243
  "related": "AdFormat",
2225
- "columnType": "UUID"
2244
+ "columnType": "UUID",
2245
+ "description": "The ad size this ad is made for."
2226
2246
  },
2227
2247
  {
2228
2248
  "name": "assetId",
2229
2249
  "type": "crossPackageRef",
2230
2250
  "required": false,
2231
2251
  "related": "@happyvertical/smrt-assets:Asset",
2232
- "columnType": "UUID"
2252
+ "columnType": "UUID",
2253
+ "description": "The picture people see."
2233
2254
  },
2234
2255
  {
2235
2256
  "name": "name",
2236
2257
  "type": "text",
2237
2258
  "required": false,
2238
2259
  "columnType": "TEXT",
2239
- "default": ""
2260
+ "default": "",
2261
+ "description": "What you call this ad, for example Version A, blue button."
2240
2262
  },
2241
2263
  {
2242
2264
  "name": "clickUrl",
2243
2265
  "type": "text",
2244
2266
  "required": false,
2245
2267
  "columnType": "TEXT",
2246
- "default": ""
2268
+ "default": "",
2269
+ "description": "The web address people go to when they tap the ad."
2247
2270
  },
2248
2271
  {
2249
2272
  "name": "altText",
2250
2273
  "type": "text",
2251
2274
  "required": false,
2252
2275
  "columnType": "TEXT",
2253
- "default": ""
2276
+ "default": "",
2277
+ "description": "A few words that describe the picture for people who cannot see it."
2254
2278
  },
2255
2279
  {
2256
2280
  "name": "weight",
2257
2281
  "type": "integer",
2258
2282
  "required": false,
2259
2283
  "columnType": "INTEGER",
2260
- "default": 1
2284
+ "default": 1,
2285
+ "description": "How often this ad shows compared with the others in its campaign: an ad with weight 2 shows twice as often as one with weight 1."
2261
2286
  },
2262
2287
  {
2263
2288
  "name": "status",
2264
2289
  "type": "text",
2265
2290
  "required": false,
2266
- "columnType": "TEXT"
2291
+ "columnType": "TEXT",
2292
+ "description": "Where the ad stands: draft, active or paused. Only active ads show."
2267
2293
  },
2268
2294
  {
2269
2295
  "name": "impressions",
2270
2296
  "type": "integer",
2271
2297
  "required": false,
2272
2298
  "columnType": "INTEGER",
2273
- "default": 0
2299
+ "default": 0,
2300
+ "description": "How many times the ad has been shown. The app counts this as it serves ads and refreshes it a little later."
2274
2301
  },
2275
2302
  {
2276
2303
  "name": "clicks",
2277
2304
  "type": "integer",
2278
2305
  "required": false,
2279
2306
  "columnType": "INTEGER",
2280
- "default": 0
2307
+ "default": 0,
2308
+ "description": "How many times the ad has been tapped. The app counts this as it serves ads and refreshes it a little later."
2281
2309
  }
2282
2310
  ],
2283
2311
  "relationships": [
@@ -3221,7 +3249,232 @@
3221
3249
  "polymorphicAssociations": 0,
3222
3250
  "uuidColumns": 30
3223
3251
  },
3224
- "agentDoc": "# @happyvertical/smrt-ads\n\nAd delivery with priority waterfall, weighted A/B testing, and immutable event tracking.\n\n## Models\n\n- **AdFormat**: IAB standard dimensions (width, height, type: banner/native/video)\n- **AdDeliveryTier**: priority levels — Sponsorship (1, FIXED pricing) > Standard (2, CPM) > House (3, fallback)\n- **AdGroup**: campaign with targeting, budget, zone restrictions\n- **AdVariation** (STI): creative variant with weighted selection for A/B. `weight=2` is 2x more likely than `weight=1`. Denormalized `impressions`/`clicks` fields.\n- **AdEvent** (STI, immutable): impression/click/conversion tracking. **Create-only** — no update/delete in API/MCP. `cli: false` (high-volume).\n\n## Cross-Package References (all plain string IDs)\n\n`contractId` → smrt-commerce `SalesContract`, `zoneId`/`siteId` → smrt-properties, `assetId` → smrt-assets, `verticalSlug` → smrt-tags\n\n## Tenancy\n\nOptional tenancy via `@TenantScoped({ mode: 'optional' })` is applied to the\nthree transactional models — `AdGroup`, `AdVariation`, and `AdEvent` — which\nparticipate in per-tenant ad serving and event tracking.\n\n`AdFormat` and `AdDeliveryTier` are deliberately **NOT** tenant-scoped: they\nare shared catalog/lookup tables.\n\n- `AdFormat` rows describe IAB standard ad dimensions (e.g. `728x90`\n Leaderboard, `300x250` Medium Rectangle). The dimensions are an industry\n standard, not a tenant-specific configuration.\n- `AdDeliveryTier` rows describe the priority waterfall for ad selection\n (Sponsorship → Standard → House). Tiers are part of the package's\n ad-serving contract; per-tenant tier definitions would fragment the\n selection algorithm without a clear use case.\n\nEither model can still be filtered by tenant manually if a deployment ever\nneeds tenant-specific overrides, but the default is global. This mirrors the\ndocumented exception pattern in `packages/secrets/AGENTS.md` (`TenantKey`).\nEach `@smrt(...)` block on these two classes carries an inline comment\npointing back here.\n\n## Gotchas\n\n- **Priority waterfall**: lower priority number = higher priority in selection\n- **Weight is relative integer**: not percentage — probability calculated from total weight across variations\n- **Denormalized counts need async refresh**: impressions/clicks on AdVariation are eventually consistent\n- **No frequency capping or budget enforcement built-in**: external responsibility\n- **Targeting rules stored as JSON string**: no schema validation\n- **Optional tenancy** on `AdGroup`, `AdVariation`, `AdEvent` only — see Tenancy section above for `AdFormat`/`AdDeliveryTier` rationale\n",
3252
+ "agentDoc": "# @happyvertical/smrt-ads\n\nAd delivery with priority waterfall, weighted A/B testing, and immutable event tracking.\n\n## Models\n\n- **AdFormat**: IAB standard dimensions (width, height, type: banner/native/video)\n- **AdDeliveryTier**: priority levels — Sponsorship (1, FIXED pricing) > Standard (2, CPM) > House (3, fallback)\n- **AdGroup**: campaign with targeting, budget, zone restrictions\n- **AdVariation** (STI): creative variant with weighted selection for A/B. `weight=2` is 2x more likely than `weight=1`. Denormalized `impressions`/`clicks` fields.\n- **AdEvent** (STI, immutable): impression/click/conversion tracking. **Create-only** — no update/delete in API/MCP. `cli: false` (high-volume).\n- **Recipe `ads.campaigns`** (`src/recipes.ts`, help in `src/campaigns.recipe.md`): lists ad campaigns, ads, ad sizes and priority tiers for the planner and other catalog hosts; `AdEvent` is left out (append-only serving log, nothing a person opens). Fields it shows carry `@field({ description })` in plain words; keep them when editing the models.\n\n## Cross-Package References (all plain string IDs)\n\n`contractId` → smrt-commerce `SalesContract`, `zoneId`/`siteId` → smrt-properties, `assetId` → smrt-assets, `verticalSlug` → smrt-tags\n\n## Tenancy\n\nOptional tenancy via `@TenantScoped({ mode: 'optional' })` is applied to the\nthree transactional models — `AdGroup`, `AdVariation`, and `AdEvent` — which\nparticipate in per-tenant ad serving and event tracking.\n\n`AdFormat` and `AdDeliveryTier` are deliberately **NOT** tenant-scoped: they\nare shared catalog/lookup tables.\n\n- `AdFormat` rows describe IAB standard ad dimensions (e.g. `728x90`\n Leaderboard, `300x250` Medium Rectangle). The dimensions are an industry\n standard, not a tenant-specific configuration.\n- `AdDeliveryTier` rows describe the priority waterfall for ad selection\n (Sponsorship → Standard → House). Tiers are part of the package's\n ad-serving contract; per-tenant tier definitions would fragment the\n selection algorithm without a clear use case.\n\nEither model can still be filtered by tenant manually if a deployment ever\nneeds tenant-specific overrides, but the default is global. This mirrors the\ndocumented exception pattern in `packages/secrets/AGENTS.md` (`TenantKey`).\nEach `@smrt(...)` block on these two classes carries an inline comment\npointing back here.\n\n## Gotchas\n\n- **Priority waterfall**: lower priority number = higher priority in selection\n- **Weight is relative integer**: not percentage — probability calculated from total weight across variations\n- **Denormalized counts need async refresh**: impressions/clicks on AdVariation are eventually consistent\n- **No frequency capping or budget enforcement built-in**: external responsibility\n- **Targeting rules stored as JSON string**: no schema validation\n- **Optional tenancy** on `AdGroup`, `AdVariation`, `AdEvent` only — see Tenancy section above for `AdFormat`/`AdDeliveryTier` rationale\n",
3253
+ "recipes": [
3254
+ {
3255
+ "id": "ads.campaigns",
3256
+ "className": "AdsCampaignsRecipe",
3257
+ "label": "Ads",
3258
+ "summary": "Run ad campaigns on your site, choose which ads show where, and see which ones get clicked.",
3259
+ "synonyms": [
3260
+ "ads",
3261
+ "advertising",
3262
+ "ad campaigns",
3263
+ "banner ads",
3264
+ "advertisements",
3265
+ "display ads"
3266
+ ],
3267
+ "models": [
3268
+ "@happyvertical/smrt-ads:AdGroup",
3269
+ "@happyvertical/smrt-ads:AdVariation",
3270
+ "@happyvertical/smrt-ads:AdFormat",
3271
+ "@happyvertical/smrt-ads:AdDeliveryTier"
3272
+ ],
3273
+ "nav": [
3274
+ {
3275
+ "label": "Ad campaigns",
3276
+ "model": "@happyvertical/smrt-ads:AdGroup",
3277
+ "icon": "tag",
3278
+ "description": "Each campaign you run, with its dates, budget and where it stands.",
3279
+ "noun": "ad campaign"
3280
+ },
3281
+ {
3282
+ "label": "Ads",
3283
+ "model": "@happyvertical/smrt-ads:AdVariation",
3284
+ "icon": "fileText",
3285
+ "description": "The ads inside each campaign, how often each shows and how many clicks it got.",
3286
+ "noun": "ad"
3287
+ },
3288
+ {
3289
+ "label": "Ad sizes",
3290
+ "model": "@happyvertical/smrt-ads:AdFormat",
3291
+ "icon": "layers",
3292
+ "description": "The shapes and sizes an ad can be, shared by every campaign.",
3293
+ "noun": "ad size"
3294
+ },
3295
+ {
3296
+ "label": "Priority tiers",
3297
+ "model": "@happyvertical/smrt-ads:AdDeliveryTier",
3298
+ "icon": "settings",
3299
+ "description": "The order campaigns are tried in when more than one could show.",
3300
+ "noun": "tier"
3301
+ }
3302
+ ],
3303
+ "requires": [],
3304
+ "section": {
3305
+ "id": "grow",
3306
+ "label": "Grow",
3307
+ "icon": "tag",
3308
+ "description": "Bring in new customers and reward the people who help."
3309
+ },
3310
+ "options": {
3311
+ "@happyvertical/smrt-ads:AdGroup": {
3312
+ "fields": {
3313
+ "name": {
3314
+ "order": 1
3315
+ },
3316
+ "status": {
3317
+ "order": 2
3318
+ },
3319
+ "tierId": {
3320
+ "label": "Priority tier",
3321
+ "order": 3
3322
+ },
3323
+ "startDate": {
3324
+ "label": "Starts on",
3325
+ "order": 4
3326
+ },
3327
+ "endDate": {
3328
+ "label": "Ends on",
3329
+ "order": 5
3330
+ },
3331
+ "dailyBudget": {
3332
+ "label": "Daily budget",
3333
+ "order": 6
3334
+ },
3335
+ "totalBudget": {
3336
+ "label": "Total budget",
3337
+ "order": 7
3338
+ },
3339
+ "tenantId": {
3340
+ "visibility": "hidden"
3341
+ },
3342
+ "contractId": {
3343
+ "label": "Sales contract",
3344
+ "visibility": "advanced"
3345
+ },
3346
+ "verticalSlug": {
3347
+ "label": "Category",
3348
+ "visibility": "advanced"
3349
+ },
3350
+ "targeting": {
3351
+ "visibility": "hidden"
3352
+ },
3353
+ "zoneIds": {
3354
+ "visibility": "hidden"
3355
+ }
3356
+ }
3357
+ },
3358
+ "@happyvertical/smrt-ads:AdVariation": {
3359
+ "fields": {
3360
+ "name": {
3361
+ "order": 1
3362
+ },
3363
+ "groupId": {
3364
+ "label": "Ad campaign",
3365
+ "order": 2
3366
+ },
3367
+ "formatId": {
3368
+ "label": "Ad size",
3369
+ "order": 3
3370
+ },
3371
+ "assetId": {
3372
+ "label": "Picture",
3373
+ "order": 4
3374
+ },
3375
+ "clickUrl": {
3376
+ "label": "Link to",
3377
+ "order": 5
3378
+ },
3379
+ "altText": {
3380
+ "label": "Words for the picture",
3381
+ "order": 6
3382
+ },
3383
+ "weight": {
3384
+ "order": 7
3385
+ },
3386
+ "status": {
3387
+ "order": 8
3388
+ },
3389
+ "tenantId": {
3390
+ "visibility": "hidden"
3391
+ },
3392
+ "impressions": {
3393
+ "label": "Times shown",
3394
+ "locked": true,
3395
+ "visibility": "advanced"
3396
+ },
3397
+ "clicks": {
3398
+ "locked": true,
3399
+ "visibility": "advanced"
3400
+ }
3401
+ }
3402
+ },
3403
+ "@happyvertical/smrt-ads:AdFormat": {
3404
+ "fields": {
3405
+ "name": {
3406
+ "order": 1
3407
+ },
3408
+ "width": {
3409
+ "order": 2
3410
+ },
3411
+ "height": {
3412
+ "order": 3
3413
+ },
3414
+ "formatType": {
3415
+ "label": "Kind",
3416
+ "order": 4
3417
+ },
3418
+ "description": {
3419
+ "order": 5
3420
+ }
3421
+ }
3422
+ },
3423
+ "@happyvertical/smrt-ads:AdDeliveryTier": {
3424
+ "fields": {
3425
+ "name": {
3426
+ "order": 1
3427
+ },
3428
+ "priority": {
3429
+ "order": 2
3430
+ },
3431
+ "pricingModel": {
3432
+ "label": "How it is charged",
3433
+ "order": 3
3434
+ },
3435
+ "description": {
3436
+ "order": 4
3437
+ }
3438
+ }
3439
+ }
3440
+ },
3441
+ "help": {
3442
+ "markdown": "## Overview\n\nAds is where you run advertising on your own site. An ad campaign sets the\ndates, the budget and the priority tier; the ads inside it are the pictures\npeople actually see, each with a link. When a campaign has more than one ad,\nthe app shares the showings between them by weight, so you can try two\nversions and see which gets more clicks.\n\nAd sizes and priority tiers are shared lists. Set them up once; every campaign\npicks from them. When more than one campaign could show in the same place, the\ntier decides which is tried first.\n\nThe app counts every showing and click as it serves the ads. Those counts are\nrefreshed on the ad a little later; you read them, you do not type them.\n\n## Tasks\n\n### Add an ad size\n\n1. Open the ad sizes and choose **New**.\n2. Type the **{field:AdFormat.name}**, for example \"Leaderboard\".\n3. Enter the **{field:AdFormat.width}** and **{field:AdFormat.height}**.\n4. Pick the **{field:AdFormat.formatType}**: a picture, a piece written to look like your own content, or a video.\n5. Save. The usual sizes are 728 by 90, 300 by 250 and 320 by 50.\n\n### Set up the priority tiers\n\n1. Open the priority tiers and choose **New**.\n2. Type the **{field:AdDeliveryTier.name}**, for example \"Sponsorship\", \"Standard\" or \"House\".\n3. Set the **{field:AdDeliveryTier.priority}**: 1 is tried first, then 2, then 3.\n4. Pick **{field:AdDeliveryTier.pricingModel}** to say how ads in this tier are charged.\n5. Save. A \"House\" tier with the last priority is a good place for your own ads, so something always shows.\n\n### Start an ad campaign\n\n1. Open the ad campaigns and choose **New**.\n2. Type the **{field:AdGroup.name}**, for example \"Summer sale\".\n3. Pick the **{field:AdGroup.tierId}** it runs in.\n4. Set when it **{field:AdGroup.startDate}** and **{field:AdGroup.endDate}**.\n5. Enter the **{field:AdGroup.dailyBudget}** and the **{field:AdGroup.totalBudget}**. The app does not stop a campaign at its budget by itself; keep an eye on the counts.\n6. Leave the **{field:AdGroup.status}** as draft until the ads are ready, then set it to active.\n7. Save.\n\n### Add an ad to a campaign\n\n1. Open the ads and choose **New**.\n2. Type the **{field:AdVariation.name}**, for example \"Version A, blue button\".\n3. Pick the **{field:AdVariation.groupId}** it belongs to and the **{field:AdVariation.formatId}** it is made for.\n4. Choose the **{field:AdVariation.assetId}** people will see.\n5. Enter the web address it should **{field:AdVariation.clickUrl}** when someone taps it.\n6. Write a few **{field:AdVariation.altText}** for people who cannot see the picture.\n7. Set the **{field:AdVariation.weight}**. An ad with weight 2 shows twice as often as one with weight 1 in the same campaign.\n8. Set the **{field:AdVariation.status}** to active when it is ready to show.\n9. Save.\n\n### Pause or finish a campaign\n\n1. Open the ad campaign.\n2. Change the **{field:AdGroup.status}** to paused to stop it for now, or to completed when it is over.\n3. Save. The ads in it stop showing straight away.\n\n### See which ad is doing better\n\n1. Open the ads and find the ads in one campaign.\n2. Compare the **{field:AdVariation.impressions}** and **{field:AdVariation.clicks}** of each. These are counted by the app as it serves the ads and refreshed a little later.\n3. Give the better ad a higher **{field:AdVariation.weight}**, or pause the weaker one by changing its **{field:AdVariation.status}**.\n",
3443
+ "fieldRefs": [
3444
+ "AdDeliveryTier.name",
3445
+ "AdDeliveryTier.pricingModel",
3446
+ "AdDeliveryTier.priority",
3447
+ "AdFormat.formatType",
3448
+ "AdFormat.height",
3449
+ "AdFormat.name",
3450
+ "AdFormat.width",
3451
+ "AdGroup.dailyBudget",
3452
+ "AdGroup.endDate",
3453
+ "AdGroup.name",
3454
+ "AdGroup.startDate",
3455
+ "AdGroup.status",
3456
+ "AdGroup.tierId",
3457
+ "AdGroup.totalBudget",
3458
+ "AdVariation.altText",
3459
+ "AdVariation.assetId",
3460
+ "AdVariation.clickUrl",
3461
+ "AdVariation.clicks",
3462
+ "AdVariation.formatId",
3463
+ "AdVariation.groupId",
3464
+ "AdVariation.impressions",
3465
+ "AdVariation.name",
3466
+ "AdVariation.status",
3467
+ "AdVariation.weight"
3468
+ ]
3469
+ },
3470
+ "demo": {
3471
+ "mode": "server",
3472
+ "reasons": [
3473
+ "Needs a server because its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624)."
3474
+ ]
3475
+ }
3476
+ }
3477
+ ],
3225
3478
  "browser": {
3226
3479
  "status": "server-only",
3227
3480
  "issues": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-ads",
3
- "version": "0.57.36",
3
+ "version": "0.57.38",
4
4
  "description": "Advertising delivery and tracking models for SMRT framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,13 +19,13 @@
19
19
  "./manifest.json": "./dist/manifest.json"
20
20
  },
21
21
  "dependencies": {
22
- "@happyvertical/smrt-core": "0.57.36",
23
- "@happyvertical/smrt-tenancy": "0.57.36"
22
+ "@happyvertical/smrt-core": "0.57.38",
23
+ "@happyvertical/smrt-tenancy": "0.57.38"
24
24
  },
25
25
  "devDependencies": {
26
- "@happyvertical/smrt-commerce": "0.57.36",
27
- "@happyvertical/smrt-vitest": "0.57.36",
28
- "@happyvertical/sql": "^0.109.0",
26
+ "@happyvertical/smrt-commerce": "0.57.38",
27
+ "@happyvertical/smrt-vitest": "0.57.38",
28
+ "@happyvertical/sql": "^0.110.0",
29
29
  "@types/node": "24.13.6",
30
30
  "typescript": "6.0.3",
31
31
  "vite": "8.1.6",