Analytics Service

Analytics engine for dashboards, aggregations, reports, and data snapshots

Analytics Service (Port 8004)

The analytics-service provides dashboard management, data aggregation, report generation, and cached analytics snapshots.

Database

Database: analytics_db

TablePurpose
dashboardsDashboard configuration
dashboard_widgetsWidget definitions
analytics_reportsReport definitions
analytics_snapshotsCached aggregation results

Database Management

Unlike most services, analytics-service uses Base.metadata.create_all() instead of Alembic:

# In api/infrastructure/database.py
from api.domain.entities import Base

async def init_db():
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)

Important: Adding columns to existing tables requires manual SQL migration — Alembic autogenerate is not available.

API Endpoints

MethodPathPurpose
GET/api/v1/dashboardsList dashboards
POST/api/v1/dashboardsCreate dashboard
GET/api/v1/dashboards/{id}Get dashboard
GET/api/v1/analytics/summaryGet overall tenant metrics
GET/api/v1/analytics/surveys/{id}Get specific survey metrics
POST/api/v1/analytics/aggregateCompute data for dashboard charts
GET/api/v1/analytics/export/{id}Export analytics (JSON, CSV, XLSX)

Data Aggregation Engine

The service computes on-the-fly aggregations for the dashboard builder:

  • Count / Distribution — Frequency of unique values
  • Average — Numeric histogram with min/max/avg summary
  • Sum — Total accumulated value for numeric fields

Results are cached in Redis for 5 minutes (TTL: 300s) using keys based on survey ID and question filters.

Celery Schedules

The analytics-beat container runs scheduled tasks:

beat_schedule = {
    "aggregate_surveys_hourly": {
        "task": "api.tasks.aggregate_surveys",
        "schedule": crontab(minute=0),  # Every hour
    },
    "cleanup_snapshots_daily": {
        "task": "api.tasks.cleanup_snapshots",
        "schedule": crontab(hour=2, minute=0),  # Daily at 2AM
    }
}

Caching Strategy

Analytics snapshots and aggregation results are cached to reduce load on the data-service. Cache is invalidated when:

  • New responses are received (via internal message bus)
  • Manual refresh is triggered
  • TTL expiration occurs (5 minutes for builder queries)