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