diff --git a/CHANGELOG.md b/CHANGELOG.md index 27e569e43..29a270e9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Changed + +- More explicit scale, legend and score for risk matrix + ## [0.10.1] - 2025-04-14 ### Fixed diff --git a/apps/console/public/data/risks/risks.json b/apps/console/public/data/risks/risks.json index 575f0e4cb..2b65fb150 100644 --- a/apps/console/public/data/risks/risks.json +++ b/apps/console/public/data/risks/risks.json @@ -5,8 +5,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.75, - "likelihood": 0.8, + "impact": 4, + "likelihood": 4, "recommendedTreatment": "Transfer" } ] @@ -17,8 +17,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 1.0, - "likelihood": 0.3, + "impact": 5, + "likelihood": 2, "recommendedTreatment": "Transfer" } ] @@ -29,8 +29,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.5, + "impact": 3, + "likelihood": 3, "recommendedTreatment": "Reduce" } ] @@ -41,8 +41,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.15, + "impact": 3, + "likelihood": 1, "recommendedTreatment": "Accept" } ] @@ -53,8 +53,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.8, + "impact": 3, + "likelihood": 4, "recommendedTreatment": "Transfer" } ] @@ -65,8 +65,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.3, + "impact": 3, + "likelihood": 2, "recommendedTreatment": "Reduce" } ] @@ -77,8 +77,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.1, - "likelihood": 0.15, + "impact": 1, + "likelihood": 1, "recommendedTreatment": "Accept" } ] @@ -89,8 +89,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.5, + "impact": 3, + "likelihood": 3, "recommendedTreatment": "Reduce" } ] @@ -101,8 +101,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.8, + "impact": 3, + "likelihood": 4, "recommendedTreatment": "Transfer" } ] @@ -113,8 +113,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.75, - "likelihood": 0.5, + "impact": 4, + "likelihood": 3, "recommendedTreatment": "Transfer" } ] @@ -125,8 +125,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.75, - "likelihood": 0.3, + "impact": 4, + "likelihood": 2, "recommendedTreatment": "Reduce" } ] @@ -137,8 +137,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.15, + "impact": 3, + "likelihood": 1, "recommendedTreatment": "Accept" } ] @@ -149,8 +149,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.25, - "likelihood": 0.5, + "impact": 1, + "likelihood": 3, "recommendedTreatment": "Reduce" } ] @@ -161,8 +161,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.5, + "impact": 3, + "likelihood": 3, "recommendedTreatment": "Reduce" } ] @@ -173,8 +173,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 1.0, - "likelihood": 0.5, + "impact": 5, + "likelihood": 3, "recommendedTreatment": "Transfer" } ] @@ -185,8 +185,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.8, + "impact": 3, + "likelihood": 4, "recommendedTreatment": "Transfer" } ] @@ -197,8 +197,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.25, - "likelihood": 0.3, + "impact": 1, + "likelihood": 2, "recommendedTreatment": "Reduce" } ] @@ -209,8 +209,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.8, + "impact": 3, + "likelihood": 4, "recommendedTreatment": "Transfer" } ] @@ -221,8 +221,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.8, + "impact": 3, + "likelihood": 4, "recommendedTreatment": "Transfer" } ] @@ -233,8 +233,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.25, - "likelihood": 1.0, + "impact": 1, + "likelihood": 5, "recommendedTreatment": "Reduce" } ] @@ -245,8 +245,8 @@ "variations": [ { "context": "B2B SaaS SMB", - "impact": 0.5, - "likelihood": 0.5, + "impact": 3, + "likelihood": 3, "recommendedTreatment": "Reduce" } ] diff --git a/apps/console/src/pages/organizations/risks/EditRiskView.tsx b/apps/console/src/pages/organizations/risks/EditRiskView.tsx index 876f27427..5af7b90fc 100644 --- a/apps/console/src/pages/organizations/risks/EditRiskView.tsx +++ b/apps/console/src/pages/organizations/risks/EditRiskView.tsx @@ -104,12 +104,10 @@ function EditRiskViewContent({ const [name, setName] = useState(""); const [description, setDescription] = useState(""); - const [inherentLikelihood, setInherentLikelihood] = - useState("OCCASIONAL"); - const [inherentImpact, setInherentImpact] = useState("MODERATE"); - const [residualLikelihood, setResidualLikelihood] = - useState("OCCASIONAL"); - const [residualImpact, setResidualImpact] = useState("MODERATE"); + const [inherentLikelihood, setInherentLikelihood] = useState(3); + const [inherentImpact, setInherentImpact] = useState(3); + const [residualLikelihood, setResidualLikelihood] = useState(3); + const [residualImpact, setResidualImpact] = useState(3); const [treatment, setTreatment] = useState("MITIGATED"); const [ownerId, setOwnerId] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); @@ -117,68 +115,16 @@ function EditRiskViewContent({ const [updateRisk, isInFlight] = useMutation(updateRiskMutation); - // Helper function to convert float to likelihood string - const floatToLikelihood = (value: number): string => { - if (value <= 0.2) return "IMPROBABLE"; - if (value <= 0.4) return "REMOTE"; - if (value <= 0.6) return "OCCASIONAL"; - if (value <= 0.8) return "PROBABLE"; - return "FREQUENT"; - }; - - // Helper function to convert float to impact string - const floatToImpact = (value: number): string => { - if (value <= 0.2) return "NEGLIGIBLE"; - if (value <= 0.4) return "LOW"; - if (value <= 0.6) return "MODERATE"; - if (value <= 0.8) return "SIGNIFICANT"; - return "CATASTROPHIC"; - }; - - // Map string values to float values - const likelihoodToFloat = (value: string): number => { - switch (value) { - case "IMPROBABLE": - return 0.1; - case "REMOTE": - return 0.3; - case "OCCASIONAL": - return 0.5; - case "PROBABLE": - return 0.7; - case "FREQUENT": - return 0.9; - default: - return 0.5; - } - }; - - const impactToFloat = (value: string): number => { - switch (value) { - case "NEGLIGIBLE": - return 0.1; - case "LOW": - return 0.3; - case "MODERATE": - return 0.5; - case "SIGNIFICANT": - return 0.7; - case "CATASTROPHIC": - return 0.9; - default: - return 0.5; - } - }; - // Initialize form with risk data useEffect(() => { if (risk) { setName(risk.name || ""); setDescription(risk.description || ""); - setInherentLikelihood(floatToLikelihood(risk.inherentLikelihood || 0.5)); - setInherentImpact(floatToImpact(risk.inherentImpact || 0.5)); - setResidualLikelihood(floatToLikelihood(risk.residualLikelihood || 0.5)); - setResidualImpact(floatToImpact(risk.residualImpact || 0.5)); + // Set values directly as integers + setInherentLikelihood(risk.inherentLikelihood || 3); + setInherentImpact(risk.inherentImpact || 3); + setResidualLikelihood(risk.residualLikelihood || 3); + setResidualImpact(risk.residualImpact || 3); setTreatment(risk.treatment || "MITIGATED"); setOwnerId(risk.owner?.id || null); } @@ -202,10 +148,10 @@ function EditRiskViewContent({ id: riskId!, name, description, - inherentLikelihood: likelihoodToFloat(inherentLikelihood), - inherentImpact: impactToFloat(inherentImpact), - residualLikelihood: likelihoodToFloat(residualLikelihood), - residualImpact: impactToFloat(residualImpact), + inherentLikelihood, + inherentImpact, + residualLikelihood, + residualImpact, treatment, ownerId: ownerId || undefined, }; @@ -302,40 +248,44 @@ function EditRiskViewContent({
- +
@@ -376,40 +326,44 @@ function EditRiskViewContent({
- +
diff --git a/apps/console/src/pages/organizations/risks/ListRiskView.tsx b/apps/console/src/pages/organizations/risks/ListRiskView.tsx index c11ee867c..678da2719 100644 --- a/apps/console/src/pages/organizations/risks/ListRiskView.tsx +++ b/apps/console/src/pages/organizations/risks/ListRiskView.tsx @@ -109,17 +109,11 @@ const deleteRiskMutation = graphql` } `; -// Helper function to convert float values to percentage -// This is kept for potential future use, like tooltips -const floatToPercentage = (value: number): string => { - return `${Math.round(value * 100)}%`; -}; - // Helper function to convert risk score to severity label const riskScoreToSeverity = (score: number): string => { - if (score >= 0.75) return "Catastrophic"; - if (score >= 0.5) return "Critical"; - if (score >= 0.25) return "Marginal"; + if (score >= 20) return "Catastrophic"; + if (score >= 12) return "Critical"; + if (score >= 5) return "Marginal"; return "Negligible"; }; @@ -207,6 +201,7 @@ const emptyRiskMatrixColors = { function RiskMatrix({ risks, isResidual = false, + organizationId, }: { risks: Array<{ id: string; @@ -217,24 +212,13 @@ function RiskMatrix({ residualImpact?: number; }>; isResidual?: boolean; + organizationId: string; }): JSX.Element { - // Define impact ranges for the vertical axis (rows) - const impactRanges: [number, number][] = [ - [0.8, 1], // Highest impact - top row - [0.6, 0.8], // High impact - [0.4, 0.6], // Medium impact - [0.2, 0.4], // Low impact - [0, 0.2], // Lowest impact - bottom row - ]; + // Define impact values for the vertical axis (rows) - from highest (5) to lowest (1) + const impactValues: number[] = [5, 4, 3, 2, 1]; - // Define likelihood ranges for the horizontal axis (columns) - const likelihoodRanges: [number, number][] = [ - [0, 0.2], // Lowest likelihood - leftmost column - [0.2, 0.4], // Low likelihood - [0.4, 0.6], // Medium likelihood - [0.6, 0.8], // High likelihood - [0.8, 1], // Highest likelihood - rightmost column - ]; + // Define likelihood values for the horizontal axis (columns) - from lowest (1) to highest (5) + const likelihoodValues: number[] = [1, 2, 3, 4, 5]; const impactLabels = [ "Catastrophic", @@ -253,10 +237,7 @@ function RiskMatrix({ ]; // Function to get cell content with risks that fall in this cell - const getCellContent = ( - impactRange: [number, number], - likelihoodRange: [number, number] - ) => { + const getCellContent = (impactValue: number, likelihoodValue: number) => { return risks.filter((risk) => { const likelihood = isResidual ? risk.residualLikelihood ?? risk.inherentLikelihood @@ -265,12 +246,7 @@ function RiskMatrix({ ? risk.residualImpact ?? risk.inherentImpact : risk.inherentImpact; - return ( - likelihood > likelihoodRange[0] && - likelihood <= likelihoodRange[1] && - impact > impactRange[0] && - impact <= impactRange[1] - ); + return likelihood === likelihoodValue && impact === impactValue; }); }; @@ -280,54 +256,63 @@ function RiskMatrix({ const getCellColor = (row: number, col: number, isEmpty: boolean): string => { const colorSet = isEmpty ? emptyRiskMatrixColors : riskMatrixColors; - // Top row (highest impact - Catastrophic) - if (row === 0) { - if (col <= 1) return colorSet.medium; // Yellow for first two cells - return colorSet.high; // Red for the rest - } + // Hard-coded color matrix where each element [row][col] represents a specific cell + // This follows the 5x5 grid with rows representing impact (5 to 1) and columns representing likelihood (1 to 5) + const colorMatrix = [ + // Impact 5 (Catastrophic) - first row + [ + colorSet.medium, + colorSet.medium, + colorSet.high, + colorSet.high, + colorSet.high, + ], + // Impact 4 (Significant) - second row + [ + colorSet.low, + colorSet.medium, + colorSet.medium, + colorSet.high, + colorSet.high, + ], + // Impact 3 (Moderate) - third row + [ + colorSet.low, + colorSet.low, + colorSet.medium, + colorSet.medium, + colorSet.high, + ], + // Impact 2 (Low) - fourth row + [ + colorSet.low, + colorSet.low, + colorSet.low, + colorSet.medium, + colorSet.medium, + ], + // Impact 1 (Negligible) - fifth row + [colorSet.low, colorSet.low, colorSet.low, colorSet.low, colorSet.medium], + ]; - // Second row (Significant impact) - if (row === 1) { - if (col === 0) return colorSet.low; // Green for first cell - if (col <= 2) return colorSet.medium; // Yellow for next two - return colorSet.high; // Red for the rest - } - - // Middle row (Moderate impact) - if (row === 2) { - if (col === 0) return colorSet.low; // Green for first cell - if (col <= 3) return colorSet.medium; // Yellow for next three - return colorSet.high; // Red for last cell - } - - // Fourth row (Low impact) - if (row === 3) { - if (col <= 1) return colorSet.low; // Green for first two - return colorSet.medium; // Yellow for the rest - } - - // Bottom row (lowest impact - Negligible) - if (row === 4) { - if (col <= 3) return colorSet.low; // Green for first four - return colorSet.medium; // Yellow for last cell - } - - return "bg-gray-100"; + return colorMatrix[row][col]; }; // Instead of using refs and tippy, we'll use a component with popover const RiskCell = ({ rowIndex, colIndex, - impactRange, - likelihoodRange, + impactValue, + likelihoodValue, + organizationId, }: { rowIndex: number; colIndex: number; - impactRange: [number, number]; - likelihoodRange: [number, number]; + impactValue: number; + likelihoodValue: number; + organizationId: string; }) => { - const cellRisks = getCellContent(impactRange, likelihoodRange); + const cellRisks = getCellContent(impactValue, likelihoodValue); const isEmpty = cellRisks.length === 0; const cellColor = getCellColor(rowIndex, colIndex, isEmpty); @@ -354,17 +339,109 @@ function RiskMatrix({
- -
- {cellRisks.length} Risk{cellRisks.length > 1 ? "s" : ""}: + +
+ {cellRisks.length} Risk{cellRisks.length > 1 ? "s" : ""}
-
    - {cellRisks.map((risk) => ( -
  • - {risk.name} -
  • - ))} -
+ +
+
+
+ Impact:{" "} + {impactValue} +
+
+ Likelihood:{" "} + {likelihoodValue} +
+
+ +
+ Risk Score: + + {impactValue * likelihoodValue} + + = 20 + ? "#ef4444" + : impactValue * likelihoodValue >= 12 + ? "#f59e0b" + : impactValue * likelihoodValue >= 5 + ? "#10b981" + : "#94a3b8", + color: + impactValue * likelihoodValue >= 12 ? "white" : "inherit", + }} + > + {impactValue * likelihoodValue >= 20 + ? "Catastrophic" + : impactValue * likelihoodValue >= 12 + ? "Critical" + : impactValue * likelihoodValue >= 5 + ? "Marginal" + : "Negligible"} + +
+
+ + {cellRisks.length > 0 && ( + <> +
Items:
+
    + {cellRisks.map((risk) => ( +
  • = 20 + ? "#ef4444" + : (isResidual + ? (risk.residualImpact || risk.inherentImpact) * + (risk.residualLikelihood || + risk.inherentLikelihood) + : risk.inherentImpact * + risk.inherentLikelihood) >= 12 + ? "#f59e0b" + : (isResidual + ? (risk.residualImpact || risk.inherentImpact) * + (risk.residualLikelihood || + risk.inherentLikelihood) + : risk.inherentImpact * + risk.inherentLikelihood) >= 5 + ? "#10b981" + : "#94a3b8", + }} + > + + {risk.name} + + + + +
  • + ))} +
