@happyvertical/smrt-analytics
Server-side analytics tracking with GA4 and Plausible integration, event logging, scheduled reports, and AI-powered performance analysis.
v0.19.0GA4PlausibleAI Insights
Overview
smrt-analytics provides server-side analytics event tracking, property/data stream management, scheduled reporting, and AI-powered performance analysis for GA4 and Plausible.
Installation
bash
npm install @happyvertical/smrt-analyticsQuick Start
typescript
import {
AnalyticsPropertyCollection,
AnalyticsDataStreamCollection,
AnalyticsEventCollection
} from '@happyvertical/smrt-analytics';
// Initialize
const properties = await AnalyticsPropertyCollection.create({ db: {...} });
const streams = await AnalyticsDataStreamCollection.create({ db: {...} });
const events = await AnalyticsEventCollection.create({ db: {...} });
// Create GA4 property
const property = await properties.create({
name: 'My Website',
providerType: 'GA4',
measurementId: 'G-XXXXXXXXXX',
apiSecret: 'your-api-secret'
});
await property.save();
// Create web data stream
const stream = await streams.create({
propertyId: property.id,
type: 'WEB_DATA_STREAM',
name: 'Web Stream',
measurementId: 'G-XXXXXXXXXX'
});
await stream.save();
// Track event
const event = await events.create({
propertyId: property.id,
eventName: 'page_view',
clientId: 'client-123',
userId: 'user-456',
params: {
page_location: 'https://example.com/products',
page_title: 'Products'
},
eventTimestamp: new Date()
});
await event.save();
// Send to GA4
await event.markSent();Core Models
AnalyticsProperty
typescript
class AnalyticsProperty extends SmrtObject {
name: string
providerType: 'GA4' | 'PLAUSIBLE'
measurementId?: string // GA4
apiSecret?: string // GA4 (encrypted)
siteDomain?: string // Plausible
lastSyncAt?: Date
async analyzePerformance(): Promise<string> // AI
async isPerformingWell(): Promise<boolean> // AI
}AnalyticsEvent
typescript
class AnalyticsEvent extends SmrtObject {
propertyId: string
eventName: string // 'page_view', 'purchase', 'sign_up', etc.
clientId: string // Anonymous client identifier
userId?: string // Authenticated user
params: Record<string, any> // Event parameters
eventTimestamp: Date
status: 'PENDING' | 'SENT' | 'FAILED'
retryCount: number
lastAttemptAt?: Date
errorMessage?: string
isPageview(): boolean
isConversion(): boolean
async markSent(): Promise<void>
async markFailed(error: string): Promise<void>
shouldRetry(): boolean
toTrackEvent(): TrackEvent // Convert to SDK format
}AnalyticsReport
typescript
class AnalyticsReport extends SmrtObject {
propertyId: string
name: string
dimensions: string[] // ['country', 'deviceCategory']
metrics: string[] // ['activeUsers', 'sessions']
dateRange: string // 'last7Days', 'last30Days', 'custom'
filters?: Record<string, any>
frequency: 'ONCE' | 'DAILY' | 'WEEKLY' | 'MONTHLY'
status: 'DRAFT' | 'SCHEDULED' | 'RUNNING' | 'COMPLETED' | 'FAILED'
resultData?: any[] // Cached results
rowCount?: number
lastRunAt?: Date
isDue(): boolean
calculateNextRun(): Date | null
async analyzeResults(): Promise<string> // AI
async hasPositiveTrends(): Promise<boolean> // AI
}Event Tracking
typescript
// Track page view
const pageView = await events.create({
propertyId: property.id,
eventName: 'page_view',
clientId: req.cookies.clientId,
userId: req.user?.id,
params: {
page_location: req.url,
page_title: 'Product Page',
page_referrer: req.headers.referer
},
eventTimestamp: new Date()
});
await pageView.save();
// Track purchase
const purchase = await events.create({
propertyId: property.id,
eventName: 'purchase',
clientId: req.cookies.clientId,
userId: req.user.id,
params: {
transaction_id: order.id,
value: order.total,
currency: 'USD',
items: order.items.map(item => ({
item_id: item.productId,
item_name: item.name,
quantity: item.quantity,
price: item.price
}))
},
eventTimestamp: new Date()
});
await purchase.save();
// Get stats
const stats = await events.getPropertyStats(property.id);
console.log(`Total: ${stats.total}, Sent: ${stats.sent}`);Scheduled Reports
typescript
// Create weekly report
const report = await reports.create({
propertyId: property.id,
name: 'Weekly Traffic Report',
dimensions: ['country', 'deviceCategory', 'date'],
metrics: ['activeUsers', 'sessions', 'bounceRate'],
dateRange: 'last7Days',
frequency: 'WEEKLY',
status: 'SCHEDULED'
});
await report.save();
// Check if due
if (report.isDue()) {
report.status = 'RUNNING';
await report.save();
// Run report (integrate with SDK)
const results = await runAnalyticsReport(report);
report.resultData = results;
report.rowCount = results.length;
report.lastRunAt = new Date();
report.status = 'COMPLETED';
await report.save();
// AI analysis
const insights = await report.analyzeResults();
console.log(insights);
}AI-Powered Analysis
typescript
// Analyze property performance
const analysis = await property.analyzePerformance();
// "Traffic up 15% this week. Top sources: organic search (45%),
// direct (30%). Mobile usage increased to 68%."
const isHealthy = await property.isPerformingWell();
// true if metrics trending positively
// Analyze report trends
const reportInsights = await report.analyzeResults();
// "US traffic grew 20%, UK declined 5%. Mobile bounce rate
// improved from 65% to 58%."
const hasGrowth = await report.hasPositiveTrends();
// true if key metrics improving