- SAAS-015 OAuth: Specified -> Completed (already implemented) - SAAS-016 Analytics: Specified -> Completed (already implemented) - ET-SAAS-015: Proposed -> Implemented - ET-SAAS-016: Proposed -> Implemented Backend implementation verified: - OAuth: 799 lines (controller + service) - Analytics: 513 lines with full metrics Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
386 lines
9.6 KiB
Markdown
386 lines
9.6 KiB
Markdown
---
|
|
id: "SAAS-016"
|
|
title: "Dashboard Analytics"
|
|
type: "Module"
|
|
status: "Completed"
|
|
priority: "P2"
|
|
module: "analytics"
|
|
version: "1.0.0"
|
|
created_date: "2026-01-24"
|
|
updated_date: "2026-01-24"
|
|
story_points: 8
|
|
---
|
|
|
|
# SAAS-016: Dashboard Analytics
|
|
|
|
## Metadata
|
|
- **Codigo:** SAAS-016
|
|
- **Modulo:** Analytics
|
|
- **Prioridad:** P2
|
|
- **Estado:** Especificado
|
|
- **Fase:** 3 - Advanced Features
|
|
- **Story Points:** 8
|
|
|
|
## Descripcion
|
|
|
|
Dashboard de analitica empresarial con metricas avanzadas para tenants y superadmin. Proporciona KPIs de usuarios, billing, uso de recursos y tendencias temporales con graficos interactivos.
|
|
|
|
## Objetivos
|
|
|
|
1. Metricas de usuarios (activos, nuevos, churn)
|
|
2. Metricas de billing (MRR, revenue, subscriptions)
|
|
3. Metricas de uso (API calls, storage, AI tokens)
|
|
4. Graficos temporales multi-periodo (7d, 30d, 90d, 1y)
|
|
5. KPIs agregados por tenant y globales (superadmin)
|
|
6. Exportacion de datos de analytics
|
|
|
|
## Alcance
|
|
|
|
### Incluido
|
|
- Dashboard de metricas por tenant
|
|
- Dashboard global para superadmin
|
|
- Graficos de tendencias temporales
|
|
- KPIs en tiempo real
|
|
- Filtros por periodo
|
|
- Cache de metricas calculadas
|
|
- Exportacion basica de datos
|
|
|
|
### Excluido
|
|
- BI avanzado (integracion con Metabase/Superset)
|
|
- Machine Learning predictions
|
|
- Alertas automaticas basadas en metricas (ver SAAS-007)
|
|
- Reportes programados (ver SAAS-017)
|
|
|
|
## Modelo de Datos
|
|
|
|
### Tablas Nuevas (schema: analytics)
|
|
|
|
**metrics_cache**
|
|
```sql
|
|
CREATE TABLE analytics.metrics_cache (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID REFERENCES tenants.tenants(id),
|
|
metric_type VARCHAR(50) NOT NULL,
|
|
period VARCHAR(20) NOT NULL, -- 'daily', 'weekly', 'monthly'
|
|
period_start DATE NOT NULL,
|
|
period_end DATE NOT NULL,
|
|
value JSONB NOT NULL,
|
|
calculated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
|
|
UNIQUE(tenant_id, metric_type, period, period_start)
|
|
);
|
|
```
|
|
|
|
**usage_events** (para tracking detallado)
|
|
```sql
|
|
CREATE TABLE analytics.usage_events (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL,
|
|
user_id UUID,
|
|
event_type VARCHAR(50) NOT NULL,
|
|
event_data JSONB,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_usage_events_tenant_type ON analytics.usage_events(tenant_id, event_type, created_at);
|
|
```
|
|
|
|
## Metricas Definidas
|
|
|
|
### Metricas de Usuarios
|
|
| Metrica | Descripcion | Calculo |
|
|
|---------|-------------|---------|
|
|
| total_users | Usuarios totales | COUNT(users) |
|
|
| active_users | Usuarios activos (7d) | Users con login en 7 dias |
|
|
| new_users | Nuevos usuarios (periodo) | Users creados en periodo |
|
|
| churn_rate | Tasa de abandono | Users inactivos / total |
|
|
| dau | Daily Active Users | Users activos hoy |
|
|
| mau | Monthly Active Users | Users activos 30d |
|
|
|
|
### Metricas de Billing
|
|
| Metrica | Descripcion | Calculo |
|
|
|---------|-------------|---------|
|
|
| mrr | Monthly Recurring Revenue | SUM(subscriptions activas) |
|
|
| arr | Annual Recurring Revenue | MRR * 12 |
|
|
| total_revenue | Revenue total (periodo) | SUM(invoices pagadas) |
|
|
| avg_revenue_per_user | ARPU | Revenue / users |
|
|
| subscriptions_active | Suscripciones activas | COUNT(active subscriptions) |
|
|
| subscriptions_churned | Suscripciones canceladas | COUNT(canceled periodo) |
|
|
|
|
### Metricas de Uso
|
|
| Metrica | Descripcion | Calculo |
|
|
|---------|-------------|---------|
|
|
| api_calls | Llamadas API (periodo) | COUNT(requests) |
|
|
| storage_used | Storage utilizado | SUM(file sizes) |
|
|
| ai_tokens_used | Tokens AI consumidos | SUM(ai_usage.tokens) |
|
|
| notifications_sent | Notificaciones enviadas | COUNT(notifications) |
|
|
| webhooks_delivered | Webhooks entregados | COUNT(successful deliveries) |
|
|
|
|
## Endpoints API
|
|
|
|
| Metodo | Endpoint | Descripcion | Auth |
|
|
|--------|----------|-------------|------|
|
|
| GET | /analytics/summary | Resumen de KPIs | JWT |
|
|
| GET | /analytics/users | Metricas de usuarios | JWT |
|
|
| GET | /analytics/billing | Metricas de billing | JWT |
|
|
| GET | /analytics/usage | Metricas de uso | JWT |
|
|
| GET | /analytics/trends | Tendencias temporales | JWT |
|
|
| GET | /analytics/export | Exportar datos | JWT |
|
|
|
|
### Detalle de Endpoints
|
|
|
|
#### GET /analytics/summary
|
|
Resumen de KPIs principales.
|
|
|
|
**Query params:**
|
|
- `period`: 7d | 30d | 90d | 1y (default: 30d)
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"period": "30d",
|
|
"users": {
|
|
"total": 1250,
|
|
"active": 890,
|
|
"new": 120,
|
|
"churn_rate": 2.5
|
|
},
|
|
"billing": {
|
|
"mrr": 45000,
|
|
"arr": 540000,
|
|
"revenue_period": 52000,
|
|
"arpu": 41.6
|
|
},
|
|
"usage": {
|
|
"api_calls": 1500000,
|
|
"storage_gb": 250,
|
|
"ai_tokens": 500000
|
|
},
|
|
"trends": {
|
|
"users_growth": 5.2,
|
|
"mrr_growth": 8.1,
|
|
"usage_growth": 12.5
|
|
}
|
|
}
|
|
```
|
|
|
|
#### GET /analytics/users
|
|
Metricas detalladas de usuarios.
|
|
|
|
**Query params:**
|
|
- `period`: 7d | 30d | 90d | 1y
|
|
- `granularity`: daily | weekly | monthly
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"summary": {
|
|
"total": 1250,
|
|
"active": 890,
|
|
"new": 120,
|
|
"churned": 15
|
|
},
|
|
"timeseries": [
|
|
{"date": "2026-01-01", "total": 1130, "active": 850, "new": 10},
|
|
{"date": "2026-01-02", "total": 1135, "active": 855, "new": 5},
|
|
...
|
|
],
|
|
"breakdown": {
|
|
"by_plan": [
|
|
{"plan": "free", "count": 800},
|
|
{"plan": "pro", "count": 350},
|
|
{"plan": "enterprise", "count": 100}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
#### GET /analytics/billing
|
|
Metricas detalladas de billing.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"summary": {
|
|
"mrr": 45000,
|
|
"arr": 540000,
|
|
"revenue_30d": 52000,
|
|
"arpu": 41.6
|
|
},
|
|
"timeseries": [
|
|
{"date": "2026-01-01", "mrr": 44500, "revenue": 1800},
|
|
...
|
|
],
|
|
"breakdown": {
|
|
"by_plan": [
|
|
{"plan": "pro", "mrr": 35000, "subscribers": 350},
|
|
{"plan": "enterprise", "mrr": 10000, "subscribers": 100}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
#### GET /analytics/usage
|
|
Metricas de uso de recursos.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"api": {
|
|
"total_calls": 1500000,
|
|
"calls_by_endpoint": [
|
|
{"endpoint": "/api/users", "calls": 250000},
|
|
...
|
|
]
|
|
},
|
|
"storage": {
|
|
"total_gb": 250,
|
|
"by_type": [
|
|
{"type": "images", "gb": 150},
|
|
{"type": "documents", "gb": 80},
|
|
{"type": "other", "gb": 20}
|
|
]
|
|
},
|
|
"ai": {
|
|
"total_tokens": 500000,
|
|
"by_model": [
|
|
{"model": "gpt-4", "tokens": 300000},
|
|
{"model": "claude-3", "tokens": 200000}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
#### GET /analytics/trends
|
|
Tendencias y comparativas.
|
|
|
|
**Query params:**
|
|
- `metrics`: users,mrr,usage (comma separated)
|
|
- `period`: 30d | 90d | 1y
|
|
- `compare_previous`: true | false
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"current_period": "2026-01-01 to 2026-01-30",
|
|
"previous_period": "2025-12-01 to 2025-12-30",
|
|
"trends": {
|
|
"users": {
|
|
"current": 1250,
|
|
"previous": 1100,
|
|
"change_percent": 13.6,
|
|
"trend": "up"
|
|
},
|
|
"mrr": {
|
|
"current": 45000,
|
|
"previous": 41000,
|
|
"change_percent": 9.8,
|
|
"trend": "up"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Implementacion Backend
|
|
|
|
### Entities
|
|
- `MetricsCache` - Cache de metricas calculadas
|
|
- `UsageEvent` - Eventos de uso
|
|
|
|
### Services
|
|
- `AnalyticsService` - Servicio principal de analytics
|
|
- `MetricsCalculatorService` - Calculo de metricas
|
|
- `MetricsCacheService` - Gestion de cache
|
|
|
|
### Controllers
|
|
- `AnalyticsController` - Endpoints de analytics
|
|
|
|
### Jobs (BullMQ)
|
|
- `CalculateMetricsJob` - Calculo periodico de metricas
|
|
- `AggregateUsageJob` - Agregacion de eventos de uso
|
|
|
|
## Implementacion Frontend
|
|
|
|
### Componentes
|
|
- `AnalyticsDashboard` - Dashboard principal
|
|
- `MetricCard` - Tarjeta de metrica individual
|
|
- `TrendChart` - Grafico de tendencias (recharts)
|
|
- `UsageBreakdown` - Desglose de uso
|
|
- `PeriodSelector` - Selector de periodo
|
|
|
|
### Paginas
|
|
- `/dashboard/analytics` - Dashboard de analytics
|
|
|
|
### Hooks
|
|
- `useAnalytics` - Fetch de datos de analytics
|
|
- `useMetrics` - Metricas especificas
|
|
- `useTrends` - Tendencias temporales
|
|
|
|
### Dependencias Frontend
|
|
```json
|
|
{
|
|
"recharts": "^2.15.0"
|
|
}
|
|
```
|
|
|
|
## Cache Strategy
|
|
|
|
1. **Metricas diarias:** Calculadas cada hora, cache 1h
|
|
2. **Metricas semanales:** Calculadas cada 6h, cache 6h
|
|
3. **Metricas mensuales:** Calculadas diariamente, cache 24h
|
|
4. **Real-time:** Sin cache, queries directas (limitado)
|
|
|
|
## Seguridad
|
|
|
|
1. **Tenant Isolation:** Cada tenant solo ve sus metricas
|
|
2. **Superadmin:** Acceso a metricas globales agregadas
|
|
3. **Rate Limiting:** Limitar queries de analytics
|
|
4. **Data Retention:** Eventos de uso se purgan despues de 90 dias
|
|
|
|
## Criterios de Aceptacion
|
|
|
|
- [ ] Dashboard muestra KPIs de usuarios, billing, uso
|
|
- [ ] Graficos de tendencias funcionan con recharts
|
|
- [ ] Selector de periodo funciona (7d, 30d, 90d, 1y)
|
|
- [ ] Cache de metricas reduce carga en BD
|
|
- [ ] Superadmin ve metricas globales
|
|
- [ ] Exportacion de datos funciona
|
|
- [ ] Tests unitarios con cobertura >70%
|
|
|
|
## Dependencias
|
|
|
|
- SAAS-004 (Billing) - Datos de suscripciones e invoices
|
|
- SAAS-003 (Users) - Datos de usuarios
|
|
- SAAS-008 (Audit) - Eventos para tracking
|
|
|
|
## Wireframes
|
|
|
|
```
|
|
+------------------------------------------+
|
|
| Analytics Dashboard [7d v] |
|
|
+------------------------------------------+
|
|
| +--------+ +--------+ +--------+ |
|
|
| | Users | | MRR | | API | |
|
|
| | 1,250 | | $45K | | 1.5M | |
|
|
| | +5.2% | | +8.1% | | +12% | |
|
|
| +--------+ +--------+ +--------+ |
|
|
| |
|
|
| [========== Trend Chart ===========] |
|
|
| | /\ | |
|
|
| | / \ /\ | |
|
|
| | / \ / \ | |
|
|
| | / \/ \__/\__ | |
|
|
| +----------------------------------+ |
|
|
| |
|
|
| Usage Breakdown |
|
|
| +----------------------------------+ |
|
|
| | API Calls | Storage | AI | |
|
|
| | [=========] | [====] | [==] | |
|
|
| +----------------------------------+ |
|
|
+------------------------------------------+
|
|
```
|
|
|
|
---
|
|
|
|
*SAAS-016 v1.0.0 - Template SaaS*
|