- Add MetricsPage and useOnboarding hook - Update superadmin controller and service - Add module documentation (docs/01-modulos/) - Add CONTEXT-MAP.yml and Sprint 5 execution report - Update project status and task traces 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
225 lines
4.7 KiB
Markdown
225 lines
4.7 KiB
Markdown
# SAAS-008: Audit Logs
|
|
|
|
## Metadata
|
|
- **Codigo:** SAAS-008
|
|
- **Modulo:** Audit
|
|
- **Prioridad:** P1
|
|
- **Estado:** Pendiente
|
|
- **Fase:** 3 - Features Core
|
|
|
|
## Descripcion
|
|
|
|
Sistema de auditoria completo: registro automatico de acciones, cambios en entidades, accesos de usuario, con busqueda y exportacion para compliance.
|
|
|
|
## Objetivos
|
|
|
|
1. Registro automatico de acciones
|
|
2. Tracking de cambios (before/after)
|
|
3. Log de accesos
|
|
4. Busqueda y filtrado
|
|
5. Exportacion para compliance
|
|
|
|
## Alcance
|
|
|
|
### Incluido
|
|
- Logs de CREATE/UPDATE/DELETE
|
|
- Diff de cambios (before/after)
|
|
- Logs de autenticacion
|
|
- IP y user agent
|
|
- Retencion configurable
|
|
- Busqueda full-text
|
|
- Export CSV/JSON
|
|
|
|
### Excluido
|
|
- Replay de acciones
|
|
- Alertas automaticas por patrones
|
|
- Integracion SIEM
|
|
|
|
## Modelo de Datos
|
|
|
|
### Tablas (schema: audit)
|
|
|
|
**audit_logs**
|
|
- id, tenant_id, user_id
|
|
- action (create/update/delete/read/auth)
|
|
- entity_type, entity_id
|
|
- changes (JSONB: {before, after, diff})
|
|
- ip_address, user_agent
|
|
- metadata (JSONB)
|
|
- created_at
|
|
|
|
**auth_logs**
|
|
- id, tenant_id, user_id
|
|
- action (login/logout/failed/mfa)
|
|
- ip_address, user_agent
|
|
- location (JSONB: {country, city})
|
|
- success, failure_reason
|
|
- created_at
|
|
|
|
## Tipos de Eventos
|
|
|
|
### Acciones de Datos
|
|
| Accion | Descripcion |
|
|
|--------|-------------|
|
|
| entity.created | Registro creado |
|
|
| entity.updated | Registro modificado |
|
|
| entity.deleted | Registro eliminado |
|
|
| entity.viewed | Registro consultado |
|
|
| bulk.import | Importacion masiva |
|
|
| bulk.export | Exportacion masiva |
|
|
|
|
### Acciones de Auth
|
|
| Accion | Descripcion |
|
|
|--------|-------------|
|
|
| auth.login | Login exitoso |
|
|
| auth.logout | Logout |
|
|
| auth.failed | Login fallido |
|
|
| auth.mfa | MFA verificado |
|
|
| auth.password_change | Password cambiado |
|
|
| auth.session_revoked | Sesion revocada |
|
|
|
|
## Endpoints API
|
|
|
|
| Metodo | Endpoint | Descripcion |
|
|
|--------|----------|-------------|
|
|
| GET | /audit/logs | Listar logs |
|
|
| GET | /audit/logs/:id | Detalle de log |
|
|
| GET | /audit/entity/:type/:id | Logs de entidad |
|
|
| GET | /audit/user/:id | Logs de usuario |
|
|
| GET | /audit/auth | Logs de auth |
|
|
| GET | /audit/export | Exportar logs |
|
|
| GET | /audit/stats | Estadisticas |
|
|
|
|
## Filtros de Busqueda
|
|
|
|
```typescript
|
|
interface AuditFilters {
|
|
dateFrom?: Date;
|
|
dateTo?: Date;
|
|
userId?: string;
|
|
action?: string;
|
|
entityType?: string;
|
|
entityId?: string;
|
|
ipAddress?: string;
|
|
search?: string; // full-text
|
|
}
|
|
```
|
|
|
|
## Implementacion
|
|
|
|
### Interceptor Automatico
|
|
```typescript
|
|
@Injectable()
|
|
export class AuditInterceptor implements NestInterceptor {
|
|
intercept(context: ExecutionContext, next: CallHandler) {
|
|
const request = context.switchToHttp().getRequest();
|
|
const before = request.body;
|
|
|
|
return next.handle().pipe(
|
|
tap(async (result) => {
|
|
await this.auditService.log({
|
|
userId: request.user.id,
|
|
action: this.getAction(request.method),
|
|
entityType: this.getEntityType(request.path),
|
|
entityId: result?.id,
|
|
changes: { before, after: result },
|
|
ip: request.ip,
|
|
userAgent: request.headers['user-agent']
|
|
});
|
|
})
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Decorator Manual
|
|
```typescript
|
|
@AuditLog('custom.action')
|
|
async customOperation() {
|
|
// Se registra automaticamente
|
|
}
|
|
```
|
|
|
|
## Retencion de Datos
|
|
|
|
| Plan | Retencion |
|
|
|------|-----------|
|
|
| Free | 7 dias |
|
|
| Starter | 30 dias |
|
|
| Pro | 90 dias |
|
|
| Enterprise | 1 año (configurable) |
|
|
|
|
## Estructura de Log
|
|
|
|
```typescript
|
|
interface AuditLog {
|
|
id: string;
|
|
tenantId: string;
|
|
userId: string;
|
|
userName: string;
|
|
action: string;
|
|
entityType: string;
|
|
entityId: string;
|
|
changes: {
|
|
before: object | null;
|
|
after: object | null;
|
|
diff: object; // solo campos cambiados
|
|
};
|
|
metadata: {
|
|
ip: string;
|
|
userAgent: string;
|
|
location?: {
|
|
country: string;
|
|
city: string;
|
|
};
|
|
requestId: string;
|
|
};
|
|
createdAt: Date;
|
|
}
|
|
```
|
|
|
|
## Entregables
|
|
|
|
| Entregable | Estado | Archivo |
|
|
|------------|--------|---------|
|
|
| audit.module.ts | Pendiente | `modules/audit/` |
|
|
| audit.service.ts | Pendiente | `services/` |
|
|
| audit.interceptor.ts | Pendiente | `interceptors/` |
|
|
| DDL audit schema | Pendiente | `ddl/schemas/audit/` |
|
|
|
|
## Dependencias
|
|
|
|
### Depende de
|
|
- SAAS-001 (Auth)
|
|
- SAAS-002 (Tenants)
|
|
- SAAS-003 (Users)
|
|
- SAAS-005 (Plans - retencion)
|
|
|
|
### Bloquea a
|
|
- Compliance reports
|
|
- Security dashboards
|
|
|
|
## Criterios de Aceptacion
|
|
|
|
- [ ] CRUD se registra automaticamente
|
|
- [ ] Auth events se registran
|
|
- [ ] Before/after se captura
|
|
- [ ] Busqueda funciona
|
|
- [ ] Export CSV funciona
|
|
- [ ] Retencion se aplica
|
|
|
|
## Feature Flag
|
|
|
|
```typescript
|
|
// Solo disponible en Enterprise
|
|
@RequiresFeature('audit_logs')
|
|
@Get('/audit/logs')
|
|
async getAuditLogs() {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
**Ultima actualizacion:** 2026-01-07
|