Claude Code Plugins

Community-maintained marketplace

Feedback
0
0

Expertise in user behavior analytics, A/B testing, and data-driven insights

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name user-analytics
version 1.0.0
description Expertise in user behavior analytics, A/B testing, and data-driven insights
author PrintCraft AI Team
tags analytics, metrics, user-behavior, data-analysis

User Analytics Skill

Overview

This skill provides comprehensive user analytics capabilities including event tracking, user journey analysis, A/B testing frameworks, and actionable insights generation for PrintCraft AI.

Core Competencies

1. Event Tracking Implementation

Flutter Analytics Integration

// Analytics service for Flutter
class AnalyticsService {
  static final AnalyticsService _instance = AnalyticsService._internal();
  factory AnalyticsService() => _instance;
  AnalyticsService._internal();
  
  final FirebaseAnalytics _firebase = FirebaseAnalytics.instance;
  final List<AnalyticsProvider> _providers = [];
  
  // Initialize analytics providers
  Future<void> initialize() async {
    // Firebase Analytics
    await _firebase.setAnalyticsCollectionEnabled(true);
    
    // Add custom providers
    _providers.addAll([
      MixpanelProvider(token: Environment.mixpanelToken),
      AmplitudeProvider(apiKey: Environment.amplitudeKey),
      CustomAnalyticsProvider(endpoint: Environment.analyticsEndpoint),
    ]);
    
    // Set user properties
    await _setDefaultUserProperties();
  }
  
  // Track events with automatic enrichment
  Future<void> track(String eventName, [Map<String, dynamic>? parameters]) async {
    final enrichedParams = await _enrichParameters(parameters ?? {});
    
    // Log to all providers
    await Future.wait([
      _firebase.logEvent(name: eventName, parameters: enrichedParams),
      ..._providers.map((p) => p.track(eventName, enrichedParams)),
    ]);
    
    // Store locally for offline support
    await _storeLocalEvent(eventName, enrichedParams);
  }
  
  // Screen view tracking with timing
  Future<void> trackScreenView({
    required String screenName,
    String? screenClass,
    Map<String, dynamic>? parameters,
  }) async {
    final startTime = DateTime.now();
    
    await _firebase.setCurrentScreen(
      screenName: screenName,
      screenClassOverride: screenClass,
    );
    
    await track('screen_view', {
      'screen_name': screenName,
      'screen_class': screenClass,
      'previous_screen': _previousScreen,
      'transition_time': _transitionTime,
      ...?parameters,
    });
    
    _previousScreen = screenName;
    _screenStartTime = startTime;
  }
  
  // User action tracking
  Future<void> trackAction({
    required String action,
    required String category,
    String? label,
    num? value,
    Map<String, dynamic>? metadata,
  }) async {
    await track('user_action', {
      'action': action,
      'category': category,
      'label': label,
      'value': value,
      'interaction_time': DateTime.now().millisecondsSinceEpoch,
      ...?metadata,
    });
  }
  
  // Generation tracking with detailed metrics
  Future<void> trackGeneration({
    required String generationId,
    required String status,
    required GenerationMetrics metrics,
  }) async {
    await track('generation_${status}', {
      'generation_id': generationId,
      'prompt_length': metrics.promptLength,
      'style': metrics.style,
      'quality': metrics.quality,
      'processing_time': metrics.processingTime,
      'model_used': metrics.modelUsed,
      'cost': metrics.cost,
      'error_code': metrics.errorCode,
      'retry_count': metrics.retryCount,
    });
  }
  
  // Conversion tracking
  Future<void> trackConversion({
    required String conversionType,
    required double value,
    String? currency,
    Map<String, dynamic>? items,
  }) async {
    await track('conversion', {
      'conversion_type': conversionType,
      'value': value,
      'currency': currency ?? 'USD',
      'items': items,
      'conversion_path': await _getConversionPath(),
    });
    
    // Special handling for revenue events
    if (conversionType == 'purchase') {
      await _firebase.logPurchase(
        currency: currency ?? 'USD',
        value: value,
        items: _convertToFirebaseItems(items),
      );
    }
  }
  
