Add risk treatment

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-04-12 10:39:05 -07:00
parent d0f69916ca
commit e3c7194afc
22 changed files with 574 additions and 175 deletions

View File

@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
## [Unreleased] ## [Unreleased]
### Added
- New risk treatment strategy options: Mitigate, Accept, Avoid, Transfer
## [0.7.0] - 2025-04-12 ## [0.7.0] - 2025-04-12
### Added ### Added

View File

@@ -24,7 +24,7 @@ import { PolicyListPage } from "./policies/PolicyListPage";
import { PolicyPage } from "./policies/PolicyPage"; import { PolicyPage } from "./policies/PolicyPage";
import { EditRiskPage } from "./risks/EditRiskPage"; import { EditRiskPage } from "./risks/EditRiskPage";
import { NewRiskPage } from "./risks/NewRiskPage"; import { NewRiskPage } from "./risks/NewRiskPage";
import { RiskListPage } from "./risks/RiskListPage"; import { ListRiskPage } from "./risks/ListRiskPage";
import ShowRiskView from "./risks/ShowRiskView"; import ShowRiskView from "./risks/ShowRiskView";
import { VendorListPage } from "./vendors/VendorListPage"; import { VendorListPage } from "./vendors/VendorListPage";
import { VendorPage } from "./vendors/VendorPage"; import { VendorPage } from "./vendors/VendorPage";
@@ -60,7 +60,7 @@ export function OrganizationsRoutes() {
<Route path="policies/new" element={<NewPolicyPage />} /> <Route path="policies/new" element={<NewPolicyPage />} />
<Route path="policies/:policyId" element={<PolicyPage />} /> <Route path="policies/:policyId" element={<PolicyPage />} />
<Route path="policies/:policyId/edit" element={<EditPolicyPage />} /> <Route path="policies/:policyId/edit" element={<EditPolicyPage />} />
<Route path="risks" element={<RiskListPage />} /> <Route path="risks" element={<ListRiskPage />} />
<Route path="risks/new" element={<NewRiskPage />} /> <Route path="risks/new" element={<NewRiskPage />} />
<Route path="risks/:riskId" element={<ShowRiskView />} /> <Route path="risks/:riskId" element={<ShowRiskView />} />
<Route path="risks/:riskId/edit" element={<EditRiskPage />} /> <Route path="risks/:riskId/edit" element={<EditRiskPage />} />

View File

@@ -34,6 +34,7 @@ import { Suspense } from "react";
import { EditRiskViewSkeleton } from "./EditRiskPage"; import { EditRiskViewSkeleton } from "./EditRiskPage";
import type { EditRiskViewQuery } from "./__generated__/EditRiskViewQuery.graphql"; import type { EditRiskViewQuery } from "./__generated__/EditRiskViewQuery.graphql";
import type { EditRiskViewUpdateRiskMutation } from "./__generated__/EditRiskViewUpdateRiskMutation.graphql"; import type { EditRiskViewUpdateRiskMutation } from "./__generated__/EditRiskViewUpdateRiskMutation.graphql";
import type { RiskTreatment } from "./__generated__/EditRiskViewUpdateRiskMutation.graphql";
// Query to get risk details // Query to get risk details
const editRiskViewQuery = graphql` const editRiskViewQuery = graphql`
@@ -47,6 +48,7 @@ const editRiskViewQuery = graphql`
inherentImpact inherentImpact
residualLikelihood residualLikelihood
residualImpact residualImpact
treatment
} }
} }
} }
@@ -64,6 +66,7 @@ const updateRiskMutation = graphql`
inherentImpact inherentImpact
residualLikelihood residualLikelihood
residualImpact residualImpact
treatment
updatedAt updatedAt
} }
} }
@@ -94,6 +97,7 @@ function EditRiskViewContent({
const [residualLikelihood, setResidualLikelihood] = const [residualLikelihood, setResidualLikelihood] =
useState<string>("MEDIUM"); useState<string>("MEDIUM");
const [residualImpact, setResidualImpact] = useState<string>("MEDIUM"); const [residualImpact, setResidualImpact] = useState<string>("MEDIUM");
const [treatment, setTreatment] = useState<RiskTreatment>("MITIGATED");
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [updateRisk, isInFlight] = const [updateRisk, isInFlight] =
@@ -161,6 +165,7 @@ function EditRiskViewContent({
setInherentImpact(floatToImpact(risk.inherentImpact || 0.5)); setInherentImpact(floatToImpact(risk.inherentImpact || 0.5));
setResidualLikelihood(floatToLikelihood(risk.residualLikelihood || 0.5)); setResidualLikelihood(floatToLikelihood(risk.residualLikelihood || 0.5));
setResidualImpact(floatToImpact(risk.residualImpact || 0.5)); setResidualImpact(floatToImpact(risk.residualImpact || 0.5));
setTreatment(risk.treatment || "MITIGATED");
} }
}, [risk]); }, [risk]);
@@ -186,6 +191,7 @@ function EditRiskViewContent({
inherentImpact: impactToFloat(inherentImpact), inherentImpact: impactToFloat(inherentImpact),
residualLikelihood: likelihoodToFloat(residualLikelihood), residualLikelihood: likelihoodToFloat(residualLikelihood),
residualImpact: impactToFloat(residualImpact), residualImpact: impactToFloat(residualImpact),
treatment,
}; };
updateRisk({ updateRisk({
@@ -308,6 +314,29 @@ function EditRiskViewContent({
<Separator /> <Separator />
<div className="space-y-2">
<Label htmlFor="treatment">Treatment Strategy</Label>
<Select
value={treatment}
onValueChange={(value: RiskTreatment) => setTreatment(value)}
>
<SelectTrigger id="treatment">
<SelectValue placeholder="Select a treatment strategy" />
</SelectTrigger>
<SelectContent className="max-h-[300px] overflow-y-auto">
<SelectItem value="AVOIDED">Avoid</SelectItem>
<SelectItem value="MITIGATED">Mitigate</SelectItem>
<SelectItem value="TRANSFERRED">Transfer</SelectItem>
<SelectItem value="ACCEPTED">Accept</SelectItem>
</SelectContent>
</Select>
<p className="text-sm text-tertiary">
Choose how you plan to address this risk
</p>
</div>
<Separator />
<div> <div>
<h3 className="text-lg font-medium mb-2">Residual Risk</h3> <h3 className="text-lg font-medium mb-2">Residual Risk</h3>
<p className="text-sm text-tertiary mb-4"> <p className="text-sm text-tertiary mb-4">
@@ -357,6 +386,8 @@ function EditRiskViewContent({
</div> </div>
</div> </div>
<Separator />
<div className="flex justify-end gap-3"> <div className="flex justify-end gap-3">
<Button <Button
type="button" type="button"

View File

@@ -4,7 +4,7 @@ import { lazy } from "@probo/react-lazy";
import { useLocation } from "react-router"; import { useLocation } from "react-router";
import { ErrorBoundaryWithLocation } from "../ErrorBoundary"; import { ErrorBoundaryWithLocation } from "../ErrorBoundary";
const RiskListView = lazy(() => import("./RiskListView")); const RiskListView = lazy(() => import("./ListRiskView"));
export function RiskViewSkeleton() { export function RiskViewSkeleton() {
return ( return (
@@ -21,7 +21,7 @@ export function RiskViewSkeleton() {
); );
} }
export function RiskListPage() { export function ListRiskPage() {
const location = useLocation(); const location = useLocation();
return ( return (

View File

@@ -15,12 +15,12 @@ import {
useState, useState,
useTransition, useTransition,
} from "react"; } from "react";
import type { RiskListViewQuery } from "./__generated__/RiskListViewQuery.graphql"; import type { ListRiskViewQuery } from "./__generated__/ListRiskViewQuery.graphql";
import { useParams, useSearchParams } from "react-router"; import { useParams, useSearchParams } from "react-router";
import { PageTemplate } from "@/components/PageTemplate"; import { PageTemplate } from "@/components/PageTemplate";
import { RiskViewSkeleton } from "./RiskListPage"; import { RiskViewSkeleton } from "./ListRiskPage";
import { RiskListViewPaginationQuery } from "./__generated__/RiskListViewPaginationQuery.graphql"; import { ListRiskViewPaginationQuery } from "./__generated__/ListRiskViewPaginationQuery.graphql";
import { RiskListView_risks$key } from "./__generated__/RiskListView_risks.graphql"; import { ListRiskView_risks$key } from "./__generated__/ListRiskView_risks.graphql";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Link } from "react-router"; import { Link } from "react-router";
@@ -34,7 +34,7 @@ import {
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { RiskListViewDeleteMutation } from "./__generated__/RiskListViewDeleteMutation.graphql"; import { ListRiskViewDeleteMutation } from "./__generated__/ListRiskViewDeleteMutation.graphql";
import { import {
Popover, Popover,
PopoverContent, PopoverContent,
@@ -45,8 +45,8 @@ import { Label } from "@/components/ui/label";
const defaultPageSize = 25; const defaultPageSize = 25;
const riskListViewQuery = graphql` const listRiskViewQuery = graphql`
query RiskListViewQuery( query ListRiskViewQuery(
$organizationId: ID! $organizationId: ID!
$first: Int $first: Int
$after: CursorKey $after: CursorKey
@@ -56,15 +56,15 @@ const riskListViewQuery = graphql`
organization: node(id: $organizationId) { organization: node(id: $organizationId) {
id id
...RiskListView_risks ...ListRiskView_risks
@arguments(first: $first, after: $after, last: $last, before: $before) @arguments(first: $first, after: $after, last: $last, before: $before)
} }
} }
`; `;
const riskListFragment = graphql` const listRiskViewFragment = graphql`
fragment RiskListView_risks on Organization fragment ListRiskView_risks on Organization
@refetchable(queryName: "RiskListViewPaginationQuery") @refetchable(queryName: "ListRiskViewPaginationQuery")
@argumentDefinitions( @argumentDefinitions(
first: { type: "Int" } first: { type: "Int" }
after: { type: "CursorKey" } after: { type: "CursorKey" }
@@ -72,7 +72,7 @@ const riskListFragment = graphql`
before: { type: "CursorKey" } before: { type: "CursorKey" }
) { ) {
risks(first: $first, after: $after, last: $last, before: $before) risks(first: $first, after: $after, last: $last, before: $before)
@connection(key: "RiskListView_risks") { @connection(key: "ListRiskView_risks") {
__id __id
edges { edges {
node { node {
@@ -82,6 +82,7 @@ const riskListFragment = graphql`
inherentImpact inherentImpact
residualLikelihood residualLikelihood
residualImpact residualImpact
treatment
description description
createdAt createdAt
updatedAt updatedAt
@@ -98,7 +99,7 @@ const riskListFragment = graphql`
`; `;
const deleteRiskMutation = graphql` const deleteRiskMutation = graphql`
mutation RiskListViewDeleteMutation( mutation ListRiskViewDeleteMutation(
$input: DeleteRiskInput! $input: DeleteRiskInput!
$connections: [ID!]! $connections: [ID!]!
) { ) {
@@ -113,6 +114,18 @@ const floatToPercentage = (value: number): string => {
return `${Math.round(value * 100)}%`; return `${Math.round(value * 100)}%`;
}; };
// Helper function to format treatment value
const formatTreatment = (treatment: string): string => {
const treatmentMap: Record<string, string> = {
MITIGATED: "Mitigate",
ACCEPTED: "Accept",
AVOIDED: "Avoid",
TRANSFERRED: "Transfer",
};
return treatmentMap[treatment] || treatment;
};
function LoadAboveButton({ function LoadAboveButton({
isLoading, isLoading,
hasMore, hasMore,
@@ -389,12 +402,12 @@ function RiskMatrix({
); );
} }
function RiskListViewContent({ function ListRiskViewContent({
queryRef, queryRef,
}: { }: {
queryRef: PreloadedQuery<RiskListViewQuery>; queryRef: PreloadedQuery<ListRiskViewQuery>;
}) { }) {
const data = usePreloadedQuery(riskListViewQuery, queryRef); const data = usePreloadedQuery(listRiskViewQuery, queryRef);
const [, setSearchParams] = useSearchParams(); const [, setSearchParams] = useSearchParams();
const [, startTransition] = useTransition(); const [, startTransition] = useTransition();
const { organizationId } = useParams<{ organizationId: string }>(); const { organizationId } = useParams<{ organizationId: string }>();
@@ -412,7 +425,7 @@ function RiskListViewContent({
// Setup delete mutation // Setup delete mutation
const [commitDeleteMutation] = const [commitDeleteMutation] =
useMutation<RiskListViewDeleteMutation>(deleteRiskMutation); useMutation<ListRiskViewDeleteMutation>(deleteRiskMutation);
const { const {
data: risksConnection, data: risksConnection,
@@ -423,9 +436,9 @@ function RiskListViewContent({
isLoadingNext, isLoadingNext,
isLoadingPrevious, isLoadingPrevious,
} = usePaginationFragment< } = usePaginationFragment<
RiskListViewPaginationQuery, ListRiskViewPaginationQuery,
RiskListView_risks$key ListRiskView_risks$key
>(riskListFragment, data.organization); >(listRiskViewFragment, data.organization);
const risks = risksConnection?.risks?.edges?.map((edge) => edge.node) || []; const risks = risksConnection?.risks?.edges?.map((edge) => edge.node) || [];
const pageInfo = risksConnection?.risks?.pageInfo; const pageInfo = risksConnection?.risks?.pageInfo;
@@ -553,10 +566,13 @@ function RiskListViewContent({
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/2"> <th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/2">
Name Name
</th> </th>
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/4"> <th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/6">
Treatment
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/6">
Inherent Severity Inherent Severity
</th> </th>
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/4"> <th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/6">
Residual Severity Residual Severity
</th> </th>
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-[120px]"> <th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-[120px]">
@@ -568,7 +584,7 @@ function RiskListViewContent({
{risks.length === 0 ? ( {risks.length === 0 ? (
<tr className="border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg"> <tr className="border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg">
<td <td
colSpan={4} colSpan={5}
className="text-center p-4 align-middle text-tertiary" className="text-center p-4 align-middle text-tertiary"
> >
No risks found. Create a new risk to get started. No risks found. Create a new risk to get started.
@@ -588,7 +604,15 @@ function RiskListViewContent({
{risk.name} {risk.name}
</Link> </Link>
</td> </td>
<td className="p-0 align-middle w-1/4 whitespace-nowrap"> <td className="p-0 align-middle w-1/6 whitespace-nowrap">
<Link
to={`/organizations/${organizationId}/risks/${risk.id}`}
className="block p-4 h-full w-full"
>
{formatTreatment(risk.treatment)}
</Link>
</td>
<td className="p-0 align-middle w-1/6 whitespace-nowrap">
<Link <Link
to={`/organizations/${organizationId}/risks/${risk.id}`} to={`/organizations/${organizationId}/risks/${risk.id}`}
className="block p-4 h-full w-full" className="block p-4 h-full w-full"
@@ -598,7 +622,7 @@ function RiskListViewContent({
)} )}
</Link> </Link>
</td> </td>
<td className="p-0 align-middle w-1/4 whitespace-nowrap"> <td className="p-0 align-middle w-1/6 whitespace-nowrap">
<Link <Link
to={`/organizations/${organizationId}/risks/${risk.id}`} to={`/organizations/${organizationId}/risks/${risk.id}`}
className="block p-4 h-full w-full" className="block p-4 h-full w-full"
@@ -698,10 +722,10 @@ function RiskListViewContent({
); );
} }
export default function RiskListView() { export default function ListRiskView() {
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const [queryRef, loadQuery] = const [queryRef, loadQuery] =
useQueryLoader<RiskListViewQuery>(riskListViewQuery); useQueryLoader<ListRiskViewQuery>(listRiskViewQuery);
const { organizationId } = useParams(); const { organizationId } = useParams();
@@ -724,7 +748,7 @@ export default function RiskListView() {
return ( return (
<Suspense fallback={<RiskViewSkeleton />}> <Suspense fallback={<RiskViewSkeleton />}>
<RiskListViewContent queryRef={queryRef} /> <ListRiskViewContent queryRef={queryRef} />
</Suspense> </Suspense>
); );
} }

View File

@@ -49,6 +49,7 @@ const createRiskMutation = graphql`
inherentImpact inherentImpact
residualLikelihood residualLikelihood
residualImpact residualImpact
treatment
createdAt createdAt
updatedAt updatedAt
} }
@@ -68,6 +69,7 @@ export default function NewRiskView() {
const [residualLikelihood, setResidualLikelihood] = const [residualLikelihood, setResidualLikelihood] =
useState<string>("MEDIUM"); useState<string>("MEDIUM");
const [residualImpact, setResidualImpact] = useState<string>("MEDIUM"); const [residualImpact, setResidualImpact] = useState<string>("MEDIUM");
const [treatment, setTreatment] = useState<string>("MITIGATED");
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [selectedTemplate, setSelectedTemplate] = useState<string>(""); const [selectedTemplate, setSelectedTemplate] = useState<string>("");
const [riskTemplates, setRiskTemplates] = useState<RiskTemplate[]>([]); const [riskTemplates, setRiskTemplates] = useState<RiskTemplate[]>([]);
@@ -141,6 +143,7 @@ export default function NewRiskView() {
setinherentImpact("MEDIUM"); setinherentImpact("MEDIUM");
setResidualLikelihood("MEDIUM"); setResidualLikelihood("MEDIUM");
setResidualImpact("MEDIUM"); setResidualImpact("MEDIUM");
setTreatment("MITIGATED");
return; return;
} }
@@ -158,6 +161,11 @@ export default function NewRiskView() {
// Set residual values to be the same as initial values by default // Set residual values to be the same as initial values by default
setResidualLikelihood(likelihoodValue); setResidualLikelihood(likelihoodValue);
setResidualImpact(impactValue); setResidualImpact(impactValue);
// Set recommended treatment if available
if (template.variations[0].recommendedTreatment) {
setTreatment(template.variations[0].recommendedTreatment.toUpperCase());
}
} }
}; };
@@ -201,6 +209,7 @@ export default function NewRiskView() {
inherentImpact: impactToFloat(inherentImpact), inherentImpact: impactToFloat(inherentImpact),
residualLikelihood: likelihoodToFloat(residualLikelihood), residualLikelihood: likelihoodToFloat(residualLikelihood),
residualImpact: impactToFloat(residualImpact), residualImpact: impactToFloat(residualImpact),
treatment,
}; };
createRisk({ createRisk({
@@ -209,7 +218,7 @@ export default function NewRiskView() {
connections: [ connections: [
ConnectionHandler.getConnectionID( ConnectionHandler.getConnectionID(
organizationId!, organizationId!,
"RiskListView_risks" "ListRiskView_risks"
), ),
], ],
}, },
@@ -344,6 +353,24 @@ export default function NewRiskView() {
</div> </div>
</div> </div>
<div className="space-y-2">
<Label htmlFor="treatment">Treatment Strategy</Label>
<Select value={treatment} onValueChange={setTreatment}>
<SelectTrigger id="treatment">
<SelectValue placeholder="Select a treatment strategy" />
</SelectTrigger>
<SelectContent className="max-h-[300px] overflow-y-auto">
<SelectItem value="AVOIDED">Avoid</SelectItem>
<SelectItem value="MITIGATED">Mitigate</SelectItem>
<SelectItem value="TRANSFERRED">Transfer</SelectItem>
<SelectItem value="ACCEPTED">Accept</SelectItem>
</SelectContent>
</Select>
<p className="text-sm text-tertiary">
Choose how you plan to address this risk
</p>
</div>
<Separator className="my-4" /> <Separator className="my-4" />
<div> <div>

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<c0da8faf6e1669e8cf890804a805b2d1>> * @generated SignedSource<<5ae729150c7f534725306ecd1cf786af>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,6 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
export type EditRiskViewQuery$variables = { export type EditRiskViewQuery$variables = {
riskId: string; riskId: string;
}; };
@@ -21,6 +22,7 @@ export type EditRiskViewQuery$data = {
readonly name?: string; readonly name?: string;
readonly residualImpact?: number; readonly residualImpact?: number;
readonly residualLikelihood?: number; readonly residualLikelihood?: number;
readonly treatment?: RiskTreatment;
}; };
}; };
export type EditRiskViewQuery = { export type EditRiskViewQuery = {
@@ -91,6 +93,13 @@ v8 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "residualImpact", "name": "residualImpact",
"storageKey": null "storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "treatment",
"storageKey": null
}; };
return { return {
"fragment": { "fragment": {
@@ -116,7 +125,8 @@ return {
(v5/*: any*/), (v5/*: any*/),
(v6/*: any*/), (v6/*: any*/),
(v7/*: any*/), (v7/*: any*/),
(v8/*: any*/) (v8/*: any*/),
(v9/*: any*/)
], ],
"type": "Risk", "type": "Risk",
"abstractKey": null "abstractKey": null
@@ -158,7 +168,8 @@ return {
(v5/*: any*/), (v5/*: any*/),
(v6/*: any*/), (v6/*: any*/),
(v7/*: any*/), (v7/*: any*/),
(v8/*: any*/) (v8/*: any*/),
(v9/*: any*/)
], ],
"type": "Risk", "type": "Risk",
"abstractKey": null "abstractKey": null
@@ -169,16 +180,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "0cf5e4b47335aeb1fe04520d137942d1", "cacheID": "cd7c9a0e53b9c1a2291e488756da9908",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "EditRiskViewQuery", "name": "EditRiskViewQuery",
"operationKind": "query", "operationKind": "query",
"text": "query EditRiskViewQuery(\n $riskId: ID!\n) {\n risk: node(id: $riskId) {\n __typename\n ... on Risk {\n id\n name\n description\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n }\n id\n }\n}\n" "text": "query EditRiskViewQuery(\n $riskId: ID!\n) {\n risk: node(id: $riskId) {\n __typename\n ... on Risk {\n id\n name\n description\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n treatment\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "d057f56759426d63136cef80269dc8a3"; (node as any).hash = "cce4cb6856fe45d8ab37fe690ac8c720";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<c9530c22837ce495259b6d3ac404da87>> * @generated SignedSource<<92886e4193283cb894a864edc361a575>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,6 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
export type UpdateRiskInput = { export type UpdateRiskInput = {
description?: string | null | undefined; description?: string | null | undefined;
id: string; id: string;
@@ -17,6 +18,7 @@ export type UpdateRiskInput = {
name?: string | null | undefined; name?: string | null | undefined;
residualImpact?: number | null | undefined; residualImpact?: number | null | undefined;
residualLikelihood?: number | null | undefined; residualLikelihood?: number | null | undefined;
treatment?: RiskTreatment | null | undefined;
}; };
export type EditRiskViewUpdateRiskMutation$variables = { export type EditRiskViewUpdateRiskMutation$variables = {
input: UpdateRiskInput; input: UpdateRiskInput;
@@ -31,6 +33,7 @@ export type EditRiskViewUpdateRiskMutation$data = {
readonly name: string; readonly name: string;
readonly residualImpact: number; readonly residualImpact: number;
readonly residualLikelihood: number; readonly residualLikelihood: number;
readonly treatment: RiskTreatment;
readonly updatedAt: string; readonly updatedAt: string;
}; };
}; };
@@ -120,6 +123,13 @@ v1 = [
"name": "residualImpact", "name": "residualImpact",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "treatment",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -152,16 +162,16 @@ return {
"selections": (v1/*: any*/) "selections": (v1/*: any*/)
}, },
"params": { "params": {
"cacheID": "1fb9a7f1a9a6dc2fd8b1c3235336324b", "cacheID": "e1bdac5dea224d79834ac952692a9bda",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "EditRiskViewUpdateRiskMutation", "name": "EditRiskViewUpdateRiskMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation EditRiskViewUpdateRiskMutation(\n $input: UpdateRiskInput!\n) {\n updateRisk(input: $input) {\n risk {\n id\n name\n description\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n updatedAt\n }\n }\n}\n" "text": "mutation EditRiskViewUpdateRiskMutation(\n $input: UpdateRiskInput!\n) {\n updateRisk(input: $input) {\n risk {\n id\n name\n description\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n treatment\n updatedAt\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "75f21269b0c81f77ce4e3547010059ee"; (node as any).hash = "6394ecc50b1e1f039b11ecdcf2724571";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<349d62a3a4ed3ea1d83c12f0c61437dd>> * @generated SignedSource<<4d228ebd230765e4ef84981f18bcd705>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,18 +12,18 @@ import { ConcreteRequest } from 'relay-runtime';
export type DeleteRiskInput = { export type DeleteRiskInput = {
riskId: string; riskId: string;
}; };
export type RiskListViewDeleteMutation$variables = { export type ListRiskViewDeleteMutation$variables = {
connections: ReadonlyArray<string>; connections: ReadonlyArray<string>;
input: DeleteRiskInput; input: DeleteRiskInput;
}; };
export type RiskListViewDeleteMutation$data = { export type ListRiskViewDeleteMutation$data = {
readonly deleteRisk: { readonly deleteRisk: {
readonly deletedRiskId: string; readonly deletedRiskId: string;
}; };
}; };
export type RiskListViewDeleteMutation = { export type ListRiskViewDeleteMutation = {
response: RiskListViewDeleteMutation$data; response: ListRiskViewDeleteMutation$data;
variables: RiskListViewDeleteMutation$variables; variables: ListRiskViewDeleteMutation$variables;
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
@@ -59,7 +59,7 @@ return {
], ],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "RiskListViewDeleteMutation", "name": "ListRiskViewDeleteMutation",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -84,7 +84,7 @@ return {
(v0/*: any*/) (v0/*: any*/)
], ],
"kind": "Operation", "kind": "Operation",
"name": "RiskListViewDeleteMutation", "name": "ListRiskViewDeleteMutation",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -117,16 +117,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "525011737d0920883b3942d2603dc31f", "cacheID": "d6c6ab49ae59bc29ee4b1a33c4a36181",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "RiskListViewDeleteMutation", "name": "ListRiskViewDeleteMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation RiskListViewDeleteMutation(\n $input: DeleteRiskInput!\n) {\n deleteRisk(input: $input) {\n deletedRiskId\n }\n}\n" "text": "mutation ListRiskViewDeleteMutation(\n $input: DeleteRiskInput!\n) {\n deleteRisk(input: $input) {\n deletedRiskId\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "4aee92e5abfd6733b44588bf01276560"; (node as any).hash = "0c83d35fb68cb67f5980df027c0d1051";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<ada1e6614842f2accf7bbe92a4e845a4>> * @generated SignedSource<<121c9ad6ab399476692b98d1838f70d7>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -10,21 +10,21 @@
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type RiskListViewPaginationQuery$variables = { export type ListRiskViewPaginationQuery$variables = {
after?: string | null | undefined; after?: string | null | undefined;
before?: string | null | undefined; before?: string | null | undefined;
first?: number | null | undefined; first?: number | null | undefined;
id: string; id: string;
last?: number | null | undefined; last?: number | null | undefined;
}; };
export type RiskListViewPaginationQuery$data = { export type ListRiskViewPaginationQuery$data = {
readonly node: { readonly node: {
readonly " $fragmentSpreads": FragmentRefs<"RiskListView_risks">; readonly " $fragmentSpreads": FragmentRefs<"ListRiskView_risks">;
}; };
}; };
export type RiskListViewPaginationQuery = { export type ListRiskViewPaginationQuery = {
response: RiskListViewPaginationQuery$data; response: ListRiskViewPaginationQuery$data;
variables: RiskListViewPaginationQuery$variables; variables: ListRiskViewPaginationQuery$variables;
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
@@ -107,7 +107,7 @@ return {
], ],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "RiskListViewPaginationQuery", "name": "ListRiskViewPaginationQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -120,7 +120,7 @@ return {
{ {
"args": (v6/*: any*/), "args": (v6/*: any*/),
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "RiskListView_risks" "name": "ListRiskView_risks"
} }
], ],
"storageKey": null "storageKey": null
@@ -139,7 +139,7 @@ return {
(v3/*: any*/) (v3/*: any*/)
], ],
"kind": "Operation", "kind": "Operation",
"name": "RiskListViewPaginationQuery", "name": "ListRiskViewPaginationQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -214,6 +214,13 @@ return {
"name": "residualImpact", "name": "residualImpact",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "treatment",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -308,7 +315,7 @@ return {
"args": (v6/*: any*/), "args": (v6/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "RiskListView_risks", "key": "ListRiskView_risks",
"kind": "LinkedHandle", "kind": "LinkedHandle",
"name": "risks" "name": "risks"
} }
@@ -322,16 +329,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "afcf1c15c2ed7722673da85d53acfef3", "cacheID": "402fdc7c2f504ba8640e2ecd2f8f2cb8",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "RiskListViewPaginationQuery", "name": "ListRiskViewPaginationQuery",
"operationKind": "query", "operationKind": "query",
"text": "query RiskListViewPaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...RiskListView_risks_pbnwq\n id\n }\n}\n\nfragment RiskListView_risks_pbnwq on Organization {\n risks(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n name\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n" "text": "query ListRiskViewPaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ListRiskView_risks_pbnwq\n id\n }\n}\n\nfragment ListRiskView_risks_pbnwq on Organization {\n risks(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n name\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n treatment\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
} }
}; };
})(); })();
(node as any).hash = "7da0a3d5e4fb09ce7f6b7ddf233702ab"; (node as any).hash = "a5f7d6424459d2a3b471bb0a4f0a4169";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<5301e57ef0b2621712f4c8ca693afdeb>> * @generated SignedSource<<677eff2bfb212e672f0d95b56adeebe7>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -10,22 +10,22 @@
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type RiskListViewQuery$variables = { export type ListRiskViewQuery$variables = {
after?: string | null | undefined; after?: string | null | undefined;
before?: string | null | undefined; before?: string | null | undefined;
first?: number | null | undefined; first?: number | null | undefined;
last?: number | null | undefined; last?: number | null | undefined;
organizationId: string; organizationId: string;
}; };
export type RiskListViewQuery$data = { export type ListRiskViewQuery$data = {
readonly organization: { readonly organization: {
readonly id: string; readonly id: string;
readonly " $fragmentSpreads": FragmentRefs<"RiskListView_risks">; readonly " $fragmentSpreads": FragmentRefs<"ListRiskView_risks">;
}; };
}; };
export type RiskListViewQuery = { export type ListRiskViewQuery = {
response: RiskListViewQuery$data; response: ListRiskViewQuery$data;
variables: RiskListViewQuery$variables; variables: ListRiskViewQuery$variables;
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
@@ -108,7 +108,7 @@ return {
], ],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "RiskListViewQuery", "name": "ListRiskViewQuery",
"selections": [ "selections": [
{ {
"alias": "organization", "alias": "organization",
@@ -122,7 +122,7 @@ return {
{ {
"args": (v7/*: any*/), "args": (v7/*: any*/),
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "RiskListView_risks" "name": "ListRiskView_risks"
} }
], ],
"storageKey": null "storageKey": null
@@ -141,7 +141,7 @@ return {
(v1/*: any*/) (v1/*: any*/)
], ],
"kind": "Operation", "kind": "Operation",
"name": "RiskListViewQuery", "name": "ListRiskViewQuery",
"selections": [ "selections": [
{ {
"alias": "organization", "alias": "organization",
@@ -216,6 +216,13 @@ return {
"name": "residualImpact", "name": "residualImpact",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "treatment",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -310,7 +317,7 @@ return {
"args": (v7/*: any*/), "args": (v7/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "RiskListView_risks", "key": "ListRiskView_risks",
"kind": "LinkedHandle", "kind": "LinkedHandle",
"name": "risks" "name": "risks"
} }
@@ -324,16 +331,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "56ddd15a8a41c48c01bf0be667569473", "cacheID": "fcdb0ca740c0a11d5e4961407baadffa",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "RiskListViewQuery", "name": "ListRiskViewQuery",
"operationKind": "query", "operationKind": "query",
"text": "query RiskListViewQuery(\n $organizationId: ID!\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...RiskListView_risks_pbnwq\n }\n}\n\nfragment RiskListView_risks_pbnwq on Organization {\n risks(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n name\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n" "text": "query ListRiskViewQuery(\n $organizationId: ID!\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...ListRiskView_risks_pbnwq\n }\n}\n\nfragment ListRiskView_risks_pbnwq on Organization {\n risks(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n name\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n treatment\n description\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
} }
}; };
})(); })();
(node as any).hash = "0fff20fd656047e6df52818ccf0a0f3b"; (node as any).hash = "8f1ba48e6663d5f1e473aa52b70c7a67";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<c2e3450de2b84e18c9ade3ac1bed3b69>> * @generated SignedSource<<9a0b8102088652729e5c161730fe26a9>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,8 +9,9 @@
// @ts-nocheck // @ts-nocheck
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type RiskListView_risks$data = { export type ListRiskView_risks$data = {
readonly id: string; readonly id: string;
readonly risks: { readonly risks: {
readonly __id: string; readonly __id: string;
@@ -24,6 +25,7 @@ export type RiskListView_risks$data = {
readonly name: string; readonly name: string;
readonly residualImpact: number; readonly residualImpact: number;
readonly residualLikelihood: number; readonly residualLikelihood: number;
readonly treatment: RiskTreatment;
readonly updatedAt: string; readonly updatedAt: string;
}; };
}>; }>;
@@ -34,11 +36,11 @@ export type RiskListView_risks$data = {
readonly startCursor: string | null | undefined; readonly startCursor: string | null | undefined;
}; };
}; };
readonly " $fragmentType": "RiskListView_risks"; readonly " $fragmentType": "ListRiskView_risks";
}; };
export type RiskListView_risks$key = { export type ListRiskView_risks$key = {
readonly " $data"?: RiskListView_risks$data; readonly " $data"?: ListRiskView_risks$data;
readonly " $fragmentSpreads": FragmentRefs<"RiskListView_risks">; readonly " $fragmentSpreads": FragmentRefs<"ListRiskView_risks">;
}; };
const node: ReaderFragment = (function(){ const node: ReaderFragment = (function(){
@@ -100,21 +102,21 @@ return {
"fragmentPathInResult": [ "fragmentPathInResult": [
"node" "node"
], ],
"operation": require('./RiskListViewPaginationQuery.graphql'), "operation": require('./ListRiskViewPaginationQuery.graphql'),
"identifierInfo": { "identifierInfo": {
"identifierField": "id", "identifierField": "id",
"identifierQueryVariableName": "id" "identifierQueryVariableName": "id"
} }
} }
}, },
"name": "RiskListView_risks", "name": "ListRiskView_risks",
"selections": [ "selections": [
{ {
"alias": "risks", "alias": "risks",
"args": null, "args": null,
"concreteType": "RiskConnection", "concreteType": "RiskConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "__RiskListView_risks_connection", "name": "__ListRiskView_risks_connection",
"plural": false, "plural": false,
"selections": [ "selections": [
{ {
@@ -169,6 +171,13 @@ return {
"name": "residualImpact", "name": "residualImpact",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "treatment",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -271,6 +280,6 @@ return {
}; };
})(); })();
(node as any).hash = "7da0a3d5e4fb09ce7f6b7ddf233702ab"; (node as any).hash = "a5f7d6424459d2a3b471bb0a4f0a4169";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<63841b5a52846eba02cc6d442cfd4133>> * @generated SignedSource<<cb8ffabeb71c2aa60fdef5f2abfc1f42>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,6 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
export type CreateRiskInput = { export type CreateRiskInput = {
description: string; description: string;
inherentImpact: number; inherentImpact: number;
@@ -17,6 +18,7 @@ export type CreateRiskInput = {
organizationId: string; organizationId: string;
residualImpact?: number | null | undefined; residualImpact?: number | null | undefined;
residualLikelihood?: number | null | undefined; residualLikelihood?: number | null | undefined;
treatment: RiskTreatment;
}; };
export type NewRiskViewCreateRiskMutation$variables = { export type NewRiskViewCreateRiskMutation$variables = {
connections: ReadonlyArray<string>; connections: ReadonlyArray<string>;
@@ -34,6 +36,7 @@ export type NewRiskViewCreateRiskMutation$data = {
readonly name: string; readonly name: string;
readonly residualImpact: number; readonly residualImpact: number;
readonly residualLikelihood: number; readonly residualLikelihood: number;
readonly treatment: RiskTreatment;
readonly updatedAt: string; readonly updatedAt: string;
}; };
}; };
@@ -127,6 +130,13 @@ v3 = {
"name": "residualImpact", "name": "residualImpact",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "treatment",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -213,16 +223,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "86d84d72c424807216edf39eb8f0c34f", "cacheID": "9f296661d12f36362aeecd2a1fd4aa63",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "NewRiskViewCreateRiskMutation", "name": "NewRiskViewCreateRiskMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation NewRiskViewCreateRiskMutation(\n $input: CreateRiskInput!\n) {\n createRisk(input: $input) {\n riskEdge {\n node {\n id\n name\n description\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n createdAt\n updatedAt\n }\n }\n }\n}\n" "text": "mutation NewRiskViewCreateRiskMutation(\n $input: CreateRiskInput!\n) {\n createRisk(input: $input) {\n riskEdge {\n node {\n id\n name\n description\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n treatment\n createdAt\n updatedAt\n }\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "7ad6c27c192e419839b8105eb2ca9ae7"; (node as any).hash = "7f70a20771d9f05f62e952a59c5484e3";
export default node; export default node;

View File

@@ -0,0 +1,4 @@
CREATE TYPE risk_treatment AS ENUM ('MITIGATED', 'TRANSFERRED', 'AVOIDED', 'ACCEPTED');
ALTER TABLE risks ADD COLUMN treatment risk_treatment NOT NULL DEFAULT 'MITIGATED';
ALTER TABLE risks ALTER COLUMN treatment DROP DEFAULT;

View File

@@ -32,6 +32,7 @@ type (
OrganizationID gid.GID `db:"organization_id"` OrganizationID gid.GID `db:"organization_id"`
Name string `db:"name"` Name string `db:"name"`
Description string `db:"description"` Description string `db:"description"`
Treatment RiskTreatment `db:"treatment"`
InherentLikelihood float64 `db:"inherent_likelihood"` InherentLikelihood float64 `db:"inherent_likelihood"`
InherentImpact float64 `db:"inherent_impact"` InherentImpact float64 `db:"inherent_impact"`
ResidualLikelihood float64 `db:"residual_likelihood"` ResidualLikelihood float64 `db:"residual_likelihood"`
@@ -72,9 +73,9 @@ WITH rsks AS (
SELECT SELECT
r.id, r.id,
r.organization_id, r.organization_id,
r.tenant_id,
r.name, r.name,
r.description, r.description,
r.treatment,
r.inherent_likelihood, r.inherent_likelihood,
r.inherent_impact, r.inherent_impact,
r.residual_likelihood, r.residual_likelihood,
@@ -93,6 +94,7 @@ SELECT
organization_id, organization_id,
name, name,
description, description,
treatment,
inherent_likelihood, inherent_likelihood,
inherent_impact, inherent_impact,
residual_likelihood, residual_likelihood,
@@ -137,6 +139,7 @@ SELECT
organization_id, organization_id,
name, name,
description, description,
treatment,
inherent_likelihood, inherent_likelihood,
inherent_impact, inherent_impact,
residual_likelihood, residual_likelihood,
@@ -180,6 +183,7 @@ SELECT
organization_id, organization_id,
name, name,
description, description,
treatment,
inherent_likelihood, inherent_likelihood,
inherent_impact, inherent_impact,
residual_likelihood, residual_likelihood,
@@ -217,8 +221,8 @@ func (r *Risk) Insert(
scope Scoper, scope Scoper,
) error { ) error {
q := ` q := `
INSERT INTO risks (id, tenant_id, organization_id, name, description, inherent_likelihood, inherent_impact, residual_likelihood, residual_impact, created_at, updated_at) INSERT INTO risks (id, tenant_id, organization_id, name, description, treatment, inherent_likelihood, inherent_impact, residual_likelihood, residual_impact, created_at, updated_at)
VALUES (@id, @tenant_id, @organization_id, @name, @description, @inherent_likelihood, @inherent_impact, @residual_likelihood, @residual_impact, @created_at, @updated_at) VALUES (@id, @tenant_id, @organization_id, @name, @description, @treatment, @inherent_likelihood, @inherent_impact, @residual_likelihood, @residual_impact, @created_at, @updated_at)
` `
args := pgx.StrictNamedArgs{ args := pgx.StrictNamedArgs{
@@ -227,6 +231,7 @@ VALUES (@id, @tenant_id, @organization_id, @name, @description, @inherent_likeli
"organization_id": r.OrganizationID, "organization_id": r.OrganizationID,
"name": r.Name, "name": r.Name,
"description": r.Description, "description": r.Description,
"treatment": r.Treatment,
"inherent_likelihood": r.InherentLikelihood, "inherent_likelihood": r.InherentLikelihood,
"inherent_impact": r.InherentImpact, "inherent_impact": r.InherentImpact,
"residual_likelihood": r.ResidualLikelihood, "residual_likelihood": r.ResidualLikelihood,
@@ -249,6 +254,7 @@ UPDATE risks
SET SET
name = @name, name = @name,
description = @description, description = @description,
treatment = @treatment,
inherent_likelihood = @inherent_likelihood, inherent_likelihood = @inherent_likelihood,
inherent_impact = @inherent_impact, inherent_impact = @inherent_impact,
residual_likelihood = @residual_likelihood, residual_likelihood = @residual_likelihood,
@@ -263,6 +269,7 @@ WHERE %s
"risk_id": r.ID, "risk_id": r.ID,
"name": r.Name, "name": r.Name,
"description": r.Description, "description": r.Description,
"treatment": r.Treatment,
"inherent_likelihood": r.InherentLikelihood, "inherent_likelihood": r.InherentLikelihood,
"inherent_impact": r.InherentImpact, "inherent_impact": r.InherentImpact,
"residual_likelihood": r.ResidualLikelihood, "residual_likelihood": r.ResidualLikelihood,

View File

@@ -0,0 +1,84 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package coredata
import (
"database/sql/driver"
"fmt"
)
type (
RiskTreatment string
)
const (
RiskTreatmentMitigated RiskTreatment = "MITIGATED"
RiskTreatmentAccepted RiskTreatment = "ACCEPTED"
RiskTreatmentAvoided RiskTreatment = "AVOIDED"
RiskTreatmentTransferred RiskTreatment = "TRANSFERRED"
)
func (rt RiskTreatment) MarshalText() ([]byte, error) {
return []byte(rt.String()), nil
}
func (rt *RiskTreatment) UnmarshalText(data []byte) error {
val := string(data)
switch val {
case RiskTreatmentMitigated.String():
*rt = RiskTreatmentMitigated
case RiskTreatmentAccepted.String():
*rt = RiskTreatmentAccepted
case RiskTreatmentAvoided.String():
*rt = RiskTreatmentAvoided
case RiskTreatmentTransferred.String():
*rt = RiskTreatmentTransferred
default:
return fmt.Errorf("invalid RiskTreatment value: %q", val)
}
return nil
}
func (rt RiskTreatment) String() string {
var val string
switch rt {
case RiskTreatmentMitigated:
val = "MITIGATED"
case RiskTreatmentAccepted:
val = "ACCEPTED"
case RiskTreatmentAvoided:
val = "AVOIDED"
case RiskTreatmentTransferred:
val = "TRANSFERRED"
}
return val
}
func (rt *RiskTreatment) Scan(value any) error {
val, ok := value.(string)
if !ok {
return fmt.Errorf("invalid scan source for RiskTreatment, expected string got %T", value)
}
return rt.UnmarshalText([]byte(val))
}
func (rt RiskTreatment) Value() (driver.Value, error) {
return rt.String(), nil
}

View File

@@ -34,6 +34,7 @@ type (
OrganizationID gid.GID OrganizationID gid.GID
Name string Name string
Description string Description string
Treatment coredata.RiskTreatment
InherentLikelihood float64 InherentLikelihood float64
InherentImpact float64 InherentImpact float64
ResidualLikelihood *float64 ResidualLikelihood *float64
@@ -44,6 +45,7 @@ type (
ID gid.GID ID gid.GID
Name *string Name *string
Description *string Description *string
Treatment *coredata.RiskTreatment
InherentLikelihood *float64 InherentLikelihood *float64
InherentImpact *float64 InherentImpact *float64
ResidualLikelihood *float64 ResidualLikelihood *float64
@@ -169,6 +171,7 @@ func (s RiskService) Create(
Description: req.Description, Description: req.Description,
InherentLikelihood: req.InherentLikelihood, InherentLikelihood: req.InherentLikelihood,
InherentImpact: req.InherentImpact, InherentImpact: req.InherentImpact,
Treatment: req.Treatment,
ResidualLikelihood: req.InherentLikelihood, ResidualLikelihood: req.InherentLikelihood,
ResidualImpact: req.InherentImpact, ResidualImpact: req.InherentImpact,
CreatedAt: now, CreatedAt: now,
@@ -254,6 +257,10 @@ func (s RiskService) Update(
risk.ResidualImpact = *req.ResidualImpact risk.ResidualImpact = *req.ResidualImpact
} }
if req.Treatment != nil {
risk.Treatment = *req.Treatment
}
risk.UpdatedAt = time.Now() risk.UpdatedAt = time.Now()
if err := risk.Update(ctx, conn, s.svc.scope); err != nil { if err := risk.Update(ctx, conn, s.svc.scope); err != nil {

View File

@@ -149,6 +149,26 @@ enum EvidenceType
LINK @goEnum(value: "github.com/getprobo/probo/pkg/coredata.EvidenceTypeLink") LINK @goEnum(value: "github.com/getprobo/probo/pkg/coredata.EvidenceTypeLink")
} }
enum RiskTreatment
@goModel(model: "github.com/getprobo/probo/pkg/coredata.RiskTreatment") {
MITIGATED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.RiskTreatmentMitigated"
)
ACCEPTED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.RiskTreatmentAccepted"
)
AVOIDED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.RiskTreatmentAvoided"
)
TRANSFERRED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.RiskTreatmentTransferred"
)
}
# Order Field Enums # Order Field Enums
enum UserOrderField enum UserOrderField
@goModel(model: "github.com/getprobo/probo/pkg/coredata.UserOrderField") { @goModel(model: "github.com/getprobo/probo/pkg/coredata.UserOrderField") {
@@ -608,6 +628,7 @@ type Risk implements Node {
id: ID! id: ID!
name: String! name: String!
description: String! description: String!
treatment: RiskTreatment!
inherentLikelihood: Float! inherentLikelihood: Float!
inherentImpact: Float! inherentImpact: Float!
inherentSeverity: Float! inherentSeverity: Float!
@@ -1064,6 +1085,7 @@ input CreateRiskInput {
organizationId: ID! organizationId: ID!
name: String! name: String!
description: String! description: String!
treatment: RiskTreatment!
inherentLikelihood: Float! inherentLikelihood: Float!
inherentImpact: Float! inherentImpact: Float!
residualLikelihood: Float residualLikelihood: Float
@@ -1074,6 +1096,7 @@ input UpdateRiskInput {
id: ID! id: ID!
name: String name: String
description: String description: String
treatment: RiskTreatment
inherentLikelihood: Float inherentLikelihood: Float
inherentImpact: Float inherentImpact: Float
residualLikelihood: Float residualLikelihood: Float

View File

@@ -425,6 +425,7 @@ type ComplexityRoot struct {
ResidualImpact func(childComplexity int) int ResidualImpact func(childComplexity int) int
ResidualLikelihood func(childComplexity int) int ResidualLikelihood func(childComplexity int) int
ResidualSeverity func(childComplexity int) int ResidualSeverity func(childComplexity int) int
Treatment func(childComplexity int) int
UpdatedAt func(childComplexity int) int UpdatedAt func(childComplexity int) int
} }
@@ -2338,6 +2339,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Risk.ResidualSeverity(childComplexity), true return e.complexity.Risk.ResidualSeverity(childComplexity), true
case "Risk.treatment":
if e.complexity.Risk.Treatment == nil {
break
}
return e.complexity.Risk.Treatment(childComplexity), true
case "Risk.updatedAt": case "Risk.updatedAt":
if e.complexity.Risk.UpdatedAt == nil { if e.complexity.Risk.UpdatedAt == nil {
break break
@@ -3225,6 +3233,26 @@ enum EvidenceType
LINK @goEnum(value: "github.com/getprobo/probo/pkg/coredata.EvidenceTypeLink") LINK @goEnum(value: "github.com/getprobo/probo/pkg/coredata.EvidenceTypeLink")
} }
enum RiskTreatment
@goModel(model: "github.com/getprobo/probo/pkg/coredata.RiskTreatment") {
MITIGATED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.RiskTreatmentMitigated"
)
ACCEPTED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.RiskTreatmentAccepted"
)
AVOIDED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.RiskTreatmentAvoided"
)
TRANSFERRED
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.RiskTreatmentTransferred"
)
}
# Order Field Enums # Order Field Enums
enum UserOrderField enum UserOrderField
@goModel(model: "github.com/getprobo/probo/pkg/coredata.UserOrderField") { @goModel(model: "github.com/getprobo/probo/pkg/coredata.UserOrderField") {
@@ -3684,6 +3712,7 @@ type Risk implements Node {
id: ID! id: ID!
name: String! name: String!
description: String! description: String!
treatment: RiskTreatment!
inherentLikelihood: Float! inherentLikelihood: Float!
inherentImpact: Float! inherentImpact: Float!
inherentSeverity: Float! inherentSeverity: Float!
@@ -4140,6 +4169,7 @@ input CreateRiskInput {
organizationId: ID! organizationId: ID!
name: String! name: String!
description: String! description: String!
treatment: RiskTreatment!
inherentLikelihood: Float! inherentLikelihood: Float!
inherentImpact: Float! inherentImpact: Float!
residualLikelihood: Float residualLikelihood: Float
@@ -4150,6 +4180,7 @@ input UpdateRiskInput {
id: ID! id: ID!
name: String name: String
description: String description: String
treatment: RiskTreatment
inherentLikelihood: Float inherentLikelihood: Float
inherentImpact: Float inherentImpact: Float
residualLikelihood: Float residualLikelihood: Float
@@ -16772,6 +16803,50 @@ func (ec *executionContext) fieldContext_Risk_description(_ context.Context, fie
return fc, nil return fc, nil
} }
func (ec *executionContext) _Risk_treatment(ctx context.Context, field graphql.CollectedField, obj *types.Risk) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Risk_treatment(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Treatment, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(coredata.RiskTreatment)
fc.Result = res
return ec.marshalNRiskTreatment2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Risk_treatment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Risk",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type RiskTreatment does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Risk_inherentLikelihood(ctx context.Context, field graphql.CollectedField, obj *types.Risk) (ret graphql.Marshaler) { func (ec *executionContext) _Risk_inherentLikelihood(ctx context.Context, field graphql.CollectedField, obj *types.Risk) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Risk_inherentLikelihood(ctx, field) fc, err := ec.fieldContext_Risk_inherentLikelihood(ctx, field)
if err != nil { if err != nil {
@@ -17500,6 +17575,8 @@ func (ec *executionContext) fieldContext_RiskEdge_node(_ context.Context, field
return ec.fieldContext_Risk_name(ctx, field) return ec.fieldContext_Risk_name(ctx, field)
case "description": case "description":
return ec.fieldContext_Risk_description(ctx, field) return ec.fieldContext_Risk_description(ctx, field)
case "treatment":
return ec.fieldContext_Risk_treatment(ctx, field)
case "inherentLikelihood": case "inherentLikelihood":
return ec.fieldContext_Risk_inherentLikelihood(ctx, field) return ec.fieldContext_Risk_inherentLikelihood(ctx, field)
case "inherentImpact": case "inherentImpact":
@@ -18681,6 +18758,8 @@ func (ec *executionContext) fieldContext_UpdateRiskPayload_risk(_ context.Contex
return ec.fieldContext_Risk_name(ctx, field) return ec.fieldContext_Risk_name(ctx, field)
case "description": case "description":
return ec.fieldContext_Risk_description(ctx, field) return ec.fieldContext_Risk_description(ctx, field)
case "treatment":
return ec.fieldContext_Risk_treatment(ctx, field)
case "inherentLikelihood": case "inherentLikelihood":
return ec.fieldContext_Risk_inherentLikelihood(ctx, field) return ec.fieldContext_Risk_inherentLikelihood(ctx, field)
case "inherentImpact": case "inherentImpact":
@@ -23710,7 +23789,7 @@ func (ec *executionContext) unmarshalInputCreateRiskInput(ctx context.Context, o
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"organizationId", "name", "description", "inherentLikelihood", "inherentImpact", "residualLikelihood", "residualImpact"} fieldsInOrder := [...]string{"organizationId", "name", "description", "treatment", "inherentLikelihood", "inherentImpact", "residualLikelihood", "residualImpact"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -23738,6 +23817,13 @@ func (ec *executionContext) unmarshalInputCreateRiskInput(ctx context.Context, o
return it, err return it, err
} }
it.Description = data it.Description = data
case "treatment":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("treatment"))
data, err := ec.unmarshalNRiskTreatment2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment(ctx, v)
if err != nil {
return it, err
}
it.Treatment = data
case "inherentLikelihood": case "inherentLikelihood":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inherentLikelihood")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inherentLikelihood"))
data, err := ec.unmarshalNFloat2float64(ctx, v) data, err := ec.unmarshalNFloat2float64(ctx, v)
@@ -25233,7 +25319,7 @@ func (ec *executionContext) unmarshalInputUpdateRiskInput(ctx context.Context, o
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"id", "name", "description", "inherentLikelihood", "inherentImpact", "residualLikelihood", "residualImpact"} fieldsInOrder := [...]string{"id", "name", "description", "treatment", "inherentLikelihood", "inherentImpact", "residualLikelihood", "residualImpact"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -25261,6 +25347,13 @@ func (ec *executionContext) unmarshalInputUpdateRiskInput(ctx context.Context, o
return it, err return it, err
} }
it.Description = data it.Description = data
case "treatment":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("treatment"))
data, err := ec.unmarshalORiskTreatment2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment(ctx, v)
if err != nil {
return it, err
}
it.Treatment = data
case "inherentLikelihood": case "inherentLikelihood":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inherentLikelihood")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inherentLikelihood"))
data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v) data, err := ec.unmarshalOFloat2ᚖfloat64(ctx, v)
@@ -29294,6 +29387,11 @@ func (ec *executionContext) _Risk(ctx context.Context, sel ast.SelectionSet, obj
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
case "treatment":
out.Values[i] = ec._Risk_treatment(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "inherentLikelihood": case "inherentLikelihood":
out.Values[i] = ec._Risk_inherentLikelihood(ctx, field, obj) out.Values[i] = ec._Risk_inherentLikelihood(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
@@ -32999,6 +33097,37 @@ var (
} }
) )
func (ec *executionContext) unmarshalNRiskTreatment2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment(ctx context.Context, v any) (coredata.RiskTreatment, error) {
tmp, err := graphql.UnmarshalString(v)
res := unmarshalNRiskTreatment2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment[tmp]
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNRiskTreatment2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment(ctx context.Context, sel ast.SelectionSet, v coredata.RiskTreatment) graphql.Marshaler {
res := graphql.MarshalString(marshalNRiskTreatment2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment[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 res
}
var (
unmarshalNRiskTreatment2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment = map[string]coredata.RiskTreatment{
"MITIGATED": coredata.RiskTreatmentMitigated,
"ACCEPTED": coredata.RiskTreatmentAccepted,
"AVOIDED": coredata.RiskTreatmentAvoided,
"TRANSFERRED": coredata.RiskTreatmentTransferred,
}
marshalNRiskTreatment2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment = map[coredata.RiskTreatment]string{
coredata.RiskTreatmentMitigated: "MITIGATED",
coredata.RiskTreatmentAccepted: "ACCEPTED",
coredata.RiskTreatmentAvoided: "AVOIDED",
coredata.RiskTreatmentTransferred: "TRANSFERRED",
}
)
func (ec *executionContext) unmarshalNServiceCriticality2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐServiceCriticality(ctx context.Context, v any) (coredata.ServiceCriticality, error) { func (ec *executionContext) unmarshalNServiceCriticality2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐServiceCriticality(ctx context.Context, v any) (coredata.ServiceCriticality, error) {
tmp, err := graphql.UnmarshalString(v) tmp, err := graphql.UnmarshalString(v)
res := unmarshalNServiceCriticality2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐServiceCriticality[tmp] res := unmarshalNServiceCriticality2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐServiceCriticality[tmp]
@@ -34317,6 +34446,38 @@ var (
} }
) )
func (ec *executionContext) unmarshalORiskTreatment2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment(ctx context.Context, v any) (*coredata.RiskTreatment, error) {
if v == nil {
return nil, nil
}
tmp, err := graphql.UnmarshalString(v)
res := unmarshalORiskTreatment2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment[tmp]
return &res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalORiskTreatment2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment(ctx context.Context, sel ast.SelectionSet, v *coredata.RiskTreatment) graphql.Marshaler {
if v == nil {
return graphql.Null
}
res := graphql.MarshalString(marshalORiskTreatment2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment[*v])
return res
}
var (
unmarshalORiskTreatment2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment = map[string]coredata.RiskTreatment{
"MITIGATED": coredata.RiskTreatmentMitigated,
"ACCEPTED": coredata.RiskTreatmentAccepted,
"AVOIDED": coredata.RiskTreatmentAvoided,
"TRANSFERRED": coredata.RiskTreatmentTransferred,
}
marshalORiskTreatment2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐRiskTreatment = map[coredata.RiskTreatment]string{
coredata.RiskTreatmentMitigated: "MITIGATED",
coredata.RiskTreatmentAccepted: "ACCEPTED",
coredata.RiskTreatmentAvoided: "AVOIDED",
coredata.RiskTreatmentTransferred: "TRANSFERRED",
}
)
func (ec *executionContext) unmarshalOServiceCriticality2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐServiceCriticality(ctx context.Context, v any) (*coredata.ServiceCriticality, error) { func (ec *executionContext) unmarshalOServiceCriticality2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐServiceCriticality(ctx context.Context, v any) (*coredata.ServiceCriticality, error) {
if v == nil { if v == nil {
return nil, nil return nil, nil

View File

@@ -48,6 +48,7 @@ func NewRisk(r *coredata.Risk) *Risk {
ID: r.ID, ID: r.ID,
Name: r.Name, Name: r.Name,
Description: r.Description, Description: r.Description,
Treatment: r.Treatment,
InherentLikelihood: r.InherentLikelihood, InherentLikelihood: r.InherentLikelihood,
InherentImpact: r.InherentImpact, InherentImpact: r.InherentImpact,
InherentSeverity: r.InherentSeverity(), InherentSeverity: r.InherentSeverity(),

View File

@@ -150,6 +150,7 @@ type CreateRiskInput struct {
OrganizationID gid.GID `json:"organizationId"` OrganizationID gid.GID `json:"organizationId"`
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description"`
Treatment coredata.RiskTreatment `json:"treatment"`
InherentLikelihood float64 `json:"inherentLikelihood"` InherentLikelihood float64 `json:"inherentLikelihood"`
InherentImpact float64 `json:"inherentImpact"` InherentImpact float64 `json:"inherentImpact"`
ResidualLikelihood *float64 `json:"residualLikelihood,omitempty"` ResidualLikelihood *float64 `json:"residualLikelihood,omitempty"`
@@ -557,6 +558,7 @@ type Risk struct {
ID gid.GID `json:"id"` ID gid.GID `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description"`
Treatment coredata.RiskTreatment `json:"treatment"`
InherentLikelihood float64 `json:"inherentLikelihood"` InherentLikelihood float64 `json:"inherentLikelihood"`
InherentImpact float64 `json:"inherentImpact"` InherentImpact float64 `json:"inherentImpact"`
InherentSeverity float64 `json:"inherentSeverity"` InherentSeverity float64 `json:"inherentSeverity"`
@@ -683,6 +685,7 @@ type UpdateRiskInput struct {
ID gid.GID `json:"id"` ID gid.GID `json:"id"`
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
Treatment *coredata.RiskTreatment `json:"treatment,omitempty"`
InherentLikelihood *float64 `json:"inherentLikelihood,omitempty"` InherentLikelihood *float64 `json:"inherentLikelihood,omitempty"`
InherentImpact *float64 `json:"inherentImpact,omitempty"` InherentImpact *float64 `json:"inherentImpact,omitempty"`
ResidualLikelihood *float64 `json:"residualLikelihood,omitempty"` ResidualLikelihood *float64 `json:"residualLikelihood,omitempty"`

View File

@@ -726,6 +726,7 @@ func (r *mutationResolver) CreateRisk(ctx context.Context, input types.CreateRis
OrganizationID: input.OrganizationID, OrganizationID: input.OrganizationID,
Name: input.Name, Name: input.Name,
Description: input.Description, Description: input.Description,
Treatment: input.Treatment,
InherentLikelihood: input.InherentLikelihood, InherentLikelihood: input.InherentLikelihood,
InherentImpact: input.InherentImpact, InherentImpact: input.InherentImpact,
ResidualLikelihood: input.ResidualLikelihood, ResidualLikelihood: input.ResidualLikelihood,
@@ -751,6 +752,7 @@ func (r *mutationResolver) UpdateRisk(ctx context.Context, input types.UpdateRis
ID: input.ID, ID: input.ID,
Name: input.Name, Name: input.Name,
Description: input.Description, Description: input.Description,
Treatment: input.Treatment,
InherentLikelihood: input.InherentLikelihood, InherentLikelihood: input.InherentLikelihood,
InherentImpact: input.InherentImpact, InherentImpact: input.InherentImpact,
ResidualLikelihood: input.ResidualLikelihood, ResidualLikelihood: input.ResidualLikelihood,
@@ -1591,36 +1593,3 @@ type taskResolver struct{ *Resolver }
type vendorResolver struct{ *Resolver } type vendorResolver struct{ *Resolver }
type vendorComplianceReportResolver struct{ *Resolver } type vendorComplianceReportResolver struct{ *Resolver }
type viewerResolver struct{ *Resolver } type viewerResolver struct{ *Resolver }
// !!! WARNING !!!
// The code below was going to be deleted when updating resolvers. It has been copied here so you have
// one last chance to move it out of harms way if you want. There are two reasons this happens:
// - When renaming or deleting a resolver the old code will be put in here. You can safely delete
// it when you're done.
// - You have helper methods in this file. Move them out to keep these resolver files clean.
/*
func (r *mutationResolver) CreateRiskControlMapping(ctx context.Context, input types.CreateRiskControlMappingInput) (*types.CreateRiskControlMappingPayload, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, input.RiskID.TenantID())
err := svc.Risks.CreateControlMapping(ctx, input.RiskID, input.ControlID)
if err != nil {
panic(fmt.Errorf("cannot create risk control mapping: %w", err))
}
return &types.CreateRiskControlMappingPayload{
Success: true,
}, nil
}
func (r *mutationResolver) DeleteRiskControlMapping(ctx context.Context, input types.DeleteRiskControlMappingInput) (*types.DeleteRiskControlMappingPayload, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, input.RiskID.TenantID())
err := svc.Risks.DeleteControlMapping(ctx, input.RiskID, input.ControlID)
if err != nil {
panic(fmt.Errorf("cannot delete risk control mapping: %w", err))
}
return &types.DeleteRiskControlMappingPayload{
Success: true,
}, nil
}
*/