Skip to main content

Analytics Controller

Path: internal/api/v1/funnels/controllers/analytics.controller.js
Service: analyticsService
Module: Funnels


Overview

The Analytics controller tracks and reports conversion metrics for funnels. It records visitor actions, form submissions, payment events, and provides aggregated analytics data for funnel performance analysis.

Key Capabilities

  • Funnel Analytics: Aggregate metrics for entire funnels
  • Step Analytics: Granular metrics per funnel step
  • Event Tracking: Record visitor actions, forms, payments
  • Conversion Tracking: Monitor funnel conversion rates
  • UTM Attribution: Track traffic sources and campaigns
  • Payment Analytics: Stripe/Square payment tracking

Methods

getAnalytics()

Retrieves aggregated analytics data for a funnel with date filtering and pagination.

Route: GET /v1/funnels/analytics
Auth: Required (account-scoped)

Request Query Parameters

{
funnel_id: string; // Funnel ID to get analytics for
start_date?: string; // Filter from date (ISO 8601)
end_date?: string; // Filter to date (ISO 8601)
limit?: number; // Results per page (default: 10)
page?: number; // Page number (0-indexed)
}

Response

{
"success": true,
"message": "SUCCESS",
"data": {
"funnel_id": "60d5ec49f1b2c72e8c8e4b1a",
"date_range": {
"start": "2024-01-01T00:00:00Z",
"end": "2024-01-31T23:59:59Z"
},
"summary": {
"total_visitors": 1250,
"unique_visitors": 980,
"total_page_views": 3840,
"total_conversions": 142,
"conversion_rate": 14.49,
"total_revenue": 28450.5,
"average_order_value": 200.36
},
"steps": [
{
"step_id": "60d5ec49f1b2c72e8c8e4b1d",
"step_name": "Landing Page",
"visitors": 1250,
"unique_visitors": 980,
"page_views": 1420,
"bounce_rate": 23.5,
"avg_time_on_page": 125.8,
"exit_rate": 18.2
},
{
"step_id": "60d5ec49f1b2c72e8c8e4b1e",
"step_name": "Checkout",
"visitors": 340,
"unique_visitors": 310,
"page_views": 485,
"bounce_rate": 12.3,
"avg_time_on_page": 215.4,
"exit_rate": 45.8
}
],
"traffic_sources": [
{
"source": "google",
"medium": "cpc",
"visitors": 620,
"conversions": 89,
"conversion_rate": 14.35
},
{
"source": "facebook",
"medium": "social",
"visitors": 380,
"conversions": 42,
"conversion_rate": 11.05
}
],
"daily_metrics": [
{
"date": "2024-01-15",
"visitors": 42,
"unique_visitors": 38,
"conversions": 6,
"revenue": 1205.5
},
{
"date": "2024-01-16",
"visitors": 55,
"unique_visitors": 48,
"conversions": 8,
"revenue": 1680.0
}
],
"form_submissions": {
"total": 234,
"conversion_rate": 23.88
},
"payments": {
"total_transactions": 142,
"successful": 138,
"failed": 4,
"success_rate": 97.18
}
}
}

MongoDB Collections

CollectionOperationPurpose
funnel_analyticsaggregateGenerate aggregated metrics
funnel_visitorsdistinctCount unique visitors
funnel_page_viewscountCount page views
form_submissionscountCount form submissions
payment_transactionsaggregateCalculate revenue metrics

Query Parameters

  • start_date: Defaults to 30 days ago if not provided
  • end_date: Defaults to current date if not provided
  • limit: Controls pagination for daily metrics
  • page: 0-indexed page number for daily metrics

getAnalytic()

Retrieves detailed analytics for a specific funnel step.

Route: GET /v1/funnels/:funnel_id/analytics/:step_id
Auth: Required (account-scoped)

Request Parameters

{
funnel_id: string; // Funnel ID
step_id: string; // Step ID
}

Response