  // Automatic parameter enrichment
  Future<Map<String, dynamic>> _enrichParameters(
    Map<String, dynamic> params,
  ) async {
    final deviceInfo = await DeviceInfoPlugin().deviceInfo;
    final packageInfo = await PackageInfo.fromPlatform();
    
    return {
      ...params,
      'timestamp': DateTime.now().toIso8601String(),
      'session_id': _sessionId,
      'user_id': _userId,
      'device_id': _deviceId,
      'platform': Platform.operatingSystem,
      'app_version': packageInfo.version,
      'build_number': packageInfo.buildNumber,
      'device_model': deviceInfo.model,
      'os_version': deviceInfo.systemVersion,
      'screen_resolution': '${window.physicalSize.width}x${window.physicalSize.height}',
      'locale': Platform.localeName,
      'timezone': DateTime.now().timeZoneName,
      'connection_type': await _getConnectionType(),
    };
  }
}

Backend Analytics Collection

export class AnalyticsCollector {
  private readonly queue: AnalyticsQueue;
  private readonly storage: AnalyticsStorage;
  
  constructor() {
    this.queue = new AnalyticsQueue({
      batchSize: 100,
      flushInterval: 5000, // 5 seconds
    });
    
    this.storage = new AnalyticsStorage({
      retention: 90, // days
      compression: true,
    });
  }
  
  // Middleware for automatic API tracking
  trackAPIUsage() {
    return async (req: Request, res: Response, next: NextFunction) => {
      const startTime = process.hrtime.bigint();
      const requestId = req.headers['x-request-id'] || uuidv4();
      
      // Capture request details
      const event: APIEvent = {
        eventType: 'api_request',
        timestamp: new Date(),
        requestId,
        userId: req.user?.id,
        method: req.method,
        endpoint: req.route?.path || req.path,
        query: req.query,
        headers: this.sanitizeHeaders(req.headers),
        ip: req.ip,
        userAgent: req.headers['user-agent'],
      };
      
      // Intercept response
      const originalSend = res.send;
      res.send = function(data: any) {
        const endTime = process.hrtime.bigint();
        const duration = Number(endTime - startTime) / 1e6; // milliseconds
        
        // Complete event
        event.responseStatus = res.statusCode;
        event.responseTime = duration;
        event.responseSize = Buffer.byteLength(data);
        
        // Queue for processing
        this.queue.push(event);
        
        return originalSend.call(this, data);
      }.bind(this);
      
      next();
    };
  }
  
  // Track custom events
  async track(event: AnalyticsEvent): Promise<void> {
    // Validate event
    const validationResult = this.validateEvent(event);
    if (!validationResult.valid) {
      throw new Error(`Invalid event: ${validationResult.errors.join(', ')}`);
    }
    
    // Enrich event
    const enrichedEvent = this.enrichEvent(event);
    
    // Add to queue
    await this.queue.push(enrichedEvent);
    
    // Real-time processing for critical events
    if (event.priority === 'high') {
      await this.processImmediately(enrichedEvent);
    }
  }
  
  // Batch processing
  async processBatch(events: AnalyticsEvent[]): Promise<void> {
    // Group by event type
    const grouped = this.groupBy(events, 'eventType');
    
    // Process each group
    await Promise.all(
      Object.entries(grouped).map(async ([type, typeEvents]) => {
        await this.processEventType(type, typeEvents);
      })
    );
    
    // Store raw events
    await this.storage.store(events);
    
    // Update aggregates
    await this.updateAggregates(events);
    
    // Trigger alerts if needed
    await this.checkAlertConditions(events);
  }
}

2. User Journey Analysis

Journey Mapping

export class UserJourneyAnalyzer {
  // Track user journey through the app
  async analyzeJourney(userId: string): Promise<UserJourney> {
    // Get user events
    const events = await this.getUserEvents(userId, {
      limit: 1000,
      timeRange: '30d',
    });
    
    // Build journey map
    const journey = this.buildJourneyMap(events);
    
    // Identify patterns
    const patterns = this.identifyPatterns(journey);
    
    // Calculate metrics
    const metrics = this.calculateJourneyMetrics(journey);
    
    // Find drop-off points
    const dropOffPoints = this.findDropOffPoints(journey);
    
    // Generate insights
    const insights = await this.generateInsights({
      journey,
      patterns,
      metrics,
      dropOffPoints,
    });
    
    return {
      userId,
      journey,
      patterns,
      metrics,
      dropOffPoints,
      insights,
    };
  }
  