+ + )}
); @@ -387,18 +464,19 @@ function RiskMatrix({
- {impactRanges.map((impactRange, rowIndex) => ( + {impactValues.map((impactValue, rowIndex) => ( - - {likelihoodRanges.map((likelihoodRange, colIndex) => ( + {likelihoodValues.map((likelihoodValue, colIndex) => ( ))} @@ -412,7 +490,7 @@ function RiskMatrix({ key={index} className="p-1 text-xs text-center border-t font-medium w-14" > - {label} + {label} ({likelihoodValues[index]}) ))} @@ -583,7 +661,11 @@ function ListRiskViewContent({ - + @@ -648,9 +730,36 @@ function ListRiskViewContent({ to={`/organizations/${organizationId}/risks/${risk.id}`} className="block p-4 h-full w-full" > - {riskScoreToSeverity( - risk.inherentLikelihood * risk.inherentImpact - )} + = + 20 + ? "#ef4444" + : risk.inherentLikelihood * + risk.inherentImpact >= + 12 + ? "#f59e0b" + : risk.inherentLikelihood * + risk.inherentImpact >= + 5 + ? "#10b981" + : "#94a3b8", + color: + risk.inherentLikelihood * + risk.inherentImpact >= + 12 + ? "white" + : "inherit", + }} + > + {riskScoreToSeverity( + risk.inherentLikelihood * risk.inherentImpact + )}{" "} + ({risk.inherentLikelihood * risk.inherentImpact}) +
- {impactLabels[rowIndex]} + + {impactLabels[rowIndex]} ({impactValue})
@@ -658,11 +767,41 @@ function ListRiskViewContent({ to={`/organizations/${organizationId}/risks/${risk.id}`} className="block p-4 h-full w-full" > - {risk.residualLikelihood && risk.residualImpact - ? riskScoreToSeverity( + {risk.residualLikelihood && risk.residualImpact ? ( + = + 20 + ? "#ef4444" + : risk.residualLikelihood * + risk.residualImpact >= + 12 + ? "#f59e0b" + : risk.residualLikelihood * + risk.residualImpact >= + 5 + ? "#10b981" + : "#94a3b8", + color: + risk.residualLikelihood * + risk.residualImpact >= + 12 + ? "white" + : "inherit", + }} + > + {riskScoreToSeverity( risk.residualLikelihood * risk.residualImpact + )}{" "} + ({risk.residualLikelihood * risk.residualImpact} ) - : "Not set"} + + ) : ( + "Not set" + )} diff --git a/apps/console/src/pages/organizations/risks/NewRiskView.tsx b/apps/console/src/pages/organizations/risks/NewRiskView.tsx index 510c79acc..aa840e0dc 100644 --- a/apps/console/src/pages/organizations/risks/NewRiskView.tsx +++ b/apps/console/src/pages/organizations/risks/NewRiskView.tsx @@ -87,12 +87,10 @@ function NewRiskForm({ const data = usePreloadedQuery(newRiskQuery, queryRef); const [name, setName] = useState(""); const [description, setDescription] = useState(""); - const [inherentLikelihood, setinherentLikelihood] = - useState("OCCASIONAL"); - const [inherentImpact, setinherentImpact] = useState("MODERATE"); - const [residualLikelihood, setResidualLikelihood] = - useState("OCCASIONAL"); - const [residualImpact, setResidualImpact] = useState("MODERATE"); + const [inherentLikelihood, setInherentLikelihood] = useState(3); + const [inherentImpact, setInherentImpact] = useState(3); + const [residualLikelihood, setResidualLikelihood] = useState(3); + const [residualImpact, setResidualImpact] = useState(3); const [treatment, setTreatment] = useState("MITIGATED"); const [ownerId, setOwnerId] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); @@ -121,41 +119,6 @@ function NewRiskForm({ loadRiskTemplates(); }, [toast]); - // Map string values to float values - const likelihoodToFloat = (value: string): number => { - switch (value) { - case "IMPROBABLE": - return 0.1; - case "REMOTE": - return 0.3; - case "OCCASIONAL": - return 0.5; - case "PROBABLE": - return 0.7; - case "FREQUENT": - return 0.9; - default: - return 0.5; - } - }; - - const impactToFloat = (value: string): number => { - switch (value) { - case "NEGLIGIBLE": - return 0.1; - case "LOW": - return 0.3; - case "MODERATE": - return 0.5; - case "SIGNIFICANT": - return 0.7; - case "CATASTROPHIC": - return 0.9; - default: - return 0.5; - } - }; - // Handle template selection and prefill form const handleTemplateChange = (templateId: string) => { setSelectedTemplate(templateId); @@ -164,10 +127,10 @@ function NewRiskForm({ // Clear form if "Select a template" is chosen setName(""); setDescription(""); - setinherentLikelihood("OCCASIONAL"); - setinherentImpact("MODERATE"); - setResidualLikelihood("OCCASIONAL"); - setResidualImpact("MODERATE"); + setInherentLikelihood(3); + setInherentImpact(3); + setResidualLikelihood(3); + setResidualImpact(3); setTreatment("MITIGATED"); return; } @@ -176,16 +139,19 @@ function NewRiskForm({ if (template) { setName(template.name); setDescription(template.description); - // Convert numeric values to string values for the select components - const likelihoodValue = floatTolikelihood( - template.variations[0].likelihood - ); - const impactValue = floatToImpact(template.variations[0].impact); - setinherentLikelihood(likelihoodValue); - setinherentImpact(impactValue); + + // Convert template values to 1-5 scale + const likelihoodValue = + Math.round(template.variations[0].likelihood * 5) || 3; + const impactValue = Math.round(template.variations[0].impact * 5) || 3; + + // Ensure values are in 1-5 range + setInherentLikelihood(Math.min(Math.max(likelihoodValue, 1), 5)); + setInherentImpact(Math.min(Math.max(impactValue, 1), 5)); + // Set residual values to be the same as initial values by default - setResidualLikelihood(likelihoodValue); - setResidualImpact(impactValue); + setResidualLikelihood(Math.min(Math.max(likelihoodValue, 1), 5)); + setResidualImpact(Math.min(Math.max(impactValue, 1), 5)); // Set recommended treatment if available if (template.variations[0].recommendedTreatment) { @@ -194,24 +160,6 @@ function NewRiskForm({ } }; - // Helper function to convert float likelihood to string - const floatTolikelihood = (value: number): string => { - if (value <= 0.2) return "IMPROBABLE"; - if (value <= 0.4) return "REMOTE"; - if (value <= 0.6) return "OCCASIONAL"; - if (value <= 0.8) return "PROBABLE"; - return "FREQUENT"; - }; - - // Helper function to convert float impact to string - const floatToImpact = (value: number): string => { - if (value <= 0.2) return "NEGLIGIBLE"; - if (value <= 0.4) return "LOW"; - if (value <= 0.6) return "MODERATE"; - if (value <= 0.8) return "SIGNIFICANT"; - return "CATASTROPHIC"; - }; - const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); @@ -230,10 +178,10 @@ function NewRiskForm({ organizationId: organizationId!, name, description, - inherentLikelihood: likelihoodToFloat(inherentLikelihood), - inherentImpact: impactToFloat(inherentImpact), - residualLikelihood: likelihoodToFloat(residualLikelihood), - residualImpact: impactToFloat(residualImpact), + inherentLikelihood, + inherentImpact, + residualLikelihood, + residualImpact, treatment, ownerId: ownerId || undefined, }; @@ -355,39 +303,43 @@ function NewRiskForm({
- +
- +
@@ -422,40 +374,44 @@ function NewRiskForm({
- +
diff --git a/apps/console/src/pages/organizations/risks/ShowRiskView.tsx b/apps/console/src/pages/organizations/risks/ShowRiskView.tsx index 71d581d15..fd0605dfa 100644 --- a/apps/console/src/pages/organizations/risks/ShowRiskView.tsx +++ b/apps/console/src/pages/organizations/risks/ShowRiskView.tsx @@ -210,30 +210,102 @@ const deleteRiskPolicyMappingMutation = graphql` function getRiskSeverity(likelihood: number, impact: number) { const score = likelihood * impact; - if (score >= 0.75) - return { level: "Catastrophic", class: "bg-red-100 text-red-800" }; - if (score >= 0.5) - return { level: "Critical", class: "bg-orange-100 text-orange-800" }; - if (score >= 0.25) - return { level: "Marginal", class: "bg-yellow-100 text-yellow-800" }; - return { level: "Negligible", class: "bg-green-100 text-green-800" }; + if (score >= 20) + return { + level: "Catastrophic", + score: score, + style: { + backgroundColor: "#ef4444", + color: "white", + }, + }; + if (score >= 12) + return { + level: "Critical", + score: score, + style: { + backgroundColor: "#f59e0b", + color: "white", + }, + }; + if (score >= 5) + return { + level: "Marginal", + score: score, + style: { + backgroundColor: "#10b981", + color: "inherit", + }, + }; + return { + level: "Negligible", + score: score, + style: { + backgroundColor: "#94a3b8", + color: "inherit", + }, + }; } // Add helper functions to convert numerical values to labels -function getLikelihoodLabel(likelihood: number): string { - if (likelihood >= 0.8) return "Frequent"; - if (likelihood >= 0.6) return "Probable"; - if (likelihood >= 0.4) return "Occasional"; - if (likelihood >= 0.2) return "Remote"; - return "Improbable"; +function getLikelihoodLabel(likelihood: number): { + label: string; + style: React.CSSProperties; +} { + if (likelihood === 5) + return { + label: "Frequent (5)", + style: { backgroundColor: "#ef4444", color: "white" }, + }; + if (likelihood === 4) + return { + label: "Probable (4)", + style: { backgroundColor: "#f59e0b", color: "white" }, + }; + if (likelihood === 3) + return { + label: "Occasional (3)", + style: { backgroundColor: "#eab308", color: "black" }, + }; + if (likelihood === 2) + return { + label: "Remote (2)", + style: { backgroundColor: "#10b981", color: "black" }, + }; + return { + label: "Improbable (1)", + style: { backgroundColor: "#94a3b8", color: "black" }, + }; } -function getImpactLabel(impact: number): string { - if (impact >= 0.8) return "Catastrophic"; - if (impact >= 0.6) return "Significant"; - if (impact >= 0.4) return "Moderate"; - if (impact >= 0.2) return "Low"; - return "Negligible"; +function getImpactLabel(impact: number): { + label: string; + style: React.CSSProperties; +} { + if (impact === 5) + return { + label: "Catastrophic (5)", + style: { backgroundColor: "#ef4444", color: "white" }, + }; + if (impact === 4) + return { + label: "Significant (4)", + style: { backgroundColor: "#f59e0b", color: "white" }, + }; + if (impact === 3) + return { + label: "Moderate (3)", + style: { backgroundColor: "#eab308", color: "black" }, + }; + if (impact === 2) + return { + label: "Low (2)", + style: { backgroundColor: "#10b981", color: "black" }, + }; + return { + label: "Negligible (1)", + style: { backgroundColor: "#94a3b8", color: "black" }, + }; } function ShowRiskViewContent({ @@ -765,65 +837,43 @@ function ShowRiskViewContent({ >
- + Risk Overview -
-
-

- Likelihood -

-

- {getLikelihoodLabel(risk.inherentLikelihood!)} -

-
-
-

Impact

-

- {getImpactLabel(risk.inherentImpact!)} -

-
-
-

Severity

-

- {severity.level} -

-
-
- - {/* Treatment and Owner section */} -
-
-
-

- Treatment -

-
- {risk.treatment === "MITIGATED" && ( - - )} - {risk.treatment === "TRANSFERRED" && ( - - )} - {risk.treatment === "AVOIDED" && ( - - )} - {risk.treatment === "ACCEPTED" && ( - - )} - +
+ {/* Risk Management Overview */} +
+
+ {risk.treatment === "MITIGATED" && ( + + )} + {risk.treatment === "TRANSFERRED" && ( + + )} + {risk.treatment === "AVOIDED" && ( + + )} + {risk.treatment === "ACCEPTED" && ( + + )} +
+

+ Treatment +

+

{risk.treatment ? risk.treatment.toLowerCase() : "N/A"} - +

-
-

- Risk Owner -

-
- - + +
+ +
+

+ Risk Owner +

+

{risk.owner ? ( +

-
-
- {/* Residual risk section */} -
-

Residual Risk

-
-
-

- Residual Likelihood -

-

- {getLikelihoodLabel(risk.residualLikelihood!)} -

-

- {risk.residualLikelihood !== risk.inherentLikelihood - ? `Mitigated` - : "No mitigation"} -

-
-
-

- Residual Impact -

-

- {getImpactLabel(risk.residualImpact!)} -

-

- {risk.residualImpact !== risk.inherentImpact - ? `Mitigated` - : "No mitigation"} -

-
-
-

- Residual Severity -

-

- - {residualSeverity.level} - -

-

- {mesures.length} mesure - {mesures.length !== 1 ? "s" : ""} applied -

+ {/* Risk Assessment */} +
+

Risk Assessment

+ +
+ {/* Initial Assessment */} +
+

+ + Initial Assessment +

+
+
+

+ Likelihood +

+
+ {getLikelihoodLabel(risk.inherentLikelihood!).label} +
+
+
+

Impact

+
+ {getImpactLabel(risk.inherentImpact!).label} +
+
+
+

Severity

+
+ {severity.level} ( + {risk.inherentLikelihood! * risk.inherentImpact!}) +
+
+
+
+ + {/* Residual Assessment */} +
+

+ + After Treatment +

+
+
+

+ Likelihood +

+
+ {getLikelihoodLabel(risk.residualLikelihood!).label} +
+
+
+

Impact

+
+ {getImpactLabel(risk.residualImpact!).label} +
+
+
+

Severity

+
+ {residualSeverity.level} ( + {risk.residualLikelihood! * risk.residualImpact!}) +
+
+
+
+ + {/* Risk Reduction Summary */} + {(risk.inherentLikelihood !== risk.residualLikelihood || + risk.inherentImpact !== risk.residualImpact) && ( +
+

+ Risk severity reduced from{" "} + + {severity.level} ( + {risk.inherentLikelihood! * risk.inherentImpact!}) + {" "} + to{" "} + + {residualSeverity.level} ( + {risk.residualLikelihood! * risk.residualImpact!}) + + {risk.treatment === "MITIGATED" && + risk.mesures?.edges && + risk.mesures.edges.length > 0 && + ` with ${risk.mesures.edges.length} ${ + risk.mesures.edges.length === 1 + ? "measure" + : "measures" + }`} +

+
+ )}
@@ -910,7 +1030,7 @@ function ShowRiskViewContent({ Link Mesure
- {risk.mesures?.edges?.length && risk.mesures?.edges?.length > 0 ? ( + {risk.mesures?.edges && risk.mesures.edges.length > 0 ? (
diff --git a/pkg/coredata/migrations/20250415T094200Z.sql b/pkg/coredata/migrations/20250415T094200Z.sql new file mode 100644 index 000000000..f8e58bc01 --- /dev/null +++ b/pkg/coredata/migrations/20250415T094200Z.sql @@ -0,0 +1,44 @@ +ALTER TABLE risks ADD COLUMN inherent_likelihood_int INTEGER; +ALTER TABLE risks ADD COLUMN inherent_impact_int INTEGER; +ALTER TABLE risks ADD COLUMN residual_likelihood_int INTEGER; +ALTER TABLE risks ADD COLUMN residual_impact_int INTEGER; + +UPDATE risks SET + inherent_likelihood_int = CASE + WHEN inherent_likelihood <= 0.20 THEN 1 + WHEN inherent_likelihood <= 0.40 THEN 2 + WHEN inherent_likelihood <= 0.60 THEN 3 + WHEN inherent_likelihood <= 0.80 THEN 4 + ELSE 5 + END, + inherent_impact_int = CASE + WHEN inherent_impact <= 0.20 THEN 1 + WHEN inherent_impact <= 0.40 THEN 2 + WHEN inherent_impact <= 0.60 THEN 3 + WHEN inherent_impact <= 0.80 THEN 4 + ELSE 5 + END, + residual_likelihood_int = CASE + WHEN residual_likelihood <= 0.20 THEN 1 + WHEN residual_likelihood <= 0.40 THEN 2 + WHEN residual_likelihood <= 0.60 THEN 3 + WHEN residual_likelihood <= 0.80 THEN 4 + ELSE 5 + END, + residual_impact_int = CASE + WHEN residual_impact <= 0.20 THEN 1 + WHEN residual_impact <= 0.40 THEN 2 + WHEN residual_impact <= 0.60 THEN 3 + WHEN residual_impact <= 0.80 THEN 4 + ELSE 5 + END; + +ALTER TABLE risks DROP COLUMN inherent_likelihood; +ALTER TABLE risks DROP COLUMN inherent_impact; +ALTER TABLE risks DROP COLUMN residual_likelihood; +ALTER TABLE risks DROP COLUMN residual_impact; + +ALTER TABLE risks RENAME COLUMN inherent_likelihood_int TO inherent_likelihood; +ALTER TABLE risks RENAME COLUMN inherent_impact_int TO inherent_impact; +ALTER TABLE risks RENAME COLUMN residual_likelihood_int TO residual_likelihood; +ALTER TABLE risks RENAME COLUMN residual_impact_int TO residual_impact; \ No newline at end of file diff --git a/pkg/coredata/risk.go b/pkg/coredata/risk.go index 9309e299c..3e38c37ae 100644 --- a/pkg/coredata/risk.go +++ b/pkg/coredata/risk.go @@ -34,10 +34,10 @@ type ( Description string `db:"description"` Treatment RiskTreatment `db:"treatment"` OwnerID *gid.GID `db:"owner_id"` - InherentLikelihood float64 `db:"inherent_likelihood"` - InherentImpact float64 `db:"inherent_impact"` - ResidualLikelihood float64 `db:"residual_likelihood"` - ResidualImpact float64 `db:"residual_impact"` + InherentLikelihood int `db:"inherent_likelihood"` + InherentImpact int `db:"inherent_impact"` + ResidualLikelihood int `db:"residual_likelihood"` + ResidualImpact int `db:"residual_impact"` CreatedAt time.Time `db:"created_at"` UpdatedAt time.Time `db:"updated_at"` } @@ -54,11 +54,11 @@ func (r *Risk) CursorKey(orderBy RiskOrderField) page.CursorKey { panic(fmt.Sprintf("unsupported order by: %s", orderBy)) } -func (r *Risk) InherentSeverity() float64 { +func (r *Risk) InherentSeverity() int { return r.InherentLikelihood * r.InherentImpact } -func (r *Risk) ResidualSeverity() float64 { +func (r *Risk) ResidualSeverity() int { return r.ResidualLikelihood * r.ResidualImpact } diff --git a/pkg/probo/risk_service.go b/pkg/probo/risk_service.go index 09303438f..b5109fdf8 100644 --- a/pkg/probo/risk_service.go +++ b/pkg/probo/risk_service.go @@ -36,10 +36,10 @@ type ( Description string Treatment coredata.RiskTreatment OwnerID *gid.GID - InherentLikelihood float64 - InherentImpact float64 - ResidualLikelihood *float64 - ResidualImpact *float64 + InherentLikelihood int + InherentImpact int + ResidualLikelihood *int + ResidualImpact *int } UpdateRiskRequest struct { @@ -48,10 +48,10 @@ type ( Description *string Treatment *coredata.RiskTreatment OwnerID *gid.GID - InherentLikelihood *float64 - InherentImpact *float64 - ResidualLikelihood *float64 - ResidualImpact *float64 + InherentLikelihood *int + InherentImpact *int + ResidualLikelihood *int + ResidualImpact *int } ) diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index b930f93fb..4ebef52b4 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -628,12 +628,12 @@ type Risk implements Node { name: String! description: String! treatment: RiskTreatment! - inherentLikelihood: Float! - inherentImpact: Float! - inherentSeverity: Float! - residualLikelihood: Float! - residualImpact: Float! - residualSeverity: Float! + inherentLikelihood: Int! + inherentImpact: Int! + inherentSeverity: Int! + residualLikelihood: Int! + residualImpact: Int! + residualSeverity: Int! owner: People @goField(forceResolver: true) @@ -1092,10 +1092,10 @@ input CreateRiskInput { description: String! ownerId: ID treatment: RiskTreatment! - inherentLikelihood: Float! - inherentImpact: Float! - residualLikelihood: Float - residualImpact: Float + inherentLikelihood: Int! + inherentImpact: Int! + residualLikelihood: Int + residualImpact: Int } input UpdateRiskInput { @@ -1104,10 +1104,10 @@ input UpdateRiskInput { description: String ownerId: ID treatment: RiskTreatment - inherentLikelihood: Float - inherentImpact: Float - residualLikelihood: Float - residualImpact: Float + inherentLikelihood: Int + inherentImpact: Int + residualLikelihood: Int + residualImpact: Int } input DeleteRiskInput { diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index e125eb6d5..2b8fdef55 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -3739,12 +3739,12 @@ type Risk implements Node { name: String! description: String! treatment: RiskTreatment! - inherentLikelihood: Float! - inherentImpact: Float! - inherentSeverity: Float! - residualLikelihood: Float! - residualImpact: Float! - residualSeverity: Float! + inherentLikelihood: Int! + inherentImpact: Int! + inherentSeverity: Int! + residualLikelihood: Int! + residualImpact: Int! + residualSeverity: Int! owner: People @goField(forceResolver: true) @@ -4203,10 +4203,10 @@ input CreateRiskInput { description: String! ownerId: ID treatment: RiskTreatment! - inherentLikelihood: Float! - inherentImpact: Float! - residualLikelihood: Float - residualImpact: Float + inherentLikelihood: Int! + inherentImpact: Int! + residualLikelihood: Int + residualImpact: Int } input UpdateRiskInput { @@ -4215,10 +4215,10 @@ input UpdateRiskInput { description: String ownerId: ID treatment: RiskTreatment - inherentLikelihood: Float - inherentImpact: Float - residualLikelihood: Float - residualImpact: Float + inherentLikelihood: Int + inherentImpact: Int + residualLikelihood: Int + residualImpact: Int } input DeleteRiskInput { @@ -16907,9 +16907,9 @@ func (ec *executionContext) _Risk_inherentLikelihood(ctx context.Context, field } return graphql.Null } - res := resTmp.(float64) + res := resTmp.(int) fc.Result = res - return ec.marshalNFloat2float64(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Risk_inherentLikelihood(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -16919,7 +16919,7 @@ func (ec *executionContext) fieldContext_Risk_inherentLikelihood(_ context.Conte IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Float does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil @@ -16951,9 +16951,9 @@ func (ec *executionContext) _Risk_inherentImpact(ctx context.Context, field grap } return graphql.Null } - res := resTmp.(float64) + res := resTmp.(int) fc.Result = res - return ec.marshalNFloat2float64(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Risk_inherentImpact(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -16963,7 +16963,7 @@ func (ec *executionContext) fieldContext_Risk_inherentImpact(_ context.Context, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Float does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil @@ -16995,9 +16995,9 @@ func (ec *executionContext) _Risk_inherentSeverity(ctx context.Context, field gr } return graphql.Null } - res := resTmp.(float64) + res := resTmp.(int) fc.Result = res - return ec.marshalNFloat2float64(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Risk_inherentSeverity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -17007,7 +17007,7 @@ func (ec *executionContext) fieldContext_Risk_inherentSeverity(_ context.Context IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Float does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil @@ -17039,9 +17039,9 @@ func (ec *executionContext) _Risk_residualLikelihood(ctx context.Context, field } return graphql.Null } - res := resTmp.(float64) + res := resTmp.(int) fc.Result = res - return ec.marshalNFloat2float64(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Risk_residualLikelihood(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -17051,7 +17051,7 @@ func (ec *executionContext) fieldContext_Risk_residualLikelihood(_ context.Conte IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Float does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil @@ -17083,9 +17083,9 @@ func (ec *executionContext) _Risk_residualImpact(ctx context.Context, field grap } return graphql.Null } - res := resTmp.(float64) + res := resTmp.(int) fc.Result = res - return ec.marshalNFloat2float64(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Risk_residualImpact(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -17095,7 +17095,7 @@ func (ec *executionContext) fieldContext_Risk_residualImpact(_ context.Context, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Float does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil @@ -17127,9 +17127,9 @@ func (ec *executionContext) _Risk_residualSeverity(ctx context.Context, field gr } return graphql.Null } - res := resTmp.(float64) + res := resTmp.(int) fc.Result = res - return ec.marshalNFloat2float64(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Risk_residualSeverity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -17139,7 +17139,7 @@ func (ec *executionContext) fieldContext_Risk_residualSeverity(_ context.Context IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Float does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil @@ -24054,28 +24054,28 @@ func (ec *executionContext) unmarshalInputCreateRiskInput(ctx context.Context, o it.Treatment = data case "inherentLikelihood": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inherentLikelihood")) - data, err := ec.unmarshalNFloat2float64(ctx, v) + data, err := ec.unmarshalNInt2int(ctx, v) if err != nil { return it, err } it.InherentLikelihood = data case "inherentImpact": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inherentImpact")) - data, err := ec.unmarshalNFloat2float64(ctx, v) + data, err := ec.unmarshalNInt2int(ctx, v) if err != nil { return it, err } it.InherentImpact = data case "residualLikelihood": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("residualLikelihood")) - data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint(ctx, v) if err != nil { return it, err } it.ResidualLikelihood = data case "residualImpact": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("residualImpact")) - data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint(ctx, v) if err != nil { return it, err } @@ -25605,28 +25605,28 @@ func (ec *executionContext) unmarshalInputUpdateRiskInput(ctx context.Context, o it.Treatment = data case "inherentLikelihood": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inherentLikelihood")) - data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint(ctx, v) if err != nil { return it, err } it.InherentLikelihood = data case "inherentImpact": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inherentImpact")) - data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint(ctx, v) if err != nil { return it, err } it.InherentImpact = data case "residualLikelihood": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("residualLikelihood")) - data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint(ctx, v) if err != nil { return it, err } it.ResidualLikelihood = data case "residualImpact": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("residualImpact")) - data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v) + data, err := ec.unmarshalOInt2ᚖint(ctx, v) if err != nil { return it, err } @@ -32508,21 +32508,6 @@ var ( } ) -func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v any) (float64, error) { - res, err := graphql.UnmarshalFloatContext(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - res := graphql.MarshalFloatContext(v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - } - return graphql.WrapContextMarshaler(ctx, res) -} - func (ec *executionContext) marshalNFramework2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐFramework(ctx context.Context, sel ast.SelectionSet, v *types.Framework) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -34555,22 +34540,6 @@ func (ec *executionContext) unmarshalOEvidenceOrder2ᚖgithubᚗcomᚋgetprobo return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalOFloat2ᚖfloat64(ctx context.Context, v any) (*float64, error) { - if v == nil { - return nil, nil - } - res, err := graphql.UnmarshalFloatContext(ctx, v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalOFloat2ᚖfloat64(ctx context.Context, sel ast.SelectionSet, v *float64) graphql.Marshaler { - if v == nil { - return graphql.Null - } - res := graphql.MarshalFloatContext(*v) - return graphql.WrapContextMarshaler(ctx, res) -} - func (ec *executionContext) unmarshalOFrameworkOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐFrameworkOrderBy(ctx context.Context, v any) (*types.FrameworkOrderBy, error) { if v == nil { return nil, nil diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 0e92c49b2..f364d59e2 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -152,10 +152,10 @@ type CreateRiskInput struct { Description string `json:"description"` OwnerID *gid.GID `json:"ownerId,omitempty"` Treatment coredata.RiskTreatment `json:"treatment"` - InherentLikelihood float64 `json:"inherentLikelihood"` - InherentImpact float64 `json:"inherentImpact"` - ResidualLikelihood *float64 `json:"residualLikelihood,omitempty"` - ResidualImpact *float64 `json:"residualImpact,omitempty"` + InherentLikelihood int `json:"inherentLikelihood"` + InherentImpact int `json:"inherentImpact"` + ResidualLikelihood *int `json:"residualLikelihood,omitempty"` + ResidualImpact *int `json:"residualImpact,omitempty"` } type CreateRiskMesureMappingInput struct { @@ -562,12 +562,12 @@ type Risk struct { Name string `json:"name"` Description string `json:"description"` Treatment coredata.RiskTreatment `json:"treatment"` - InherentLikelihood float64 `json:"inherentLikelihood"` - InherentImpact float64 `json:"inherentImpact"` - InherentSeverity float64 `json:"inherentSeverity"` - ResidualLikelihood float64 `json:"residualLikelihood"` - ResidualImpact float64 `json:"residualImpact"` - ResidualSeverity float64 `json:"residualSeverity"` + InherentLikelihood int `json:"inherentLikelihood"` + InherentImpact int `json:"inherentImpact"` + InherentSeverity int `json:"inherentSeverity"` + ResidualLikelihood int `json:"residualLikelihood"` + ResidualImpact int `json:"residualImpact"` + ResidualSeverity int `json:"residualSeverity"` Owner *People `json:"owner,omitempty"` Mesures *MesureConnection `json:"mesures"` Policies *PolicyConnection `json:"policies"` @@ -691,10 +691,10 @@ type UpdateRiskInput struct { Description *string `json:"description,omitempty"` OwnerID *gid.GID `json:"ownerId,omitempty"` Treatment *coredata.RiskTreatment `json:"treatment,omitempty"` - InherentLikelihood *float64 `json:"inherentLikelihood,omitempty"` - InherentImpact *float64 `json:"inherentImpact,omitempty"` - ResidualLikelihood *float64 `json:"residualLikelihood,omitempty"` - ResidualImpact *float64 `json:"residualImpact,omitempty"` + InherentLikelihood *int `json:"inherentLikelihood,omitempty"` + InherentImpact *int `json:"inherentImpact,omitempty"` + ResidualLikelihood *int `json:"residualLikelihood,omitempty"` + ResidualImpact *int `json:"residualImpact,omitempty"` } type UpdateRiskPayload struct {