{
"success": true,
"message": "SUCCESS",
"data": {
"funnel_id": "60d5ec49f1b2c72e8c8e4b1a",
"step_id": "60d5ec49f1b2c72e8c8e4b1d",
"step_name": "Landing Page",
"metrics": {
"total_visitors": 1250,
"unique_visitors": 980,
"total_page_views": 1420,
"avg_page_views_per_visitor": 1.14,
"bounce_rate": 23.5,
"exit_rate": 18.2,
"avg_time_on_page": 125.8,
"conversions": 142,
"conversion_rate": 14.49
},
"visitor_flow": {
"entries": 1250,
"next_steps": [
{
"step_id": "60d5ec49f1b2c72e8c8e4b1e",
"step_name": "Checkout",
"visitors": 340,
"percentage": 27.2
}
],
"exits": 228,
"exit_percentage": 18.2
},
"devices": [
{
"type": "desktop",
"visitors": 675,
"percentage": 54.0
},
{
"type": "mobile",
"visitors": 525,
"percentage": 42.0
},
{
"type": "tablet",
"visitors": 50,
"percentage": 4.0
}
],
"browsers": [
{
"name": "Chrome",
"visitors": 825,
"percentage": 66.0
},
{
"name": "Safari",
"visitors": 250,
"percentage": 20.0
},
{
"name": "Firefox",
"visitors": 125,
"percentage": 10.0
}
],
"locations": [
{
"country": "United States",
"visitors": 875,
"percentage": 70.0
},
{
"country": "Canada",
"visitors": 188,
"percentage": 15.0
},
{
"country": "United Kingdom",
"visitors": 125,
"percentage": 10.0
}
],
"hourly_distribution": [
{
"hour": 9,
"visitors": 98,
"conversions": 14
},
{
"hour": 10,
"visitors": 125,
"conversions": 18
},
{
"hour": 14,
"visitors": 142,
"conversions": 22
}
],
"form_submissions": [
{
"form_id": "contact-form",
"submissions": 156,
"conversion_rate": 15.92
},
{
"form_id": "newsletter-signup",
"submissions": 78,
"conversion_rate": 7.96
}
]
}
}

MongoDB Collections

CollectionOperationPurpose
funnel_analyticsaggregateStep-specific metrics
funnel_page_viewsaggregatePage view analysis
funnel_visitorsaggregateVisitor behavior patterns
form_submissionsaggregateForm performance
visitor_sessionsaggregateDevice/browser/location data

addAnalytics()

Records analytics events (page views, form submissions, payments).

Route: POST /v1/funnels/analytics
Auth: Optional (can be called from client-side)

Request Body

{
"items": [
{
"event_type": "page_view",
"step_id": "60d5ec49f1b2c72e8c8e4b1d",
"funnel_id": "60d5ec49f1b2c72e8c8e4b1a",
"timestamp": "2024-01-22T14:30:00Z"
},
{
"event_type": "form_submission",
"step_id": "60d5ec49f1b2c72e8c8e4b1d",
"funnel_id": "60d5ec49f1b2c72e8c8e4b1a",
"form_id": "contact-form",
"timestamp": "2024-01-22T14:32:00Z"
}
],
"form_id": "contact-form",
"response_id": "60d5ec49f1b2c72e8c8e4b2c",
"page_id": "60d5ec49f1b2c72e8c8e4b1d",
"site_id": "60d5ec49f1b2c72e8c8e4b1a",
"payment_details": {
"amount": 99.99,
"currency": "USD",
"payment_method": "stripe",
"transaction_id": "ch_abc123",
"status": "succeeded"
},
"visitor_id": "vis_abc123",
"contact_id": "60d5ec49f1b2c72e8c8e4b30",
"customer_id": "cus_abc123",
"unique_visit": true,
"timestamp": "2024-01-22T14:30:00Z",
"utms": {
"source": "google",
"medium": "cpc",
"campaign": "spring_sale_2024",
"term": "buy+shoes+online",
"content": "ad_variant_a"
}
}

Response

{
"success": true,
"message": "SUCCESS",
"data": {
"_id": "60d5ec49f1b2c72e8c8e4b31",
"events_recorded": 2,
"visitor_id": "vis_abc123",
"timestamp": "2024-01-22T14:30:00Z"
}
}

MongoDB Collections

CollectionOperationPurpose
funnel_analyticsinsertManyInsert event records
funnel_visitorsfindOneAndUpdate (upsert)Track visitor data
funnel_page_viewsinsertManyRecord page views
form_submissionsinsertOneRecord form submission
payment_transactionsinsertOneRecord payment