  private buildJourneyMap(events: AnalyticsEvent[]): JourneyMap {
    const sessions = this.groupIntoSessions(events);
    const journeyMap: JourneyMap = {
      nodes: new Map(),
      edges: new Map(),
      sessions,
    };
    
    sessions.forEach(session => {
      let previousEvent: AnalyticsEvent | null = null;
      
      session.events.forEach(event => {
        // Add node
        const nodeId = this.getNodeId(event);
        if (!journeyMap.nodes.has(nodeId)) {
          journeyMap.nodes.set(nodeId, {
            id: nodeId,
            type: event.eventType,
            name: event.eventName,
            count: 0,
            totalDuration: 0,
            conversions: 0,
          });
        }
        
        const node = journeyMap.nodes.get(nodeId)!;
        node.count++;
        
        // Add edge
        if (previousEvent) {
          const edgeId = `${this.getNodeId(previousEvent)}->${nodeId}`;
          if (!journeyMap.edges.has(edgeId)) {
            journeyMap.edges.set(edgeId, {
              id: edgeId,
              source: this.getNodeId(previousEvent),
              target: nodeId,
              count: 0,
              averageDuration: 0,
            });
          }
          
          const edge = journeyMap.edges.get(edgeId)!;
          edge.count++;
          edge.averageDuration = this.updateAverage(
            edge.averageDuration,
            event.timestamp - previousEvent.timestamp,
            edge.count
          );
        }
        
        previousEvent = event;
      });
    });
    
    return journeyMap;
  }
  
  private identifyPatterns(journey: JourneyMap): Pattern[] {
    const patterns: Pattern[] = [];
    
    // Common paths
    const commonPaths = this.findCommonPaths(journey, {
      minSupport: 0.1, // 10% of users
      maxLength: 10,
    });
    patterns.push(...commonPaths);
    
    // Loops and returns
    const loops = this.findLoops(journey);
    patterns.push(...loops);
    
    // Fast/slow paths
    const speedPatterns = this.analyzePathSpeed(journey);
    patterns.push(...speedPatterns);
    
    // Success patterns
    const successPatterns = this.findSuccessPatterns(journey);
    patterns.push(...successPatterns);
    
    return patterns;
  }
  
  // Funnel analysis
  async analyzeFunnel(
    funnelDefinition: FunnelDefinition
  ): Promise<FunnelAnalysis> {
    const results: FunnelAnalysis = {
      funnel: funnelDefinition,
      steps: [],
      overallConversion: 0,
      averageTime: 0,
    };
    
    // Get users who entered the funnel
    const enteredUsers = await this.getUsersAtStep(funnelDefinition.steps[0]);
    let currentUsers = new Set(enteredUsers);
    
    // Analyze each step
    for (let i = 0; i < funnelDefinition.steps.length; i++) {
      const step = funnelDefinition.steps[i];
      const stepUsers = await this.getUsersAtStep(step);
      const convertedUsers = new Set(
        [...currentUsers].filter(u => stepUsers.has(u))
      );
      
      const conversionRate = currentUsers.size > 0
        ? convertedUsers.size / currentUsers.size
        : 0;
      
      results.steps.push({
        step,
        users: convertedUsers.size,
        conversionRate,
        dropOff: currentUsers.size - convertedUsers.size,
        averageTime: await this.getAverageTimeBetweenSteps(
          i > 0 ? funnelDefinition.steps[i - 1] : null,
          step
        ),
      });
      
      currentUsers = convertedUsers;
    }
    
    results.overallConversion = currentUsers.size / enteredUsers.size;
    results.averageTime = results.steps.reduce(
      (sum, step) => sum + step.averageTime,
      0
    );
    
    return results;
  }
}

3. A/B Testing Framework

A/B Test Implementation

export class ABTestingFramework {
  private tests: Map<string, ABTest> = new Map();
  
