# Analytics Service

# Analytics Service (Port 8004) {#analytics-service-port-8004}


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


## Database {#database}


**Database:** `analytics_db`

| Table | Purpose |
|-------|---------|
| `dashboards` | Dashboard configuration |
| `dashboard_widgets` | Widget definitions |
| `analytics_reports` | Report definitions |
| `analytics_snapshots` | Cached aggregation results |


## Database Management {#database-management}


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

```python
# 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 {#api-endpoints}


| Method | Path | Purpose |
|--------|------|---------|
| GET | `/api/v1/dashboards` | List dashboards |
| POST | `/api/v1/dashboards` | Create dashboard |
| GET | `/api/v1/dashboards/{id}` | Get dashboard |
| GET | `/api/v1/analytics/summary` | Get overall tenant metrics |
| GET | `/api/v1/analytics/surveys/{id}` | Get specific survey metrics |
| POST | `/api/v1/analytics/aggregate` | Compute data for dashboard charts |
| GET | `/api/v1/analytics/export/{id}` | Export analytics (JSON, CSV, XLSX) |


## Data Aggregation Engine {#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 {#celery-schedules}


The `analytics-beat` container runs scheduled tasks:

```python
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 {#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)
