import { SmrtCollection } from '@happyvertical/smrt-core'; import { SmrtObject } from '@happyvertical/smrt-core'; import { SmrtObjectOptions } from '@happyvertical/smrt-core'; /** * AdDeliveryTier defines priority levels for ad serving. * * Ads are selected by priority (lower = higher priority): * 1. Sponsorship - Guaranteed, premium placements * 2. Standard - Regular programmatic ads * 3. House - Self-promotional/fallback ads * * @example * ```typescript * const sponsorship = await tiers.create({ * name: 'Sponsorship', * priority: 1, * pricingModel: PricingModel.FIXED, * description: 'Premium guaranteed placements' * }); * ``` */ export declare class AdDeliveryTier extends SmrtObject { /** * Display name (e.g., "Sponsorship", "Standard", "House") */ name: string; /** * Priority level (lower = higher priority: 1, 2, 3...) */ priority: number; /** * Pricing model for this tier */ pricingModel: PricingModel; /** * Optional description */ description: string; constructor(options?: AdDeliveryTierOptions); /** * Check if this tier is higher priority than another */ isHigherPriorityThan(other: AdDeliveryTier): boolean; /** * Check if this is a fixed pricing tier */ isFixedPricing(): boolean; /** * Check if this is a performance-based tier (CPC, CPA) */ isPerformanceBased(): boolean; } export declare class AdDeliveryTierCollection extends SmrtCollection { static readonly _itemClass: typeof AdDeliveryTier; /** * Find tiers ordered by priority (ascending, lower = higher priority) * * @returns Array of tiers ordered by priority */ findByPriority(): Promise; /** * Find tiers by pricing model * * @param pricingModel - Pricing model to filter by * @returns Array of matching tiers */ findByPricingModel(pricingModel: PricingModel): Promise; /** * Get the highest priority tier * * @returns Highest priority tier or null */ getHighestPriority(): Promise; /** * Find fixed pricing tiers */ findFixedPricing(): Promise; /** * Find CPM-based tiers */ findCPM(): Promise; /** * Find performance-based tiers (CPC, CPA) */ findPerformanceBased(): Promise; } /** * Options for constructing an {@link AdDeliveryTier}. */ declare interface AdDeliveryTierOptions extends SmrtObjectOptions { name?: string; priority?: number; pricingModel?: PricingModel; description?: string; } /** * AdEvent tracks ad impressions, clicks, and conversions. * Events are immutable (append-only, no update/delete). * * References: * - variationId: FK to AdVariation (within package) * - zoneId: String reference to smrt-properties Zone (cross-package) * - siteId: Denormalized for query efficiency (cross-package) * * @example * ```typescript * // Track an impression * const impression = await events.create({ * variationId: variation.id, * zoneId: 'zone-uuid', * siteId: 'site-uuid', * eventType: AdEventType.IMPRESSION, * metadata: JSON.stringify({ * ip: '192.168.1.1', * userAgent: 'Mozilla/5.0...', * referrer: 'https://example.com' * }) * }); * * // Track a click * const click = await events.create({ * variationId: variation.id, * zoneId: 'zone-uuid', * siteId: 'site-uuid', * eventType: AdEventType.CLICK * }); * ``` */ export declare class AdEvent extends SmrtObject { /** * Tenant ID for multi-tenancy support */ tenantId: string | null; /** * Variation ID (FK to AdVariation) */ variationId: string; /** * Zone ID (FK to smrt-properties Zone, cross-package) */ zoneId: string; /** * Site ID (denormalized from Zone for query efficiency) */ siteId: string; /** * Event type (impression, click, conversion) */ eventType: AdEventType; /** * Event timestamp */ timestamp: Date; /** * Analytics metadata as JSON string * (IP, user agent, referrer, etc.) */ metadata: string; constructor(options?: AdEventOptions); /** * Get metadata as object */ getMetadata(): Record; /** * Set metadata from object */ setMetadata(data: Record): void; /** * Check if this is an impression event */ isImpression(): boolean; /** * Check if this is a click event */ isClick(): boolean; /** * Check if this is a conversion event */ isConversion(): boolean; } export declare class AdEventCollection extends SmrtCollection { static readonly _itemClass: typeof AdEvent; /** * Find events by variation * * @param variationId - Variation ID * @returns Array of events */ findByVariation(variationId: string): Promise; /** * Find events by zone * * @param zoneId - Zone ID * @returns Array of events */ findByZone(zoneId: string): Promise; /** * Find events by site * * @param siteId - Site ID * @returns Array of events */ findBySite(siteId: string): Promise; /** * Find events in date range * * @param start - Start date * @param end - End date * @returns Array of events */ findByDateRange(start: Date, end: Date): Promise; /** * Find events by type * * @param eventType - Event type * @returns Array of events */ findByType(eventType: AdEventType): Promise; /** * Count events by type for a variation * * @param variationId - Variation ID * @param eventType - Event type * @returns Count of events */ countByType(variationId: string, eventType: AdEventType): Promise; /** * Count impressions for a variation */ countImpressions(variationId: string): Promise; /** * Count clicks for a variation */ countClicks(variationId: string): Promise; /** * Count conversions for a variation */ countConversions(variationId: string): Promise; /** * Find all impressions */ findImpressions(): Promise; /** * Find all clicks */ findClicks(): Promise; /** * Find all conversions */ findConversions(): Promise; /** * Get aggregate stats for a variation * * @param variationId - Variation ID * @returns Stats object with impressions, clicks, conversions, CTR */ getVariationStats(variationId: string): Promise<{ impressions: number; clicks: number; conversions: number; ctr: number; conversionRate: number; }>; /** * Find ad events belonging to a specific tenant * * @param tenantId - Tenant ID to filter by * @returns Array of ad events for the tenant */ findByTenant(tenantId: string): Promise; /** * Find global ad events (no tenant association). * * Routes through the shared tenant-global helper so it does not throw under * an active tenant context (an explicit `tenant_id IS NULL` filter would be * flagged as an isolation violation). (#1600) * * @returns Array of global ad events */ findGlobal(): Promise; /** * Find ad events for a tenant including global (shared) events. * * Fails closed if an active tenant context requests a different tenant's * rows; the admin/system path keeps the cross-tenant capability. (#1600) * * @param tenantId - Tenant ID to include * @returns Array of tenant-specific and global ad events */ findWithGlobals(tenantId: string): Promise; } /** * Options for constructing an {@link AdEvent}. */ declare interface AdEventOptions extends SmrtObjectOptions { tenantId?: string | null; variationId?: string; zoneId?: string; siteId?: string; eventType?: AdEventType; timestamp?: Date; metadata?: string; } /** * Event types for ad tracking */ export declare enum AdEventType { IMPRESSION = "impression", CLICK = "click", CONVERSION = "conversion" } /** * AdFormat defines standard ad dimensions and types (IAB standards). * * @example * ```typescript * const leaderboard = await formats.create({ * name: 'Leaderboard', * width: 728, * height: 90, * formatType: AdFormatType.BANNER * }); * ``` */ export declare class AdFormat extends SmrtObject { /** * Display name (e.g., "Leaderboard", "Medium Rectangle") */ name: string; /** * Width in pixels */ width: number; /** * Height in pixels */ height: number; /** * Format type (banner, native, video) */ formatType: AdFormatType; /** * Optional description */ description: string; constructor(options?: AdFormatOptions); /** * Get dimensions as string (e.g., "728x90") */ getDimensions(): string; /** * Check if format matches specific dimensions */ matchesDimensions(width: number, height: number): boolean; } export declare class AdFormatCollection extends SmrtCollection { static readonly _itemClass: typeof AdFormat; /** * Find format by dimensions * * @param width - Width in pixels * @param height - Height in pixels * @returns Matching format or null */ findByDimensions(width: number, height: number): Promise; /** * Find formats by type * * @param formatType - Format type (banner, native, video) * @returns Array of matching formats */ findByType(formatType: AdFormatType): Promise; /** * Find all banner formats */ findBanners(): Promise; /** * Find all native formats */ findNative(): Promise; /** * Find all video formats */ findVideo(): Promise; } /** * Options for constructing an {@link AdFormat}. */ declare interface AdFormatOptions extends SmrtObjectOptions { name?: string; width?: number; height?: number; formatType?: AdFormatType; description?: string; } /** * Types and enums for smrt-ads package */ /** * Ad format types for different creative types */ export declare enum AdFormatType { BANNER = "banner", NATIVE = "native", VIDEO = "video" } /** * AdGroup organizes ad creatives with targeting and budget controls. * * References: * - tierId: FK to AdDeliveryTier (within package) * - contractId: String reference to smrt-commerce Contract (cross-package) * - zoneIds: JSON array of allowed smrt-properties Zone IDs (cross-package) * - verticalSlug: Tag slug from smrt-tags (cross-package) * * @example * ```typescript * const adGroup = await groups.create({ * contractId: 'contract-uuid', * tierId: tier.id, * name: 'Summer Sale - Desktop', * verticalSlug: 'retail', * targeting: JSON.stringify({ device: 'desktop' }), * zoneIds: JSON.stringify(['zone-1', 'zone-2']), * dailyBudget: 100.00, * totalBudget: 3000.00, * startDate: new Date('2024-06-01'), * endDate: new Date('2024-08-31') * }); * ``` */ export declare class AdGroup extends SmrtObject { /** * Tenant ID for multi-tenancy support */ tenantId: string | null; /** * Contract ID (FK to smrt-commerce Contract, cross-package) */ contractId: string; /** * Delivery tier ID (FK to AdDeliveryTier) */ tierId: string; /** * Display name (e.g., "Summer Sale - Desktop") */ name: string; /** * Vertical/category tag slug from smrt-tags (context="advertising") */ verticalSlug: string; /** * Targeting rules as JSON string */ targeting: string; /** * Allowed Zone IDs as JSON array string (FK to smrt-properties Zone) */ zoneIds: string; /** * Campaign start date */ startDate: Date | null; /** * Campaign end date */ endDate: Date | null; /** * Daily budget limit */ dailyBudget: number; /** * Total campaign budget */ totalBudget: number; /** * Current status */ status: AdGroupStatus; constructor(options?: AdGroupOptions); /** * Get zone IDs as array */ getZoneIds(): string[]; /** * Set zone IDs from array */ setZoneIds(ids: string[]): void; /** * Add a zone ID */ addZoneId(zoneId: string): void; /** * Remove a zone ID */ removeZoneId(zoneId: string): void; /** * Check if zone ID is allowed */ hasZoneId(zoneId: string): boolean; /** * Get targeting rules as object */ getTargeting(): Record; /** * Set targeting rules from object */ setTargeting(rules: Record): void; /** * Check if ad group is currently active */ isActive(): boolean; /** * Check if ad group is in draft state */ isDraft(): boolean; /** * Check if ad group is paused */ isPaused(): boolean; /** * Check if ad group is completed */ isCompleted(): boolean; /** * Check if ad group has ended (past end date) */ hasEnded(): boolean; /** * Check if ad group has started */ hasStarted(): boolean; } export declare class AdGroupCollection extends SmrtCollection { static readonly _itemClass: typeof AdGroup; /** * Find ad groups by contract * * @param contractId - Contract ID * @returns Array of ad groups */ findByContract(contractId: string): Promise; /** * Find ad groups by tier * * @param tierId - Delivery tier ID * @returns Array of ad groups */ findByTier(tierId: string): Promise; /** * Find ad groups by status * * @param status - Ad group status * @returns Array of ad groups */ findByStatus(status: AdGroupStatus): Promise; /** * Find currently active ad groups * (status=active, started, not ended) * * @returns Array of active ad groups */ findActive(): Promise; /** * Find ad groups by vertical slug * * @param verticalSlug - Tag slug from smrt-tags * @returns Array of ad groups */ findByVertical(verticalSlug: string): Promise; /** * Find ad groups that can serve to a specific zone * * @param zoneId - Zone ID to check * @returns Array of ad groups containing zone */ findByZone(zoneId: string): Promise; /** * Find ad groups eligible to serve for a zone * (active, has zone, within date range) * * @param zoneId - Zone ID to check * @returns Array of eligible ad groups */ findEligibleForZone(zoneId: string): Promise; /** * Find all draft ad groups */ findDrafts(): Promise; /** * Find all paused ad groups */ findPaused(): Promise; /** * Find all completed ad groups */ findCompleted(): Promise; /** * Find ad groups belonging to a specific tenant * * @param tenantId - Tenant ID to filter by * @returns Array of ad groups for the tenant */ findByTenant(tenantId: string): Promise; /** * Find global ad groups (no tenant association). * * Routes through the shared tenant-global helper so it does not throw under * an active tenant context (an explicit `tenant_id IS NULL` filter would be * flagged as an isolation violation). (#1600) * * @returns Array of global ad groups */ findGlobal(): Promise; /** * Find ad groups for a tenant including global (shared) ad groups. * * Fails closed if an active tenant context requests a different tenant's * rows; the admin/system path keeps the cross-tenant capability. (#1600) * * @param tenantId - Tenant ID to include * @returns Array of tenant-specific and global ad groups */ findWithGlobals(tenantId: string): Promise; } /** * Options for constructing an {@link AdGroup}. */ declare interface AdGroupOptions extends SmrtObjectOptions { tenantId?: string | null; contractId?: string; tierId?: string; name?: string; verticalSlug?: string; targeting?: string; zoneIds?: string; startDate?: Date | null; endDate?: Date | null; dailyBudget?: number; totalBudget?: number; status?: AdGroupStatus; } /** * Status for ad groups */ export declare enum AdGroupStatus { DRAFT = "draft", ACTIVE = "active", PAUSED = "paused", COMPLETED = "completed" } /** * AdVariation represents a creative asset within an ad group. * Supports A/B testing via weighted selection. * * References: * - groupId: FK to AdGroup (within package) * - formatId: FK to AdFormat (within package) * - assetId: String reference to smrt-assets Asset (cross-package) * * @example * ```typescript * const variation = await variations.create({ * groupId: adGroup.id, * formatId: leaderboard.id, * assetId: 'asset-uuid', * name: 'Version A - Blue CTA', * clickUrl: 'https://example.com/landing', * altText: 'Summer Sale - 50% off', * weight: 2 // 2x more likely than weight=1 * }); * ``` */ export declare class AdVariation extends SmrtObject { /** * Tenant ID for multi-tenancy support */ tenantId: string | null; /** * Ad group ID (FK to AdGroup) */ groupId: string; /** * Ad format ID (FK to AdFormat) */ formatId: string; /** * Asset ID (FK to smrt-assets Asset, cross-package) */ assetId: string; /** * Display name (e.g., "Version A - Blue CTA") */ name: string; /** * Click destination URL */ clickUrl: string; /** * Accessibility alt text */ altText: string; /** * A/B testing weight (higher = more likely to be selected) */ weight: number; /** * Current status */ status: AdVariationStatus; /** * Denormalized impression count (updated async) */ impressions: number; /** * Denormalized click count (updated async) */ clicks: number; constructor(options?: AdVariationOptions); /** * Check if variation is active */ isActive(): boolean; /** * Check if variation is in draft state */ isDraft(): boolean; /** * Check if variation is paused */ isPaused(): boolean; /** * Calculate click-through rate (CTR) */ getCTR(): number; /** * Increment impression count */ recordImpression(): void; /** * Increment click count */ recordClick(): void; } export declare class AdVariationCollection extends SmrtCollection { static readonly _itemClass: typeof AdVariation; /** * Find variations by ad group * * @param groupId - Ad group ID * @returns Array of variations */ findByGroup(groupId: string): Promise; /** * Find variations by format * * @param formatId - Ad format ID * @returns Array of variations */ findByFormat(formatId: string): Promise; /** * Find active variations for a group * * @param groupId - Ad group ID * @returns Array of active variations */ findActiveByGroup(groupId: string): Promise; /** * Select a variation using weighted random selection * Higher weight = more likely to be selected * * @param groupId - Ad group ID * @returns Selected variation or null if none available */ selectByWeight(groupId: string): Promise; /** * Find variations by status * * @param status - Variation status * @returns Array of variations */ findByStatus(status: AdVariationStatus): Promise; /** * Find all active variations */ findActive(): Promise; /** * Find all draft variations */ findDrafts(): Promise; /** * Find all paused variations */ findPaused(): Promise; /** * Find top performing variations by CTR * * @param limit - Maximum number to return * @returns Array of variations sorted by CTR descending */ findTopPerformers(limit?: number): Promise; /** * Find ad variations belonging to a specific tenant * * @param tenantId - Tenant ID to filter by * @returns Array of ad variations for the tenant */ findByTenant(tenantId: string): Promise; /** * Find global ad variations (no tenant association). * * Routes through the shared tenant-global helper so it does not throw under * an active tenant context (an explicit `tenant_id IS NULL` filter would be * flagged as an isolation violation). (#1600) * * @returns Array of global ad variations */ findGlobal(): Promise; /** * Find ad variations for a tenant including global (shared) variations. * * Fails closed if an active tenant context requests a different tenant's * rows; the admin/system path keeps the cross-tenant capability. (#1600) * * @param tenantId - Tenant ID to include * @returns Array of tenant-specific and global ad variations */ findWithGlobals(tenantId: string): Promise; } /** * Options for constructing an {@link AdVariation}. */ declare interface AdVariationOptions extends SmrtObjectOptions { tenantId?: string | null; groupId?: string; formatId?: string; assetId?: string; name?: string; clickUrl?: string; altText?: string; weight?: number; status?: AdVariationStatus; impressions?: number; clicks?: number; } /** * Status for ad variations */ export declare enum AdVariationStatus { DRAFT = "draft", ACTIVE = "active", PAUSED = "paused" } /** * Pricing models for ad delivery tiers */ export declare enum PricingModel { FIXED = "fixed", CPM = "cpm", CPC = "cpc", CPA = "cpa" } export { }