  // Create and configure A/B test
  async createTest(config: ABTestConfig): Promise<ABTest> {
    const test: ABTest = {
      id: uuidv4(),
      name: config.name,
      hypothesis: config.hypothesis,
      variants: config.variants,
      allocation: config.allocation || this.calculateAllocation(config.variants),
      targeting: config.targeting,
      metrics: config.metrics,
      status: 'draft',
      createdAt: new Date(),
      statistics: {
        sampleSize: this.calculateSampleSize(config),
        duration: this.estimateDuration(config),
        confidence: config.confidence || 0.95,
        power: config.power || 0.8,
      },
    };
    
    // Validate test
    await this.validateTest(test);
    
    // Store test
    this.tests.set(test.id, test);
    await this.storage.saveTest(test);
    
    return test;
  }
  
  // Start A/B test
  async startTest(testId: string): Promise<void> {
    const test = this.tests.get(testId);
    if (!test) throw new Error('Test not found');
    
    if (test.status !== 'draft') {
      throw new Error(`Cannot start test in ${test.status} status`);
    }
    
    test.status = 'running';
    test.startedAt = new Date();
    
    // Initialize metrics collection
    await this.initializeMetrics(test);
    
    // Start traffic allocation
    await this.startTrafficAllocation(test);
    
    // Schedule analysis
    this.scheduleAnalysis(test);
    
    await this.storage.updateTest(test);
  }
  
  // Get variant for user
  async getVariant(testId: string, userId: string): Promise<Variant> {
    const test = this.tests.get(testId);
    if (!test || test.status !== 'running') {
      return { id: 'control', name: 'Control' };
    }
    
    // Check targeting
    if (test.targeting && !await this.matchesTargeting(userId, test.targeting)) {
      return { id: 'control', name: 'Control' };
    }
    
    // Check if user already assigned
    const existingAssignment = await this.getAssignment(testId, userId);
    if (existingAssignment) {
      return existingAssignment;
    }
    
    // Assign variant
    const variant = this.assignVariant(test, userId);
    await this.saveAssignment(testId, userId, variant);
    
    // Track assignment
    await this.trackAssignment(test, userId, variant);
    
    return variant;
  }
  
  // Analyze test results
  async analyzeTest(testId: string): Promise<TestAnalysis> {
    const test = this.tests.get(testId);
    if (!test) throw new Error('Test not found');
    
    const analysis: TestAnalysis = {
      test,
      variants: [],
      winner: null,
      confidence: 0,
      recommendation: '',
    };
    
    // Get data for each variant
    for (const variant of test.variants) {
      const data = await this.getVariantData(test, variant);
      const stats = this.calculateStatistics(data, test.metrics);
      
      analysis.variants.push({
        variant,
        users: data.users,
        ...stats,
      });
    }
    
    // Perform statistical tests
    const significance = await this.performSignificanceTest(analysis.variants);
    
    // Determine winner
    if (significance.significant) {
      analysis.winner = significance.winner;
      analysis.confidence = significance.confidence;
    }
    
    // Generate recommendation
    analysis.recommendation = this.generateRecommendation(analysis, significance);
    
    // Check for early stopping
    if (this.shouldStopEarly(analysis)) {
      await this.stopTest(testId, 'early_stopping');
    }
    
    return analysis;
  }
  
  // Statistical significance testing
  private async performSignificanceTest(
    variants: VariantData[]
  ): Promise<SignificanceResult> {
    // Use appropriate test based on metric type
    const control = variants.find(v => v.variant.id === 'control');
    const treatment = variants.find(v => v.variant.id !== 'control');
    
    if (!control || !treatment) {
      throw new Error('Missing control or treatment variant');
    }
    
    // For conversion metrics - Chi-square test
    if (this.isConversionMetric(control.metric)) {
      return this.chiSquareTest(control, treatment);
    }
    
    // For continuous metrics - t-test
    return this.tTest(control, treatment);
  }
  
