feat: Mejoras en auditoría - incidentes de seguridad y esquema de colores

- Backend:
  * Agregado endpoint /v1/audit/security/incidents con paginación y filtros
  * Nuevos schemas SecurityIncidentResponse y SecurityIncidentListResponse
  * Fix timezone: datetime.utcnow() → datetime.now(timezone.utc) en 4 ubicaciones
  * Detección automática de incidentes: mass deletion, brute force, privilege escalation

- Frontend (Internal):
  * Nueva sección de Incidentes de Seguridad con modal de detalles
  * Filtros por severidad, estado y tipo de incidente
  * Conversión completa a esquema grayscale (gray-100 a gray-900)
  * Eliminados todos los emojis de páginas audit y security
  * Implementada paginación para incidentes

- Fixes:
  * Resuelto error 500: TypeError con datetimes timezone-aware/naive
  * Resuelto error 404: endpoint de incidentes faltante
This commit is contained in:
2026-02-16 12:45:33 -07:00
parent 32cc8b6ccd
commit be762585d2
6 changed files with 1038 additions and 96 deletions

View File

@@ -100,6 +100,38 @@ class SecurityActionResponse(BaseModel):
action_id: Optional[UUID4] = Field(None, description="ID de la acción registrada")
class SecurityIncidentResponse(BaseModel):
"""Respuesta para incidentes de seguridad."""
id: str = Field(description="ID único del incidente")
title: str = Field(description="Título del incidente")
description: Optional[str] = Field(None, description="Descripción detallada")
severity: str = Field(description="Severidad: low, medium, high, critical")
status: str = Field(description="Estado: active, investigating, resolved")
incident_type: str = Field(description="Tipo de incidente")
affected_user: Optional[str] = Field(None, description="Usuario afectado")
source_ip: Optional[str] = Field(None, description="IP origen del incidente")
evidence: list[str] = Field(default=[], description="Evidencia del incidente")
metadata: Optional[Dict[str, Any]] = Field(None, description="Metadata adicional")
created_at: datetime = Field(description="Fecha de creación")
updated_at: Optional[datetime] = Field(None, description="Última actualización")
resolved_at: Optional[datetime] = Field(None, description="Fecha de resolución")
class Config:
from_attributes = True
class SecurityIncidentListResponse(BaseModel):
"""Respuesta paginada de incidentes de seguridad."""
incidents: list[SecurityIncidentResponse]
total: int = Field(description="Total de incidentes")
page: int = Field(description="Página actual")
per_page: int = Field(description="Incidentes por página")
total_pages: int = Field(description="Total de páginas")
class Config:
from_attributes = True
class AuditLogFilters(BaseModel):
"""
Filtros para consulta de audit logs.