Event Types

Event TypeDescriptionRequired Fields
page_viewVisitor loads a funnel stepstep_id, funnel_id, visitor_id
form_submissionForm submitted on stepstep_id, funnel_id, form_id, response_id
paymentPayment processedstep_id, funnel_id, payment_details
conversionVisitor completes funnel goalstep_id, funnel_id, visitor_id
exitVisitor leaves funnelstep_id, funnel_id, visitor_id

Data Models

Funnel Analytics Document

{
_id: ObjectId;
funnel_id: ObjectId;
step_id?: ObjectId; // Optional: specific step
event_type: 'page_view' | 'form_submission' | 'payment' | 'conversion' | 'exit';
visitor_id: string;
contact_id?: ObjectId; // Optional: linked contact
customer_id?: string; // Optional: payment provider customer
session_id?: string; // Optional: session tracking
timestamp: Date;

// UTM parameters
utm_source?: string;
utm_medium?: string;
utm_campaign?: string;
utm_term?: string;
utm_content?: string;

// Device info
device_type?: 'desktop' | 'mobile' | 'tablet';
browser?: string;
os?: string;

// Location
country?: string;
region?: string;
city?: string;
ip_address?: string;

// Form-specific
form_id?: string;
response_id?: ObjectId;

// Payment-specific
payment_details?: {
amount: number;
currency: string;
payment_method: string;
transaction_id: string;
status: 'succeeded' | 'failed' | 'pending';
};

created_at: Date;
}

Funnel Visitor Document

{
_id: ObjectId;
visitor_id: string; // Unique visitor identifier (cookie/fingerprint)
funnel_id: ObjectId;
account_id: ObjectId;

// First visit info
first_visit_at: Date;
first_utm_source?: string;
first_utm_medium?: string;
first_utm_campaign?: string;

// Latest visit info
last_visit_at: Date;
last_utm_source?: string;
last_utm_medium?: string;
last_utm_campaign?: string;

// Aggregated metrics
total_visits: number;
total_page_views: number;
total_time_spent: number; // Seconds
conversion_count: number;

// Device/location (from latest visit)
device_type?: string;
browser?: string;
country?: string;

// Linked records
contact_id?: ObjectId; // If visitor becomes known contact
customer_id?: string; // If visitor makes purchase

created_at: Date;
updated_at: Date;
}

Funnel Page View Document

{
_id: ObjectId;
funnel_id: ObjectId;
step_id: ObjectId;
visitor_id: string;
session_id?: string;

// Timing
entered_at: Date;
exited_at?: Date;
time_on_page?: number; // Seconds

// Referrer
referrer_url?: string;
referrer_domain?: string;

// Exit tracking
exited_to_step?: ObjectId; // Next step visited
is_exit: boolean; // Last page in session

created_at: Date;
}

Payment Transaction Document

{
_id: ObjectId;
funnel_id: ObjectId;
step_id: ObjectId;
visitor_id: string;
contact_id?: ObjectId;

// Payment info
amount: number;
currency: string;
payment_method: 'stripe' | 'square' | 'paypal';
transaction_id: string;
status: 'succeeded' | 'failed' | 'pending' | 'refunded';

// Provider details
provider_customer_id?: string;
provider_payment_intent?: string;

// Attribution
utm_source?: string;
utm_medium?: string;
utm_campaign?: string;

// Timestamps
initiated_at: Date;
completed_at?: Date;
created_at: Date;
}

Business Logic & Workflows

Page View Tracking Flow

sequenceDiagram
participant Browser
participant Analytics
participant Database
participant Aggregation

Browser->>Analytics: POST /analytics (page_view event)
Analytics->>Database: Insert page view record
Analytics->>Database: Upsert visitor record
Database-->>Analytics: Records saved

alt Unique Visit
Analytics->>Database: Increment unique visitor count
end

Analytics->>Aggregation: Trigger async aggregation
Aggregation->>Database: Update funnel metrics
Analytics-->>Browser: 200 OK

Conversion Tracking Flow

sequenceDiagram
participant Browser
participant Analytics
participant Database
participant Notification