  private chiSquareTest(
    control: VariantData,
    treatment: VariantData
  ): SignificanceResult {
    const n1 = control.users;
    const n2 = treatment.users;
    const x1 = control.conversions || 0;
    const x2 = treatment.conversions || 0;
    
    const p1 = x1 / n1;
    const p2 = x2 / n2;
    const p = (x1 + x2) / (n1 + n2);
    
    const z = (p2 - p1) / Math.sqrt(p * (1 - p) * (1/n1 + 1/n2));
    const pValue = 2 * (1 - this.normalCDF(Math.abs(z)));
    
    return {
      significant: pValue < 0.05,
      pValue,
      confidence: 1 - pValue,
      winner: p2 > p1 ? treatment.variant : control.variant,
      uplift: ((p2 - p1) / p1) * 100,
    };
  }
}

4. Real-time Analytics

Stream Processing

export class RealTimeAnalytics {
  private streams: Map<string, AnalyticsStream> = new Map();
  
  // Initialize real-time processing
  async initialize(): Promise<void> {
    // User activity stream
    this.createStream('user_activity', {
      windowSize: 60000, // 1 minute
      slideInterval: 5000, // 5 seconds
      aggregations: ['count', 'unique', 'rate'],
    });
    
    // Conversion stream
    this.createStream('conversions', {
      windowSize: 300000, // 5 minutes
      slideInterval: 30000, // 30 seconds
      aggregations: ['sum', 'rate', 'funnel'],
    });
    
    // Error stream
    this.createStream('errors', {
      windowSize: 300000, // 5 minutes
      slideInterval: 10000, // 10 seconds
      aggregations: ['count', 'rate', 'pattern'],
    });
    
    // Performance stream
    this.createStream('performance', {
      windowSize: 60000, // 1 minute
      slideInterval: 10000, // 10 seconds
      aggregations: ['avg', 'p95', 'p99'],
    });
  }
  
  // Process incoming events
  async processEvent(event: AnalyticsEvent): Promise<void> {
    // Route to appropriate streams
    const streams = this.getStreamsForEvent(event);
    
    await Promise.all(
      streams.map(stream => stream.addEvent(event))
    );
    
    // Check for anomalies
    await this.detectAnomalies(event);
    
    // Update dashboards
    await this.updateDashboards(event);
  }
  
  // Real-time dashboard data
  async getDashboardData(): Promise<DashboardData> {
    return {
      activeUsers: await this.getActiveUsers(),
      currentConversions: await this.getCurrentConversions(),
      realtimeMetrics: await this.getRealtimeMetrics(),
      alerts: await this.getActiveAlerts(),
      trends: await this.getRealtimeTrends(),
    };
  }
  
  private async getActiveUsers(): Promise<ActiveUsersData> {
    const stream = this.streams.get('user_activity')!;
    const windows = stream.getWindows();
    
    return {
      current: windows[0].uniqueUsers,
      trend: this.calculateTrend(windows.map(w => w.uniqueUsers)),
      byPlatform: this.groupBy(windows[0].events, 'platform'),
      byCountry: this.groupBy(windows[0].events, 'country'),
      newVsReturning: {
        new: windows[0].newUsers,
        returning: windows[0].returningUsers,
      },
    };
  }
  
  // Anomaly detection
  private async detectAnomalies(event: AnalyticsEvent): Promise<void> {
    const detectors = [
      new ThresholdDetector(),
      new PatternDetector(),
      new MLAnomalyDetector(),
    ];
    
    for (const detector of detectors) {
      const anomaly = await detector.detect(event, this.getContext());
      
      if (anomaly) {
        await this.handleAnomaly(anomaly);
      }
    }
  }
}

5. Insights Generation

Automated Insights

export class InsightsGenerator {
  // Generate insights from analytics data
  async generateInsights(
    timeRange: TimeRange
  ): Promise<Insight[]> {
    const insights: Insight[] = [];
    
    // User behavior insights
    insights.push(...await this.generateUserInsights(timeRange));
    
    // Conversion insights
    insights.push(...await this.generateConversionInsights(timeRange));
    
    // Performance insights
    insights.push(...await this.generatePerformanceInsights(timeRange));
    
    // Revenue insights
    insights.push(...await this.generateRevenueInsights(timeRange));
    
    // Predictive insights
    insights.push(...await this.generatePredictiveInsights(timeRange));
    
    // Rank by importance
    return this.rankInsights(insights);
  }
  
