[TASK-2026-01-24] docs: Add SAAS-015, SAAS-016, SAAS-017 specifications
This commit is contained in:
parent
f675591224
commit
a6489b0caf
329
docs/01-modulos/SAAS-015-oauth.md
Normal file
329
docs/01-modulos/SAAS-015-oauth.md
Normal file
@ -0,0 +1,329 @@
|
||||
---
|
||||
id: "SAAS-015"
|
||||
title: "OAuth 2.0 Endpoints"
|
||||
type: "Module"
|
||||
status: "Specified"
|
||||
priority: "P1"
|
||||
module: "oauth"
|
||||
version: "1.0.0"
|
||||
created_date: "2026-01-24"
|
||||
updated_date: "2026-01-24"
|
||||
story_points: 5
|
||||
---
|
||||
|
||||
# SAAS-015: OAuth 2.0 Endpoints
|
||||
|
||||
## Metadata
|
||||
- **Codigo:** SAAS-015
|
||||
- **Modulo:** OAuth (extension de Auth)
|
||||
- **Prioridad:** P1
|
||||
- **Estado:** Especificado
|
||||
- **Fase:** 2 - Integraciones
|
||||
- **Story Points:** 5
|
||||
|
||||
## Descripcion
|
||||
|
||||
Implementacion completa de endpoints OAuth 2.0 para autenticacion federada con multiples proveedores. Permite a los usuarios autenticarse usando sus cuentas de Google, Microsoft, GitHub o Apple.
|
||||
|
||||
**Nota:** La tabla DDL `auth.oauth_connections` ya existe. Este modulo completa la implementacion backend y frontend.
|
||||
|
||||
## Objetivos
|
||||
|
||||
1. Autenticacion via Google OAuth 2.0
|
||||
2. Autenticacion via Microsoft OAuth 2.0
|
||||
3. Autenticacion via GitHub OAuth 2.0
|
||||
4. Autenticacion via Apple Sign-In
|
||||
5. Vincular/desvincular cuentas OAuth a usuarios existentes
|
||||
6. Gestion de conexiones OAuth del usuario
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluido
|
||||
- Flujo OAuth completo para 4 proveedores
|
||||
- Passport.js strategies para cada proveedor
|
||||
- Callback handling con creacion/vinculacion de usuario
|
||||
- Gestion de conexiones OAuth por usuario
|
||||
- Refresh de tokens OAuth cuando expiran
|
||||
- UI para login con proveedores
|
||||
- UI para gestionar conexiones en perfil
|
||||
|
||||
### Excluido
|
||||
- SSO/SAML (enterprise feature - SAAS-E01)
|
||||
- OAuth como proveedor (ser IdP) - futuro
|
||||
- Proveedores adicionales (LinkedIn, Twitter) - bajo demanda
|
||||
|
||||
## Modelo de Datos
|
||||
|
||||
### Tablas Existentes (schema: auth)
|
||||
|
||||
**oauth_connections** (DDL ya existe)
|
||||
```sql
|
||||
- id: UUID PRIMARY KEY
|
||||
- user_id: UUID REFERENCES users.users(id)
|
||||
- provider: oauth_provider ENUM ('google', 'microsoft', 'github', 'apple')
|
||||
- provider_user_id: VARCHAR(255) NOT NULL
|
||||
- access_token: TEXT
|
||||
- refresh_token: TEXT
|
||||
- token_expires_at: TIMESTAMPTZ
|
||||
- profile_data: JSONB
|
||||
- created_at: TIMESTAMPTZ DEFAULT NOW()
|
||||
- updated_at: TIMESTAMPTZ DEFAULT NOW()
|
||||
|
||||
UNIQUE(provider, provider_user_id)
|
||||
UNIQUE(user_id, provider)
|
||||
```
|
||||
|
||||
### ENUMs Existentes
|
||||
|
||||
```sql
|
||||
CREATE TYPE auth.oauth_provider AS ENUM (
|
||||
'google',
|
||||
'microsoft',
|
||||
'github',
|
||||
'apple'
|
||||
);
|
||||
```
|
||||
|
||||
## Endpoints API
|
||||
|
||||
| Metodo | Endpoint | Descripcion | Auth |
|
||||
|--------|----------|-------------|------|
|
||||
| GET | /auth/oauth/:provider | Iniciar flujo OAuth | No |
|
||||
| GET | /auth/oauth/:provider/callback | Callback del proveedor | No |
|
||||
| POST | /auth/oauth/link/:provider | Vincular a cuenta existente | JWT |
|
||||
| DELETE | /auth/oauth/:provider | Desvincular proveedor | JWT |
|
||||
| GET | /auth/oauth/connections | Listar conexiones del usuario | JWT |
|
||||
|
||||
### Detalle de Endpoints
|
||||
|
||||
#### GET /auth/oauth/:provider
|
||||
Inicia el flujo OAuth redirigiendo al proveedor.
|
||||
|
||||
**Parametros:**
|
||||
- `provider`: google | microsoft | github | apple
|
||||
- `redirect_uri` (query): URL de retorno post-auth
|
||||
|
||||
**Response:** Redirect 302 a URL del proveedor
|
||||
|
||||
#### GET /auth/oauth/:provider/callback
|
||||
Procesa el callback del proveedor OAuth.
|
||||
|
||||
**Query params:**
|
||||
- `code`: Authorization code del proveedor
|
||||
- `state`: State para validar CSRF
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"access_token": "jwt_token",
|
||||
"refresh_token": "refresh_token",
|
||||
"user": {
|
||||
"id": "uuid",
|
||||
"email": "user@example.com",
|
||||
"name": "Usuario"
|
||||
},
|
||||
"is_new_user": true
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /auth/oauth/link/:provider
|
||||
Vincula un proveedor OAuth a la cuenta actual.
|
||||
|
||||
**Headers:** Authorization: Bearer {jwt}
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Provider linked successfully",
|
||||
"connection": {
|
||||
"provider": "google",
|
||||
"email": "user@gmail.com",
|
||||
"linked_at": "2026-01-24T12:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### DELETE /auth/oauth/:provider
|
||||
Desvincula un proveedor OAuth de la cuenta.
|
||||
|
||||
**Headers:** Authorization: Bearer {jwt}
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Provider unlinked successfully"
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /auth/oauth/connections
|
||||
Lista todas las conexiones OAuth del usuario.
|
||||
|
||||
**Headers:** Authorization: Bearer {jwt}
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"connections": [
|
||||
{
|
||||
"provider": "google",
|
||||
"email": "user@gmail.com",
|
||||
"linked_at": "2026-01-24T12:00:00Z"
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"username": "user123",
|
||||
"linked_at": "2026-01-20T10:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Implementacion Backend
|
||||
|
||||
### Entities
|
||||
- `OAuthConnection` - Entity TypeORM para oauth_connections
|
||||
|
||||
### Services
|
||||
- `OAuthService` - Logica de negocio OAuth
|
||||
- `OAuthCallbackService` - Procesamiento de callbacks
|
||||
|
||||
### Controllers
|
||||
- `OAuthController` - Endpoints OAuth
|
||||
|
||||
### Passport Strategies
|
||||
- `GoogleStrategy` - Passport Google OAuth 2.0
|
||||
- `MicrosoftStrategy` - Passport Microsoft OAuth 2.0
|
||||
- `GitHubStrategy` - Passport GitHub OAuth 2.0
|
||||
- `AppleStrategy` - Passport Apple Sign-In
|
||||
|
||||
### Dependencias NPM
|
||||
```json
|
||||
{
|
||||
"passport": "^0.7.0",
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"passport-microsoft": "^1.0.0",
|
||||
"passport-github2": "^0.1.12",
|
||||
"passport-apple": "^2.0.2"
|
||||
}
|
||||
```
|
||||
|
||||
## Implementacion Frontend
|
||||
|
||||
### Componentes
|
||||
- `OAuthButtons` - Botones de login OAuth
|
||||
- `OAuthCallback` - Pagina de callback
|
||||
- `OAuthConnections` - Gestion de conexiones en perfil
|
||||
|
||||
### Paginas
|
||||
- `/auth/oauth/callback` - Procesa callback OAuth
|
||||
|
||||
### Hooks
|
||||
- `useOAuthLogin` - Iniciar flujo OAuth
|
||||
- `useOAuthConnections` - Gestionar conexiones
|
||||
|
||||
## Flujos
|
||||
|
||||
### Login con OAuth (nuevo usuario)
|
||||
```
|
||||
1. Usuario click "Login con Google"
|
||||
2. Frontend redirige a GET /auth/oauth/google
|
||||
3. Backend redirige a Google
|
||||
4. Usuario autoriza en Google
|
||||
5. Google redirige a /auth/oauth/google/callback
|
||||
6. Backend:
|
||||
a. Valida code con Google
|
||||
b. Obtiene perfil del usuario
|
||||
c. Crea nuevo User + Tenant
|
||||
d. Crea OAuthConnection
|
||||
e. Genera JWT tokens
|
||||
7. Redirect a frontend con tokens
|
||||
8. Usuario autenticado
|
||||
```
|
||||
|
||||
### Login con OAuth (usuario existente)
|
||||
```
|
||||
1. Usuario click "Login con Google"
|
||||
2-5. (Mismo flujo)
|
||||
6. Backend:
|
||||
a. Valida code con Google
|
||||
b. Busca OAuthConnection existente
|
||||
c. Obtiene User vinculado
|
||||
d. Genera JWT tokens
|
||||
7. Redirect a frontend con tokens
|
||||
8. Usuario autenticado
|
||||
```
|
||||
|
||||
### Vincular OAuth a cuenta existente
|
||||
```
|
||||
1. Usuario autenticado va a Perfil > Conexiones
|
||||
2. Click "Vincular Google"
|
||||
3. Redirige a Google OAuth
|
||||
4. Usuario autoriza
|
||||
5. Backend:
|
||||
a. Valida que no existe conexion con ese provider_user_id
|
||||
b. Crea OAuthConnection para user actual
|
||||
6. Muestra conexion en lista
|
||||
```
|
||||
|
||||
## Configuracion
|
||||
|
||||
### Variables de Entorno
|
||||
```env
|
||||
# Google OAuth
|
||||
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
|
||||
GOOGLE_CLIENT_SECRET=xxx
|
||||
GOOGLE_CALLBACK_URL=https://app.example.com/auth/oauth/google/callback
|
||||
|
||||
# Microsoft OAuth
|
||||
MICROSOFT_CLIENT_ID=xxx
|
||||
MICROSOFT_CLIENT_SECRET=xxx
|
||||
MICROSOFT_CALLBACK_URL=https://app.example.com/auth/oauth/microsoft/callback
|
||||
|
||||
# GitHub OAuth
|
||||
GITHUB_CLIENT_ID=xxx
|
||||
GITHUB_CLIENT_SECRET=xxx
|
||||
GITHUB_CALLBACK_URL=https://app.example.com/auth/oauth/github/callback
|
||||
|
||||
# Apple Sign-In
|
||||
APPLE_CLIENT_ID=xxx
|
||||
APPLE_TEAM_ID=xxx
|
||||
APPLE_KEY_ID=xxx
|
||||
APPLE_PRIVATE_KEY=xxx
|
||||
APPLE_CALLBACK_URL=https://app.example.com/auth/oauth/apple/callback
|
||||
```
|
||||
|
||||
## Seguridad
|
||||
|
||||
1. **CSRF Protection:** Usar state parameter en flujo OAuth
|
||||
2. **Token Storage:** Encriptar access/refresh tokens en BD
|
||||
3. **Scope Minimo:** Solicitar solo email y perfil basico
|
||||
4. **Validacion de Dominio:** Verificar callback URL contra whitelist
|
||||
5. **Rate Limiting:** Limitar intentos de OAuth por IP
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Login con Google funciona end-to-end
|
||||
- [ ] Login con Microsoft funciona end-to-end
|
||||
- [ ] Login con GitHub funciona end-to-end
|
||||
- [ ] Login con Apple funciona end-to-end
|
||||
- [ ] Usuario puede vincular multiples proveedores
|
||||
- [ ] Usuario puede desvincular proveedores (si tiene password o otro provider)
|
||||
- [ ] Conexiones se muestran en perfil
|
||||
- [ ] Tests unitarios con cobertura >70%
|
||||
- [ ] Tests E2E para flujo completo
|
||||
|
||||
## Dependencias
|
||||
|
||||
- SAAS-001 (Auth) - Base de autenticacion
|
||||
- SAAS-003 (Users) - Gestion de usuarios
|
||||
|
||||
## Referencias
|
||||
|
||||
- [Google OAuth 2.0](https://developers.google.com/identity/protocols/oauth2)
|
||||
- [Microsoft Identity Platform](https://docs.microsoft.com/en-us/azure/active-directory/develop/)
|
||||
- [GitHub OAuth](https://docs.github.com/en/developers/apps/building-oauth-apps)
|
||||
- [Apple Sign-In](https://developer.apple.com/sign-in-with-apple/)
|
||||
|
||||
---
|
||||
|
||||
*SAAS-015 v1.0.0 - Template SaaS*
|
||||
385
docs/01-modulos/SAAS-016-analytics.md
Normal file
385
docs/01-modulos/SAAS-016-analytics.md
Normal file
@ -0,0 +1,385 @@
|
||||
---
|
||||
id: "SAAS-016"
|
||||
title: "Dashboard Analytics"
|
||||
type: "Module"
|
||||
status: "Specified"
|
||||
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*
|
||||
363
docs/01-modulos/SAAS-017-reports.md
Normal file
363
docs/01-modulos/SAAS-017-reports.md
Normal file
@ -0,0 +1,363 @@
|
||||
---
|
||||
id: "SAAS-017"
|
||||
title: "Reportes Exportables"
|
||||
type: "Module"
|
||||
status: "Specified"
|
||||
priority: "P2"
|
||||
module: "reports"
|
||||
version: "1.0.0"
|
||||
created_date: "2026-01-24"
|
||||
updated_date: "2026-01-24"
|
||||
story_points: 5
|
||||
---
|
||||
|
||||
# SAAS-017: Reportes Exportables
|
||||
|
||||
## Metadata
|
||||
- **Codigo:** SAAS-017
|
||||
- **Modulo:** Reports
|
||||
- **Prioridad:** P2
|
||||
- **Estado:** Especificado
|
||||
- **Fase:** 3 - Advanced Features
|
||||
- **Story Points:** 5
|
||||
|
||||
## Descripcion
|
||||
|
||||
Sistema de generacion y exportacion de reportes en multiples formatos. Permite exportar datos de usuarios, billing, audit logs y uso en PDF (formateados), Excel (tabulares) y CSV (crudos).
|
||||
|
||||
## Objetivos
|
||||
|
||||
1. Exportar reportes de usuarios en PDF/Excel/CSV
|
||||
2. Exportar reportes de billing en PDF/Excel
|
||||
3. Exportar audit logs en CSV
|
||||
4. Exportar metricas de uso en Excel
|
||||
5. Templates predefinidos de reportes
|
||||
6. Base para reportes programados (futuro)
|
||||
|
||||
## Alcance
|
||||
|
||||
### Incluido
|
||||
- Generacion de PDF con formato profesional
|
||||
- Exportacion a Excel con datos tabulares
|
||||
- Exportacion a CSV con datos crudos
|
||||
- Templates predefinidos para cada tipo de reporte
|
||||
- Filtros por fecha y criterios
|
||||
- Descarga directa o envio por email
|
||||
|
||||
### Excluido
|
||||
- Reportes programados/scheduled (fase posterior)
|
||||
- Designer de reportes custom
|
||||
- Reportes con graficos embebidos en PDF
|
||||
- Integracion con BI tools externos
|
||||
|
||||
## Tipos de Reportes
|
||||
|
||||
### Reportes de Usuarios
|
||||
| Reporte | Formatos | Descripcion |
|
||||
|---------|----------|-------------|
|
||||
| Lista de Usuarios | PDF, Excel, CSV | Todos los usuarios con roles |
|
||||
| Usuarios Activos | PDF, Excel | Usuarios activos en periodo |
|
||||
| Nuevos Registros | PDF, Excel | Usuarios registrados en periodo |
|
||||
| Usuarios por Plan | PDF, Excel | Distribucion por plan |
|
||||
|
||||
### Reportes de Billing
|
||||
| Reporte | Formatos | Descripcion |
|
||||
|---------|----------|-------------|
|
||||
| Resumen Facturacion | PDF | Resumen mensual de billing |
|
||||
| Invoices | PDF, Excel | Lista de facturas emitidas |
|
||||
| Revenue | Excel | Ingresos detallados |
|
||||
| Suscripciones | Excel | Estado de suscripciones |
|
||||
|
||||
### Reportes de Auditoria
|
||||
| Reporte | Formatos | Descripcion |
|
||||
|---------|----------|-------------|
|
||||
| Audit Log | CSV | Log completo de acciones |
|
||||
| Login History | CSV | Historial de logins |
|
||||
| Changes Log | CSV | Cambios en configuracion |
|
||||
|
||||
### Reportes de Uso
|
||||
| Reporte | Formatos | Descripcion |
|
||||
|---------|----------|-------------|
|
||||
| API Usage | Excel | Uso de API por endpoint |
|
||||
| Storage Usage | Excel | Uso de storage por tipo |
|
||||
| AI Usage | Excel | Consumo de tokens AI |
|
||||
|
||||
## Endpoints API
|
||||
|
||||
| Metodo | Endpoint | Descripcion | Auth |
|
||||
|--------|----------|-------------|------|
|
||||
| GET | /reports/users/pdf | Reporte usuarios PDF | JWT |
|
||||
| GET | /reports/users/excel | Reporte usuarios Excel | JWT |
|
||||
| GET | /reports/users/csv | Reporte usuarios CSV | JWT |
|
||||
| GET | /reports/billing/pdf | Reporte billing PDF | JWT |
|
||||
| GET | /reports/billing/excel | Reporte billing Excel | JWT |
|
||||
| GET | /reports/audit/csv | Audit log CSV | JWT |
|
||||
| GET | /reports/usage/excel | Reporte uso Excel | JWT |
|
||||
| POST | /reports/send-email | Enviar reporte por email | JWT |
|
||||
|
||||
### Query Parameters Comunes
|
||||
|
||||
```
|
||||
?start_date=2026-01-01
|
||||
&end_date=2026-01-31
|
||||
&filters[status]=active
|
||||
&filters[plan]=pro
|
||||
&sort=created_at
|
||||
&order=desc
|
||||
```
|
||||
|
||||
### Detalle de Endpoints
|
||||
|
||||
#### GET /reports/users/pdf
|
||||
Genera reporte de usuarios en PDF.
|
||||
|
||||
**Query params:**
|
||||
- `start_date`, `end_date`: Rango de fechas
|
||||
- `status`: active | inactive | all
|
||||
- `plan`: free | pro | enterprise | all
|
||||
|
||||
**Response:** application/pdf (binary)
|
||||
|
||||
**Headers:**
|
||||
```
|
||||
Content-Type: application/pdf
|
||||
Content-Disposition: attachment; filename="users-report-2026-01.pdf"
|
||||
```
|
||||
|
||||
#### GET /reports/billing/excel
|
||||
Genera reporte de billing en Excel.
|
||||
|
||||
**Query params:**
|
||||
- `start_date`, `end_date`: Rango de fechas
|
||||
- `type`: invoices | subscriptions | revenue
|
||||
|
||||
**Response:** application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
|
||||
#### GET /reports/audit/csv
|
||||
Exporta audit log en CSV.
|
||||
|
||||
**Query params:**
|
||||
- `start_date`, `end_date`: Rango de fechas
|
||||
- `action`: login | logout | create | update | delete | all
|
||||
- `user_id`: Filtrar por usuario especifico
|
||||
|
||||
**Response:** text/csv
|
||||
|
||||
#### POST /reports/send-email
|
||||
Genera y envia reporte por email.
|
||||
|
||||
**Body:**
|
||||
```json
|
||||
{
|
||||
"report_type": "users",
|
||||
"format": "pdf",
|
||||
"filters": {
|
||||
"start_date": "2026-01-01",
|
||||
"end_date": "2026-01-31",
|
||||
"status": "active"
|
||||
},
|
||||
"recipients": ["admin@company.com"],
|
||||
"subject": "Monthly Users Report",
|
||||
"message": "Attached is the monthly users report."
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Report sent successfully",
|
||||
"sent_to": ["admin@company.com"],
|
||||
"report_type": "users",
|
||||
"format": "pdf"
|
||||
}
|
||||
```
|
||||
|
||||
## Implementacion Backend
|
||||
|
||||
### Services
|
||||
- `ReportsService` - Servicio principal de reportes
|
||||
- `PdfGeneratorService` - Generacion de PDFs
|
||||
- `ExcelGeneratorService` - Generacion de Excel
|
||||
- `CsvGeneratorService` - Generacion de CSV
|
||||
|
||||
### Controllers
|
||||
- `ReportsController` - Endpoints de reportes
|
||||
|
||||
### Dependencias NPM
|
||||
```json
|
||||
{
|
||||
"pdfkit": "^0.15.0",
|
||||
"exceljs": "^4.4.0"
|
||||
}
|
||||
```
|
||||
|
||||
### Templates de PDF
|
||||
|
||||
Los templates PDF se definen en codigo usando PDFKit:
|
||||
|
||||
```typescript
|
||||
// templates/users-report.template.ts
|
||||
export const generateUsersReportPdf = (data: UserReportData) => {
|
||||
const doc = new PDFDocument();
|
||||
|
||||
// Header
|
||||
doc.fontSize(20).text('Users Report', { align: 'center' });
|
||||
doc.fontSize(12).text(`Period: ${data.startDate} - ${data.endDate}`);
|
||||
|
||||
// Table
|
||||
doc.moveDown();
|
||||
drawTable(doc, data.users, ['Name', 'Email', 'Plan', 'Status', 'Created']);
|
||||
|
||||
// Summary
|
||||
doc.moveDown();
|
||||
doc.fontSize(14).text('Summary');
|
||||
doc.fontSize(12).text(`Total Users: ${data.total}`);
|
||||
doc.text(`Active: ${data.active}`);
|
||||
doc.text(`New in Period: ${data.new}`);
|
||||
|
||||
return doc;
|
||||
};
|
||||
```
|
||||
|
||||
### Templates de Excel
|
||||
|
||||
```typescript
|
||||
// templates/users-report.excel.ts
|
||||
export const generateUsersReportExcel = async (data: UserReportData) => {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const sheet = workbook.addWorksheet('Users');
|
||||
|
||||
// Headers
|
||||
sheet.columns = [
|
||||
{ header: 'Name', key: 'name', width: 30 },
|
||||
{ header: 'Email', key: 'email', width: 35 },
|
||||
{ header: 'Plan', key: 'plan', width: 15 },
|
||||
{ header: 'Status', key: 'status', width: 12 },
|
||||
{ header: 'Created', key: 'createdAt', width: 20 }
|
||||
];
|
||||
|
||||
// Data rows
|
||||
data.users.forEach(user => sheet.addRow(user));
|
||||
|
||||
// Styling
|
||||
sheet.getRow(1).font = { bold: true };
|
||||
|
||||
return workbook;
|
||||
};
|
||||
```
|
||||
|
||||
## Implementacion Frontend
|
||||
|
||||
### Componentes
|
||||
- `ReportGenerator` - UI para generar reportes
|
||||
- `ReportFilters` - Filtros de reportes
|
||||
- `ReportDownloadButton` - Boton de descarga
|
||||
- `ReportEmailModal` - Modal para enviar por email
|
||||
|
||||
### Paginas
|
||||
- `/reports` - Lista de reportes disponibles
|
||||
- `/reports/generate` - Generador de reportes
|
||||
|
||||
### Hooks
|
||||
- `useReportDownload` - Descarga de reportes
|
||||
- `useReportEmail` - Envio por email
|
||||
|
||||
## Flujos
|
||||
|
||||
### Descarga Directa
|
||||
```
|
||||
1. Usuario selecciona tipo de reporte
|
||||
2. Configura filtros y formato
|
||||
3. Click "Download"
|
||||
4. Backend genera reporte
|
||||
5. Browser descarga archivo
|
||||
```
|
||||
|
||||
### Envio por Email
|
||||
```
|
||||
1. Usuario selecciona tipo de reporte
|
||||
2. Configura filtros y formato
|
||||
3. Ingresa destinatarios
|
||||
4. Click "Send"
|
||||
5. Backend genera reporte
|
||||
6. Backend envia email con adjunto
|
||||
7. Muestra confirmacion
|
||||
```
|
||||
|
||||
## Seguridad
|
||||
|
||||
1. **Permisos:** Solo usuarios con rol admin pueden generar reportes
|
||||
2. **Tenant Isolation:** Reportes solo incluyen datos del tenant
|
||||
3. **Rate Limiting:** Limitar generacion de reportes (costoso)
|
||||
4. **Audit Log:** Registrar cada reporte generado
|
||||
5. **Data Masking:** Ocultar datos sensibles si aplica
|
||||
|
||||
## Performance
|
||||
|
||||
1. **Limite de registros:** Max 10,000 registros por reporte
|
||||
2. **Streaming:** PDFs grandes se generan con streaming
|
||||
3. **Background Jobs:** Reportes muy grandes se procesan async
|
||||
4. **Cache:** Templates compilados se cachean
|
||||
|
||||
## Criterios de Aceptacion
|
||||
|
||||
- [ ] Generar PDF de usuarios con formato profesional
|
||||
- [ ] Generar Excel de usuarios con datos tabulares
|
||||
- [ ] Generar CSV de audit log
|
||||
- [ ] Filtros por fecha funcionan correctamente
|
||||
- [ ] Envio por email funciona
|
||||
- [ ] Limite de 10,000 registros se respeta
|
||||
- [ ] Reportes solo muestran datos del tenant
|
||||
- [ ] Tests unitarios con cobertura >70%
|
||||
|
||||
## Dependencias
|
||||
|
||||
- SAAS-003 (Users) - Datos de usuarios
|
||||
- SAAS-004 (Billing) - Datos de billing
|
||||
- SAAS-008 (Audit) - Datos de auditoria
|
||||
- SAAS-013 (Email) - Envio de reportes por email
|
||||
- SAAS-016 (Analytics) - Datos de uso (opcional)
|
||||
|
||||
## Wireframes
|
||||
|
||||
```
|
||||
+------------------------------------------+
|
||||
| Reports |
|
||||
+------------------------------------------+
|
||||
| |
|
||||
| Report Type: [Users v] |
|
||||
| Format: [PDF v] |
|
||||
| |
|
||||
| +-- Filters ---------------------------+|
|
||||
| | Date Range: [2026-01-01] to [01-31] ||
|
||||
| | Status: [Active v] ||
|
||||
| | Plan: [All v] ||
|
||||
| +--------------------------------------+|
|
||||
| |
|
||||
| [Download] [Send by Email] |
|
||||
| |
|
||||
+------------------------------------------+
|
||||
|
||||
+------------------------------------------+
|
||||
| Send Report by Email [X] |
|
||||
+------------------------------------------+
|
||||
| |
|
||||
| Recipients: |
|
||||
| [admin@company.com ] |
|
||||
| [+ Add recipient] |
|
||||
| |
|
||||
| Subject: |
|
||||
| [Monthly Users Report ] |
|
||||
| |
|
||||
| Message (optional): |
|
||||
| [ ] |
|
||||
| [ ] |
|
||||
| |
|
||||
| [Cancel] [Send Report] |
|
||||
| |
|
||||
+------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*SAAS-017 v1.0.0 - Template SaaS*
|
||||
Loading…
Reference in New Issue
Block a user