-
-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add New Chart Components and Client Dashboard #160
Conversation
- Updated the `AverageCVSS` component to accept and handle `clientName`. - Modified `ClientDashboard` to pass `clientName` to `AverageCVSS` and set it correctly. - Created a new service `getAuditsByClientName` to fetch audits based on the client's name.
… component - Added "recharts" library with version "^2.13.3" to the frontend/package.json file. - Created a new React functional component CIATriadChart in frontend/src/components/charts/CIATriadChart.tsx that displays a radar chart representing the average CIA triad data. - The component takes an array of CIAData objects containing subject, current, and target properties as props and renders a RadarChart using the recharts library. - The RadarChart includes PolarGrid, PolarAngleAxis, and two Radar components for "Current" and "Target" data with corresponding colors and styles.
This commit introduces two new components: 1. **CVSSChart**: A React functional component for rendering a bar chart displaying CVSS data, including average CVSS score. 2. **CWECloud**: Another React functional component for displaying Common Weakness Enumeration (CWE) items in a cloud format, highlighting the most common CWE found.
… remediation priority.
…eChart components
… CWECloud component.
…PieChart component.
…Chart to ClientDashboard
…ts in ClientDashboard component
…n to helper functions
…ies by severity chart
This commit refactors the CIATriadChart component to include additional configurations for the 'r' scale such as angle lines, suggested min/max values, ticks, point labels, and grid styling. It also enhances the plugin settings for legend and tooltip in the chart. In the ClientDashboard component, the commit introduces changes to calculate the CIA data dynamically based on the findings retrieved from audits. This includes initializing temporary CIA data objects, updating their current values, and computing averages. Finally, the updated CIA data is set in the component state for further use.
….tsx to match confidentiality, integrity, availability order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Outside diff range and nitpick comments (4)
frontend/src/components/charts/CWECloud.tsx (1)
26-41
: ¡La implementación del grid necesita ser más robusta!
- Los breakpoints están hardcodeados en las clases de Tailwind
- La key del map solo usa item.id, lo cual podría causar problemas si hay IDs duplicados
- No hay límite en el número de items mostrados, lo que podría afectar el rendimiento
Considera estas mejoras:
- <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4"> + <div className={clsx( + 'grid gap-4', + 'grid-cols-1', + 'sm:grid-cols-2', + 'md:grid-cols-3', + items.length > 9 && 'overflow-y-auto max-h-[500px]' + )}> {items.map(item => ( <div className="bg-gray-800 p-4 rounded-lg shadow-md flex items-center" - key={item.id} + key={`${item.id}-${item.size}`}frontend/src/components/dashboard/CIATriad.tsx (3)
Line range hint
19-31
: Mejora necesaria en el manejo de valores CVSS inválidosLa función
cvssStringTo
no valida si el valor extraído del vector CVSS es válido antes de acceder al objetovalues
. Esto podría causar errores silenciosos si el vector CVSS está malformado.Aplica este diff para agregar validación:
const cvssStringTo = ( field: 'integrity' | 'availability' | 'confidentiality', cvssVector: string, ) => { const values: Record<string, number> = { H: 3, M: 2, L: 1, } as const; const substrings = { confidentiality: 35, integrity: 39, availability: 43, } as const; + const value = cvssVector.substring(substrings[field], substrings[field] + 1); + if (!Object.keys(values).includes(value)) { + console.error(`Valor CVSS inválido: ${value} para el campo ${field}`); + return 0; + } - return values[cvssVector.substring(substrings[field], substrings[field] + 1)]; + return values[value]; };
Line range hint
66-92
: Optimización necesaria en el manejo de datosEl código actual regenera colores aleatorios cada vez que se actualiza el estado, lo que puede causar parpadeo visual. Además, la lógica de mapeo se puede simplificar.
Considera estas mejoras:
+ const generateColor = (index: number) => { + // Usar una semilla basada en el índice para generar colores consistentes + const r = ((index * 123) % 155) + 100; + const g = ((index * 456) % 155) + 100; + const b = ((index * 789) % 155) + 100; + return `rgba(${r}, ${g}, ${b}, 0.2)`; + }; useEffect(() => { getAuditById(auditId) .then(audit => { setData({ labels: ['Integrity', 'Availability', 'Confidentiality'], datasets: audit.datas.findings.map((finding, index) => ({ label: finding.title, data: finding.cvssv3 ? [ cvssStringTo('integrity', finding.cvssv3), cvssStringTo('availability', finding.cvssv3), cvssStringTo('confidentiality', finding.cvssv3), ] : [0, 0, 0], - backgroundColor: `rgba(${Math.floor(Math.random() * 155 + 100)}, ...`, + backgroundColor: generateColor(index), borderColor: 'rgba(255, 255, 255, 0.2)', borderWidth: 2, })), }); }) .catch(error => { + console.error('Error al cargar datos del audit:', error); + setData({ + labels: ['Integrity', 'Availability', 'Confidentiality'], + datasets: [], + }); }); }, [auditId]);
Line range hint
47-48
: Validación de ID faltanteNo se está validando que el
auditId
sea una cadena no vacía antes de hacer la llamada a la API.Agrega validación:
const paramId = useParams().auditId; if (!auditId) { auditId = paramId; } + if (!auditId?.trim()) { + console.error('ID de auditoría no válido'); + return <div className="text-red-500">ID de auditoría no válido</div>; + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (5)
frontend/package.json
(2 hunks)frontend/src/components/charts/CWECloud.tsx
(1 hunks)frontend/src/components/dashboard/CIATriad.tsx
(1 hunks)frontend/src/i18n/en-US/index.ts
(1 hunks)frontend/src/routes/dashboard/dashboard.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- frontend/package.json
- frontend/src/i18n/en-US/index.ts
🔇 Additional comments (2)
frontend/src/routes/dashboard/dashboard.tsx (2)
36-44
:
¡El manejo de errores en cvssStringToScore es inaceptablemente débil!
La función silenciosamente retorna 0 cuando hay un error, lo que puede llevar a cálculos incorrectos y ocultar problemas graves.
Implementa un manejo de errores apropiado:
const cvssStringToScore = (cvssScore: string) => {
+ if (!cvssScore?.trim()) {
+ throw new Error('El vector CVSS no puede estar vacío');
+ }
try {
const cvssVector = new Cvss3P1(cvssScore);
return cvssVector.calculateExactOverallScore();
} catch (error) {
- console.error('Invalid CVSS vector:', error);
+ throw new Error(`Vector CVSS inválido: ${error.message}`);
}
- return 0;
};
Likely invalid or redundant comment.
46-58
: 🛠️ Refactor suggestion
¡La función severityByScore necesita una refactorización urgente!
Los problemas incluyen:
- Uso de números mágicos para los umbrales
- Retorno de índices numéricos crípticos
- Falta de tipado seguro para los valores de retorno
Implementa esta versión mejorada:
+enum Severity {
+ Critical = 0,
+ High = 1,
+ Medium = 2,
+ Low = 3,
+ Informative = 4,
+}
+
+const SEVERITY_THRESHOLDS = {
+ CRITICAL: 9.0,
+ HIGH: 7.0,
+ MEDIUM: 4.0,
+ LOW: 0.1,
+} as const;
+
-const severityByScore = (score: number) => {
+const severityByScore = (score: number): Severity => {
if (score >= 9.0) {
- return 0;
+ return Severity.Critical;
} else if (score >= 7.0) {
- return 1;
+ return Severity.High;
} else if (score >= 4.0) {
- return 2;
+ return Severity.Medium;
} else if (score >= 0.1) {
- return 3;
+ return Severity.Low;
} else {
- return 4;
+ return Severity.Informative;
}
};
Likely invalid or redundant comment.
- Updated CVSS vector values: 'H' from 3 to 2, added 'N' with value 0.
…everities in components.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (7)
frontend/src/components/dashboard/CVSSScore.tsx (2)
Line range hint
12-29
: ¡La función necesita mejor manejo de errores y tipos!La implementación actual de
cvssStringToSeverity
podría ser más robusta. Es necesario:
- Agregar tipos TypeScript específicos para el parámetro y el valor de retorno
- Mejorar el manejo de errores para casos específicos de CVSS inválidos
- Documentar los niveles de severidad y sus rangos
Te sugiero aplicar estos cambios:
-const cvssStringToSeverity = (cvssScore: string) => { +type SeverityLevel = 'C' | 'H' | 'M' | 'L' | 'I'; + +/** + * Convierte un vector CVSS a un nivel de severidad + * @param cvssScore - Vector CVSS v3.1 + * @returns Nivel de severidad: + * - C: Crítico (9.0-10.0) + * - H: Alto (7.0-8.9) + * - M: Medio (4.0-6.9) + * - L: Bajo (0.1-3.9) + * - I: Informativo (0.0 o inválido) + */ +const cvssStringToSeverity = (cvssScore: string): SeverityLevel => { try { const cvssVector = new Cvss3P1(cvssScore); const score = cvssVector.calculateExactOverallScore(); if (score >= 9.0) { return 'C'; } if (score >= 7.0) { return 'H'; } if (score >= 4.0) { return 'M'; } if (score >= 0.1) { return 'L'; } } catch (error) { - console.error('Invalid CVSS vector:', error); + console.error(`Vector CVSS inválido "${cvssScore}":`, error); } return 'I'; };
75-87
: ¡Buen manejo de valores nulos, pero podemos mejorarlo!La implementación del operador de coalescencia nula (
??
) es correcta y consistente. Sin embargo, podríamos mejorar la seguridad de tipos.Sugiero agregar una interfaz para el objeto finding:
interface Finding { cvssv3: string | undefined; // ... otros campos }Esto haría el código más mantenible y type-safe.
frontend/src/routes/audits/edit/AuditRoot.tsx (3)
Line range hint
41-63
: La funcióncvssStringToSeverity
necesita una mejor gestión de erroresLa función actual tiene varias deficiencias:
- Solo registra el error en la consola y continúa
- Retorna 'I' silenciosamente en caso de error
- No valida la entrada antes de crear el objeto Cvss3P1
Te sugiero implementar una gestión de errores más robusta:
const cvssStringToSeverity = (cvssScore: string) => { + if (!cvssScore.trim()) { + console.warn('Vector CVSS vacío o inválido'); + return 'I'; + } try { const cvssVector = new Cvss3P1(cvssScore); const score = cvssVector.calculateExactOverallScore(); if (score >= 9.0) { return 'C'; } if (score >= 7.0) { return 'H'; } if (score >= 4.0) { return 'M'; } if (score >= 0.1) { return 'L'; } } catch (error) { - console.error('Invalid CVSS vector:', error); + console.error(`Error al procesar vector CVSS "${cvssScore}":`, error); + throw new Error(`Vector CVSS inválido: ${cvssScore}`); } - return 'I'; };
Line range hint
106-115
: La transformación de findings podría ser más robustaEl mapeo actual de findings no maneja adecuadamente casos extremos y podría beneficiarse de valores por defecto más seguros.
Considera esta implementación más defensiva:
setFindings( audit.datas.findings.map((finding: Finding) => { return { - id: finding.identifier, - name: finding.title, - category: 'No Category', - severity: cvssStringToSeverity(finding.cvssv3 ?? ''), - identifier: finding._id, + id: finding.identifier ?? 'sin-id', + name: finding.title?.trim() || 'Sin título', + category: finding.category?.trim() || 'Sin Categoría', + severity: finding.cvssv3 ? cvssStringToSeverity(finding.cvssv3) : 'I', + identifier: finding._id ?? `temp-${Date.now()}`, }; }), );
Line range hint
65-89
: Considera manejar errores de red de forma más eleganteEl uso de
catch(console.error)
es demasiado simplista para una aplicación en producción.Implementa un mejor manejo de errores:
useEffect(() => { getCustomSections() .then(section => { setSections( section.datas.map((item: Section) => ({ field: item.field, name: item.name, icon: item.icon, })), ); }) - .catch(console.error); + .catch(error => { + console.error('Error al obtener secciones:', error); + // TODO: Mostrar un mensaje de error al usuario + setSections([]); + }); }, []);frontend/src/components/charts/CVSSChart.tsx (2)
100-100
: Internacionaliza el texto "Average CVSS"El texto "Average CVSS" está hardcoded en inglés en la línea 100. Deberías utilizar la función
t()
para permitir la traducción y soportar múltiples idiomas.Aplica este cambio:
- Average CVSS: {averageCVSS} + {t('averageCVSS')}: {averageCVSS}Asegúrate de agregar la clave
averageCVSS
en tus archivos de traducción.
100-100
: El color del texto podría afectar la accesibilidadEl uso de
text-green-400
puede no ofrecer suficiente contraste para todos los usuarios. Considera utilizar un tono más oscuro, comotext-green-700
, para mejorar la legibilidad y cumplir con las pautas de accesibilidad.Aplica este cambio:
- <div className="absolute top-0 left-0 w-full text-right pr-4 text-green-400 text-sm"> + <div className="absolute top-0 left-0 w-full text-right pr-4 text-green-700 text-sm">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
frontend/src/components/charts/CVSSChart.tsx
(1 hunks)frontend/src/components/dashboard/AverageCVSS.tsx
(3 hunks)frontend/src/components/dashboard/CIATriad.tsx
(2 hunks)frontend/src/components/dashboard/CVSSScore.tsx
(1 hunks)frontend/src/routes/audits/edit/AuditRoot.tsx
(1 hunks)frontend/src/routes/dashboard/dashboard.tsx
(1 hunks)frontend/src/services/audits.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- frontend/src/components/dashboard/AverageCVSS.tsx
- frontend/src/components/dashboard/CIATriad.tsx
- frontend/src/services/audits.ts
🔇 Additional comments (6)
frontend/src/routes/audits/edit/AuditRoot.tsx (1)
112-112
: ¡Bien hecho con el manejo de nulos!
La adición del operador de coalescencia nula (??
) es una mejora necesaria para prevenir errores cuando cvssv3
es undefined
o null
.
frontend/src/routes/dashboard/dashboard.tsx (5)
1-21
: ¡Las importaciones y definiciones de tipos están correctas!
La estructura de importaciones está bien organizada y el tipo ListItem
está bien definido.
36-44
:
¡El manejo de errores en cvssStringToScore es inadecuado!
La función:
- Retorna 0 silenciosamente cuando hay un error
- Solo registra el error en consola
- No valida la entrada
Implementa esta corrección:
const cvssStringToScore = (cvssScore: string) => {
+ if (!cvssScore?.trim()) {
+ throw new Error('Vector CVSS no puede estar vacío');
+ }
try {
const cvssVector = new Cvss3P1(cvssScore);
return cvssVector.calculateExactOverallScore();
} catch (error) {
- console.error('Invalid CVSS vector:', error);
+ throw new Error(`Vector CVSS inválido: ${error.message}`);
}
- return 0;
};
Likely invalid or redundant comment.
110-121
:
¡El manejo de errores y estados de carga es deficiente!
La función fetchClients
tiene varias deficiencias críticas:
- No hay gestión del estado de carga
- El manejo de errores es básico
- No hay feedback visual para el usuario
Implementa un mejor manejo de estados:
+const [isLoading, setIsLoading] = useState(false);
+const [error, setError] = useState<Error | null>(null);
const fetchClients = async () => {
+ setIsLoading(true);
+ setError(null);
try {
const data = await getCompanies();
const clientName: ListItem[] = data.datas.map((cliente, index) => ({
id: index,
value: cliente.name,
}));
setClientName(clientName);
} catch (error) {
- console.error('Error fetching audits:', error);
+ setError(error as Error);
+ console.error('Error al obtener clientes:', error);
+ } finally {
+ setIsLoading(false);
}
};
Likely invalid or redundant comment.
46-58
: 🛠️ Refactor suggestion
¡La función severityByScore necesita una refactorización urgente!
La implementación actual:
- Usa números mágicos para los umbrales
- Retorna índices numéricos crípticos
- No tiene seguridad de tipos para los valores de retorno
Implementa esta mejora:
+enum Severity {
+ Critical = 0,
+ High = 1,
+ Medium = 2,
+ Low = 3,
+ Informative = 4,
+}
+
+const SEVERITY_THRESHOLDS = {
+ CRITICAL: 9.0,
+ HIGH: 7.0,
+ MEDIUM: 4.0,
+ LOW: 0.1,
+} as const;
+
-const severityByScore = (score: number) => {
+const severityByScore = (score: number): Severity => {
if (score >= 9.0) {
- return 0;
+ return Severity.Critical;
} else if (score >= 7.0) {
- return 1;
+ return Severity.High;
} else if (score >= 4.0) {
- return 2;
+ return Severity.Medium;
} else if (score >= 0.1) {
- return 3;
+ return Severity.Low;
} else {
- return 4;
+ return Severity.Informative;
}
};
Likely invalid or redundant comment.
23-34
:
¡La función cvssStringTo es extremadamente frágil!
La implementación actual es peligrosa porque:
- Usa índices hardcodeados que se romperán si cambia el formato del vector CVSS
- No valida la entrada
- No maneja casos donde el substring está fuera de rango
Implementa esta solución más robusta:
-const cvssStringTo = (
+const cvssStringTo = (
field: 'integrity' | 'availability' | 'confidentiality',
cvssVector: string,
) => {
+ if (!cvssVector?.trim()) {
+ throw new Error('Vector CVSS no puede estar vacío');
+ }
+
+ const metrics = cvssVector.split('/');
+ const metricMap = {
+ integrity: 'I',
+ availability: 'A',
+ confidentiality: 'C',
+ };
+
const values: Record<string, number> = { H: 2, L: 1, N: 0 } as const;
- const substrings = {
- confidentiality: 35,
- integrity: 39,
- availability: 43,
- } as const;
- return values[cvssVector.substring(substrings[field], substrings[field] + 1)];
+
+ const metric = metrics.find(m => m.startsWith(metricMap[field]));
+ if (!metric) {
+ throw new Error(`Métrica ${field} no encontrada en el vector CVSS`);
+ }
+
+ const value = metric.split(':')[1];
+ if (!(value in values)) {
+ throw new Error(`Valor inválido ${value} para la métrica ${field}`);
+ }
+
+ return values[value];
};
Likely invalid or redundant comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
- Added `@radix-ui/react-tooltip` dependency in `package.json`. - Imported Tooltip components in CWECloud chart. - Implemented TooltipProvider, Tooltip, TooltipTrigger, and TooltipContent in the CWECloud component for displaying tooltips when hovering over items in the chart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM x2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM !!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (3)
frontend/src/components/ui/tooltip.tsx (2)
6-10
: ¡Buena implementación de los componentes base!La re-exportación de los primitivos de Radix UI es una práctica común y correcta. Esto permite:
- Centralizar la configuración de los componentes
- Facilitar cambios futuros sin afectar a los consumidores
- Mantener una API consistente
12-26
: ¡La implementación necesita mejor organización!El componente funciona correctamente, pero la cadena de clases es demasiado larga y difícil de mantener.
Sugiero extraer las clases a una constante separada:
+const tooltipContentStyles = 'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2' const TooltipContent = React.forwardRef< React.ElementRef<typeof TooltipPrimitive.Content>, React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> >(({ className, sideOffset = 4, ...props }, ref) => ( <TooltipPrimitive.Content ref={ref} sideOffset={sideOffset} - className={cn( - 'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', - className, - )} + className={cn(tooltipContentStyles, className)} {...props} /> ));frontend/src/components/charts/CWECloud.tsx (1)
1-10
: ¡La organización de las importaciones necesita ser más estructurada!Las importaciones deberían estar agrupadas de la siguiente manera:
- Dependencias externas (React, i18next)
- Componentes de UI (Radix)
- Iconos
- Tipos y utilidades
+// External dependencies import { t } from 'i18next'; import React from 'react'; -import { FaBug } from 'react-icons/fa'; +// UI Components import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '../ui/tooltip'; + +// Icons +import { FaBug } from 'react-icons/fa';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
frontend/package.json
(2 hunks)frontend/src/components/charts/CWECloud.tsx
(1 hunks)frontend/src/components/ui/tooltip.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/package.json
🔇 Additional comments (4)
frontend/src/components/ui/tooltip.tsx (2)
1-4
: ¡Las importaciones están correctamente organizadas!
La organización de las importaciones es clara y todas son necesarias para la implementación del componente.
28-28
: ¡Las exportaciones están correctamente definidas!
Todos los componentes necesarios están disponibles para su uso en la aplicación.
frontend/src/components/charts/CWECloud.tsx (2)
12-20
: ¡Referencia a comentario anterior sobre tipos!
El comentario anterior sobre la necesidad de restricciones más estrictas en los tipos y documentación adicional sigue siendo válido.
35-58
:
¡La implementación no coincide con el nombre del componente!
Este componente se llama CWECloud
pero está implementado como una cuadrícula. Esto viola el principio de menor sorpresa y no cumple con los objetivos del PR que mencionan el uso de @visx/wordcloud
.
Debes:
- Implementar una verdadera nube de palabras usando
@visx/wordcloud
- O renombrar el componente a
CWEGrid
para reflejar su implementación actual
Descripción
Este pull request introduce varios nuevos componentes de gráficos y un dashboard de clientes a la aplicación frontend. Los cambios incluyen:
Nuevas Dependencias:
@visx/text
y@visx/wordcloud
apackage.json
.Nuevos Componentes de Gráficos:
CIATriadChart
: Un gráfico de radar para mostrar datos del triángulo CIA.CVSSChart
: Un gráfico de barras para mostrar puntuaciones CVSS.CWECloud
: Una nube de palabras para mostrar datos CWE.RemediationPriorityChart
: Un gráfico de barras para mostrar prioridades de remediación.SeverityPieChart
: Un gráfico de dona para mostrar vulnerabilidades por severidad.TimePerAuditChart
: Un gráfico de barras para mostrar el tiempo por auditoría.Integración del Dashboard:
ClientDashboard
que integra todos los nuevos componentes de gráficos./dashboard
para acceder al dashboard de clientes.Navbar
para incluir un enlace al dashboard.Actualizaciones de Servicios:
getAuditsByClientName
enclients.ts
para obtener auditorías por nombre de cliente.audits.ts
para hacer opcionales los camposremediationComplexity
ypriority
.Actualizaciones de Componentes:
AverageCVSS
para soportar la obtención de datos por nombre de cliente.Motivación y Contexto
HU16
¿Cómo ha sido probado?
Tipos de cambios
Lista de verificación:
Summary by CodeRabbit
Nuevas Funciones
Mejoras
Correcciones de Errores
Finding
para permitir campos opcionales, mejorando la flexibilidad del manejo de datos.