  private async generateUserInsights(
    timeRange: TimeRange
  ): Promise<Insight[]> {
    const insights: Insight[] = [];
    
    // User growth analysis
    const growth = await this.analyzeUserGrowth(timeRange);
    if (growth.significant) {
      insights.push({
        type: 'user_growth',
        title: growth.trend > 0 
          ? `User growth increased by ${growth.percentage}%`
          : `User growth decreased by ${Math.abs(growth.percentage)}%`,
        description: this.explainUserGrowth(growth),
        impact: 'high',
        recommendations: this.getUserGrowthRecommendations(growth),
        data: growth,
      });
    }
    
    // Cohort analysis
    const cohorts = await this.analyzeCohorts(timeRange);
    for (const cohort of cohorts.significantFindings) {
      insights.push({
        type: 'cohort_behavior',
        title: `${cohort.name} shows ${cohort.behavior}`,
        description: cohort.description,
        impact: cohort.impact,
        recommendations: cohort.recommendations,
        data: cohort.data,
      });
    }
    
    // User segmentation insights
    const segments = await this.analyzeUserSegments(timeRange);
    insights.push(...this.generateSegmentInsights(segments));
    
    return insights;
  }
  
  // Machine learning for predictive insights
  private async generatePredictiveInsights(
    timeRange: TimeRange
  ): Promise<Insight[]> {
    const insights: Insight[] = [];
    
    // Churn prediction
    const churnPrediction = await this.predictChurn();
    if (churnPrediction.riskUsers.length > 0) {
      insights.push({
        type: 'churn_risk',
        title: `${churnPrediction.riskUsers.length} users at risk of churning`,
        description: 'Based on usage patterns, these users show signs of disengagement',
        impact: 'high',
        recommendations: [
          'Send re-engagement campaigns',
          'Offer personalized incentives',
          'Analyze common characteristics',
        ],
        data: churnPrediction,
      });
    }
    
    // Revenue prediction
    const revenuePrediction = await this.predictRevenue();
    insights.push({
      type: 'revenue_forecast',
      title: `Projected revenue: $${revenuePrediction.forecast.toFixed(2)}`,
      description: `Based on current trends, expected ${revenuePrediction.confidence}% confidence`,
      impact: 'medium',
      recommendations: revenuePrediction.recommendations,
      data: revenuePrediction,
    });
    
    // Feature adoption prediction
    const adoptionPrediction = await this.predictFeatureAdoption();
    insights.push(...this.generateAdoptionInsights(adoptionPrediction));
    
    return insights;
  }
}

6. Privacy & Compliance

Data Privacy Implementation

export class PrivacyCompliantAnalytics {
  // GDPR compliant data collection
  async collectData(
    event: AnalyticsEvent,
    consent: UserConsent
  ): Promise<void> {
    // Check consent
    if (!consent.analytics) {
      return; // Don't collect
    }
    
    // Anonymize PII
    const anonymized = this.anonymizeEvent(event);
    
    // Apply data minimization
    const minimized = this.minimizeData(anonymized, consent.level);
    
    // Add privacy metadata
    minimized.privacy = {
      consentId: consent.id,
      consentTimestamp: consent.timestamp,
      dataRetention: this.getRetentionPeriod(consent),
      purposes: consent.purposes,
    };
    
    // Store with encryption
    await this.secureStore(minimized);
  }
  
  // Data anonymization
  private anonymizeEvent(event: AnalyticsEvent): AnalyticsEvent {
    const anonymized = { ...event };
    
    // Hash user ID
    if (anonymized.userId) {
      anonymized.userId = this.hashUserId(anonymized.userId);
    }
    
    // Remove/mask IP address
    if (anonymized.ip) {
      anonymized.ip = this.maskIP(anonymized.ip);
    }
    
    // Remove exact location
    if (anonymized.location) {
      anonymized.location = {
        country: anonymized.location.country,
        region: anonymized.location.region,
        // Remove city and exact coordinates
      };
    }
    
    // Remove device identifiers
    delete anonymized.deviceId;
    delete anonymized.advertisingId;
    
    return anonymized;
  }
  
