template-saas/docs/01-modulos/SAAS-008-audit-logs.md
rckrdmrd 50a821a415
Some checks failed
CI / Backend CI (push) Has been cancelled
CI / Frontend CI (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / CI Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones de configuracion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:08 -06:00

238 lines
4.9 KiB
Markdown

---
id: "SAAS-008"
title: "Audit Logs"
type: "Module"
status: "Published"
priority: "P1"
module: "audit-logs"
version: "1.0.0"
created_date: "2026-01-07"
updated_date: "2026-01-10"
---
# SAAS-008: Audit Logs
## Metadata
- **Codigo:** SAAS-008
- **Modulo:** Audit
- **Prioridad:** P1
- **Estado:** Completado
- **Fase:** 3 - Features Core
- **Ultima Actualizacion:** 2026-01-10
## 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 (Pendiente implementacion) |
| 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 | Completado | `modules/audit/` |
| audit.service.ts | Completado | `services/` |
| audit.interceptor.ts | Completado | `interceptors/` |
| DDL audit schema | Completado | `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
- [x] CRUD se registra automaticamente
- [x] Auth events se registran
- [x] Before/after se captura
- [x] Busqueda funciona
- [x] Export CSV funciona
- [x] Retencion se aplica
## Feature Flag
```typescript
// Solo disponible en Enterprise
@RequiresFeature('audit_logs')
@Get('/audit/logs')
async getAuditLogs() {
// ...
}
```
---
**Ultima actualizacion:** 2026-01-10