import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core'; import { ReportFrequency, ReportStatus } from '../types/index.js'; /** * Options for constructing an {@link AnalyticsReport}. * * `metrics` is omitted from the {@link SmrtObjectOptions} base before being * re-declared: the framework option carries an observability `MetricsConfig`, * whereas this report field is a JSON-encoded list of analytics metrics. */ export interface AnalyticsReportOptions extends Omit { tenantId?: string | null; propertyId?: string; name?: string; description?: string; dimensions?: string; metrics?: string; dateRangeStart?: string; dateRangeEnd?: string; dimensionFilter?: string; metricFilter?: string; orderBy?: string; maxResults?: number; status?: ReportStatus; frequency?: ReportFrequency; lastRunAt?: Date | null; nextRunAt?: Date | null; resultData?: string; rowCount?: number; lastError?: string; } /** * AnalyticsReport represents a saved report configuration with optional scheduling. * * @example * ```typescript * const report = await reports.create({ * propertyId: property.id, * name: 'Weekly Traffic Report', * dimensions: JSON.stringify([{ name: 'country' }, { name: 'deviceCategory' }]), * metrics: JSON.stringify([{ name: 'activeUsers' }, { name: 'sessions' }]), * frequency: ReportFrequency.WEEKLY * }); * ``` */ export declare class AnalyticsReport extends SmrtObject { /** * Tenant ID for multi-tenancy isolation (#1410). * * Reports persist `resultData` rows that may contain tenant-private metrics * and PII-bearing dimensions. Without tenant scoping the generated * `list`/`get` API returns every tenant's cached report data, and the * AI-powered `analyze`/`run` operations could run over another tenant's * rows. `@TenantScoped` auto-filters reads and binds writes to the tenant. */ tenantId: string | null; /** * Parent property ID (references AnalyticsProperty) */ propertyId: string; /** * Report name */ name: string; /** * Report description */ description: string; /** * Dimensions to group by (JSON array) */ dimensions: string; /** * Metrics to retrieve (JSON array) */ metrics: string; /** * Date range start (relative or absolute) */ dateRangeStart: string; /** * Date range end (relative or absolute) */ dateRangeEnd: string; /** * Dimension filter expression (JSON) */ dimensionFilter: string; /** * Metric filter expression (JSON) */ metricFilter: string; /** * Sort order (JSON array) */ orderBy: string; /** * Maximum results to return */ maxResults: number; /** * Report status */ status: ReportStatus; /** * Scheduling frequency */ frequency: ReportFrequency; /** * Last run timestamp */ lastRunAt: Date | null; /** * Next scheduled run */ nextRunAt: Date | null; /** * Cached result data (JSON) */ resultData: string; /** * Row count from last run */ rowCount: number; /** * Error message from last failed run */ lastError: string; constructor(options?: AnalyticsReportOptions); /** * Get parsed dimensions */ getDimensions(): Array<{ name: string; }>; /** * Set dimensions */ setDimensions(dimensions: Array<{ name: string; }>): void; /** * Get parsed metrics */ getMetrics(): Array<{ name: string; }>; /** * Set metrics */ setMetrics(metrics: Array<{ name: string; }>): void; /** * Get parsed result data */ getResultData(): Record | null; /** * Set result data */ setResultData(data: Record): void; /** * Mark report as running */ markRunning(): void; /** * Mark report as completed with results */ markCompleted(rowCount: number): void; /** * Mark report as failed */ markFailed(error: string): void; /** * Calculate next scheduled run based on frequency */ calculateNextRun(): void; /** * Check if report is due to run */ isDue(): boolean; /** * AI-powered: Analyze report results. * * Uses the `smrtAnalytics.report.analyzeResults` prompt registered via * `@happyvertical/smrt-prompts`, allowing tenant- or instance-level * overrides of the template, model, and parameters at runtime. * * Internal identifiers (`id`, `propertyId`, `tenantId`, `lastError`, raw * `dimensionFilter` / `metricFilter` JSON) are excluded from the prompt * variables — see `../prompts.ts` for the exclusion rationale. * * **`resultData` is FORWARDED VERBATIM.** The persisted result rows are * JSON-stringified into the `reportData` variable; this package cannot * strip PII because the row schema is determined by which dimensions / * metrics the caller asked the analytics provider to return. If the * persisted rows contain `userPseudoId`, `clientId`, IP-derived * geolocation, or any other identifier, those fields WILL reach the AI * provider. Callers are responsible for excluding PII-bearing dimensions * before persisting, applying a column allowlist at the call site, or * overriding the prompt template via `PromptOverride`. The forwarding is * pinned by a regression test in * `__tests__/analytics-report-prompt.test.ts`. * * The previous implementation issued a second freeform `this.do()` call * to re-summarize "top 3 insights"; that behaviour is now folded into * the single registered template (which already asks for findings, * trends, and recommendations) — `insights` mirrors `analysis` so the * return shape is preserved without a redundant AI round-trip. */ analyzeResults(_options?: Record): Promise<{ action: string; analysis: string; insights: string; }>; /** * AI-powered: Check if results show positive trends. * * Uses the `smrtAnalytics.report.hasPositiveTrends` prompt registered * via `@happyvertical/smrt-prompts`. Only the metric labels and the * aggregate `resultData` JSON are sent to the AI provider — though as * with `analyzeResults`, `resultData` is forwarded verbatim and may * carry PII the caller persisted; see `analyzeResults` docstring and * `../prompts.ts`. * * Boolean coercion uses `/^\s*(yes|true)\b/i` against the trimmed * response. The registered prompt template explicitly instructs the * model to begin its answer with the literal word "yes" or "no" so * this regex is reliable; tenant overrides MUST preserve that leading- * word convention or the boolean will silently fall to `false`. */ hasPositiveTrends(): Promise; } export default AnalyticsReport; //# sourceMappingURL=AnalyticsReport.d.ts.map