  // Handle data deletion requests
  async deleteUserData(userId: string): Promise<void> {
    const hashedUserId = this.hashUserId(userId);
    
    // Delete from all stores
    await Promise.all([
      this.storage.deleteUserEvents(hashedUserId),
      this.storage.deleteUserProfile(hashedUserId),
      this.storage.deleteUserSegments(hashedUserId),
      this.cache.purgeUser(hashedUserId),
    ]);
    
    // Log deletion for compliance
    await this.auditLog.log({
      action: 'user_data_deletion',
      userId: hashedUserId,
      timestamp: new Date(),
      reason: 'user_request',
    });
  }
}

Analytics Dashboards

1. Executive Dashboard

export const executiveDashboard = {
  metrics: [
    {
      id: 'daily_active_users',
      name: 'Daily Active Users',
      query: 'SELECT COUNT(DISTINCT user_id) FROM events WHERE date = TODAY',
      visualization: 'number',
      comparison: 'previous_period',
    },
    {
      id: 'revenue',
      name: 'Revenue',
      query: 'SELECT SUM(value) FROM conversions WHERE type = "purchase"',
      visualization: 'currency',
      comparison: 'target',
    },
    {
      id: 'conversion_rate',
      name: 'Conversion Rate',
      query: 'SELECT COUNT(DISTINCT user_id) FILTER (WHERE converted) / COUNT(DISTINCT user_id)',
      visualization: 'percentage',
      comparison: 'previous_period',
    },
  ],
  charts: [
    {
      id: 'user_growth',
      name: 'User Growth',
      type: 'line',
      metrics: ['new_users', 'active_users', 'retained_users'],
      timeRange: '30d',
    },
    {
      id: 'revenue_breakdown',
      name: 'Revenue by Product',
      type: 'pie',
      metric: 'revenue',
      dimension: 'product_category',
    },
  ],
};

2. Product Analytics Dashboard

class ProductAnalyticsDashboard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DashboardLayout(
      title: 'Product Analytics',
      widgets: [
        // Feature adoption
        AnalyticsCard(
          title: 'Feature Adoption',
          child: FeatureAdoptionChart(
            features: [
              'AI Generation',
              'Style Selection',
              'Advanced Settings',
              'Sharing',
            ],
          ),
        ),
        
        // User flow
        AnalyticsCard(
          title: 'User Flow',
          child: SankeyDiagram(
            data: UserFlowData.fetch(),
          ),
        ),
        
        // Engagement metrics
        AnalyticsCard(
          title: 'Engagement',
          child: EngagementMetrics(
            metrics: [
              'Session Duration',
              'Screens per Session',
              'Return Rate',
            ],
          ),
        ),
        
        // A/B test results
        AnalyticsCard(
          title: 'Active Experiments',
          child: ABTestResults(),
        ),
      ],
    );
  }
}

Best Practices

1. Event Naming Convention

export const eventNamingConvention = {
  format: '{category}_{action}_{target}_{status}',
  examples: [
    'generation_start_image_initiated',
    'user_signup_email_completed',
    'payment_process_subscription_failed',
    'feature_use_advancedsettings_enabled',
  ],
  categories: [
    'user',
    'generation',
    'payment',
    'feature',
    'system',
  ],
  required_properties: [
    'timestamp',
    'user_id',
    'session_id',
    'platform',
  ],
};

2. Analytics Implementation Checklist

analytics_checklist:
  implementation:
    - Define KPIs and success metrics
    - Create event taxonomy
    - Implement tracking code
    - Set up data pipeline
    - Configure dashboards
    
  validation:
    - Verify event firing
    - Check data accuracy
    - Test edge cases
    - Validate privacy compliance
    - Performance impact assessment
    
  optimization:
    - Remove redundant events
    - Batch event sending
    - Implement sampling for high-volume events
    - Cache frequent queries
    - Archive old data

Integration Examples

With Product Team

  • Feature usage analytics
  • A/B test coordination
  • User feedback integration
  • Product metrics dashboards

With Marketing Team

  • Campaign attribution
  • User acquisition analytics
  • Conversion funnel optimization
  • Customer segmentation

With Engineering Team

  • Performance metrics
  • Error tracking integration
  • API usage analytics
  • Infrastructure monitoring

This skill provides comprehensive analytics capabilities to drive data-informed decisions for PrintCraft AI.