Browser->>Analytics: POST /analytics (conversion event)
Analytics->>Database: Insert conversion record
Analytics->>Database: Update visitor status
Analytics->>Database: Calculate conversion rate
Database-->>Analytics: Conversion saved

Analytics->>Notification: Trigger conversion notification
Analytics-->>Browser: 200 OK

Notification->>Database: Check notification rules
Notification-->>Admin: Email: New Conversion Alert

Revenue Attribution Flow

sequenceDiagram
participant Payment
participant Analytics
participant Database
participant Reports

Payment->>Analytics: POST /analytics (payment event)
Analytics->>Database: Insert payment transaction
Analytics->>Database: Link to visitor record

alt Has UTM Data
Analytics->>Database: Attribute to campaign
Analytics->>Database: Update campaign revenue
end

Analytics->>Reports: Update revenue metrics
Database-->>Analytics: Payment recorded
Analytics-->>Payment: 200 OK

Integration Points

Stripe Integration

  • Purpose: Track payment conversions from Stripe checkouts
  • Data: Transaction ID, amount, currency, status
  • Attribution: Links payments to visitor UTM sources

Square Integration

  • Purpose: Track payment conversions from Square checkouts
  • Data: Order ID, amount, currency, status
  • Attribution: Links payments to visitor UTM sources

Form Submissions

  • Purpose: Track form conversion events
  • Integration: Links to form_submissions collection
  • Metrics: Form-specific conversion rates

Contact/CRM Integration

  • Purpose: Link anonymous visitors to known contacts
  • Data: Contact ID association
  • Benefit: Full customer journey tracking

Performance Considerations

Real-time vs Batch Processing

  • Real-time: Page views, form submissions recorded immediately
  • Batch: Aggregate metrics calculated hourly/daily
  • Optimization: Uses MongoDB aggregation pipelines for efficiency

Data Retention

  • Raw events: 90 days (configurable)
  • Aggregated data: Indefinite retention
  • Visitor records: 2 years of inactivity

Query Optimization

  • Indexed fields: funnel_id, step_id, visitor_id, timestamp, event_type
  • Compound indexes: (funnel_id, timestamp), (visitor_id, event_type)
  • Aggregation caching: Pre-calculated daily/monthly summaries

Error Handling

Common Errors

// Invalid funnel ID
{
"success": false,
"message": "Funnel not found",
"statusCode": 404
}

// Invalid step ID
{
"success": false,
"message": "Step not found",
"statusCode": 404
}

// Missing required fields
{
"success": false,
"message": "Missing required field: visitor_id",
"statusCode": 400
}

// Invalid date range
{
"success": false,
"message": "start_date must be before end_date",
"statusCode": 400
}

Security

Multi-Tenant Isolation

  • All analytics queries filtered by account (through funnel ownership)
  • Visitor data scoped to account funnels
  • No cross-account visitor tracking

Data Privacy

  • Visitor IDs are anonymized hashes
  • IP addresses optionally anonymized (last octet removed)
  • GDPR compliance: Visitor data can be purged on request

Rate Limiting

  • Analytics ingestion: 1000 events per minute per account
  • Query endpoints: 100 requests per minute per account

Best Practices

When to Use This Controller

  • ✅ Building funnel analytics dashboards
  • ✅ Tracking conversion rates and revenue
  • ✅ Analyzing traffic sources and campaigns
  • ✅ Monitoring funnel performance
  • ✅ A/B testing funnel variations

Common Patterns

  1. Batch event recording: Use items array to record multiple events in one call
  2. UTM tracking: Always include UTM parameters for attribution
  3. Unique visitors: Use consistent visitor_id across sessions
  4. Time-based queries: Use date ranges to limit result sets

Edge Cases

  • Duplicate events: Implement client-side deduplication with event IDs
  • Bot traffic: Filter by user agent patterns
  • Cross-device tracking: Requires contact_id linking
  • Timezone handling: All timestamps stored in UTC

  • Funnels Controller: Funnel CRUD and step management
  • Forms Controller: Form submission handling
  • Stripe/Square Webhooks: Payment event integration
  • Reports Module: Advanced analytics and reporting

Last Updated: January 2025
API Version: v1
Maintained By: DashClicks Engineering

💬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:31 AM