@happyvertical/smrt-ads 0.57.38 → 0.57.40

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["AdFormatType","PricingModel","AdGroupStatus","AdVariationStatus","AdEventType"],"sources":["../src/__smrt-register__.ts","../src/types/index.ts","../src/models/AdDeliveryTier.ts","../src/collections/AdDeliveryTierCollection.ts","../src/models/AdEvent.ts","../src/collections/AdEventCollection.ts","../src/models/AdFormat.ts","../src/collections/AdFormatCollection.ts","../src/models/AdGroup.ts","../src/collections/AdGroupCollection.ts","../src/models/AdVariation.ts","../src/collections/AdVariationCollection.ts","../src/recipes.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"packageVersion\\\":\\\"0.57.38\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-ads:AdDeliveryTierCollection\\\":{\\\"name\\\":\\\"addeliverytiercollection\\\",\\\"className\\\":\\\"AdDeliveryTierCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdDeliveryTierCollection\\\",\\\"collection\\\":\\\"addeliverytiers\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdDeliveryTierCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByPriority\\\":{\\\"name\\\":\\\"findByPriority\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByPricingModel\\\":{\\\"name\\\":\\\"findByPricingModel\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"pricingModel\\\",\\\"type\\\":\\\"PricingModel\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getHighestPriority\\\":{\\\"name\\\":\\\"getHighestPriority\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findFixedPricing\\\":{\\\"name\\\":\\\"findFixedPricing\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findCPM\\\":{\\\"name\\\":\\\"findCPM\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findPerformanceBased\\\":{\\\"name\\\":\\\"findPerformanceBased\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdDeliveryTier\\\",\\\"exportName\\\":\\\"AdDeliveryTierCollection\\\",\\\"collectionExportName\\\":\\\"AdDeliveryTierCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_delivery_tiers\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_delivery_tiers\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"priority\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"pricing_model\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"priority\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"pricing_model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_delivery_tiers_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"ad_delivery_tiers_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"df0ec0ff\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdEventCollection\\\":{\\\"name\\\":\\\"adeventcollection\\\",\\\"className\\\":\\\"AdEventCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdEventCollection\\\",\\\"collection\\\":\\\"adevents\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdEventCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByVariation\\\":{\\\"name\\\":\\\"findByVariation\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByZone\\\":{\\\"name\\\":\\\"findByZone\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findBySite\\\":{\\\"name\\\":\\\"findBySite\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"siteId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByDateRange\\\":{\\\"name\\\":\\\"findByDateRange\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"start\\\",\\\"type\\\":\\\"Date\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"end\\\",\\\"type\\\":\\\"Date\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"eventType\\\",\\\"type\\\":\\\"AdEventType\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countByType\\\":{\\\"name\\\":\\\"countByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"eventType\\\",\\\"type\\\":\\\"AdEventType\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countImpressions\\\":{\\\"name\\\":\\\"countImpressions\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countClicks\\\":{\\\"name\\\":\\\"countClicks\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countConversions\\\":{\\\"name\\\":\\\"countConversions\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findImpressions\\\":{\\\"name\\\":\\\"findImpressions\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findClicks\\\":{\\\"name\\\":\\\"findClicks\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findConversions\\\":{\\\"name\\\":\\\"findConversions\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getVariationStats\\\":{\\\"name\\\":\\\"getVariationStats\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<object>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTenant\\\":{\\\"name\\\":\\\"findByTenant\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findGlobal\\\":{\\\"name\\\":\\\"findGlobal\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findWithGlobals\\\":{\\\"name\\\":\\\"findWithGlobals\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"create\\\",\\\"list\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"create\\\"]},\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdEvent\\\",\\\"exportName\\\":\\\"AdEventCollection\\\",\\\"collectionExportName\\\":\\\"AdEventCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_events\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_events\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"variation_id\\\\\\\" UUID,\\\\n \\\\\\\"zone_id\\\\\\\" UUID,\\\\n \\\\\\\"site_id\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"event_type\\\\\\\" TEXT,\\\\n \\\\\\\"timestamp\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"metadata\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"variation_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_variations\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"zone_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"site_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"event_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"timestamp\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"metadata\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_events_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_events_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_events_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_events_variation_id_idx\\\",\\\"columns\\\":[\\\"variation_id\\\"]},{\\\"name\\\":\\\"ad_events_zone_id_idx\\\",\\\"columns\\\":[\\\"zone_id\\\"]}],\\\"version\\\":\\\"306d8050\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdFormatCollection\\\":{\\\"name\\\":\\\"adformatcollection\\\",\\\"className\\\":\\\"AdFormatCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdFormatCollection\\\",\\\"collection\\\":\\\"adformats\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdFormatCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByDimensions\\\":{\\\"name\\\":\\\"findByDimensions\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"width\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"height\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdFormat | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"formatType\\\",\\\"type\\\":\\\"AdFormatType\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdFormat[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findBanners\\\":{\\\"name\\\":\\\"findBanners\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdFormat[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findNative\\\":{\\\"name\\\":\\\"findNative\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdFormat[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findVideo\\\":{\\\"name\\\":\\\"findVideo\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdFormat[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdFormat\\\",\\\"exportName\\\":\\\"AdFormatCollection\\\",\\\"collectionExportName\\\":\\\"AdFormatCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_formats\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_formats\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"width\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"height\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"format_type\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"width\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"height\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"format_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_formats_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"ad_formats_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"df40cc03\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdGroupCollection\\\":{\\\"name\\\":\\\"adgroupcollection\\\",\\\"className\\\":\\\"AdGroupCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdGroupCollection\\\",\\\"collection\\\":\\\"adgroups\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdGroupCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByContract\\\":{\\\"name\\\":\\\"findByContract\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"contractId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTier\\\":{\\\"name\\\":\\\"findByTier\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tierId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByStatus\\\":{\\\"name\\\":\\\"findByStatus\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"status\\\",\\\"type\\\":\\\"AdGroupStatus\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findActive\\\":{\\\"name\\\":\\\"findActive\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByVertical\\\":{\\\"name\\\":\\\"findByVertical\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"verticalSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByZone\\\":{\\\"name\\\":\\\"findByZone\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findEligibleForZone\\\":{\\\"name\\\":\\\"findEligibleForZone\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findDrafts\\\":{\\\"name\\\":\\\"findDrafts\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findPaused\\\":{\\\"name\\\":\\\"findPaused\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findCompleted\\\":{\\\"name\\\":\\\"findCompleted\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTenant\\\":{\\\"name\\\":\\\"findByTenant\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findGlobal\\\":{\\\"name\\\":\\\"findGlobal\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findWithGlobals\\\":{\\\"name\\\":\\\"findWithGlobals\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\"]}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdGroup\\\",\\\"exportName\\\":\\\"AdGroupCollection\\\",\\\"collectionExportName\\\":\\\"AdGroupCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_groups\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_groups\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"contract_id\\\\\\\" UUID,\\\\n \\\\\\\"tier_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"vertical_slug\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"targeting\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"zone_ids\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"start_date\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"end_date\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"daily_budget\\\\\\\" REAL DEFAULT 0,\\\\n \\\\\\\"total_budget\\\\\\\" REAL DEFAULT 0,\\\\n \\\\\\\"status\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"contract_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"tier_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_delivery_tiers\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"vertical_slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"targeting\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"zone_ids\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"start_date\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"end_date\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"daily_budget\\\":{\\\"type\\\":\\\"REAL\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"total_budget\\\":{\\\"type\\\":\\\"REAL\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_groups_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_groups_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_groups_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_groups_contract_id_idx\\\",\\\"columns\\\":[\\\"contract_id\\\"]},{\\\"name\\\":\\\"ad_groups_tier_id_idx\\\",\\\"columns\\\":[\\\"tier_id\\\"]}],\\\"version\\\":\\\"3f8a3fea\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdVariationCollection\\\":{\\\"name\\\":\\\"advariationcollection\\\",\\\"className\\\":\\\"AdVariationCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdVariationCollection\\\",\\\"collection\\\":\\\"advariations\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdVariationCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByGroup\\\":{\\\"name\\\":\\\"findByGroup\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"groupId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByFormat\\\":{\\\"name\\\":\\\"findByFormat\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"formatId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findActiveByGroup\\\":{\\\"name\\\":\\\"findActiveByGroup\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"groupId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"selectByWeight\\\":{\\\"name\\\":\\\"selectByWeight\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"groupId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByStatus\\\":{\\\"name\\\":\\\"findByStatus\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"status\\\",\\\"type\\\":\\\"AdVariationStatus\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findActive\\\":{\\\"name\\\":\\\"findActive\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findDrafts\\\":{\\\"name\\\":\\\"findDrafts\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findPaused\\\":{\\\"name\\\":\\\"findPaused\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findTopPerformers\\\":{\\\"name\\\":\\\"findTopPerformers\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"limit\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTenant\\\":{\\\"name\\\":\\\"findByTenant\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findGlobal\\\":{\\\"name\\\":\\\"findGlobal\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findWithGlobals\\\":{\\\"name\\\":\\\"findWithGlobals\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\"]}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdVariation\\\",\\\"exportName\\\":\\\"AdVariationCollection\\\",\\\"collectionExportName\\\":\\\"AdVariationCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_variations\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_variations\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"group_id\\\\\\\" UUID,\\\\n \\\\\\\"format_id\\\\\\\" UUID,\\\\n \\\\\\\"asset_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"click_url\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"alt_text\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"weight\\\\\\\" INTEGER DEFAULT 1,\\\\n \\\\\\\"status\\\\\\\" TEXT,\\\\n \\\\\\\"impressions\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"clicks\\\\\\\" INTEGER DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"group_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_groups\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"format_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_formats\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"asset_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"click_url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"alt_text\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"weight\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":1},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"impressions\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"clicks\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_variations_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_variations_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_variations_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_variations_group_id_idx\\\",\\\"columns\\\":[\\\"group_id\\\"]},{\\\"name\\\":\\\"ad_variations_format_id_idx\\\",\\\"columns\\\":[\\\"format_id\\\"]},{\\\"name\\\":\\\"ad_variations_asset_id_idx\\\",\\\"columns\\\":[\\\"asset_id\\\"]}],\\\"version\\\":\\\"e8fb6233\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\":{\\\"name\\\":\\\"addeliverytier\\\",\\\"className\\\":\\\"AdDeliveryTier\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\",\\\"collection\\\":\\\"addeliverytiers\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdDeliveryTier.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"What the tier is called, for example Sponsorship, Standard or House.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What the tier is called, for example Sponsorship, Standard or House.\\\"}},\\\"priority\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"The order tiers are tried in: 1 is tried first, then 2, and so on.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The order tiers are tried in: 1 is tried first, then 2, and so on.\\\"}},\\\"pricingModel\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"description\\\":\\\"How ads in this tier are charged: a fixed price, per thousand showings, per click, or per sale.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How ads in this tier are charged: a fixed price, per thousand showings, per click, or per sale.\\\"},\\\"enum\\\":[\\\"fixed\\\",\\\"cpm\\\",\\\"cpc\\\",\\\"cpa\\\"]},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"A note about what this tier is for.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"A note about what this tier is for.\\\"}}},\\\"methods\\\":{\\\"isHigherPriorityThan\\\":{\\\"name\\\":\\\"isHigherPriorityThan\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"other\\\",\\\"type\\\":\\\"AdDeliveryTier\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isFixedPricing\\\":{\\\"name\\\":\\\"isFixedPricing\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isPerformanceBased\\\":{\\\"name\\\":\\\"isPerformanceBased\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdDeliveryTier\\\",\\\"collectionExportName\\\":\\\"AdDeliveryTierCollection\\\",\\\"displayLabelField\\\":\\\"name\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_delivery_tiers\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_delivery_tiers\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"priority\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"pricing_model\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"priority\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"pricing_model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_delivery_tiers_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"ad_delivery_tiers_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"df0ec0ff\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdEvent\\\":{\\\"name\\\":\\\"adevent\\\",\\\"className\\\":\\\"AdEvent\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdEvent\\\",\\\"collection\\\":\\\"adevents\\\",\\\"description\\\":\\\"AdEvent tracks ad impressions, clicks, and conversions. Events are immutable (append-only, no update/delete).\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdEvent.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"variationId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AdVariation\\\"},\\\"zoneId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-properties:Zone\\\"},\\\"siteId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"eventType\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"enum\\\":[\\\"impression\\\",\\\"click\\\",\\\"conversion\\\"]},\\\"timestamp\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"metadata\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"}},\\\"methods\\\":{\\\"getMetadata\\\":{\\\"name\\\":\\\"getMetadata\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Record<string, unknown>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setMetadata\\\":{\\\"name\\\":\\\"setMetadata\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"data\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isImpression\\\":{\\\"name\\\":\\\"isImpression\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isClick\\\":{\\\"name\\\":\\\"isClick\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isConversion\\\":{\\\"name\\\":\\\"isConversion\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"create\\\",\\\"list\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"create\\\"]},\\\"cli\\\":false,\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdEvent\\\",\\\"collectionExportName\\\":\\\"AdEventCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_events\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_events\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"variation_id\\\\\\\" UUID,\\\\n \\\\\\\"zone_id\\\\\\\" UUID,\\\\n \\\\\\\"site_id\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"event_type\\\\\\\" TEXT,\\\\n \\\\\\\"timestamp\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"metadata\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"variation_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_variations\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"zone_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"site_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"event_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"timestamp\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"metadata\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_events_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_events_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_events_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_events_variation_id_idx\\\",\\\"columns\\\":[\\\"variation_id\\\"]},{\\\"name\\\":\\\"ad_events_zone_id_idx\\\",\\\"columns\\\":[\\\"zone_id\\\"]}],\\\"version\\\":\\\"306d8050\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdFormat\\\":{\\\"name\\\":\\\"adformat\\\",\\\"className\\\":\\\"AdFormat\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdFormat\\\",\\\"collection\\\":\\\"adformats\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdFormat.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"What the size is called, for example Leaderboard.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What the size is called, for example Leaderboard.\\\"}},\\\"width\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"How wide the ad is, in pixels.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How wide the ad is, in pixels.\\\"}},\\\"height\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"How tall the ad is, in pixels.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How tall the ad is, in pixels.\\\"}},\\\"formatType\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"description\\\":\\\"What kind of ad fits this size: a picture, a piece written to look like your own content, or a video.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What kind of ad fits this size: a picture, a piece written to look like your own content, or a video.\\\"},\\\"enum\\\":[\\\"banner\\\",\\\"native\\\",\\\"video\\\"]},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"A note about where this size is usually used.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"A note about where this size is usually used.\\\"}}},\\\"methods\\\":{\\\"getDimensions\\\":{\\\"name\\\":\\\"getDimensions\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"string\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"matchesDimensions\\\":{\\\"name\\\":\\\"matchesDimensions\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"width\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"height\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdFormat\\\",\\\"collectionExportName\\\":\\\"AdFormatCollection\\\",\\\"displayLabelField\\\":\\\"name\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_formats\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_formats\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"width\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"height\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"format_type\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"width\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"height\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"format_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_formats_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"ad_formats_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"df40cc03\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdGroup\\\":{\\\"name\\\":\\\"adgroup\\\",\\\"className\\\":\\\"AdGroup\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdGroup\\\",\\\"collection\\\":\\\"adgroups\\\",\\\"description\\\":\\\"AdGroup organizes ad creatives with targeting and budget controls.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdGroup.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"contractId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-commerce:SalesContract\\\",\\\"description\\\":\\\"The sales contract this campaign is sold under, if there is one.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The sales contract this campaign is sold under, if there is one.\\\",\\\"validateSubtype\\\":true}},\\\"tierId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AdDeliveryTier\\\",\\\"description\\\":\\\"The priority tier the campaign runs in. Tiers are tried in order when more than one campaign could show.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The priority tier the campaign runs in. Tiers are tried in order when more than one campaign could show.\\\"}},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"What you call the campaign, for example Summer sale.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What you call the campaign, for example Summer sale.\\\"}},\\\"verticalSlug\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"The category the campaign belongs to, such as retail.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The category the campaign belongs to, such as retail.\\\"}},\\\"targeting\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"zoneIds\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"startDate\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false,\\\"description\\\":\\\"The first day the campaign can show.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The first day the campaign can show.\\\"}},\\\"endDate\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false,\\\"description\\\":\\\"The last day the campaign can show.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The last day the campaign can show.\\\"}},\\\"dailyBudget\\\":{\\\"type\\\":\\\"decimal\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"The most to spend in one day. The app shows this but does not stop the campaign by itself.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The most to spend in one day. The app shows this but does not stop the campaign by itself.\\\"}},\\\"totalBudget\\\":{\\\"type\\\":\\\"decimal\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"The most to spend over the whole campaign.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The most to spend over the whole campaign.\\\"}},\\\"status\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"description\\\":\\\"Where the campaign stands: draft, active, paused or completed. Only active campaigns show ads.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"Where the campaign stands: draft, active, paused or completed. Only active campaigns show ads.\\\"},\\\"enum\\\":[\\\"draft\\\",\\\"active\\\",\\\"paused\\\",\\\"completed\\\"]}},\\\"methods\\\":{\\\"getZoneIds\\\":{\\\"name\\\":\\\"getZoneIds\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"string[]\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setZoneIds\\\":{\\\"name\\\":\\\"setZoneIds\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"ids\\\",\\\"type\\\":\\\"string[]\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addZoneId\\\":{\\\"name\\\":\\\"addZoneId\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeZoneId\\\":{\\\"name\\\":\\\"removeZoneId\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"hasZoneId\\\":{\\\"name\\\":\\\"hasZoneId\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTargeting\\\":{\\\"name\\\":\\\"getTargeting\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Record<string, unknown>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setTargeting\\\":{\\\"name\\\":\\\"setTargeting\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"rules\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isActive\\\":{\\\"name\\\":\\\"isActive\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isDraft\\\":{\\\"name\\\":\\\"isDraft\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isPaused\\\":{\\\"name\\\":\\\"isPaused\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isCompleted\\\":{\\\"name\\\":\\\"isCompleted\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"hasEnded\\\":{\\\"name\\\":\\\"hasEnded\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"hasStarted\\\":{\\\"name\\\":\\\"hasStarted\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdGroup\\\",\\\"collectionExportName\\\":\\\"AdGroupCollection\\\",\\\"displayLabelField\\\":\\\"name\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_groups\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_groups\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"contract_id\\\\\\\" UUID,\\\\n \\\\\\\"tier_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"vertical_slug\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"targeting\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"zone_ids\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"start_date\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"end_date\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"daily_budget\\\\\\\" REAL DEFAULT 0,\\\\n \\\\\\\"total_budget\\\\\\\" REAL DEFAULT 0,\\\\n \\\\\\\"status\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"contract_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"tier_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_delivery_tiers\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"vertical_slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"targeting\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"zone_ids\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"start_date\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"end_date\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"daily_budget\\\":{\\\"type\\\":\\\"REAL\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"total_budget\\\":{\\\"type\\\":\\\"REAL\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_groups_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_groups_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_groups_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_groups_contract_id_idx\\\",\\\"columns\\\":[\\\"contract_id\\\"]},{\\\"name\\\":\\\"ad_groups_tier_id_idx\\\",\\\"columns\\\":[\\\"tier_id\\\"]}],\\\"version\\\":\\\"3f8a3fea\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdVariation\\\":{\\\"name\\\":\\\"advariation\\\",\\\"className\\\":\\\"AdVariation\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdVariation\\\",\\\"collection\\\":\\\"advariations\\\",\\\"description\\\":\\\"AdVariation represents a creative asset within an ad group. Supports A/B testing via weighted selection.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdVariation.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"groupId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AdGroup\\\",\\\"description\\\":\\\"The campaign this ad belongs to.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The campaign this ad belongs to.\\\"}},\\\"formatId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AdFormat\\\",\\\"description\\\":\\\"The ad size this ad is made for.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The ad size this ad is made for.\\\"}},\\\"assetId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-assets:Asset\\\",\\\"description\\\":\\\"The picture people see.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The picture people see.\\\"}},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"What you call this ad, for example Version A, blue button.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What you call this ad, for example Version A, blue button.\\\"}},\\\"clickUrl\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"The web address people go to when they tap the ad.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The web address people go to when they tap the ad.\\\"}},\\\"altText\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"A few words that describe the picture for people who cannot see it.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"A few words that describe the picture for people who cannot see it.\\\"}},\\\"weight\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":1,\\\"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.\\\",\\\"_meta\\\":{\\\"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.\\\"}},\\\"status\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"description\\\":\\\"Where the ad stands: draft, active or paused. Only active ads show.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"Where the ad stands: draft, active or paused. Only active ads show.\\\"},\\\"enum\\\":[\\\"draft\\\",\\\"active\\\",\\\"paused\\\"]},\\\"impressions\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"How many times the ad has been shown. The app counts this as it serves ads and refreshes it a little later.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How many times the ad has been shown. The app counts this as it serves ads and refreshes it a little later.\\\"}},\\\"clicks\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"How many times the ad has been tapped. The app counts this as it serves ads and refreshes it a little later.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How many times the ad has been tapped. The app counts this as it serves ads and refreshes it a little later.\\\"}}},\\\"methods\\\":{\\\"isActive\\\":{\\\"name\\\":\\\"isActive\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isDraft\\\":{\\\"name\\\":\\\"isDraft\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isPaused\\\":{\\\"name\\\":\\\"isPaused\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getCTR\\\":{\\\"name\\\":\\\"getCTR\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"number\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordImpression\\\":{\\\"name\\\":\\\"recordImpression\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordClick\\\":{\\\"name\\\":\\\"recordClick\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdVariation\\\",\\\"collectionExportName\\\":\\\"AdVariationCollection\\\",\\\"displayLabelField\\\":\\\"name\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_variations\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_variations\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"group_id\\\\\\\" UUID,\\\\n \\\\\\\"format_id\\\\\\\" UUID,\\\\n \\\\\\\"asset_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"click_url\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"alt_text\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"weight\\\\\\\" INTEGER DEFAULT 1,\\\\n \\\\\\\"status\\\\\\\" TEXT,\\\\n \\\\\\\"impressions\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"clicks\\\\\\\" INTEGER DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"group_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_groups\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"format_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_formats\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"asset_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"click_url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"alt_text\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"weight\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":1},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"impressions\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"clicks\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_variations_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_variations_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_variations_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_variations_group_id_idx\\\",\\\"columns\\\":[\\\"group_id\\\"]},{\\\"name\\\":\\\"ad_variations_format_id_idx\\\",\\\"columns\\\":[\\\"format_id\\\"]},{\\\"name\\\":\\\"ad_variations_asset_id_idx\\\",\\\"columns\\\":[\\\"asset_id\\\"]}],\\\"version\\\":\\\"e8fb6233\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"recipes\\\":[{\\\"id\\\":\\\"ads.campaigns\\\",\\\"className\\\":\\\"AdsCampaignsRecipe\\\",\\\"label\\\":\\\"Ads\\\",\\\"summary\\\":\\\"Run ad campaigns on your site, choose which ads show where, and see which ones get clicked.\\\",\\\"synonyms\\\":[\\\"ads\\\",\\\"advertising\\\",\\\"ad campaigns\\\",\\\"banner ads\\\",\\\"advertisements\\\",\\\"display ads\\\"],\\\"models\\\":[\\\"@happyvertical/smrt-ads:AdGroup\\\",\\\"@happyvertical/smrt-ads:AdVariation\\\",\\\"@happyvertical/smrt-ads:AdFormat\\\",\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\"],\\\"nav\\\":[{\\\"label\\\":\\\"Ad campaigns\\\",\\\"model\\\":\\\"@happyvertical/smrt-ads:AdGroup\\\",\\\"icon\\\":\\\"tag\\\",\\\"description\\\":\\\"Each campaign you run, with its dates, budget and where it stands.\\\",\\\"noun\\\":\\\"ad campaign\\\"},{\\\"label\\\":\\\"Ads\\\",\\\"model\\\":\\\"@happyvertical/smrt-ads:AdVariation\\\",\\\"icon\\\":\\\"fileText\\\",\\\"description\\\":\\\"The ads inside each campaign, how often each shows and how many clicks it got.\\\",\\\"noun\\\":\\\"ad\\\"},{\\\"label\\\":\\\"Ad sizes\\\",\\\"model\\\":\\\"@happyvertical/smrt-ads:AdFormat\\\",\\\"icon\\\":\\\"layers\\\",\\\"description\\\":\\\"The shapes and sizes an ad can be, shared by every campaign.\\\",\\\"noun\\\":\\\"ad size\\\"},{\\\"label\\\":\\\"Priority tiers\\\",\\\"model\\\":\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\",\\\"icon\\\":\\\"settings\\\",\\\"description\\\":\\\"The order campaigns are tried in when more than one could show.\\\",\\\"noun\\\":\\\"tier\\\"}],\\\"requires\\\":[],\\\"section\\\":{\\\"id\\\":\\\"grow\\\",\\\"label\\\":\\\"Grow\\\",\\\"icon\\\":\\\"tag\\\",\\\"description\\\":\\\"Bring in new customers and reward the people who help.\\\"},\\\"options\\\":{\\\"@happyvertical/smrt-ads:AdGroup\\\":{\\\"fields\\\":{\\\"name\\\":{\\\"order\\\":1},\\\"status\\\":{\\\"order\\\":2},\\\"tierId\\\":{\\\"label\\\":\\\"Priority tier\\\",\\\"order\\\":3},\\\"startDate\\\":{\\\"label\\\":\\\"Starts on\\\",\\\"order\\\":4},\\\"endDate\\\":{\\\"label\\\":\\\"Ends on\\\",\\\"order\\\":5},\\\"dailyBudget\\\":{\\\"label\\\":\\\"Daily budget\\\",\\\"order\\\":6},\\\"totalBudget\\\":{\\\"label\\\":\\\"Total budget\\\",\\\"order\\\":7},\\\"tenantId\\\":{\\\"visibility\\\":\\\"hidden\\\"},\\\"contractId\\\":{\\\"label\\\":\\\"Sales contract\\\",\\\"visibility\\\":\\\"advanced\\\"},\\\"verticalSlug\\\":{\\\"label\\\":\\\"Category\\\",\\\"visibility\\\":\\\"advanced\\\"},\\\"targeting\\\":{\\\"visibility\\\":\\\"hidden\\\"},\\\"zoneIds\\\":{\\\"visibility\\\":\\\"hidden\\\"}}},\\\"@happyvertical/smrt-ads:AdVariation\\\":{\\\"fields\\\":{\\\"name\\\":{\\\"order\\\":1},\\\"groupId\\\":{\\\"label\\\":\\\"Ad campaign\\\",\\\"order\\\":2},\\\"formatId\\\":{\\\"label\\\":\\\"Ad size\\\",\\\"order\\\":3},\\\"assetId\\\":{\\\"label\\\":\\\"Picture\\\",\\\"order\\\":4},\\\"clickUrl\\\":{\\\"label\\\":\\\"Link to\\\",\\\"order\\\":5},\\\"altText\\\":{\\\"label\\\":\\\"Words for the picture\\\",\\\"order\\\":6},\\\"weight\\\":{\\\"order\\\":7},\\\"status\\\":{\\\"order\\\":8},\\\"tenantId\\\":{\\\"visibility\\\":\\\"hidden\\\"},\\\"impressions\\\":{\\\"label\\\":\\\"Times shown\\\",\\\"locked\\\":true,\\\"visibility\\\":\\\"advanced\\\"},\\\"clicks\\\":{\\\"locked\\\":true,\\\"visibility\\\":\\\"advanced\\\"}}},\\\"@happyvertical/smrt-ads:AdFormat\\\":{\\\"fields\\\":{\\\"name\\\":{\\\"order\\\":1},\\\"width\\\":{\\\"order\\\":2},\\\"height\\\":{\\\"order\\\":3},\\\"formatType\\\":{\\\"label\\\":\\\"Kind\\\",\\\"order\\\":4},\\\"description\\\":{\\\"order\\\":5}}},\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\":{\\\"fields\\\":{\\\"name\\\":{\\\"order\\\":1},\\\"priority\\\":{\\\"order\\\":2},\\\"pricingModel\\\":{\\\"label\\\":\\\"How it is charged\\\",\\\"order\\\":3},\\\"description\\\":{\\\"order\\\":4}}}},\\\"help\\\":{\\\"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\\\",\\\"fieldRefs\\\":[\\\"AdDeliveryTier.name\\\",\\\"AdDeliveryTier.pricingModel\\\",\\\"AdDeliveryTier.priority\\\",\\\"AdFormat.formatType\\\",\\\"AdFormat.height\\\",\\\"AdFormat.name\\\",\\\"AdFormat.width\\\",\\\"AdGroup.dailyBudget\\\",\\\"AdGroup.endDate\\\",\\\"AdGroup.name\\\",\\\"AdGroup.startDate\\\",\\\"AdGroup.status\\\",\\\"AdGroup.tierId\\\",\\\"AdGroup.totalBudget\\\",\\\"AdVariation.altText\\\",\\\"AdVariation.assetId\\\",\\\"AdVariation.clickUrl\\\",\\\"AdVariation.clicks\\\",\\\"AdVariation.formatId\\\",\\\"AdVariation.groupId\\\",\\\"AdVariation.impressions\\\",\\\"AdVariation.name\\\",\\\"AdVariation.status\\\",\\\"AdVariation.weight\\\"]},\\\"demo\\\":{\\\"mode\\\":\\\"server\\\",\\\"reasons\\\":[\\\"Needs a server because its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624).\\\"]}}],\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-commerce\\\",\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"browser\\\":{\\\"status\\\":\\\"server-only\\\",\\\"issues\\\":[\\\"#3624\\\"],\\\"via\\\":[\\\"@happyvertical/smrt-tenancy\\\"]},\\\"stampsConstructors\\\":true}\"));\n","/**\n * Types and enums for smrt-ads package\n */\n\n/**\n * Ad format types for different creative types\n */\nexport enum AdFormatType {\n BANNER = 'banner',\n NATIVE = 'native',\n VIDEO = 'video',\n}\n\n/**\n * Pricing models for ad delivery tiers\n */\nexport enum PricingModel {\n FIXED = 'fixed',\n CPM = 'cpm',\n CPC = 'cpc',\n CPA = 'cpa',\n}\n\n/**\n * Status for ad groups\n */\nexport enum AdGroupStatus {\n DRAFT = 'draft',\n ACTIVE = 'active',\n PAUSED = 'paused',\n COMPLETED = 'completed',\n}\n\n/**\n * Status for ad variations\n */\nexport enum AdVariationStatus {\n DRAFT = 'draft',\n ACTIVE = 'active',\n PAUSED = 'paused',\n}\n\n/**\n * Event types for ad tracking\n */\nexport enum AdEventType {\n IMPRESSION = 'impression',\n CLICK = 'click',\n CONVERSION = 'conversion',\n}\n","/**\n * AdDeliveryTier model - Priority waterfall for ad selection\n * @packageDocumentation\n */\n\nimport {\n field,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { PricingModel } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdDeliveryTier}.\n */\nexport interface AdDeliveryTierOptions extends SmrtObjectOptions {\n name?: string;\n priority?: number;\n pricingModel?: PricingModel;\n description?: string;\n}\n\n/**\n * AdDeliveryTier defines priority levels for ad serving.\n *\n * Ads are selected by priority (lower = higher priority):\n * 1. Sponsorship - Guaranteed, premium placements\n * 2. Standard - Regular programmatic ads\n * 3. House - Self-promotional/fallback ads\n *\n * @example\n * ```typescript\n * const sponsorship = await tiers.create({\n * name: 'Sponsorship',\n * priority: 1,\n * pricingModel: PricingModel.FIXED,\n * description: 'Premium guaranteed placements'\n * });\n * ```\n */\n// Intentional exception to standards.md §7 (`@TenantScoped`):\n// `AdDeliveryTier` is a shared catalog model describing the priority waterfall\n// for ad selection (Sponsorship → Standard → House). Tier definitions are part\n// of the package's ad-serving contract, not per-tenant configuration. Adding\n// `@TenantScoped` would require every tenant to seed the same three rows and\n// would fragment the selection algorithm without a clear use case. See\n// `packages/ads/CLAUDE.md` \"Tenancy\" section for context.\n@smrt({\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get'] },\n cli: { skipApiCheck: true },\n})\nexport class AdDeliveryTier extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Display name (e.g., \"Sponsorship\", \"Standard\", \"House\")\n */\n @field({\n description:\n 'What the tier is called, for example Sponsorship, Standard or House.',\n })\n name: string = '';\n\n /**\n * Priority level (lower = higher priority: 1, 2, 3...)\n */\n @field({\n description:\n 'The order tiers are tried in: 1 is tried first, then 2, and so on.',\n })\n priority: number = 0;\n\n /**\n * Pricing model for this tier\n */\n @field({\n description:\n 'How ads in this tier are charged: a fixed price, per thousand showings, per click, or per sale.',\n })\n pricingModel: PricingModel = PricingModel.CPM;\n\n /**\n * Optional description\n */\n @field({ description: 'A note about what this tier is for.' })\n description: string = '';\n\n constructor(options: AdDeliveryTierOptions = {}) {\n super(options);\n if (options.name !== undefined) this.name = options.name;\n if (options.priority !== undefined) this.priority = options.priority;\n if (options.pricingModel !== undefined)\n this.pricingModel = options.pricingModel;\n if (options.description !== undefined)\n this.description = options.description;\n }\n\n /**\n * Check if this tier is higher priority than another\n */\n isHigherPriorityThan(other: AdDeliveryTier): boolean {\n return this.priority < other.priority;\n }\n\n /**\n * Check if this is a fixed pricing tier\n */\n isFixedPricing(): boolean {\n return this.pricingModel === PricingModel.FIXED;\n }\n\n /**\n * Check if this is a performance-based tier (CPC, CPA)\n */\n isPerformanceBased(): boolean {\n return (\n this.pricingModel === PricingModel.CPC ||\n this.pricingModel === PricingModel.CPA\n );\n }\n}\n\nexport default AdDeliveryTier;\n","/**\n * AdDeliveryTierCollection - Collection manager for AdDeliveryTier objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { AdDeliveryTier } from '../models/AdDeliveryTier.js';\nimport { PricingModel } from '../types/index.js';\n\nexport class AdDeliveryTierCollection extends SmrtCollection<AdDeliveryTier> {\n static readonly _itemClass = AdDeliveryTier;\n\n /**\n * Find tiers ordered by priority (ascending, lower = higher priority)\n *\n * @returns Array of tiers ordered by priority\n */\n async findByPriority(): Promise<AdDeliveryTier[]> {\n return await this.list({\n orderBy: 'priority ASC',\n });\n }\n\n /**\n * Find tiers by pricing model\n *\n * @param pricingModel - Pricing model to filter by\n * @returns Array of matching tiers\n */\n async findByPricingModel(\n pricingModel: PricingModel,\n ): Promise<AdDeliveryTier[]> {\n return await this.list({\n where: { pricingModel },\n orderBy: 'priority ASC',\n });\n }\n\n /**\n * Get the highest priority tier\n *\n * @returns Highest priority tier or null\n */\n async getHighestPriority(): Promise<AdDeliveryTier | null> {\n const results = await this.list({\n orderBy: 'priority ASC',\n limit: 1,\n });\n return results.length > 0 ? results[0] : null;\n }\n\n /**\n * Find fixed pricing tiers\n */\n async findFixedPricing(): Promise<AdDeliveryTier[]> {\n return await this.findByPricingModel(PricingModel.FIXED);\n }\n\n /**\n * Find CPM-based tiers\n */\n async findCPM(): Promise<AdDeliveryTier[]> {\n return await this.findByPricingModel(PricingModel.CPM);\n }\n\n /**\n * Find performance-based tiers (CPC, CPA)\n */\n async findPerformanceBased(): Promise<AdDeliveryTier[]> {\n const cpc = await this.findByPricingModel(PricingModel.CPC);\n const cpa = await this.findByPricingModel(PricingModel.CPA);\n return [...cpc, ...cpa].sort((a, b) => a.priority - b.priority);\n }\n}\n","/**\n * AdEvent model - Immutable event tracking (impressions, clicks)\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { AdEventType } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdEvent}.\n */\nexport interface AdEventOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n variationId?: string;\n zoneId?: string;\n siteId?: string;\n eventType?: AdEventType;\n timestamp?: Date;\n metadata?: string;\n}\n\n/**\n * AdEvent tracks ad impressions, clicks, and conversions.\n * Events are immutable (append-only, no update/delete).\n *\n * References:\n * - variationId: FK to AdVariation (within package)\n * - zoneId: String reference to smrt-properties Zone (cross-package)\n * - siteId: Denormalized for query efficiency (cross-package)\n *\n * @example\n * ```typescript\n * // Track an impression\n * const impression = await events.create({\n * variationId: variation.id,\n * zoneId: 'zone-uuid',\n * siteId: 'site-uuid',\n * eventType: AdEventType.IMPRESSION,\n * metadata: JSON.stringify({\n * ip: '192.168.1.1',\n * userAgent: 'Mozilla/5.0...',\n * referrer: 'https://example.com'\n * })\n * });\n *\n * // Track a click\n * const click = await events.create({\n * variationId: variation.id,\n * zoneId: 'zone-uuid',\n * siteId: 'site-uuid',\n * eventType: AdEventType.CLICK\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['create', 'list'] }, // No update/delete (immutable)\n mcp: { include: ['create'] },\n cli: false, // High volume, not useful in CLI\n})\nexport class AdEvent extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Tenant ID for multi-tenancy support\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Variation ID (FK to AdVariation)\n */\n @foreignKey('AdVariation')\n variationId: string = '';\n\n /**\n * Zone ID (FK to smrt-properties Zone, cross-package)\n */\n @crossPackageRef('@happyvertical/smrt-properties:Zone')\n zoneId: string = '';\n\n /**\n * Site ID (denormalized from Zone for query efficiency)\n */\n siteId: string = '';\n\n /**\n * Event type (impression, click, conversion)\n */\n eventType: AdEventType = AdEventType.IMPRESSION;\n\n /**\n * Event timestamp\n */\n timestamp: Date = new Date();\n\n /**\n * Analytics metadata as JSON string\n * (IP, user agent, referrer, etc.)\n */\n metadata: string = '';\n\n constructor(options: AdEventOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.variationId !== undefined)\n this.variationId = options.variationId;\n if (options.zoneId !== undefined) this.zoneId = options.zoneId;\n if (options.siteId !== undefined) this.siteId = options.siteId;\n if (options.eventType !== undefined) this.eventType = options.eventType;\n if (options.timestamp !== undefined) this.timestamp = options.timestamp;\n if (options.metadata !== undefined) this.metadata = options.metadata;\n }\n\n /**\n * Get metadata as object\n */\n getMetadata(): Record<string, unknown> {\n if (!this.metadata) return {};\n try {\n return JSON.parse(this.metadata);\n } catch {\n return {};\n }\n }\n\n /**\n * Set metadata from object\n */\n setMetadata(data: Record<string, unknown>): void {\n this.metadata = JSON.stringify(data);\n }\n\n /**\n * Check if this is an impression event\n */\n isImpression(): boolean {\n return this.eventType === AdEventType.IMPRESSION;\n }\n\n /**\n * Check if this is a click event\n */\n isClick(): boolean {\n return this.eventType === AdEventType.CLICK;\n }\n\n /**\n * Check if this is a conversion event\n */\n isConversion(): boolean {\n return this.eventType === AdEventType.CONVERSION;\n }\n}\n\nexport default AdEvent;\n","/**\n * AdEventCollection - Collection manager for AdEvent objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { AdEvent } from '../models/AdEvent.js';\nimport { AdEventType } from '../types/index.js';\n\nexport class AdEventCollection extends SmrtCollection<AdEvent> {\n static readonly _itemClass = AdEvent;\n\n /**\n * Find events by variation\n *\n * @param variationId - Variation ID\n * @returns Array of events\n */\n async findByVariation(variationId: string): Promise<AdEvent[]> {\n return await this.list({\n where: { variationId },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Find events by zone\n *\n * @param zoneId - Zone ID\n * @returns Array of events\n */\n async findByZone(zoneId: string): Promise<AdEvent[]> {\n return await this.list({\n where: { zoneId },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Find events by site\n *\n * @param siteId - Site ID\n * @returns Array of events\n */\n async findBySite(siteId: string): Promise<AdEvent[]> {\n return await this.list({\n where: { siteId },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Find events in date range\n *\n * @param start - Start date\n * @param end - End date\n * @returns Array of events\n */\n async findByDateRange(start: Date, end: Date): Promise<AdEvent[]> {\n return await this.list({\n where: {\n 'timestamp >=': start.toISOString(),\n 'timestamp <=': end.toISOString(),\n },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Find events by type\n *\n * @param eventType - Event type\n * @returns Array of events\n */\n async findByType(eventType: AdEventType): Promise<AdEvent[]> {\n return await this.list({\n where: { eventType },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Count events by type for a variation\n *\n * @param variationId - Variation ID\n * @param eventType - Event type\n * @returns Count of events\n */\n async countByType(\n variationId: string,\n eventType: AdEventType,\n ): Promise<number> {\n const events = await this.list({\n where: { variationId, eventType },\n });\n return events.length;\n }\n\n /**\n * Count impressions for a variation\n */\n async countImpressions(variationId: string): Promise<number> {\n return await this.countByType(variationId, AdEventType.IMPRESSION);\n }\n\n /**\n * Count clicks for a variation\n */\n async countClicks(variationId: string): Promise<number> {\n return await this.countByType(variationId, AdEventType.CLICK);\n }\n\n /**\n * Count conversions for a variation\n */\n async countConversions(variationId: string): Promise<number> {\n return await this.countByType(variationId, AdEventType.CONVERSION);\n }\n\n /**\n * Find all impressions\n */\n async findImpressions(): Promise<AdEvent[]> {\n return await this.findByType(AdEventType.IMPRESSION);\n }\n\n /**\n * Find all clicks\n */\n async findClicks(): Promise<AdEvent[]> {\n return await this.findByType(AdEventType.CLICK);\n }\n\n /**\n * Find all conversions\n */\n async findConversions(): Promise<AdEvent[]> {\n return await this.findByType(AdEventType.CONVERSION);\n }\n\n /**\n * Get aggregate stats for a variation\n *\n * @param variationId - Variation ID\n * @returns Stats object with impressions, clicks, conversions, CTR\n */\n async getVariationStats(variationId: string): Promise<{\n impressions: number;\n clicks: number;\n conversions: number;\n ctr: number;\n conversionRate: number;\n }> {\n const impressions = await this.countImpressions(variationId);\n const clicks = await this.countClicks(variationId);\n const conversions = await this.countConversions(variationId);\n\n return {\n impressions,\n clicks,\n conversions,\n ctr: impressions > 0 ? clicks / impressions : 0,\n conversionRate: clicks > 0 ? conversions / clicks : 0,\n };\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tenancy Helper Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Find ad events belonging to a specific tenant\n *\n * @param tenantId - Tenant ID to filter by\n * @returns Array of ad events for the tenant\n */\n async findByTenant(tenantId: string): Promise<AdEvent[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find global ad events (no tenant association).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global ad events\n */\n async findGlobal(): Promise<AdEvent[]> {\n return queryGlobal<AdEvent>(this);\n }\n\n /**\n * Find ad events for a tenant including global (shared) events.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID to include\n * @returns Array of tenant-specific and global ad events\n */\n async findWithGlobals(tenantId: string): Promise<AdEvent[]> {\n return queryWithGlobals<AdEvent>(this, tenantId, 'AdEvent.findWithGlobals');\n }\n}\n","/**\n * AdFormat model - Standard IAB ad dimensions and types\n * @packageDocumentation\n */\n\nimport {\n field,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { AdFormatType } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdFormat}.\n */\nexport interface AdFormatOptions extends SmrtObjectOptions {\n name?: string;\n width?: number;\n height?: number;\n formatType?: AdFormatType;\n description?: string;\n}\n\n/**\n * AdFormat defines standard ad dimensions and types (IAB standards).\n *\n * @example\n * ```typescript\n * const leaderboard = await formats.create({\n * name: 'Leaderboard',\n * width: 728,\n * height: 90,\n * formatType: AdFormatType.BANNER\n * });\n * ```\n */\n// Intentional exception to standards.md §7 (`@TenantScoped`):\n// `AdFormat` is a shared catalog model describing IAB standard ad dimensions\n// (e.g. 728x90 Leaderboard). The dimensions are an industry standard, not a\n// per-tenant configuration. Adding `@TenantScoped` would require every tenant\n// to seed the same IAB rows. See `packages/ads/CLAUDE.md` \"Tenancy\" section\n// for context.\n@smrt({\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get'] },\n cli: { skipApiCheck: true },\n})\nexport class AdFormat extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Display name (e.g., \"Leaderboard\", \"Medium Rectangle\")\n */\n @field({ description: 'What the size is called, for example Leaderboard.' })\n name: string = '';\n\n /**\n * Width in pixels\n */\n @field({ description: 'How wide the ad is, in pixels.' })\n width: number = 0;\n\n /**\n * Height in pixels\n */\n @field({ description: 'How tall the ad is, in pixels.' })\n height: number = 0;\n\n /**\n * Format type (banner, native, video)\n */\n @field({\n description:\n 'What kind of ad fits this size: a picture, a piece written to look like your own content, or a video.',\n })\n formatType: AdFormatType = AdFormatType.BANNER;\n\n /**\n * Optional description\n */\n @field({ description: 'A note about where this size is usually used.' })\n description: string = '';\n\n constructor(options: AdFormatOptions = {}) {\n super(options);\n if (options.name !== undefined) this.name = options.name;\n if (options.width !== undefined) this.width = options.width;\n if (options.height !== undefined) this.height = options.height;\n if (options.formatType !== undefined) this.formatType = options.formatType;\n if (options.description !== undefined)\n this.description = options.description;\n }\n\n /**\n * Get dimensions as string (e.g., \"728x90\")\n */\n getDimensions(): string {\n return `${this.width}x${this.height}`;\n }\n\n /**\n * Check if format matches specific dimensions\n */\n matchesDimensions(width: number, height: number): boolean {\n return this.width === width && this.height === height;\n }\n}\n\nexport default AdFormat;\n","/**\n * AdFormatCollection - Collection manager for AdFormat objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { AdFormat } from '../models/AdFormat.js';\nimport { AdFormatType } from '../types/index.js';\n\nexport class AdFormatCollection extends SmrtCollection<AdFormat> {\n static readonly _itemClass = AdFormat;\n\n /**\n * Find format by dimensions\n *\n * @param width - Width in pixels\n * @param height - Height in pixels\n * @returns Matching format or null\n */\n async findByDimensions(\n width: number,\n height: number,\n ): Promise<AdFormat | null> {\n const results = await this.list({\n where: { width, height },\n limit: 1,\n });\n return results.length > 0 ? results[0] : null;\n }\n\n /**\n * Find formats by type\n *\n * @param formatType - Format type (banner, native, video)\n * @returns Array of matching formats\n */\n async findByType(formatType: AdFormatType): Promise<AdFormat[]> {\n return await this.list({\n where: { formatType },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find all banner formats\n */\n async findBanners(): Promise<AdFormat[]> {\n return await this.findByType(AdFormatType.BANNER);\n }\n\n /**\n * Find all native formats\n */\n async findNative(): Promise<AdFormat[]> {\n return await this.findByType(AdFormatType.NATIVE);\n }\n\n /**\n * Find all video formats\n */\n async findVideo(): Promise<AdFormat[]> {\n return await this.findByType(AdFormatType.VIDEO);\n }\n}\n","/**\n * AdGroup model - Campaign targeting and creative organization\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { AdGroupStatus } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdGroup}.\n */\nexport interface AdGroupOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n tierId?: string;\n name?: string;\n verticalSlug?: string;\n targeting?: string;\n zoneIds?: string;\n startDate?: Date | null;\n endDate?: Date | null;\n dailyBudget?: number;\n totalBudget?: number;\n status?: AdGroupStatus;\n}\n\n/**\n * AdGroup organizes ad creatives with targeting and budget controls.\n *\n * References:\n * - tierId: FK to AdDeliveryTier (within package)\n * - contractId: String reference to smrt-commerce Contract (cross-package)\n * - zoneIds: JSON array of allowed smrt-properties Zone IDs (cross-package)\n * - verticalSlug: Tag slug from smrt-tags (cross-package)\n *\n * @example\n * ```typescript\n * const adGroup = await groups.create({\n * contractId: 'contract-uuid',\n * tierId: tier.id,\n * name: 'Summer Sale - Desktop',\n * verticalSlug: 'retail',\n * targeting: JSON.stringify({ device: 'desktop' }),\n * zoneIds: JSON.stringify(['zone-1', 'zone-2']),\n * dailyBudget: 100.00,\n * totalBudget: 3000.00,\n * startDate: new Date('2024-06-01'),\n * endDate: new Date('2024-08-31')\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get', 'create'] },\n cli: { skipApiCheck: true },\n})\nexport class AdGroup extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Tenant ID for multi-tenancy support\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Sales contract ID (cross-package reference to smrt-commerce)\n */\n @crossPackageRef('@happyvertical/smrt-commerce:SalesContract', {\n validateSubtype: true,\n })\n @field({\n description:\n 'The sales contract this campaign is sold under, if there is one.',\n })\n contractId: string = '';\n\n /**\n * Delivery tier ID (FK to AdDeliveryTier)\n */\n @foreignKey('AdDeliveryTier')\n @field({\n description:\n 'The priority tier the campaign runs in. Tiers are tried in order when more than one campaign could show.',\n })\n tierId: string = '';\n\n /**\n * Display name (e.g., \"Summer Sale - Desktop\")\n */\n @field({\n description: 'What you call the campaign, for example Summer sale.',\n })\n name: string = '';\n\n /**\n * Vertical/category tag slug from smrt-tags (context=\"advertising\")\n */\n @field({\n description: 'The category the campaign belongs to, such as retail.',\n })\n verticalSlug: string = '';\n\n /**\n * Targeting rules as JSON string\n */\n targeting: string = '';\n\n /**\n * Allowed Zone IDs as JSON array string (FK to smrt-properties Zone)\n */\n zoneIds: string = '';\n\n /**\n * Campaign start date\n */\n @field({ description: 'The first day the campaign can show.' })\n startDate: Date | null = null;\n\n /**\n * Campaign end date\n */\n @field({ description: 'The last day the campaign can show.' })\n endDate: Date | null = null;\n\n /**\n * Daily budget limit\n */\n @field({\n description:\n 'The most to spend in one day. The app shows this but does not stop the campaign by itself.',\n })\n dailyBudget: number = 0.0;\n\n /**\n * Total campaign budget\n */\n @field({ description: 'The most to spend over the whole campaign.' })\n totalBudget: number = 0.0;\n\n /**\n * Current status\n */\n @field({\n description:\n 'Where the campaign stands: draft, active, paused or completed. Only active campaigns show ads.',\n })\n status: AdGroupStatus = AdGroupStatus.DRAFT;\n\n constructor(options: AdGroupOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.contractId !== undefined) this.contractId = options.contractId;\n if (options.tierId !== undefined) this.tierId = options.tierId;\n if (options.name !== undefined) this.name = options.name;\n if (options.verticalSlug !== undefined)\n this.verticalSlug = options.verticalSlug;\n if (options.targeting !== undefined) this.targeting = options.targeting;\n if (options.zoneIds !== undefined) this.zoneIds = options.zoneIds;\n if (options.startDate !== undefined) this.startDate = options.startDate;\n if (options.endDate !== undefined) this.endDate = options.endDate;\n if (options.dailyBudget !== undefined)\n this.dailyBudget = options.dailyBudget;\n if (options.totalBudget !== undefined)\n this.totalBudget = options.totalBudget;\n if (options.status !== undefined) this.status = options.status;\n }\n\n /**\n * Get zone IDs as array\n */\n getZoneIds(): string[] {\n if (!this.zoneIds) return [];\n try {\n return JSON.parse(this.zoneIds);\n } catch {\n return [];\n }\n }\n\n /**\n * Set zone IDs from array\n */\n setZoneIds(ids: string[]): void {\n this.zoneIds = JSON.stringify(ids);\n }\n\n /**\n * Add a zone ID\n */\n addZoneId(zoneId: string): void {\n const ids = this.getZoneIds();\n if (!ids.includes(zoneId)) {\n ids.push(zoneId);\n this.setZoneIds(ids);\n }\n }\n\n /**\n * Remove a zone ID\n */\n removeZoneId(zoneId: string): void {\n const ids = this.getZoneIds().filter((id) => id !== zoneId);\n this.setZoneIds(ids);\n }\n\n /**\n * Check if zone ID is allowed\n */\n hasZoneId(zoneId: string): boolean {\n return this.getZoneIds().includes(zoneId);\n }\n\n /**\n * Get targeting rules as object\n */\n getTargeting(): Record<string, unknown> {\n if (!this.targeting) return {};\n try {\n return JSON.parse(this.targeting);\n } catch {\n return {};\n }\n }\n\n /**\n * Set targeting rules from object\n */\n setTargeting(rules: Record<string, unknown>): void {\n this.targeting = JSON.stringify(rules);\n }\n\n /**\n * Check if ad group is currently active\n */\n isActive(): boolean {\n if (this.status !== AdGroupStatus.ACTIVE) return false;\n const now = new Date();\n if (this.startDate && now < this.startDate) return false;\n if (this.endDate && now > this.endDate) return false;\n return true;\n }\n\n /**\n * Check if ad group is in draft state\n */\n isDraft(): boolean {\n return this.status === AdGroupStatus.DRAFT;\n }\n\n /**\n * Check if ad group is paused\n */\n isPaused(): boolean {\n return this.status === AdGroupStatus.PAUSED;\n }\n\n /**\n * Check if ad group is completed\n */\n isCompleted(): boolean {\n return this.status === AdGroupStatus.COMPLETED;\n }\n\n /**\n * Check if ad group has ended (past end date)\n */\n hasEnded(): boolean {\n if (!this.endDate) return false;\n return new Date() > this.endDate;\n }\n\n /**\n * Check if ad group has started\n */\n hasStarted(): boolean {\n if (!this.startDate) return true;\n return new Date() >= this.startDate;\n }\n}\n\nexport default AdGroup;\n","/**\n * AdGroupCollection - Collection manager for AdGroup objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { AdGroup } from '../models/AdGroup.js';\nimport { AdGroupStatus } from '../types/index.js';\n\nexport class AdGroupCollection extends SmrtCollection<AdGroup> {\n static readonly _itemClass = AdGroup;\n\n /**\n * Find ad groups by contract\n *\n * @param contractId - Contract ID\n * @returns Array of ad groups\n */\n async findByContract(contractId: string): Promise<AdGroup[]> {\n return await this.list({\n where: { contractId },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find ad groups by tier\n *\n * @param tierId - Delivery tier ID\n * @returns Array of ad groups\n */\n async findByTier(tierId: string): Promise<AdGroup[]> {\n return await this.list({\n where: { tierId },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find ad groups by status\n *\n * @param status - Ad group status\n * @returns Array of ad groups\n */\n async findByStatus(status: AdGroupStatus): Promise<AdGroup[]> {\n return await this.list({\n where: { status },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find currently active ad groups\n * (status=active, started, not ended)\n *\n * @returns Array of active ad groups\n */\n async findActive(): Promise<AdGroup[]> {\n const results = await this.list({\n where: {\n status: AdGroupStatus.ACTIVE,\n },\n orderBy: 'created_at DESC',\n });\n // Filter by date in memory (complex date logic)\n return results.filter((group) => group.isActive());\n }\n\n /**\n * Find ad groups by vertical slug\n *\n * @param verticalSlug - Tag slug from smrt-tags\n * @returns Array of ad groups\n */\n async findByVertical(verticalSlug: string): Promise<AdGroup[]> {\n return await this.list({\n where: { verticalSlug },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find ad groups that can serve to a specific zone\n *\n * @param zoneId - Zone ID to check\n * @returns Array of ad groups containing zone\n */\n async findByZone(zoneId: string): Promise<AdGroup[]> {\n // Must filter in memory since zoneIds is JSON\n const all = await this.list({\n where: { status: AdGroupStatus.ACTIVE },\n });\n return all.filter((group) => group.hasZoneId(zoneId));\n }\n\n /**\n * Find ad groups eligible to serve for a zone\n * (active, has zone, within date range)\n *\n * @param zoneId - Zone ID to check\n * @returns Array of eligible ad groups\n */\n async findEligibleForZone(zoneId: string): Promise<AdGroup[]> {\n const groups = await this.findByZone(zoneId);\n return groups.filter((group) => group.isActive());\n }\n\n /**\n * Find all draft ad groups\n */\n async findDrafts(): Promise<AdGroup[]> {\n return await this.findByStatus(AdGroupStatus.DRAFT);\n }\n\n /**\n * Find all paused ad groups\n */\n async findPaused(): Promise<AdGroup[]> {\n return await this.findByStatus(AdGroupStatus.PAUSED);\n }\n\n /**\n * Find all completed ad groups\n */\n async findCompleted(): Promise<AdGroup[]> {\n return await this.findByStatus(AdGroupStatus.COMPLETED);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tenancy Helper Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Find ad groups belonging to a specific tenant\n *\n * @param tenantId - Tenant ID to filter by\n * @returns Array of ad groups for the tenant\n */\n async findByTenant(tenantId: string): Promise<AdGroup[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find global ad groups (no tenant association).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global ad groups\n */\n async findGlobal(): Promise<AdGroup[]> {\n return queryGlobal<AdGroup>(this);\n }\n\n /**\n * Find ad groups for a tenant including global (shared) ad groups.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID to include\n * @returns Array of tenant-specific and global ad groups\n */\n async findWithGlobals(tenantId: string): Promise<AdGroup[]> {\n return queryWithGlobals<AdGroup>(this, tenantId, 'AdGroup.findWithGlobals');\n }\n}\n","/**\n * AdVariation model - Creative asset with A/B testing support\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { AdVariationStatus } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdVariation}.\n */\nexport interface AdVariationOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n groupId?: string;\n formatId?: string;\n assetId?: string;\n name?: string;\n clickUrl?: string;\n altText?: string;\n weight?: number;\n status?: AdVariationStatus;\n impressions?: number;\n clicks?: number;\n}\n\n/**\n * AdVariation represents a creative asset within an ad group.\n * Supports A/B testing via weighted selection.\n *\n * References:\n * - groupId: FK to AdGroup (within package)\n * - formatId: FK to AdFormat (within package)\n * - assetId: String reference to smrt-assets Asset (cross-package)\n *\n * @example\n * ```typescript\n * const variation = await variations.create({\n * groupId: adGroup.id,\n * formatId: leaderboard.id,\n * assetId: 'asset-uuid',\n * name: 'Version A - Blue CTA',\n * clickUrl: 'https://example.com/landing',\n * altText: 'Summer Sale - 50% off',\n * weight: 2 // 2x more likely than weight=1\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get', 'create'] },\n cli: { skipApiCheck: true },\n})\nexport class AdVariation extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Tenant ID for multi-tenancy support\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Ad group ID (FK to AdGroup)\n */\n @foreignKey('AdGroup')\n @field({ description: 'The campaign this ad belongs to.' })\n groupId: string = '';\n\n /**\n * Ad format ID (FK to AdFormat)\n */\n @foreignKey('AdFormat')\n @field({ description: 'The ad size this ad is made for.' })\n formatId: string = '';\n\n /**\n * Asset ID (FK to smrt-assets Asset, cross-package)\n */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n @field({ description: 'The picture people see.' })\n assetId: string = '';\n\n /**\n * Display name (e.g., \"Version A - Blue CTA\")\n */\n @field({\n description: 'What you call this ad, for example Version A, blue button.',\n })\n name: string = '';\n\n /**\n * Click destination URL\n */\n @field({ description: 'The web address people go to when they tap the ad.' })\n clickUrl: string = '';\n\n /**\n * Accessibility alt text\n */\n @field({\n description:\n 'A few words that describe the picture for people who cannot see it.',\n })\n altText: string = '';\n\n /**\n * A/B testing weight (higher = more likely to be selected)\n */\n @field({\n description:\n '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.',\n })\n weight: number = 1;\n\n /**\n * Current status\n */\n @field({\n description:\n 'Where the ad stands: draft, active or paused. Only active ads show.',\n })\n status: AdVariationStatus = AdVariationStatus.DRAFT;\n\n /**\n * Denormalized impression count (updated async)\n */\n @field({\n description:\n 'How many times the ad has been shown. The app counts this as it serves ads and refreshes it a little later.',\n })\n impressions: number = 0;\n\n /**\n * Denormalized click count (updated async)\n */\n @field({\n description:\n 'How many times the ad has been tapped. The app counts this as it serves ads and refreshes it a little later.',\n })\n clicks: number = 0;\n\n constructor(options: AdVariationOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.groupId !== undefined) this.groupId = options.groupId;\n if (options.formatId !== undefined) this.formatId = options.formatId;\n if (options.assetId !== undefined) this.assetId = options.assetId;\n if (options.name !== undefined) this.name = options.name;\n if (options.clickUrl !== undefined) this.clickUrl = options.clickUrl;\n if (options.altText !== undefined) this.altText = options.altText;\n if (options.weight !== undefined) this.weight = options.weight;\n if (options.status !== undefined) this.status = options.status;\n if (options.impressions !== undefined)\n this.impressions = options.impressions;\n if (options.clicks !== undefined) this.clicks = options.clicks;\n }\n\n /**\n * Check if variation is active\n */\n isActive(): boolean {\n return this.status === AdVariationStatus.ACTIVE;\n }\n\n /**\n * Check if variation is in draft state\n */\n isDraft(): boolean {\n return this.status === AdVariationStatus.DRAFT;\n }\n\n /**\n * Check if variation is paused\n */\n isPaused(): boolean {\n return this.status === AdVariationStatus.PAUSED;\n }\n\n /**\n * Calculate click-through rate (CTR)\n */\n getCTR(): number {\n if (this.impressions === 0) return 0;\n return this.clicks / this.impressions;\n }\n\n /**\n * Increment impression count\n */\n recordImpression(): void {\n this.impressions += 1;\n }\n\n /**\n * Increment click count\n */\n recordClick(): void {\n this.clicks += 1;\n }\n}\n\nexport default AdVariation;\n","/**\n * AdVariationCollection - Collection manager for AdVariation objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { AdVariation } from '../models/AdVariation.js';\nimport { AdVariationStatus } from '../types/index.js';\n\nexport class AdVariationCollection extends SmrtCollection<AdVariation> {\n static readonly _itemClass = AdVariation;\n\n /**\n * Find variations by ad group\n *\n * @param groupId - Ad group ID\n * @returns Array of variations\n */\n async findByGroup(groupId: string): Promise<AdVariation[]> {\n return await this.list({\n where: { groupId },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find variations by format\n *\n * @param formatId - Ad format ID\n * @returns Array of variations\n */\n async findByFormat(formatId: string): Promise<AdVariation[]> {\n return await this.list({\n where: { formatId },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find active variations for a group\n *\n * @param groupId - Ad group ID\n * @returns Array of active variations\n */\n async findActiveByGroup(groupId: string): Promise<AdVariation[]> {\n return await this.list({\n where: {\n groupId,\n status: AdVariationStatus.ACTIVE,\n },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Select a variation using weighted random selection\n * Higher weight = more likely to be selected\n *\n * @param groupId - Ad group ID\n * @returns Selected variation or null if none available\n */\n async selectByWeight(groupId: string): Promise<AdVariation | null> {\n const active = await this.findActiveByGroup(groupId);\n if (active.length === 0) return null;\n if (active.length === 1) return active[0];\n\n // Calculate total weight\n const totalWeight = active.reduce((sum, v) => sum + v.weight, 0);\n if (totalWeight <= 0) return active[0];\n\n // Random selection weighted by weight\n let random = Math.random() * totalWeight;\n for (const variation of active) {\n random -= variation.weight;\n if (random <= 0) {\n return variation;\n }\n }\n\n // Fallback to last variation\n return active[active.length - 1];\n }\n\n /**\n * Find variations by status\n *\n * @param status - Variation status\n * @returns Array of variations\n */\n async findByStatus(status: AdVariationStatus): Promise<AdVariation[]> {\n return await this.list({\n where: { status },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find all active variations\n */\n async findActive(): Promise<AdVariation[]> {\n return await this.findByStatus(AdVariationStatus.ACTIVE);\n }\n\n /**\n * Find all draft variations\n */\n async findDrafts(): Promise<AdVariation[]> {\n return await this.findByStatus(AdVariationStatus.DRAFT);\n }\n\n /**\n * Find all paused variations\n */\n async findPaused(): Promise<AdVariation[]> {\n return await this.findByStatus(AdVariationStatus.PAUSED);\n }\n\n /**\n * Find top performing variations by CTR\n *\n * @param limit - Maximum number to return\n * @returns Array of variations sorted by CTR descending\n */\n async findTopPerformers(limit: number = 10): Promise<AdVariation[]> {\n const all = await this.list({\n where: { status: AdVariationStatus.ACTIVE },\n });\n // Sort by CTR descending\n return all\n .filter((v) => v.impressions > 0)\n .sort((a, b) => b.getCTR() - a.getCTR())\n .slice(0, limit);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tenancy Helper Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Find ad variations belonging to a specific tenant\n *\n * @param tenantId - Tenant ID to filter by\n * @returns Array of ad variations for the tenant\n */\n async findByTenant(tenantId: string): Promise<AdVariation[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find global ad variations (no tenant association).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global ad variations\n */\n async findGlobal(): Promise<AdVariation[]> {\n return queryGlobal<AdVariation>(this);\n }\n\n /**\n * Find ad variations for a tenant including global (shared) variations.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID to include\n * @returns Array of tenant-specific and global ad variations\n */\n async findWithGlobals(tenantId: string): Promise<AdVariation[]> {\n return queryWithGlobals<AdVariation>(\n this,\n tenantId,\n 'AdVariation.findWithGlobals',\n );\n }\n}\n","/**\n * Declared recipes for smrt-ads (#4409, #4437): user-facing units of\n * functionality an app or agent can pick instead of the whole package.\n * The scanner reads these statics into the `recipes` array of `manifest.json`\n * and `smrt-knowledge.json`; nothing here runs at that point.\n *\n * @packageDocumentation\n */\n\nimport { SmrtRecipe } from '@happyvertical/smrt-core';\nimport { AdDeliveryTier } from './models/AdDeliveryTier.js';\nimport { AdFormat } from './models/AdFormat.js';\nimport { AdGroup } from './models/AdGroup.js';\nimport { AdVariation } from './models/AdVariation.js';\n\n/**\n * Ads: run ad campaigns on your site and see which ads get clicked.\n *\n * `AdEvent` is left out on purpose: it is the append-only record of every\n * showing and click the app writes while serving ads (create and list only,\n * no CLI, high volume). Nobody opens it as a list; the counts a person reads\n * live on the ad itself (`AdVariation.impressions` / `clicks`).\n */\nexport class AdsCampaignsRecipe extends SmrtRecipe {\n static id = 'ads.campaigns';\n static help = './campaigns.recipe.md';\n static label = 'Ads';\n static summary =\n 'Run ad campaigns on your site, choose which ads show where, and see which ones get clicked.';\n static synonyms = [\n 'ads',\n 'advertising',\n 'ad campaigns',\n 'banner ads',\n 'advertisements',\n 'display ads',\n ];\n static section = {\n id: 'grow',\n label: 'Grow',\n icon: 'tag',\n description: 'Bring in new customers and reward the people who help.',\n };\n static models = [AdGroup, AdVariation, AdFormat, AdDeliveryTier];\n static nav = [\n {\n label: 'Ad campaigns',\n model: AdGroup,\n icon: 'tag',\n description:\n 'Each campaign you run, with its dates, budget and where it stands.',\n noun: 'ad campaign',\n },\n {\n label: 'Ads',\n model: AdVariation,\n icon: 'fileText',\n description:\n 'The ads inside each campaign, how often each shows and how many clicks it got.',\n noun: 'ad',\n },\n {\n label: 'Ad sizes',\n model: AdFormat,\n icon: 'layers',\n description:\n 'The shapes and sizes an ad can be, shared by every campaign.',\n noun: 'ad size',\n },\n {\n label: 'Priority tiers',\n model: AdDeliveryTier,\n icon: 'settings',\n description:\n 'The order campaigns are tried in when more than one could show.',\n noun: 'tier',\n },\n ];\n static options = {\n AdGroup: {\n fields: {\n name: { order: 1 },\n status: { order: 2 },\n tierId: { label: 'Priority tier', order: 3 },\n startDate: { label: 'Starts on', order: 4 },\n endDate: { label: 'Ends on', order: 5 },\n dailyBudget: { label: 'Daily budget', order: 6 },\n totalBudget: { label: 'Total budget', order: 7 },\n tenantId: { visibility: 'hidden' },\n contractId: { label: 'Sales contract', visibility: 'advanced' },\n verticalSlug: { label: 'Category', visibility: 'advanced' },\n targeting: { visibility: 'hidden' },\n zoneIds: { visibility: 'hidden' },\n },\n },\n AdVariation: {\n fields: {\n name: { order: 1 },\n groupId: { label: 'Ad campaign', order: 2 },\n formatId: { label: 'Ad size', order: 3 },\n assetId: { label: 'Picture', order: 4 },\n clickUrl: { label: 'Link to', order: 5 },\n altText: { label: 'Words for the picture', order: 6 },\n weight: { order: 7 },\n status: { order: 8 },\n tenantId: { visibility: 'hidden' },\n impressions: {\n label: 'Times shown',\n locked: true,\n visibility: 'advanced',\n },\n clicks: { locked: true, visibility: 'advanced' },\n },\n },\n AdFormat: {\n fields: {\n name: { order: 1 },\n width: { order: 2 },\n height: { order: 3 },\n formatType: { label: 'Kind', order: 4 },\n description: { order: 5 },\n },\n },\n AdDeliveryTier: {\n fields: {\n name: { order: 1 },\n priority: { order: 2 },\n pricingModel: { label: 'How it is charged', order: 3 },\n description: { order: 4 },\n },\n },\n } as const;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["AdFormatType","PricingModel","AdGroupStatus","AdVariationStatus","AdEventType"],"sources":["../src/__smrt-register__.ts","../src/types/index.ts","../src/models/AdDeliveryTier.ts","../src/collections/AdDeliveryTierCollection.ts","../src/models/AdEvent.ts","../src/collections/AdEventCollection.ts","../src/models/AdFormat.ts","../src/collections/AdFormatCollection.ts","../src/models/AdGroup.ts","../src/collections/AdGroupCollection.ts","../src/models/AdVariation.ts","../src/collections/AdVariationCollection.ts","../src/recipes.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"packageVersion\\\":\\\"0.57.40\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-ads:AdDeliveryTierCollection\\\":{\\\"name\\\":\\\"addeliverytiercollection\\\",\\\"className\\\":\\\"AdDeliveryTierCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdDeliveryTierCollection\\\",\\\"collection\\\":\\\"addeliverytiers\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdDeliveryTierCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByPriority\\\":{\\\"name\\\":\\\"findByPriority\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByPricingModel\\\":{\\\"name\\\":\\\"findByPricingModel\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"pricingModel\\\",\\\"type\\\":\\\"PricingModel\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getHighestPriority\\\":{\\\"name\\\":\\\"getHighestPriority\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findFixedPricing\\\":{\\\"name\\\":\\\"findFixedPricing\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findCPM\\\":{\\\"name\\\":\\\"findCPM\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findPerformanceBased\\\":{\\\"name\\\":\\\"findPerformanceBased\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdDeliveryTier[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdDeliveryTier\\\",\\\"exportName\\\":\\\"AdDeliveryTierCollection\\\",\\\"collectionExportName\\\":\\\"AdDeliveryTierCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_delivery_tiers\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_delivery_tiers\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"priority\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"pricing_model\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"priority\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"pricing_model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_delivery_tiers_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"ad_delivery_tiers_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"df0ec0ff\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdEventCollection\\\":{\\\"name\\\":\\\"adeventcollection\\\",\\\"className\\\":\\\"AdEventCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdEventCollection\\\",\\\"collection\\\":\\\"adevents\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdEventCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByVariation\\\":{\\\"name\\\":\\\"findByVariation\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByZone\\\":{\\\"name\\\":\\\"findByZone\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findBySite\\\":{\\\"name\\\":\\\"findBySite\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"siteId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByDateRange\\\":{\\\"name\\\":\\\"findByDateRange\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"start\\\",\\\"type\\\":\\\"Date\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"end\\\",\\\"type\\\":\\\"Date\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"eventType\\\",\\\"type\\\":\\\"AdEventType\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countByType\\\":{\\\"name\\\":\\\"countByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"eventType\\\",\\\"type\\\":\\\"AdEventType\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countImpressions\\\":{\\\"name\\\":\\\"countImpressions\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countClicks\\\":{\\\"name\\\":\\\"countClicks\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countConversions\\\":{\\\"name\\\":\\\"countConversions\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findImpressions\\\":{\\\"name\\\":\\\"findImpressions\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findClicks\\\":{\\\"name\\\":\\\"findClicks\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findConversions\\\":{\\\"name\\\":\\\"findConversions\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getVariationStats\\\":{\\\"name\\\":\\\"getVariationStats\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"variationId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<object>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTenant\\\":{\\\"name\\\":\\\"findByTenant\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findGlobal\\\":{\\\"name\\\":\\\"findGlobal\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findWithGlobals\\\":{\\\"name\\\":\\\"findWithGlobals\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdEvent[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"create\\\",\\\"list\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"create\\\"]},\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdEvent\\\",\\\"exportName\\\":\\\"AdEventCollection\\\",\\\"collectionExportName\\\":\\\"AdEventCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_events\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_events\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"variation_id\\\\\\\" UUID,\\\\n \\\\\\\"zone_id\\\\\\\" UUID,\\\\n \\\\\\\"site_id\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"event_type\\\\\\\" TEXT,\\\\n \\\\\\\"timestamp\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"metadata\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"variation_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_variations\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"zone_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"site_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"event_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"timestamp\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"metadata\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_events_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_events_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_events_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_events_variation_id_idx\\\",\\\"columns\\\":[\\\"variation_id\\\"]},{\\\"name\\\":\\\"ad_events_zone_id_idx\\\",\\\"columns\\\":[\\\"zone_id\\\"]}],\\\"version\\\":\\\"306d8050\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdFormatCollection\\\":{\\\"name\\\":\\\"adformatcollection\\\",\\\"className\\\":\\\"AdFormatCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdFormatCollection\\\",\\\"collection\\\":\\\"adformats\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdFormatCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByDimensions\\\":{\\\"name\\\":\\\"findByDimensions\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"width\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"height\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdFormat | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"formatType\\\",\\\"type\\\":\\\"AdFormatType\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdFormat[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findBanners\\\":{\\\"name\\\":\\\"findBanners\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdFormat[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findNative\\\":{\\\"name\\\":\\\"findNative\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdFormat[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findVideo\\\":{\\\"name\\\":\\\"findVideo\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdFormat[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdFormat\\\",\\\"exportName\\\":\\\"AdFormatCollection\\\",\\\"collectionExportName\\\":\\\"AdFormatCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_formats\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_formats\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"width\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"height\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"format_type\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"width\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"height\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"format_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_formats_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"ad_formats_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"df40cc03\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdGroupCollection\\\":{\\\"name\\\":\\\"adgroupcollection\\\",\\\"className\\\":\\\"AdGroupCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdGroupCollection\\\",\\\"collection\\\":\\\"adgroups\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdGroupCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByContract\\\":{\\\"name\\\":\\\"findByContract\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"contractId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTier\\\":{\\\"name\\\":\\\"findByTier\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tierId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByStatus\\\":{\\\"name\\\":\\\"findByStatus\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"status\\\",\\\"type\\\":\\\"AdGroupStatus\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findActive\\\":{\\\"name\\\":\\\"findActive\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByVertical\\\":{\\\"name\\\":\\\"findByVertical\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"verticalSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByZone\\\":{\\\"name\\\":\\\"findByZone\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findEligibleForZone\\\":{\\\"name\\\":\\\"findEligibleForZone\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findDrafts\\\":{\\\"name\\\":\\\"findDrafts\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findPaused\\\":{\\\"name\\\":\\\"findPaused\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findCompleted\\\":{\\\"name\\\":\\\"findCompleted\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTenant\\\":{\\\"name\\\":\\\"findByTenant\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findGlobal\\\":{\\\"name\\\":\\\"findGlobal\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findWithGlobals\\\":{\\\"name\\\":\\\"findWithGlobals\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdGroup[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\"]}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdGroup\\\",\\\"exportName\\\":\\\"AdGroupCollection\\\",\\\"collectionExportName\\\":\\\"AdGroupCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_groups\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_groups\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"contract_id\\\\\\\" UUID,\\\\n \\\\\\\"tier_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"vertical_slug\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"targeting\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"zone_ids\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"start_date\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"end_date\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"daily_budget\\\\\\\" REAL DEFAULT 0,\\\\n \\\\\\\"total_budget\\\\\\\" REAL DEFAULT 0,\\\\n \\\\\\\"status\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"contract_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"tier_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_delivery_tiers\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"vertical_slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"targeting\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"zone_ids\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"start_date\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"end_date\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"daily_budget\\\":{\\\"type\\\":\\\"REAL\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"total_budget\\\":{\\\"type\\\":\\\"REAL\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_groups_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_groups_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_groups_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_groups_contract_id_idx\\\",\\\"columns\\\":[\\\"contract_id\\\"]},{\\\"name\\\":\\\"ad_groups_tier_id_idx\\\",\\\"columns\\\":[\\\"tier_id\\\"]}],\\\"version\\\":\\\"3f8a3fea\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdVariationCollection\\\":{\\\"name\\\":\\\"advariationcollection\\\",\\\"className\\\":\\\"AdVariationCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdVariationCollection\\\",\\\"collection\\\":\\\"advariations\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/collections/AdVariationCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByGroup\\\":{\\\"name\\\":\\\"findByGroup\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"groupId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByFormat\\\":{\\\"name\\\":\\\"findByFormat\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"formatId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findActiveByGroup\\\":{\\\"name\\\":\\\"findActiveByGroup\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"groupId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"selectByWeight\\\":{\\\"name\\\":\\\"selectByWeight\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"groupId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByStatus\\\":{\\\"name\\\":\\\"findByStatus\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"status\\\",\\\"type\\\":\\\"AdVariationStatus\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findActive\\\":{\\\"name\\\":\\\"findActive\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findDrafts\\\":{\\\"name\\\":\\\"findDrafts\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findPaused\\\":{\\\"name\\\":\\\"findPaused\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findTopPerformers\\\":{\\\"name\\\":\\\"findTopPerformers\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"limit\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTenant\\\":{\\\"name\\\":\\\"findByTenant\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findGlobal\\\":{\\\"name\\\":\\\"findGlobal\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findWithGlobals\\\":{\\\"name\\\":\\\"findWithGlobals\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AdVariation[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\"]}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AdVariation\\\",\\\"exportName\\\":\\\"AdVariationCollection\\\",\\\"collectionExportName\\\":\\\"AdVariationCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_variations\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_variations\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"group_id\\\\\\\" UUID,\\\\n \\\\\\\"format_id\\\\\\\" UUID,\\\\n \\\\\\\"asset_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"click_url\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"alt_text\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"weight\\\\\\\" INTEGER DEFAULT 1,\\\\n \\\\\\\"status\\\\\\\" TEXT,\\\\n \\\\\\\"impressions\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"clicks\\\\\\\" INTEGER DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"group_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_groups\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"format_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_formats\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"asset_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"click_url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"alt_text\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"weight\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":1},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"impressions\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"clicks\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_variations_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_variations_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_variations_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_variations_group_id_idx\\\",\\\"columns\\\":[\\\"group_id\\\"]},{\\\"name\\\":\\\"ad_variations_format_id_idx\\\",\\\"columns\\\":[\\\"format_id\\\"]},{\\\"name\\\":\\\"ad_variations_asset_id_idx\\\",\\\"columns\\\":[\\\"asset_id\\\"]}],\\\"version\\\":\\\"e8fb6233\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\":{\\\"name\\\":\\\"addeliverytier\\\",\\\"className\\\":\\\"AdDeliveryTier\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\",\\\"collection\\\":\\\"addeliverytiers\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdDeliveryTier.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"What the tier is called, for example Sponsorship, Standard or House.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What the tier is called, for example Sponsorship, Standard or House.\\\"}},\\\"priority\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"The order tiers are tried in: 1 is tried first, then 2, and so on.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The order tiers are tried in: 1 is tried first, then 2, and so on.\\\"}},\\\"pricingModel\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"description\\\":\\\"How ads in this tier are charged: a fixed price, per thousand showings, per click, or per sale.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How ads in this tier are charged: a fixed price, per thousand showings, per click, or per sale.\\\"},\\\"enum\\\":[\\\"fixed\\\",\\\"cpm\\\",\\\"cpc\\\",\\\"cpa\\\"]},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"A note about what this tier is for.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"A note about what this tier is for.\\\"}}},\\\"methods\\\":{\\\"isHigherPriorityThan\\\":{\\\"name\\\":\\\"isHigherPriorityThan\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"other\\\",\\\"type\\\":\\\"AdDeliveryTier\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isFixedPricing\\\":{\\\"name\\\":\\\"isFixedPricing\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isPerformanceBased\\\":{\\\"name\\\":\\\"isPerformanceBased\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdDeliveryTier\\\",\\\"collectionExportName\\\":\\\"AdDeliveryTierCollection\\\",\\\"displayLabelField\\\":\\\"name\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_delivery_tiers\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_delivery_tiers\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"priority\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"pricing_model\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"priority\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"pricing_model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_delivery_tiers_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"ad_delivery_tiers_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"df0ec0ff\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdEvent\\\":{\\\"name\\\":\\\"adevent\\\",\\\"className\\\":\\\"AdEvent\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdEvent\\\",\\\"collection\\\":\\\"adevents\\\",\\\"description\\\":\\\"AdEvent tracks ad impressions, clicks, and conversions. Events are immutable (append-only, no update/delete).\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdEvent.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"variationId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AdVariation\\\"},\\\"zoneId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-properties:Zone\\\"},\\\"siteId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"eventType\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"enum\\\":[\\\"impression\\\",\\\"click\\\",\\\"conversion\\\"]},\\\"timestamp\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"metadata\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"}},\\\"methods\\\":{\\\"getMetadata\\\":{\\\"name\\\":\\\"getMetadata\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Record<string, unknown>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setMetadata\\\":{\\\"name\\\":\\\"setMetadata\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"data\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isImpression\\\":{\\\"name\\\":\\\"isImpression\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isClick\\\":{\\\"name\\\":\\\"isClick\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isConversion\\\":{\\\"name\\\":\\\"isConversion\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"create\\\",\\\"list\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"create\\\"]},\\\"cli\\\":false,\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdEvent\\\",\\\"collectionExportName\\\":\\\"AdEventCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_events\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_events\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"variation_id\\\\\\\" UUID,\\\\n \\\\\\\"zone_id\\\\\\\" UUID,\\\\n \\\\\\\"site_id\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"event_type\\\\\\\" TEXT,\\\\n \\\\\\\"timestamp\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"metadata\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"variation_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_variations\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"zone_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"site_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"event_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"timestamp\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"metadata\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_events_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_events_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_events_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_events_variation_id_idx\\\",\\\"columns\\\":[\\\"variation_id\\\"]},{\\\"name\\\":\\\"ad_events_zone_id_idx\\\",\\\"columns\\\":[\\\"zone_id\\\"]}],\\\"version\\\":\\\"306d8050\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdFormat\\\":{\\\"name\\\":\\\"adformat\\\",\\\"className\\\":\\\"AdFormat\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdFormat\\\",\\\"collection\\\":\\\"adformats\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdFormat.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"What the size is called, for example Leaderboard.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What the size is called, for example Leaderboard.\\\"}},\\\"width\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"How wide the ad is, in pixels.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How wide the ad is, in pixels.\\\"}},\\\"height\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"How tall the ad is, in pixels.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How tall the ad is, in pixels.\\\"}},\\\"formatType\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"description\\\":\\\"What kind of ad fits this size: a picture, a piece written to look like your own content, or a video.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What kind of ad fits this size: a picture, a piece written to look like your own content, or a video.\\\"},\\\"enum\\\":[\\\"banner\\\",\\\"native\\\",\\\"video\\\"]},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"A note about where this size is usually used.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"A note about where this size is usually used.\\\"}}},\\\"methods\\\":{\\\"getDimensions\\\":{\\\"name\\\":\\\"getDimensions\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"string\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"matchesDimensions\\\":{\\\"name\\\":\\\"matchesDimensions\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"width\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"height\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdFormat\\\",\\\"collectionExportName\\\":\\\"AdFormatCollection\\\",\\\"displayLabelField\\\":\\\"name\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_formats\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_formats\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"width\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"height\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"format_type\\\\\\\" TEXT,\\\\n \\\\\\\"description\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"width\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"height\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"format_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_formats_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"ad_formats_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"df40cc03\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdGroup\\\":{\\\"name\\\":\\\"adgroup\\\",\\\"className\\\":\\\"AdGroup\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdGroup\\\",\\\"collection\\\":\\\"adgroups\\\",\\\"description\\\":\\\"AdGroup organizes ad creatives with targeting and budget controls.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdGroup.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"contractId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-commerce:SalesContract\\\",\\\"description\\\":\\\"The sales contract this campaign is sold under, if there is one.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The sales contract this campaign is sold under, if there is one.\\\",\\\"validateSubtype\\\":true}},\\\"tierId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AdDeliveryTier\\\",\\\"description\\\":\\\"The priority tier the campaign runs in. Tiers are tried in order when more than one campaign could show.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The priority tier the campaign runs in. Tiers are tried in order when more than one campaign could show.\\\"}},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"What you call the campaign, for example Summer sale.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What you call the campaign, for example Summer sale.\\\"}},\\\"verticalSlug\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"The category the campaign belongs to, such as retail.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The category the campaign belongs to, such as retail.\\\"}},\\\"targeting\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"zoneIds\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"startDate\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false,\\\"description\\\":\\\"The first day the campaign can show.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The first day the campaign can show.\\\"}},\\\"endDate\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false,\\\"description\\\":\\\"The last day the campaign can show.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The last day the campaign can show.\\\"}},\\\"dailyBudget\\\":{\\\"type\\\":\\\"decimal\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"The most to spend in one day. The app shows this but does not stop the campaign by itself.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The most to spend in one day. The app shows this but does not stop the campaign by itself.\\\"}},\\\"totalBudget\\\":{\\\"type\\\":\\\"decimal\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"The most to spend over the whole campaign.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The most to spend over the whole campaign.\\\"}},\\\"status\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"description\\\":\\\"Where the campaign stands: draft, active, paused or completed. Only active campaigns show ads.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"Where the campaign stands: draft, active, paused or completed. Only active campaigns show ads.\\\"},\\\"enum\\\":[\\\"draft\\\",\\\"active\\\",\\\"paused\\\",\\\"completed\\\"]}},\\\"methods\\\":{\\\"getZoneIds\\\":{\\\"name\\\":\\\"getZoneIds\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"string[]\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setZoneIds\\\":{\\\"name\\\":\\\"setZoneIds\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"ids\\\",\\\"type\\\":\\\"string[]\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addZoneId\\\":{\\\"name\\\":\\\"addZoneId\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeZoneId\\\":{\\\"name\\\":\\\"removeZoneId\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"hasZoneId\\\":{\\\"name\\\":\\\"hasZoneId\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"zoneId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTargeting\\\":{\\\"name\\\":\\\"getTargeting\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Record<string, unknown>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setTargeting\\\":{\\\"name\\\":\\\"setTargeting\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"rules\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isActive\\\":{\\\"name\\\":\\\"isActive\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isDraft\\\":{\\\"name\\\":\\\"isDraft\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isPaused\\\":{\\\"name\\\":\\\"isPaused\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isCompleted\\\":{\\\"name\\\":\\\"isCompleted\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"hasEnded\\\":{\\\"name\\\":\\\"hasEnded\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"hasStarted\\\":{\\\"name\\\":\\\"hasStarted\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdGroup\\\",\\\"collectionExportName\\\":\\\"AdGroupCollection\\\",\\\"displayLabelField\\\":\\\"name\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_groups\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_groups\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"contract_id\\\\\\\" UUID,\\\\n \\\\\\\"tier_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"vertical_slug\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"targeting\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"zone_ids\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"start_date\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"end_date\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"daily_budget\\\\\\\" REAL DEFAULT 0,\\\\n \\\\\\\"total_budget\\\\\\\" REAL DEFAULT 0,\\\\n \\\\\\\"status\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"contract_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"tier_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_delivery_tiers\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"vertical_slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"targeting\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"zone_ids\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"start_date\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"end_date\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"daily_budget\\\":{\\\"type\\\":\\\"REAL\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"total_budget\\\":{\\\"type\\\":\\\"REAL\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_groups_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_groups_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_groups_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_groups_contract_id_idx\\\",\\\"columns\\\":[\\\"contract_id\\\"]},{\\\"name\\\":\\\"ad_groups_tier_id_idx\\\",\\\"columns\\\":[\\\"tier_id\\\"]}],\\\"version\\\":\\\"3f8a3fea\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"},\\\"@happyvertical/smrt-ads:AdVariation\\\":{\\\"name\\\":\\\"advariation\\\",\\\"className\\\":\\\"AdVariation\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-ads:AdVariation\\\",\\\"collection\\\":\\\"advariations\\\",\\\"description\\\":\\\"AdVariation represents a creative asset within an ad group. Supports A/B testing via weighted selection.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/ads/src/models/AdVariation.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-ads\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"groupId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AdGroup\\\",\\\"description\\\":\\\"The campaign this ad belongs to.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The campaign this ad belongs to.\\\"}},\\\"formatId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"AdFormat\\\",\\\"description\\\":\\\"The ad size this ad is made for.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The ad size this ad is made for.\\\"}},\\\"assetId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":false,\\\"related\\\":\\\"@happyvertical/smrt-assets:Asset\\\",\\\"description\\\":\\\"The picture people see.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The picture people see.\\\"}},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"What you call this ad, for example Version A, blue button.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"What you call this ad, for example Version A, blue button.\\\"}},\\\"clickUrl\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"The web address people go to when they tap the ad.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"The web address people go to when they tap the ad.\\\"}},\\\"altText\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"description\\\":\\\"A few words that describe the picture for people who cannot see it.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"A few words that describe the picture for people who cannot see it.\\\"}},\\\"weight\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":1,\\\"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.\\\",\\\"_meta\\\":{\\\"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.\\\"}},\\\"status\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"description\\\":\\\"Where the ad stands: draft, active or paused. Only active ads show.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"Where the ad stands: draft, active or paused. Only active ads show.\\\"},\\\"enum\\\":[\\\"draft\\\",\\\"active\\\",\\\"paused\\\"]},\\\"impressions\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"How many times the ad has been shown. The app counts this as it serves ads and refreshes it a little later.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How many times the ad has been shown. The app counts this as it serves ads and refreshes it a little later.\\\"}},\\\"clicks\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"description\\\":\\\"How many times the ad has been tapped. The app counts this as it serves ads and refreshes it a little later.\\\",\\\"_meta\\\":{\\\"description\\\":\\\"How many times the ad has been tapped. The app counts this as it serves ads and refreshes it a little later.\\\"}}},\\\"methods\\\":{\\\"isActive\\\":{\\\"name\\\":\\\"isActive\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isDraft\\\":{\\\"name\\\":\\\"isDraft\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isPaused\\\":{\\\"name\\\":\\\"isPaused\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getCTR\\\":{\\\"name\\\":\\\"getCTR\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"number\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordImpression\\\":{\\\"name\\\":\\\"recordImpression\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordClick\\\":{\\\"name\\\":\\\"recordClick\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AdVariation\\\",\\\"collectionExportName\\\":\\\"AdVariationCollection\\\",\\\"displayLabelField\\\":\\\"name\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"ad_variations\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"ad_variations\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"group_id\\\\\\\" UUID,\\\\n \\\\\\\"format_id\\\\\\\" UUID,\\\\n \\\\\\\"asset_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"click_url\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"alt_text\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"weight\\\\\\\" INTEGER DEFAULT 1,\\\\n \\\\\\\"status\\\\\\\" TEXT,\\\\n \\\\\\\"impressions\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"clicks\\\\\\\" INTEGER DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"group_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_groups\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"format_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"ad_formats\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"asset_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"click_url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"alt_text\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"weight\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":1},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"impressions\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":0},\\\"clicks\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"ad_variations_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"ad_variations_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"ad_variations_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"ad_variations_group_id_idx\\\",\\\"columns\\\":[\\\"group_id\\\"]},{\\\"name\\\":\\\"ad_variations_format_id_idx\\\",\\\"columns\\\":[\\\"format_id\\\"]},{\\\"name\\\":\\\"ad_variations_asset_id_idx\\\",\\\"columns\\\":[\\\"asset_id\\\"]}],\\\"version\\\":\\\"e8fb6233\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-ads\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"recipes\\\":[{\\\"id\\\":\\\"ads.campaigns\\\",\\\"className\\\":\\\"AdsCampaignsRecipe\\\",\\\"label\\\":\\\"Ads\\\",\\\"summary\\\":\\\"Run ad campaigns on your site, choose which ads show where, and see which ones get clicked.\\\",\\\"synonyms\\\":[\\\"ads\\\",\\\"advertising\\\",\\\"ad campaigns\\\",\\\"banner ads\\\",\\\"advertisements\\\",\\\"display ads\\\"],\\\"models\\\":[\\\"@happyvertical/smrt-ads:AdGroup\\\",\\\"@happyvertical/smrt-ads:AdVariation\\\",\\\"@happyvertical/smrt-ads:AdFormat\\\",\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\"],\\\"nav\\\":[{\\\"label\\\":\\\"Ad campaigns\\\",\\\"model\\\":\\\"@happyvertical/smrt-ads:AdGroup\\\",\\\"icon\\\":\\\"tag\\\",\\\"description\\\":\\\"Each campaign you run, with its dates, budget and where it stands.\\\",\\\"noun\\\":\\\"ad campaign\\\"},{\\\"label\\\":\\\"Ads\\\",\\\"model\\\":\\\"@happyvertical/smrt-ads:AdVariation\\\",\\\"icon\\\":\\\"fileText\\\",\\\"description\\\":\\\"The ads inside each campaign, how often each shows and how many clicks it got.\\\",\\\"noun\\\":\\\"ad\\\"},{\\\"label\\\":\\\"Ad sizes\\\",\\\"model\\\":\\\"@happyvertical/smrt-ads:AdFormat\\\",\\\"icon\\\":\\\"layers\\\",\\\"description\\\":\\\"The shapes and sizes an ad can be, shared by every campaign.\\\",\\\"noun\\\":\\\"ad size\\\"},{\\\"label\\\":\\\"Priority tiers\\\",\\\"model\\\":\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\",\\\"icon\\\":\\\"settings\\\",\\\"description\\\":\\\"The order campaigns are tried in when more than one could show.\\\",\\\"noun\\\":\\\"tier\\\"}],\\\"requires\\\":[],\\\"section\\\":{\\\"id\\\":\\\"grow\\\",\\\"label\\\":\\\"Grow\\\",\\\"icon\\\":\\\"tag\\\",\\\"description\\\":\\\"Bring in new customers and reward the people who help.\\\"},\\\"options\\\":{\\\"@happyvertical/smrt-ads:AdGroup\\\":{\\\"fields\\\":{\\\"name\\\":{\\\"order\\\":1},\\\"status\\\":{\\\"order\\\":2},\\\"tierId\\\":{\\\"label\\\":\\\"Priority tier\\\",\\\"order\\\":3},\\\"startDate\\\":{\\\"label\\\":\\\"Starts on\\\",\\\"order\\\":4},\\\"endDate\\\":{\\\"label\\\":\\\"Ends on\\\",\\\"order\\\":5},\\\"dailyBudget\\\":{\\\"label\\\":\\\"Daily budget\\\",\\\"order\\\":6},\\\"totalBudget\\\":{\\\"label\\\":\\\"Total budget\\\",\\\"order\\\":7},\\\"tenantId\\\":{\\\"visibility\\\":\\\"hidden\\\"},\\\"contractId\\\":{\\\"label\\\":\\\"Sales contract\\\",\\\"visibility\\\":\\\"advanced\\\"},\\\"verticalSlug\\\":{\\\"label\\\":\\\"Category\\\",\\\"visibility\\\":\\\"advanced\\\"},\\\"targeting\\\":{\\\"visibility\\\":\\\"hidden\\\"},\\\"zoneIds\\\":{\\\"visibility\\\":\\\"hidden\\\"}}},\\\"@happyvertical/smrt-ads:AdVariation\\\":{\\\"fields\\\":{\\\"name\\\":{\\\"order\\\":1},\\\"groupId\\\":{\\\"label\\\":\\\"Ad campaign\\\",\\\"order\\\":2},\\\"formatId\\\":{\\\"label\\\":\\\"Ad size\\\",\\\"order\\\":3},\\\"assetId\\\":{\\\"label\\\":\\\"Picture\\\",\\\"order\\\":4},\\\"clickUrl\\\":{\\\"label\\\":\\\"Link to\\\",\\\"order\\\":5},\\\"altText\\\":{\\\"label\\\":\\\"Words for the picture\\\",\\\"order\\\":6},\\\"weight\\\":{\\\"order\\\":7},\\\"status\\\":{\\\"order\\\":8},\\\"tenantId\\\":{\\\"visibility\\\":\\\"hidden\\\"},\\\"impressions\\\":{\\\"label\\\":\\\"Times shown\\\",\\\"locked\\\":true,\\\"visibility\\\":\\\"advanced\\\"},\\\"clicks\\\":{\\\"locked\\\":true,\\\"visibility\\\":\\\"advanced\\\"}}},\\\"@happyvertical/smrt-ads:AdFormat\\\":{\\\"fields\\\":{\\\"name\\\":{\\\"order\\\":1},\\\"width\\\":{\\\"order\\\":2},\\\"height\\\":{\\\"order\\\":3},\\\"formatType\\\":{\\\"label\\\":\\\"Kind\\\",\\\"order\\\":4},\\\"description\\\":{\\\"order\\\":5}}},\\\"@happyvertical/smrt-ads:AdDeliveryTier\\\":{\\\"fields\\\":{\\\"name\\\":{\\\"order\\\":1},\\\"priority\\\":{\\\"order\\\":2},\\\"pricingModel\\\":{\\\"label\\\":\\\"How it is charged\\\",\\\"order\\\":3},\\\"description\\\":{\\\"order\\\":4}}}},\\\"help\\\":{\\\"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\\\",\\\"fieldRefs\\\":[\\\"AdDeliveryTier.name\\\",\\\"AdDeliveryTier.pricingModel\\\",\\\"AdDeliveryTier.priority\\\",\\\"AdFormat.formatType\\\",\\\"AdFormat.height\\\",\\\"AdFormat.name\\\",\\\"AdFormat.width\\\",\\\"AdGroup.dailyBudget\\\",\\\"AdGroup.endDate\\\",\\\"AdGroup.name\\\",\\\"AdGroup.startDate\\\",\\\"AdGroup.status\\\",\\\"AdGroup.tierId\\\",\\\"AdGroup.totalBudget\\\",\\\"AdVariation.altText\\\",\\\"AdVariation.assetId\\\",\\\"AdVariation.clickUrl\\\",\\\"AdVariation.clicks\\\",\\\"AdVariation.formatId\\\",\\\"AdVariation.groupId\\\",\\\"AdVariation.impressions\\\",\\\"AdVariation.name\\\",\\\"AdVariation.status\\\",\\\"AdVariation.weight\\\"]},\\\"demo\\\":{\\\"mode\\\":\\\"server\\\",\\\"reasons\\\":[\\\"Needs a server because its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624).\\\"]}}],\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-commerce\\\",\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"browser\\\":{\\\"status\\\":\\\"server-only\\\",\\\"issues\\\":[\\\"#3624\\\"],\\\"via\\\":[\\\"@happyvertical/smrt-tenancy\\\"]},\\\"stampsConstructors\\\":true}\"));\n","/**\n * Types and enums for smrt-ads package\n */\n\n/**\n * Ad format types for different creative types\n */\nexport enum AdFormatType {\n BANNER = 'banner',\n NATIVE = 'native',\n VIDEO = 'video',\n}\n\n/**\n * Pricing models for ad delivery tiers\n */\nexport enum PricingModel {\n FIXED = 'fixed',\n CPM = 'cpm',\n CPC = 'cpc',\n CPA = 'cpa',\n}\n\n/**\n * Status for ad groups\n */\nexport enum AdGroupStatus {\n DRAFT = 'draft',\n ACTIVE = 'active',\n PAUSED = 'paused',\n COMPLETED = 'completed',\n}\n\n/**\n * Status for ad variations\n */\nexport enum AdVariationStatus {\n DRAFT = 'draft',\n ACTIVE = 'active',\n PAUSED = 'paused',\n}\n\n/**\n * Event types for ad tracking\n */\nexport enum AdEventType {\n IMPRESSION = 'impression',\n CLICK = 'click',\n CONVERSION = 'conversion',\n}\n","/**\n * AdDeliveryTier model - Priority waterfall for ad selection\n * @packageDocumentation\n */\n\nimport {\n field,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { PricingModel } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdDeliveryTier}.\n */\nexport interface AdDeliveryTierOptions extends SmrtObjectOptions {\n name?: string;\n priority?: number;\n pricingModel?: PricingModel;\n description?: string;\n}\n\n/**\n * AdDeliveryTier defines priority levels for ad serving.\n *\n * Ads are selected by priority (lower = higher priority):\n * 1. Sponsorship - Guaranteed, premium placements\n * 2. Standard - Regular programmatic ads\n * 3. House - Self-promotional/fallback ads\n *\n * @example\n * ```typescript\n * const sponsorship = await tiers.create({\n * name: 'Sponsorship',\n * priority: 1,\n * pricingModel: PricingModel.FIXED,\n * description: 'Premium guaranteed placements'\n * });\n * ```\n */\n// Intentional exception to standards.md §7 (`@TenantScoped`):\n// `AdDeliveryTier` is a shared catalog model describing the priority waterfall\n// for ad selection (Sponsorship → Standard → House). Tier definitions are part\n// of the package's ad-serving contract, not per-tenant configuration. Adding\n// `@TenantScoped` would require every tenant to seed the same three rows and\n// would fragment the selection algorithm without a clear use case. See\n// `packages/ads/CLAUDE.md` \"Tenancy\" section for context.\n@smrt({\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get'] },\n cli: { skipApiCheck: true },\n})\nexport class AdDeliveryTier extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Display name (e.g., \"Sponsorship\", \"Standard\", \"House\")\n */\n @field({\n description:\n 'What the tier is called, for example Sponsorship, Standard or House.',\n })\n name: string = '';\n\n /**\n * Priority level (lower = higher priority: 1, 2, 3...)\n */\n @field({\n description:\n 'The order tiers are tried in: 1 is tried first, then 2, and so on.',\n })\n priority: number = 0;\n\n /**\n * Pricing model for this tier\n */\n @field({\n description:\n 'How ads in this tier are charged: a fixed price, per thousand showings, per click, or per sale.',\n })\n pricingModel: PricingModel = PricingModel.CPM;\n\n /**\n * Optional description\n */\n @field({ description: 'A note about what this tier is for.' })\n description: string = '';\n\n constructor(options: AdDeliveryTierOptions = {}) {\n super(options);\n if (options.name !== undefined) this.name = options.name;\n if (options.priority !== undefined) this.priority = options.priority;\n if (options.pricingModel !== undefined)\n this.pricingModel = options.pricingModel;\n if (options.description !== undefined)\n this.description = options.description;\n }\n\n /**\n * Check if this tier is higher priority than another\n */\n isHigherPriorityThan(other: AdDeliveryTier): boolean {\n return this.priority < other.priority;\n }\n\n /**\n * Check if this is a fixed pricing tier\n */\n isFixedPricing(): boolean {\n return this.pricingModel === PricingModel.FIXED;\n }\n\n /**\n * Check if this is a performance-based tier (CPC, CPA)\n */\n isPerformanceBased(): boolean {\n return (\n this.pricingModel === PricingModel.CPC ||\n this.pricingModel === PricingModel.CPA\n );\n }\n}\n\nexport default AdDeliveryTier;\n","/**\n * AdDeliveryTierCollection - Collection manager for AdDeliveryTier objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { AdDeliveryTier } from '../models/AdDeliveryTier.js';\nimport { PricingModel } from '../types/index.js';\n\nexport class AdDeliveryTierCollection extends SmrtCollection<AdDeliveryTier> {\n static readonly _itemClass = AdDeliveryTier;\n\n /**\n * Find tiers ordered by priority (ascending, lower = higher priority)\n *\n * @returns Array of tiers ordered by priority\n */\n async findByPriority(): Promise<AdDeliveryTier[]> {\n return await this.list({\n orderBy: 'priority ASC',\n });\n }\n\n /**\n * Find tiers by pricing model\n *\n * @param pricingModel - Pricing model to filter by\n * @returns Array of matching tiers\n */\n async findByPricingModel(\n pricingModel: PricingModel,\n ): Promise<AdDeliveryTier[]> {\n return await this.list({\n where: { pricingModel },\n orderBy: 'priority ASC',\n });\n }\n\n /**\n * Get the highest priority tier\n *\n * @returns Highest priority tier or null\n */\n async getHighestPriority(): Promise<AdDeliveryTier | null> {\n const results = await this.list({\n orderBy: 'priority ASC',\n limit: 1,\n });\n return results.length > 0 ? results[0] : null;\n }\n\n /**\n * Find fixed pricing tiers\n */\n async findFixedPricing(): Promise<AdDeliveryTier[]> {\n return await this.findByPricingModel(PricingModel.FIXED);\n }\n\n /**\n * Find CPM-based tiers\n */\n async findCPM(): Promise<AdDeliveryTier[]> {\n return await this.findByPricingModel(PricingModel.CPM);\n }\n\n /**\n * Find performance-based tiers (CPC, CPA)\n */\n async findPerformanceBased(): Promise<AdDeliveryTier[]> {\n const cpc = await this.findByPricingModel(PricingModel.CPC);\n const cpa = await this.findByPricingModel(PricingModel.CPA);\n return [...cpc, ...cpa].sort((a, b) => a.priority - b.priority);\n }\n}\n","/**\n * AdEvent model - Immutable event tracking (impressions, clicks)\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { AdEventType } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdEvent}.\n */\nexport interface AdEventOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n variationId?: string;\n zoneId?: string;\n siteId?: string;\n eventType?: AdEventType;\n timestamp?: Date;\n metadata?: string;\n}\n\n/**\n * AdEvent tracks ad impressions, clicks, and conversions.\n * Events are immutable (append-only, no update/delete).\n *\n * References:\n * - variationId: FK to AdVariation (within package)\n * - zoneId: String reference to smrt-properties Zone (cross-package)\n * - siteId: Denormalized for query efficiency (cross-package)\n *\n * @example\n * ```typescript\n * // Track an impression\n * const impression = await events.create({\n * variationId: variation.id,\n * zoneId: 'zone-uuid',\n * siteId: 'site-uuid',\n * eventType: AdEventType.IMPRESSION,\n * metadata: JSON.stringify({\n * ip: '192.168.1.1',\n * userAgent: 'Mozilla/5.0...',\n * referrer: 'https://example.com'\n * })\n * });\n *\n * // Track a click\n * const click = await events.create({\n * variationId: variation.id,\n * zoneId: 'zone-uuid',\n * siteId: 'site-uuid',\n * eventType: AdEventType.CLICK\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['create', 'list'] }, // No update/delete (immutable)\n mcp: { include: ['create'] },\n cli: false, // High volume, not useful in CLI\n})\nexport class AdEvent extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Tenant ID for multi-tenancy support\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Variation ID (FK to AdVariation)\n */\n @foreignKey('AdVariation')\n variationId: string = '';\n\n /**\n * Zone ID (FK to smrt-properties Zone, cross-package)\n */\n @crossPackageRef('@happyvertical/smrt-properties:Zone')\n zoneId: string = '';\n\n /**\n * Site ID (denormalized from Zone for query efficiency)\n */\n siteId: string = '';\n\n /**\n * Event type (impression, click, conversion)\n */\n eventType: AdEventType = AdEventType.IMPRESSION;\n\n /**\n * Event timestamp\n */\n timestamp: Date = new Date();\n\n /**\n * Analytics metadata as JSON string\n * (IP, user agent, referrer, etc.)\n */\n metadata: string = '';\n\n constructor(options: AdEventOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.variationId !== undefined)\n this.variationId = options.variationId;\n if (options.zoneId !== undefined) this.zoneId = options.zoneId;\n if (options.siteId !== undefined) this.siteId = options.siteId;\n if (options.eventType !== undefined) this.eventType = options.eventType;\n if (options.timestamp !== undefined) this.timestamp = options.timestamp;\n if (options.metadata !== undefined) this.metadata = options.metadata;\n }\n\n /**\n * Get metadata as object\n */\n getMetadata(): Record<string, unknown> {\n if (!this.metadata) return {};\n try {\n return JSON.parse(this.metadata);\n } catch {\n return {};\n }\n }\n\n /**\n * Set metadata from object\n */\n setMetadata(data: Record<string, unknown>): void {\n this.metadata = JSON.stringify(data);\n }\n\n /**\n * Check if this is an impression event\n */\n isImpression(): boolean {\n return this.eventType === AdEventType.IMPRESSION;\n }\n\n /**\n * Check if this is a click event\n */\n isClick(): boolean {\n return this.eventType === AdEventType.CLICK;\n }\n\n /**\n * Check if this is a conversion event\n */\n isConversion(): boolean {\n return this.eventType === AdEventType.CONVERSION;\n }\n}\n\nexport default AdEvent;\n","/**\n * AdEventCollection - Collection manager for AdEvent objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { AdEvent } from '../models/AdEvent.js';\nimport { AdEventType } from '../types/index.js';\n\nexport class AdEventCollection extends SmrtCollection<AdEvent> {\n static readonly _itemClass = AdEvent;\n\n /**\n * Find events by variation\n *\n * @param variationId - Variation ID\n * @returns Array of events\n */\n async findByVariation(variationId: string): Promise<AdEvent[]> {\n return await this.list({\n where: { variationId },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Find events by zone\n *\n * @param zoneId - Zone ID\n * @returns Array of events\n */\n async findByZone(zoneId: string): Promise<AdEvent[]> {\n return await this.list({\n where: { zoneId },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Find events by site\n *\n * @param siteId - Site ID\n * @returns Array of events\n */\n async findBySite(siteId: string): Promise<AdEvent[]> {\n return await this.list({\n where: { siteId },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Find events in date range\n *\n * @param start - Start date\n * @param end - End date\n * @returns Array of events\n */\n async findByDateRange(start: Date, end: Date): Promise<AdEvent[]> {\n return await this.list({\n where: {\n 'timestamp >=': start.toISOString(),\n 'timestamp <=': end.toISOString(),\n },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Find events by type\n *\n * @param eventType - Event type\n * @returns Array of events\n */\n async findByType(eventType: AdEventType): Promise<AdEvent[]> {\n return await this.list({\n where: { eventType },\n orderBy: 'timestamp DESC',\n });\n }\n\n /**\n * Count events by type for a variation\n *\n * @param variationId - Variation ID\n * @param eventType - Event type\n * @returns Count of events\n */\n async countByType(\n variationId: string,\n eventType: AdEventType,\n ): Promise<number> {\n const events = await this.list({\n where: { variationId, eventType },\n });\n return events.length;\n }\n\n /**\n * Count impressions for a variation\n */\n async countImpressions(variationId: string): Promise<number> {\n return await this.countByType(variationId, AdEventType.IMPRESSION);\n }\n\n /**\n * Count clicks for a variation\n */\n async countClicks(variationId: string): Promise<number> {\n return await this.countByType(variationId, AdEventType.CLICK);\n }\n\n /**\n * Count conversions for a variation\n */\n async countConversions(variationId: string): Promise<number> {\n return await this.countByType(variationId, AdEventType.CONVERSION);\n }\n\n /**\n * Find all impressions\n */\n async findImpressions(): Promise<AdEvent[]> {\n return await this.findByType(AdEventType.IMPRESSION);\n }\n\n /**\n * Find all clicks\n */\n async findClicks(): Promise<AdEvent[]> {\n return await this.findByType(AdEventType.CLICK);\n }\n\n /**\n * Find all conversions\n */\n async findConversions(): Promise<AdEvent[]> {\n return await this.findByType(AdEventType.CONVERSION);\n }\n\n /**\n * Get aggregate stats for a variation\n *\n * @param variationId - Variation ID\n * @returns Stats object with impressions, clicks, conversions, CTR\n */\n async getVariationStats(variationId: string): Promise<{\n impressions: number;\n clicks: number;\n conversions: number;\n ctr: number;\n conversionRate: number;\n }> {\n const impressions = await this.countImpressions(variationId);\n const clicks = await this.countClicks(variationId);\n const conversions = await this.countConversions(variationId);\n\n return {\n impressions,\n clicks,\n conversions,\n ctr: impressions > 0 ? clicks / impressions : 0,\n conversionRate: clicks > 0 ? conversions / clicks : 0,\n };\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tenancy Helper Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Find ad events belonging to a specific tenant\n *\n * @param tenantId - Tenant ID to filter by\n * @returns Array of ad events for the tenant\n */\n async findByTenant(tenantId: string): Promise<AdEvent[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find global ad events (no tenant association).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global ad events\n */\n async findGlobal(): Promise<AdEvent[]> {\n return queryGlobal<AdEvent>(this);\n }\n\n /**\n * Find ad events for a tenant including global (shared) events.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID to include\n * @returns Array of tenant-specific and global ad events\n */\n async findWithGlobals(tenantId: string): Promise<AdEvent[]> {\n return queryWithGlobals<AdEvent>(this, tenantId, 'AdEvent.findWithGlobals');\n }\n}\n","/**\n * AdFormat model - Standard IAB ad dimensions and types\n * @packageDocumentation\n */\n\nimport {\n field,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { AdFormatType } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdFormat}.\n */\nexport interface AdFormatOptions extends SmrtObjectOptions {\n name?: string;\n width?: number;\n height?: number;\n formatType?: AdFormatType;\n description?: string;\n}\n\n/**\n * AdFormat defines standard ad dimensions and types (IAB standards).\n *\n * @example\n * ```typescript\n * const leaderboard = await formats.create({\n * name: 'Leaderboard',\n * width: 728,\n * height: 90,\n * formatType: AdFormatType.BANNER\n * });\n * ```\n */\n// Intentional exception to standards.md §7 (`@TenantScoped`):\n// `AdFormat` is a shared catalog model describing IAB standard ad dimensions\n// (e.g. 728x90 Leaderboard). The dimensions are an industry standard, not a\n// per-tenant configuration. Adding `@TenantScoped` would require every tenant\n// to seed the same IAB rows. See `packages/ads/CLAUDE.md` \"Tenancy\" section\n// for context.\n@smrt({\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get'] },\n cli: { skipApiCheck: true },\n})\nexport class AdFormat extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Display name (e.g., \"Leaderboard\", \"Medium Rectangle\")\n */\n @field({ description: 'What the size is called, for example Leaderboard.' })\n name: string = '';\n\n /**\n * Width in pixels\n */\n @field({ description: 'How wide the ad is, in pixels.' })\n width: number = 0;\n\n /**\n * Height in pixels\n */\n @field({ description: 'How tall the ad is, in pixels.' })\n height: number = 0;\n\n /**\n * Format type (banner, native, video)\n */\n @field({\n description:\n 'What kind of ad fits this size: a picture, a piece written to look like your own content, or a video.',\n })\n formatType: AdFormatType = AdFormatType.BANNER;\n\n /**\n * Optional description\n */\n @field({ description: 'A note about where this size is usually used.' })\n description: string = '';\n\n constructor(options: AdFormatOptions = {}) {\n super(options);\n if (options.name !== undefined) this.name = options.name;\n if (options.width !== undefined) this.width = options.width;\n if (options.height !== undefined) this.height = options.height;\n if (options.formatType !== undefined) this.formatType = options.formatType;\n if (options.description !== undefined)\n this.description = options.description;\n }\n\n /**\n * Get dimensions as string (e.g., \"728x90\")\n */\n getDimensions(): string {\n return `${this.width}x${this.height}`;\n }\n\n /**\n * Check if format matches specific dimensions\n */\n matchesDimensions(width: number, height: number): boolean {\n return this.width === width && this.height === height;\n }\n}\n\nexport default AdFormat;\n","/**\n * AdFormatCollection - Collection manager for AdFormat objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { AdFormat } from '../models/AdFormat.js';\nimport { AdFormatType } from '../types/index.js';\n\nexport class AdFormatCollection extends SmrtCollection<AdFormat> {\n static readonly _itemClass = AdFormat;\n\n /**\n * Find format by dimensions\n *\n * @param width - Width in pixels\n * @param height - Height in pixels\n * @returns Matching format or null\n */\n async findByDimensions(\n width: number,\n height: number,\n ): Promise<AdFormat | null> {\n const results = await this.list({\n where: { width, height },\n limit: 1,\n });\n return results.length > 0 ? results[0] : null;\n }\n\n /**\n * Find formats by type\n *\n * @param formatType - Format type (banner, native, video)\n * @returns Array of matching formats\n */\n async findByType(formatType: AdFormatType): Promise<AdFormat[]> {\n return await this.list({\n where: { formatType },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find all banner formats\n */\n async findBanners(): Promise<AdFormat[]> {\n return await this.findByType(AdFormatType.BANNER);\n }\n\n /**\n * Find all native formats\n */\n async findNative(): Promise<AdFormat[]> {\n return await this.findByType(AdFormatType.NATIVE);\n }\n\n /**\n * Find all video formats\n */\n async findVideo(): Promise<AdFormat[]> {\n return await this.findByType(AdFormatType.VIDEO);\n }\n}\n","/**\n * AdGroup model - Campaign targeting and creative organization\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { AdGroupStatus } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdGroup}.\n */\nexport interface AdGroupOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n contractId?: string;\n tierId?: string;\n name?: string;\n verticalSlug?: string;\n targeting?: string;\n zoneIds?: string;\n startDate?: Date | null;\n endDate?: Date | null;\n dailyBudget?: number;\n totalBudget?: number;\n status?: AdGroupStatus;\n}\n\n/**\n * AdGroup organizes ad creatives with targeting and budget controls.\n *\n * References:\n * - tierId: FK to AdDeliveryTier (within package)\n * - contractId: String reference to smrt-commerce Contract (cross-package)\n * - zoneIds: JSON array of allowed smrt-properties Zone IDs (cross-package)\n * - verticalSlug: Tag slug from smrt-tags (cross-package)\n *\n * @example\n * ```typescript\n * const adGroup = await groups.create({\n * contractId: 'contract-uuid',\n * tierId: tier.id,\n * name: 'Summer Sale - Desktop',\n * verticalSlug: 'retail',\n * targeting: JSON.stringify({ device: 'desktop' }),\n * zoneIds: JSON.stringify(['zone-1', 'zone-2']),\n * dailyBudget: 100.00,\n * totalBudget: 3000.00,\n * startDate: new Date('2024-06-01'),\n * endDate: new Date('2024-08-31')\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get', 'create'] },\n cli: { skipApiCheck: true },\n})\nexport class AdGroup extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Tenant ID for multi-tenancy support\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Sales contract ID (cross-package reference to smrt-commerce)\n */\n @crossPackageRef('@happyvertical/smrt-commerce:SalesContract', {\n validateSubtype: true,\n })\n @field({\n description:\n 'The sales contract this campaign is sold under, if there is one.',\n })\n contractId: string = '';\n\n /**\n * Delivery tier ID (FK to AdDeliveryTier)\n */\n @foreignKey('AdDeliveryTier')\n @field({\n description:\n 'The priority tier the campaign runs in. Tiers are tried in order when more than one campaign could show.',\n })\n tierId: string = '';\n\n /**\n * Display name (e.g., \"Summer Sale - Desktop\")\n */\n @field({\n description: 'What you call the campaign, for example Summer sale.',\n })\n name: string = '';\n\n /**\n * Vertical/category tag slug from smrt-tags (context=\"advertising\")\n */\n @field({\n description: 'The category the campaign belongs to, such as retail.',\n })\n verticalSlug: string = '';\n\n /**\n * Targeting rules as JSON string\n */\n targeting: string = '';\n\n /**\n * Allowed Zone IDs as JSON array string (FK to smrt-properties Zone)\n */\n zoneIds: string = '';\n\n /**\n * Campaign start date\n */\n @field({ description: 'The first day the campaign can show.' })\n startDate: Date | null = null;\n\n /**\n * Campaign end date\n */\n @field({ description: 'The last day the campaign can show.' })\n endDate: Date | null = null;\n\n /**\n * Daily budget limit\n */\n @field({\n description:\n 'The most to spend in one day. The app shows this but does not stop the campaign by itself.',\n })\n dailyBudget: number = 0.0;\n\n /**\n * Total campaign budget\n */\n @field({ description: 'The most to spend over the whole campaign.' })\n totalBudget: number = 0.0;\n\n /**\n * Current status\n */\n @field({\n description:\n 'Where the campaign stands: draft, active, paused or completed. Only active campaigns show ads.',\n })\n status: AdGroupStatus = AdGroupStatus.DRAFT;\n\n constructor(options: AdGroupOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.contractId !== undefined) this.contractId = options.contractId;\n if (options.tierId !== undefined) this.tierId = options.tierId;\n if (options.name !== undefined) this.name = options.name;\n if (options.verticalSlug !== undefined)\n this.verticalSlug = options.verticalSlug;\n if (options.targeting !== undefined) this.targeting = options.targeting;\n if (options.zoneIds !== undefined) this.zoneIds = options.zoneIds;\n if (options.startDate !== undefined) this.startDate = options.startDate;\n if (options.endDate !== undefined) this.endDate = options.endDate;\n if (options.dailyBudget !== undefined)\n this.dailyBudget = options.dailyBudget;\n if (options.totalBudget !== undefined)\n this.totalBudget = options.totalBudget;\n if (options.status !== undefined) this.status = options.status;\n }\n\n /**\n * Get zone IDs as array\n */\n getZoneIds(): string[] {\n if (!this.zoneIds) return [];\n try {\n return JSON.parse(this.zoneIds);\n } catch {\n return [];\n }\n }\n\n /**\n * Set zone IDs from array\n */\n setZoneIds(ids: string[]): void {\n this.zoneIds = JSON.stringify(ids);\n }\n\n /**\n * Add a zone ID\n */\n addZoneId(zoneId: string): void {\n const ids = this.getZoneIds();\n if (!ids.includes(zoneId)) {\n ids.push(zoneId);\n this.setZoneIds(ids);\n }\n }\n\n /**\n * Remove a zone ID\n */\n removeZoneId(zoneId: string): void {\n const ids = this.getZoneIds().filter((id) => id !== zoneId);\n this.setZoneIds(ids);\n }\n\n /**\n * Check if zone ID is allowed\n */\n hasZoneId(zoneId: string): boolean {\n return this.getZoneIds().includes(zoneId);\n }\n\n /**\n * Get targeting rules as object\n */\n getTargeting(): Record<string, unknown> {\n if (!this.targeting) return {};\n try {\n return JSON.parse(this.targeting);\n } catch {\n return {};\n }\n }\n\n /**\n * Set targeting rules from object\n */\n setTargeting(rules: Record<string, unknown>): void {\n this.targeting = JSON.stringify(rules);\n }\n\n /**\n * Check if ad group is currently active\n */\n isActive(): boolean {\n if (this.status !== AdGroupStatus.ACTIVE) return false;\n const now = new Date();\n if (this.startDate && now < this.startDate) return false;\n if (this.endDate && now > this.endDate) return false;\n return true;\n }\n\n /**\n * Check if ad group is in draft state\n */\n isDraft(): boolean {\n return this.status === AdGroupStatus.DRAFT;\n }\n\n /**\n * Check if ad group is paused\n */\n isPaused(): boolean {\n return this.status === AdGroupStatus.PAUSED;\n }\n\n /**\n * Check if ad group is completed\n */\n isCompleted(): boolean {\n return this.status === AdGroupStatus.COMPLETED;\n }\n\n /**\n * Check if ad group has ended (past end date)\n */\n hasEnded(): boolean {\n if (!this.endDate) return false;\n return new Date() > this.endDate;\n }\n\n /**\n * Check if ad group has started\n */\n hasStarted(): boolean {\n if (!this.startDate) return true;\n return new Date() >= this.startDate;\n }\n}\n\nexport default AdGroup;\n","/**\n * AdGroupCollection - Collection manager for AdGroup objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { AdGroup } from '../models/AdGroup.js';\nimport { AdGroupStatus } from '../types/index.js';\n\nexport class AdGroupCollection extends SmrtCollection<AdGroup> {\n static readonly _itemClass = AdGroup;\n\n /**\n * Find ad groups by contract\n *\n * @param contractId - Contract ID\n * @returns Array of ad groups\n */\n async findByContract(contractId: string): Promise<AdGroup[]> {\n return await this.list({\n where: { contractId },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find ad groups by tier\n *\n * @param tierId - Delivery tier ID\n * @returns Array of ad groups\n */\n async findByTier(tierId: string): Promise<AdGroup[]> {\n return await this.list({\n where: { tierId },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find ad groups by status\n *\n * @param status - Ad group status\n * @returns Array of ad groups\n */\n async findByStatus(status: AdGroupStatus): Promise<AdGroup[]> {\n return await this.list({\n where: { status },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find currently active ad groups\n * (status=active, started, not ended)\n *\n * @returns Array of active ad groups\n */\n async findActive(): Promise<AdGroup[]> {\n const results = await this.list({\n where: {\n status: AdGroupStatus.ACTIVE,\n },\n orderBy: 'created_at DESC',\n });\n // Filter by date in memory (complex date logic)\n return results.filter((group) => group.isActive());\n }\n\n /**\n * Find ad groups by vertical slug\n *\n * @param verticalSlug - Tag slug from smrt-tags\n * @returns Array of ad groups\n */\n async findByVertical(verticalSlug: string): Promise<AdGroup[]> {\n return await this.list({\n where: { verticalSlug },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find ad groups that can serve to a specific zone\n *\n * @param zoneId - Zone ID to check\n * @returns Array of ad groups containing zone\n */\n async findByZone(zoneId: string): Promise<AdGroup[]> {\n // Must filter in memory since zoneIds is JSON\n const all = await this.list({\n where: { status: AdGroupStatus.ACTIVE },\n });\n return all.filter((group) => group.hasZoneId(zoneId));\n }\n\n /**\n * Find ad groups eligible to serve for a zone\n * (active, has zone, within date range)\n *\n * @param zoneId - Zone ID to check\n * @returns Array of eligible ad groups\n */\n async findEligibleForZone(zoneId: string): Promise<AdGroup[]> {\n const groups = await this.findByZone(zoneId);\n return groups.filter((group) => group.isActive());\n }\n\n /**\n * Find all draft ad groups\n */\n async findDrafts(): Promise<AdGroup[]> {\n return await this.findByStatus(AdGroupStatus.DRAFT);\n }\n\n /**\n * Find all paused ad groups\n */\n async findPaused(): Promise<AdGroup[]> {\n return await this.findByStatus(AdGroupStatus.PAUSED);\n }\n\n /**\n * Find all completed ad groups\n */\n async findCompleted(): Promise<AdGroup[]> {\n return await this.findByStatus(AdGroupStatus.COMPLETED);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tenancy Helper Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Find ad groups belonging to a specific tenant\n *\n * @param tenantId - Tenant ID to filter by\n * @returns Array of ad groups for the tenant\n */\n async findByTenant(tenantId: string): Promise<AdGroup[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find global ad groups (no tenant association).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global ad groups\n */\n async findGlobal(): Promise<AdGroup[]> {\n return queryGlobal<AdGroup>(this);\n }\n\n /**\n * Find ad groups for a tenant including global (shared) ad groups.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID to include\n * @returns Array of tenant-specific and global ad groups\n */\n async findWithGlobals(tenantId: string): Promise<AdGroup[]> {\n return queryWithGlobals<AdGroup>(this, tenantId, 'AdGroup.findWithGlobals');\n }\n}\n","/**\n * AdVariation model - Creative asset with A/B testing support\n * @packageDocumentation\n */\n\nimport {\n crossPackageRef,\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport { TenantScoped, tenantId } from '@happyvertical/smrt-tenancy';\nimport { AdVariationStatus } from '../types/index.js';\n\n/**\n * Options for constructing an {@link AdVariation}.\n */\nexport interface AdVariationOptions extends SmrtObjectOptions {\n tenantId?: string | null;\n groupId?: string;\n formatId?: string;\n assetId?: string;\n name?: string;\n clickUrl?: string;\n altText?: string;\n weight?: number;\n status?: AdVariationStatus;\n impressions?: number;\n clicks?: number;\n}\n\n/**\n * AdVariation represents a creative asset within an ad group.\n * Supports A/B testing via weighted selection.\n *\n * References:\n * - groupId: FK to AdGroup (within package)\n * - formatId: FK to AdFormat (within package)\n * - assetId: String reference to smrt-assets Asset (cross-package)\n *\n * @example\n * ```typescript\n * const variation = await variations.create({\n * groupId: adGroup.id,\n * formatId: leaderboard.id,\n * assetId: 'asset-uuid',\n * name: 'Version A - Blue CTA',\n * clickUrl: 'https://example.com/landing',\n * altText: 'Summer Sale - 50% off',\n * weight: 2 // 2x more likely than weight=1\n * });\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableStrategy: 'sti',\n api: { include: ['list', 'get', 'create', 'update'] },\n mcp: { include: ['list', 'get', 'create'] },\n cli: { skipApiCheck: true },\n})\nexport class AdVariation extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-ads\";\n /**\n * Tenant ID for multi-tenancy support\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Ad group ID (FK to AdGroup)\n */\n @foreignKey('AdGroup')\n @field({ description: 'The campaign this ad belongs to.' })\n groupId: string = '';\n\n /**\n * Ad format ID (FK to AdFormat)\n */\n @foreignKey('AdFormat')\n @field({ description: 'The ad size this ad is made for.' })\n formatId: string = '';\n\n /**\n * Asset ID (FK to smrt-assets Asset, cross-package)\n */\n @crossPackageRef('@happyvertical/smrt-assets:Asset')\n @field({ description: 'The picture people see.' })\n assetId: string = '';\n\n /**\n * Display name (e.g., \"Version A - Blue CTA\")\n */\n @field({\n description: 'What you call this ad, for example Version A, blue button.',\n })\n name: string = '';\n\n /**\n * Click destination URL\n */\n @field({ description: 'The web address people go to when they tap the ad.' })\n clickUrl: string = '';\n\n /**\n * Accessibility alt text\n */\n @field({\n description:\n 'A few words that describe the picture for people who cannot see it.',\n })\n altText: string = '';\n\n /**\n * A/B testing weight (higher = more likely to be selected)\n */\n @field({\n description:\n '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.',\n })\n weight: number = 1;\n\n /**\n * Current status\n */\n @field({\n description:\n 'Where the ad stands: draft, active or paused. Only active ads show.',\n })\n status: AdVariationStatus = AdVariationStatus.DRAFT;\n\n /**\n * Denormalized impression count (updated async)\n */\n @field({\n description:\n 'How many times the ad has been shown. The app counts this as it serves ads and refreshes it a little later.',\n })\n impressions: number = 0;\n\n /**\n * Denormalized click count (updated async)\n */\n @field({\n description:\n 'How many times the ad has been tapped. The app counts this as it serves ads and refreshes it a little later.',\n })\n clicks: number = 0;\n\n constructor(options: AdVariationOptions = {}) {\n super(options);\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.groupId !== undefined) this.groupId = options.groupId;\n if (options.formatId !== undefined) this.formatId = options.formatId;\n if (options.assetId !== undefined) this.assetId = options.assetId;\n if (options.name !== undefined) this.name = options.name;\n if (options.clickUrl !== undefined) this.clickUrl = options.clickUrl;\n if (options.altText !== undefined) this.altText = options.altText;\n if (options.weight !== undefined) this.weight = options.weight;\n if (options.status !== undefined) this.status = options.status;\n if (options.impressions !== undefined)\n this.impressions = options.impressions;\n if (options.clicks !== undefined) this.clicks = options.clicks;\n }\n\n /**\n * Check if variation is active\n */\n isActive(): boolean {\n return this.status === AdVariationStatus.ACTIVE;\n }\n\n /**\n * Check if variation is in draft state\n */\n isDraft(): boolean {\n return this.status === AdVariationStatus.DRAFT;\n }\n\n /**\n * Check if variation is paused\n */\n isPaused(): boolean {\n return this.status === AdVariationStatus.PAUSED;\n }\n\n /**\n * Calculate click-through rate (CTR)\n */\n getCTR(): number {\n if (this.impressions === 0) return 0;\n return this.clicks / this.impressions;\n }\n\n /**\n * Increment impression count\n */\n recordImpression(): void {\n this.impressions += 1;\n }\n\n /**\n * Increment click count\n */\n recordClick(): void {\n this.clicks += 1;\n }\n}\n\nexport default AdVariation;\n","/**\n * AdVariationCollection - Collection manager for AdVariation objects\n * @packageDocumentation\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { queryGlobal, queryWithGlobals } from '@happyvertical/smrt-tenancy';\nimport { AdVariation } from '../models/AdVariation.js';\nimport { AdVariationStatus } from '../types/index.js';\n\nexport class AdVariationCollection extends SmrtCollection<AdVariation> {\n static readonly _itemClass = AdVariation;\n\n /**\n * Find variations by ad group\n *\n * @param groupId - Ad group ID\n * @returns Array of variations\n */\n async findByGroup(groupId: string): Promise<AdVariation[]> {\n return await this.list({\n where: { groupId },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find variations by format\n *\n * @param formatId - Ad format ID\n * @returns Array of variations\n */\n async findByFormat(formatId: string): Promise<AdVariation[]> {\n return await this.list({\n where: { formatId },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Find active variations for a group\n *\n * @param groupId - Ad group ID\n * @returns Array of active variations\n */\n async findActiveByGroup(groupId: string): Promise<AdVariation[]> {\n return await this.list({\n where: {\n groupId,\n status: AdVariationStatus.ACTIVE,\n },\n orderBy: 'name ASC',\n });\n }\n\n /**\n * Select a variation using weighted random selection\n * Higher weight = more likely to be selected\n *\n * @param groupId - Ad group ID\n * @returns Selected variation or null if none available\n */\n async selectByWeight(groupId: string): Promise<AdVariation | null> {\n const active = await this.findActiveByGroup(groupId);\n if (active.length === 0) return null;\n if (active.length === 1) return active[0];\n\n // Calculate total weight\n const totalWeight = active.reduce((sum, v) => sum + v.weight, 0);\n if (totalWeight <= 0) return active[0];\n\n // Random selection weighted by weight\n let random = Math.random() * totalWeight;\n for (const variation of active) {\n random -= variation.weight;\n if (random <= 0) {\n return variation;\n }\n }\n\n // Fallback to last variation\n return active[active.length - 1];\n }\n\n /**\n * Find variations by status\n *\n * @param status - Variation status\n * @returns Array of variations\n */\n async findByStatus(status: AdVariationStatus): Promise<AdVariation[]> {\n return await this.list({\n where: { status },\n orderBy: 'created_at DESC',\n });\n }\n\n /**\n * Find all active variations\n */\n async findActive(): Promise<AdVariation[]> {\n return await this.findByStatus(AdVariationStatus.ACTIVE);\n }\n\n /**\n * Find all draft variations\n */\n async findDrafts(): Promise<AdVariation[]> {\n return await this.findByStatus(AdVariationStatus.DRAFT);\n }\n\n /**\n * Find all paused variations\n */\n async findPaused(): Promise<AdVariation[]> {\n return await this.findByStatus(AdVariationStatus.PAUSED);\n }\n\n /**\n * Find top performing variations by CTR\n *\n * @param limit - Maximum number to return\n * @returns Array of variations sorted by CTR descending\n */\n async findTopPerformers(limit: number = 10): Promise<AdVariation[]> {\n const all = await this.list({\n where: { status: AdVariationStatus.ACTIVE },\n });\n // Sort by CTR descending\n return all\n .filter((v) => v.impressions > 0)\n .sort((a, b) => b.getCTR() - a.getCTR())\n .slice(0, limit);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tenancy Helper Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Find ad variations belonging to a specific tenant\n *\n * @param tenantId - Tenant ID to filter by\n * @returns Array of ad variations for the tenant\n */\n async findByTenant(tenantId: string): Promise<AdVariation[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find global ad variations (no tenant association).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global ad variations\n */\n async findGlobal(): Promise<AdVariation[]> {\n return queryGlobal<AdVariation>(this);\n }\n\n /**\n * Find ad variations for a tenant including global (shared) variations.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID to include\n * @returns Array of tenant-specific and global ad variations\n */\n async findWithGlobals(tenantId: string): Promise<AdVariation[]> {\n return queryWithGlobals<AdVariation>(\n this,\n tenantId,\n 'AdVariation.findWithGlobals',\n );\n }\n}\n","/**\n * Declared recipes for smrt-ads (#4409, #4437): user-facing units of\n * functionality an app or agent can pick instead of the whole package.\n * The scanner reads these statics into the `recipes` array of `manifest.json`\n * and `smrt-knowledge.json`; nothing here runs at that point.\n *\n * @packageDocumentation\n */\n\nimport { SmrtRecipe } from '@happyvertical/smrt-core';\nimport { AdDeliveryTier } from './models/AdDeliveryTier.js';\nimport { AdFormat } from './models/AdFormat.js';\nimport { AdGroup } from './models/AdGroup.js';\nimport { AdVariation } from './models/AdVariation.js';\n\n/**\n * Ads: run ad campaigns on your site and see which ads get clicked.\n *\n * `AdEvent` is left out on purpose: it is the append-only record of every\n * showing and click the app writes while serving ads (create and list only,\n * no CLI, high volume). Nobody opens it as a list; the counts a person reads\n * live on the ad itself (`AdVariation.impressions` / `clicks`).\n */\nexport class AdsCampaignsRecipe extends SmrtRecipe {\n static id = 'ads.campaigns';\n static help = './campaigns.recipe.md';\n static label = 'Ads';\n static summary =\n 'Run ad campaigns on your site, choose which ads show where, and see which ones get clicked.';\n static synonyms = [\n 'ads',\n 'advertising',\n 'ad campaigns',\n 'banner ads',\n 'advertisements',\n 'display ads',\n ];\n static section = {\n id: 'grow',\n label: 'Grow',\n icon: 'tag',\n description: 'Bring in new customers and reward the people who help.',\n };\n static models = [AdGroup, AdVariation, AdFormat, AdDeliveryTier];\n static nav = [\n {\n label: 'Ad campaigns',\n model: AdGroup,\n icon: 'tag',\n description:\n 'Each campaign you run, with its dates, budget and where it stands.',\n noun: 'ad campaign',\n },\n {\n label: 'Ads',\n model: AdVariation,\n icon: 'fileText',\n description:\n 'The ads inside each campaign, how often each shows and how many clicks it got.',\n noun: 'ad',\n },\n {\n label: 'Ad sizes',\n model: AdFormat,\n icon: 'layers',\n description:\n 'The shapes and sizes an ad can be, shared by every campaign.',\n noun: 'ad size',\n },\n {\n label: 'Priority tiers',\n model: AdDeliveryTier,\n icon: 'settings',\n description:\n 'The order campaigns are tried in when more than one could show.',\n noun: 'tier',\n },\n ];\n static options = {\n AdGroup: {\n fields: {\n name: { order: 1 },\n status: { order: 2 },\n tierId: { label: 'Priority tier', order: 3 },\n startDate: { label: 'Starts on', order: 4 },\n endDate: { label: 'Ends on', order: 5 },\n dailyBudget: { label: 'Daily budget', order: 6 },\n totalBudget: { label: 'Total budget', order: 7 },\n tenantId: { visibility: 'hidden' },\n contractId: { label: 'Sales contract', visibility: 'advanced' },\n verticalSlug: { label: 'Category', visibility: 'advanced' },\n targeting: { visibility: 'hidden' },\n zoneIds: { visibility: 'hidden' },\n },\n },\n AdVariation: {\n fields: {\n name: { order: 1 },\n groupId: { label: 'Ad campaign', order: 2 },\n formatId: { label: 'Ad size', order: 3 },\n assetId: { label: 'Picture', order: 4 },\n clickUrl: { label: 'Link to', order: 5 },\n altText: { label: 'Words for the picture', order: 6 },\n weight: { order: 7 },\n status: { order: 8 },\n tenantId: { visibility: 'hidden' },\n impressions: {\n label: 'Times shown',\n locked: true,\n visibility: 'advanced',\n },\n clicks: { locked: true, visibility: 'advanced' },\n },\n },\n AdFormat: {\n fields: {\n name: { order: 1 },\n width: { order: 2 },\n height: { order: 3 },\n formatType: { label: 'Kind', order: 4 },\n description: { order: 5 },\n },\n },\n AdDeliveryTier: {\n fields: {\n name: { order: 1 },\n priority: { order: 2 },\n pricingModel: { label: 'How it is charged', order: 3 },\n description: { order: 4 },\n },\n },\n } as const;\n}\n"],"mappings":"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"}