Add categories on risk

Signed-off-by: Antoine Bouchardy <antoine@getprobo.com>
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Antoine Bouchardy
2025-04-19 15:19:48 -07:00
committed by Bryan Frimin
parent 09fb70d75f
commit b137ec6bdf
20 changed files with 677 additions and 244 deletions

View File

@@ -46,6 +46,7 @@ const editRiskViewQuery = graphql`
id
name
description
category
inherentLikelihood
inherentImpact
residualLikelihood
@@ -71,6 +72,7 @@ const updateRiskMutation = graphql`
id
name
description
category
inherentLikelihood
inherentImpact
residualLikelihood
@@ -104,6 +106,7 @@ function EditRiskViewContent({
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [category, setCategory] = useState("");
const [inherentLikelihood, setInherentLikelihood] = useState<number>(3);
const [inherentImpact, setInherentImpact] = useState<number>(3);
const [residualLikelihood, setResidualLikelihood] = useState<number>(3);
@@ -120,6 +123,7 @@ function EditRiskViewContent({
if (risk) {
setName(risk.name || "");
setDescription(risk.description || "");
setCategory(risk.category || "");
// Set values directly as integers
setInherentLikelihood(risk.inherentLikelihood || 3);
setInherentImpact(risk.inherentImpact || 3);
@@ -148,6 +152,7 @@ function EditRiskViewContent({
id: riskId!,
name,
description,
category,
inherentLikelihood,
inherentImpact,
residualLikelihood,
@@ -203,6 +208,17 @@ function EditRiskViewContent({
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
<div className="space-y-2">
<Label htmlFor="category">Category</Label>
<Input
id="category"
placeholder="Risk category"
value={category}
onChange={(e) => setCategory(e.target.value)}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="name">Name</Label>
<Input

View File

@@ -16,6 +16,7 @@ import {
useTransition,
} from "react";
import type { ListRiskViewQuery } from "./__generated__/ListRiskViewQuery.graphql";
import type { RiskTreatment } from "./__generated__/ListRiskView_risks.graphql";
import { useParams, useSearchParams } from "react-router";
import { PageTemplate } from "@/components/PageTemplate";
import { RiskViewSkeleton } from "./ListRiskPage";
@@ -84,8 +85,20 @@ const listRiskViewFragment = graphql`
residualImpact
treatment
description
category
createdAt
updatedAt
owner {
id
fullName
}
mesures(first: 1) {
edges {
node {
category
}
}
}
}
}
pageInfo {
@@ -197,6 +210,31 @@ const emptyRiskMatrixColors = {
high: "bg-red-50 text-black",
};
type RiskNode = {
readonly id: string;
readonly name: string;
readonly inherentLikelihood: number;
readonly inherentImpact: number;
readonly residualLikelihood: number;
readonly residualImpact: number;
readonly treatment: RiskTreatment;
readonly description: string;
readonly category: string;
readonly createdAt: string;
readonly updatedAt: string;
readonly owner: {
readonly id: string;
readonly fullName: string;
} | null;
readonly mesures: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
};
}>;
};
};
// Risk Matrix Component
function RiskMatrix({
risks,
@@ -676,17 +714,23 @@ function ListRiskViewContent({
<table className="w-full caption-bottom text-sm">
<thead className="[&_tr]:border-b">
<tr className="border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg">
<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/6">
Category
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/3">
Name
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/6">
Inherent
</th>
<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
Residual
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/6">
Residual Severity
Owner
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-[120px]">
Action
@@ -697,7 +741,7 @@ function ListRiskViewContent({
{risks.length === 0 ? (
<tr className="border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg">
<td
colSpan={5}
colSpan={7}
className="text-center p-4 align-middle text-tertiary"
>
No risks found. Create a new risk to get started.
@@ -709,7 +753,15 @@ function ListRiskViewContent({
key={risk.id}
className="border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg cursor-pointer"
>
<td className="p-0 align-middle font-medium w-1/2">
<td className="p-0 align-middle w-1/6">
<Link
to={`/organizations/${organizationId}/risks/${risk.id}`}
className="block p-4 h-full w-full"
>
{risk.category}
</Link>
</td>
<td className="p-0 align-middle font-medium w-1/3">
<Link
to={`/organizations/${organizationId}/risks/${risk.id}`}
className="block p-4 h-full w-full"
@@ -717,14 +769,6 @@ function ListRiskViewContent({
{risk.name}
</Link>
</td>
<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
to={`/organizations/${organizationId}/risks/${risk.id}`}
@@ -734,23 +778,15 @@ function ListRiskViewContent({
className="px-2 py-0.5 text-xs rounded-full font-medium inline-block"
style={{
backgroundColor:
risk.inherentLikelihood *
risk.inherentImpact >=
20
risk.inherentLikelihood * risk.inherentImpact >= 20
? "#ef4444"
: risk.inherentLikelihood *
risk.inherentImpact >=
12
: risk.inherentLikelihood * risk.inherentImpact >= 12
? "#f59e0b"
: risk.inherentLikelihood *
risk.inherentImpact >=
5
: risk.inherentLikelihood * risk.inherentImpact >= 5
? "#10b981"
: "#94a3b8",
color:
risk.inherentLikelihood *
risk.inherentImpact >=
12
risk.inherentLikelihood * risk.inherentImpact >= 12
? "white"
: "inherit",
}}
@@ -762,6 +798,14 @@ function ListRiskViewContent({
</span>
</Link>
</td>
<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
to={`/organizations/${organizationId}/risks/${risk.id}`}
@@ -772,23 +816,15 @@ function ListRiskViewContent({
className="px-2 py-0.5 text-xs rounded-full font-medium inline-block"
style={{
backgroundColor:
risk.residualLikelihood *
risk.residualImpact >=
20
risk.residualLikelihood * risk.residualImpact >= 20
? "#ef4444"
: risk.residualLikelihood *
risk.residualImpact >=
12
: risk.residualLikelihood * risk.residualImpact >= 12
? "#f59e0b"
: risk.residualLikelihood *
risk.residualImpact >=
5
: risk.residualLikelihood * risk.residualImpact >= 5
? "#10b981"
: "#94a3b8",
color:
risk.residualLikelihood *
risk.residualImpact >=
12
risk.residualLikelihood * risk.residualImpact >= 12
? "white"
: "inherit",
}}
@@ -796,14 +832,21 @@ function ListRiskViewContent({
{riskScoreToSeverity(
risk.residualLikelihood * risk.residualImpact
)}{" "}
({risk.residualLikelihood * risk.residualImpact}
)
({risk.residualLikelihood * risk.residualImpact})
</span>
) : (
"Not set"
)}
</Link>
</td>
<td className="p-0 align-middle w-1/6">
<Link
to={`/organizations/${organizationId}/risks/${risk.id}`}
className="block p-4 h-full w-full"
>
{risk.owner?.fullName || "Unassigned"}
</Link>
</td>
<td className="p-4 align-middle w-[120px]">
<div className="flex">
<Button

View File

@@ -30,7 +30,7 @@ import {
} from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import PeopleSelector from "@/components/PeopleSelector";
import { User } from "lucide-react";
import { User, Loader2 } from "lucide-react";
import { Suspense } from "react";
import type { NewRiskViewQuery } from "./__generated__/NewRiskViewQuery.graphql";
@@ -43,6 +43,7 @@ interface RiskTemplate {
likelihood: number;
recommendedTreatment: string;
}[];
category: string;
}
const newRiskQuery = graphql`
@@ -64,6 +65,7 @@ const createRiskMutation = graphql`
id
name
description
category
inherentLikelihood
inherentImpact
residualLikelihood
@@ -95,14 +97,45 @@ function NewRiskForm({
const [ownerId, setOwnerId] = useState<string | null>(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const [selectedTemplate, setSelectedTemplate] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string>("");
const [riskTemplates, setRiskTemplates] = useState<RiskTemplate[]>([]);
const [ownerError, setOwnerError] = useState<string>("");
const [isLoadingTemplates, setIsLoadingTemplates] = useState(true);
const { toast } = useToast();
const [createRisk, isInFlight] = useMutation(createRiskMutation);
// Get unique categories from risk templates
const categories = Array.from(new Set(riskTemplates.map(template => template.category)));
// Filter risks by selected category
const filteredRisks = riskTemplates.filter(template =>
!selectedCategory || template.category === selectedCategory
).map(template => ({
...template,
originalIndex: riskTemplates.findIndex(t => t.name === template.name && t.description === template.description)
}));
// Handle category selection
const selectCategory = (category: string) => {
setSelectedCategory(category);
// Only reset template if we're changing categories
if (selectedCategory !== category) {
setSelectedTemplate("");
}
// Focus on the risk dropdown after a short delay to ensure it's rendered
setTimeout(() => {
const selectTrigger = document.getElementById('template');
if (selectTrigger) {
selectTrigger.focus();
}
}, 0);
};
useEffect(() => {
const loadRiskTemplates = async () => {
try {
setIsLoadingTemplates(true);
const response = await fetch("/data/risks/risks.json");
const data = await response.json();
setRiskTemplates(data);
@@ -113,6 +146,8 @@ function NewRiskForm({
description: "Failed to load risk templates. Please try again.",
variant: "destructive",
});
} finally {
setIsLoadingTemplates(false);
}
};
@@ -135,33 +170,24 @@ function NewRiskForm({
return;
}
const template = riskTemplates[parseInt(templateId)];
const selectedIndex = parseInt(templateId);
const template = riskTemplates[selectedIndex];
if (template) {
setName(template.name);
setDescription(template.description);
// 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(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) {
setTreatment(template.variations[0].recommendedTreatment.toUpperCase());
}
setTreatment("MITIGATED");
}
};
// Clear error when owner is selected
const handleOwnerSelect = (id: string | null) => {
setOwnerId(id);
setOwnerError("");
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
let hasError = false;
if (!name.trim()) {
toast({
@@ -169,6 +195,15 @@ function NewRiskForm({
description: "Please enter a name for the risk.",
variant: "destructive",
});
hasError = true;
}
if (!ownerId) {
setOwnerError("Please select a risk owner");
hasError = true;
}
if (hasError) {
return;
}
@@ -178,6 +213,7 @@ function NewRiskForm({
organizationId: organizationId!,
name,
description,
category: selectedCategory,
inherentLikelihood,
inherentImpact,
residualLikelihood,
@@ -242,27 +278,52 @@ function NewRiskForm({
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
<div className="space-y-2">
<Label htmlFor="template">Risk Template</Label>
<Select
value={selectedTemplate}
onValueChange={handleTemplateChange}
>
<SelectTrigger id="template">
<SelectValue placeholder="Select a risk template" />
</SelectTrigger>
<SelectContent className="max-h-[300px] overflow-y-auto">
<SelectItem value="none">Select a template</SelectItem>
{riskTemplates.map((template, index) => (
<SelectItem key={index} value={index.toString()}>
{template.name}
</SelectItem>
))}
</SelectContent>
</Select>
<p className="text-sm text-tertiary">
Select a template to prefill the form or create a custom risk.
</p>
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="template">Risk Template</Label>
<div className="flex flex-wrap gap-2 mb-2">
{isLoadingTemplates ? (
<div className="flex items-center gap-2 text-tertiary">
<Loader2 className="h-4 w-4 animate-spin" />
<span>Loading categories...</span>
</div>
) : (
categories.map((category) => (
<Button
key={category}
variant={selectedCategory === category ? "default" : "outline"}
size="sm"
onClick={() => selectCategory(category)}
className="rounded-full"
>
{category}
</Button>
))
)}
</div>
<Select
value={selectedTemplate}
onValueChange={handleTemplateChange}
>
<SelectTrigger id="template">
<SelectValue placeholder="Select a risk template" />
</SelectTrigger>
<SelectContent className="max-h-[300px] overflow-y-auto">
<SelectItem value="none">Select a template</SelectItem>
{filteredRisks.map((template) => (
<SelectItem
key={template.originalIndex}
value={template.originalIndex.toString()}
>
{template.name}
</SelectItem>
))}
</SelectContent>
</Select>
<p className="text-sm text-tertiary">
Select a risk template to prefill the form or create a custom risk.
</p>
</div>
</div>
<div className="space-y-2">
@@ -291,14 +352,18 @@ function NewRiskForm({
<Label htmlFor="owner" className="flex items-center gap-2">
<User className="h-4 w-4" />
Risk Owner
<span className="text-destructive">*</span>
</Label>
<PeopleSelector
organizationRef={data.organization}
selectedPersonId={ownerId}
onSelect={setOwnerId}
placeholder="Select risk owner (optional)"
required={false}
onSelect={handleOwnerSelect}
placeholder="Select risk owner"
required={true}
/>
{ownerError && (
<p className="text-sm text-destructive mt-1">Please select a risk owner</p>
)}
</div>
<div className="grid grid-cols-2 gap-4">

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<fc9fe251d08f57babcab4e395b6c0aec>>
* @generated SignedSource<<028d64b4c532fdc04b77de62bd70311b>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -20,6 +20,7 @@ export type EditRiskViewQuery$data = {
readonly " $fragmentSpreads": FragmentRefs<"PeopleSelector_organization">;
};
readonly risk: {
readonly category?: string;
readonly description?: string;
readonly id?: string;
readonly inherentImpact?: number;
@@ -82,45 +83,52 @@ v6 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "inherentLikelihood",
"name": "category",
"storageKey": null
},
v7 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "inherentImpact",
"name": "inherentLikelihood",
"storageKey": null
},
v8 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "residualLikelihood",
"name": "inherentImpact",
"storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "residualImpact",
"name": "residualLikelihood",
"storageKey": null
},
v10 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "treatment",
"name": "residualImpact",
"storageKey": null
},
v11 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"name": "treatment",
"storageKey": null
},
v12 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
v13 = {
"alias": null,
"args": null,
"concreteType": "People",
@@ -129,25 +137,25 @@ v12 = {
"plural": false,
"selections": [
(v3/*: any*/),
(v11/*: any*/)
(v12/*: any*/)
],
"storageKey": null
},
v13 = [
v14 = [
{
"kind": "Variable",
"name": "id",
"variableName": "organizationId"
}
],
v14 = {
v15 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v15 = [
v16 = [
{
"kind": "Literal",
"name": "first",
@@ -191,7 +199,8 @@ return {
(v8/*: any*/),
(v9/*: any*/),
(v10/*: any*/),
(v12/*: any*/)
(v11/*: any*/),
(v13/*: any*/)
],
"type": "Risk",
"abstractKey": null
@@ -201,7 +210,7 @@ return {
},
{
"alias": "organization",
"args": (v13/*: any*/),
"args": (v14/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
@@ -236,7 +245,7 @@ return {
"name": "node",
"plural": false,
"selections": [
(v14/*: any*/),
(v15/*: any*/),
(v3/*: any*/),
{
"kind": "InlineFragment",
@@ -248,7 +257,8 @@ return {
(v8/*: any*/),
(v9/*: any*/),
(v10/*: any*/),
(v12/*: any*/)
(v11/*: any*/),
(v13/*: any*/)
],
"type": "Risk",
"abstractKey": null
@@ -258,20 +268,20 @@ return {
},
{
"alias": "organization",
"args": (v13/*: any*/),
"args": (v14/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v14/*: any*/),
(v15/*: any*/),
(v3/*: any*/),
{
"kind": "InlineFragment",
"selections": [
{
"alias": null,
"args": (v15/*: any*/),
"args": (v16/*: any*/),
"concreteType": "PeopleConnection",
"kind": "LinkedField",
"name": "peoples",
@@ -294,7 +304,7 @@ return {
"plural": false,
"selections": [
(v3/*: any*/),
(v11/*: any*/),
(v12/*: any*/),
{
"alias": null,
"args": null,
@@ -302,7 +312,7 @@ return {
"name": "primaryEmailAddress",
"storageKey": null
},
(v14/*: any*/)
(v15/*: any*/)
],
"storageKey": null
},
@@ -346,7 +356,7 @@ return {
},
{
"alias": null,
"args": (v15/*: any*/),
"args": (v16/*: any*/),
"filters": [
"orderBy"
],
@@ -365,16 +375,16 @@ return {
]
},
"params": {
"cacheID": "5d84f3bb7bcc5123adcf8fe776baea73",
"cacheID": "cdae5e406ef1b70c372791cc998e82ac",
"id": null,
"metadata": {},
"name": "EditRiskViewQuery",
"operationKind": "query",
"text": "query EditRiskViewQuery(\n $riskId: ID!\n $organizationId: 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 owner {\n id\n fullName\n }\n }\n id\n }\n organization: node(id: $organizationId) {\n __typename\n ...PeopleSelector_organization\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
"text": "query EditRiskViewQuery(\n $riskId: ID!\n $organizationId: ID!\n) {\n risk: node(id: $riskId) {\n __typename\n ... on Risk {\n id\n name\n description\n category\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n treatment\n owner {\n id\n fullName\n }\n }\n id\n }\n organization: node(id: $organizationId) {\n __typename\n ...PeopleSelector_organization\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
}
};
})();
(node as any).hash = "616261dd100b7243f955cd94e39e7ac9";
(node as any).hash = "3ea38c607c8a1d3f18eaa964476f1529";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<feef659391195d68121d9db49de0ffc6>>
* @generated SignedSource<<5a97a0d2387d66d74de35ec9b5bc86cf>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -11,6 +11,7 @@
import { ConcreteRequest } from 'relay-runtime';
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
export type UpdateRiskInput = {
category?: string | null | undefined;
description?: string | null | undefined;
id: string;
inherentImpact?: number | null | undefined;
@@ -27,6 +28,7 @@ export type EditRiskViewUpdateRiskMutation$variables = {
export type EditRiskViewUpdateRiskMutation$data = {
readonly updateRisk: {
readonly risk: {
readonly category: string;
readonly description: string;
readonly id: string;
readonly inherentImpact: number;
@@ -101,6 +103,13 @@ v2 = [
"name": "description",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
},
{
"alias": null,
"args": null,
@@ -187,16 +196,16 @@ return {
"selections": (v2/*: any*/)
},
"params": {
"cacheID": "31fc731869a56e3bdc73aae7c114a385",
"cacheID": "a640c5be0a7614478f2d229154d9206a",
"id": null,
"metadata": {},
"name": "EditRiskViewUpdateRiskMutation",
"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 treatment\n updatedAt\n owner {\n id\n fullName\n }\n }\n }\n}\n"
"text": "mutation EditRiskViewUpdateRiskMutation(\n $input: UpdateRiskInput!\n) {\n updateRisk(input: $input) {\n risk {\n id\n name\n description\n category\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n treatment\n updatedAt\n owner {\n id\n fullName\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "777e70d85a1de9db8b625b1f5b109c7e";
(node as any).hash = "7f4cfbd3d1e3fa396b7ffbcac1e12b0a";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<121c9ad6ab399476692b98d1838f70d7>>
* @generated SignedSource<<f0234c8da839e9d7babc696edb1171aa>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -95,6 +95,13 @@ v8 = {
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
};
return {
"fragment": {
@@ -228,6 +235,7 @@ return {
"name": "description",
"storageKey": null
},
(v9/*: any*/),
{
"alias": null,
"args": null,
@@ -242,6 +250,66 @@ return {
"name": "updatedAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "owner",
"plural": false,
"selections": [
(v8/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": [
{
"kind": "Literal",
"name": "first",
"value": 1
}
],
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "mesures",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v9/*: any*/),
(v8/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "mesures(first:1)"
},
(v7/*: any*/)
],
"storageKey": null
@@ -329,16 +397,16 @@ return {
]
},
"params": {
"cacheID": "402fdc7c2f504ba8640e2ecd2f8f2cb8",
"cacheID": "398efd65ce3f24d13b357e8cf32c4f6e",
"id": null,
"metadata": {},
"name": "ListRiskViewPaginationQuery",
"operationKind": "query",
"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"
"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 category\n createdAt\n updatedAt\n owner {\n id\n fullName\n }\n mesures(first: 1) {\n edges {\n node {\n category\n id\n }\n }\n }\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 = "a5f7d6424459d2a3b471bb0a4f0a4169";
(node as any).hash = "3fc46af4f252617f4547c988184bb168";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<677eff2bfb212e672f0d95b56adeebe7>>
* @generated SignedSource<<d4fc01f5c38bce1054b2198af7e021f2>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -96,6 +96,13 @@ v8 = {
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
};
return {
"fragment": {
@@ -230,6 +237,7 @@ return {
"name": "description",
"storageKey": null
},
(v9/*: any*/),
{
"alias": null,
"args": null,
@@ -244,6 +252,66 @@ return {
"name": "updatedAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "owner",
"plural": false,
"selections": [
(v6/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": [
{
"kind": "Literal",
"name": "first",
"value": 1
}
],
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "mesures",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v9/*: any*/),
(v6/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "mesures(first:1)"
},
(v8/*: any*/)
],
"storageKey": null
@@ -331,12 +399,12 @@ return {
]
},
"params": {
"cacheID": "fcdb0ca740c0a11d5e4961407baadffa",
"cacheID": "519139d7f492b8d719abf1b0e788853a",
"id": null,
"metadata": {},
"name": "ListRiskViewQuery",
"operationKind": "query",
"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"
"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 category\n createdAt\n updatedAt\n owner {\n id\n fullName\n }\n mesures(first: 1) {\n edges {\n node {\n category\n id\n }\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
}
};
})();

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<9a0b8102088652729e5c161730fe26a9>>
* @generated SignedSource<<1dd4443afe99bdd114d082b0d175776d>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -17,12 +17,24 @@ export type ListRiskView_risks$data = {
readonly __id: string;
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
readonly createdAt: string;
readonly description: string;
readonly id: string;
readonly inherentImpact: number;
readonly inherentLikelihood: number;
readonly mesures: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
};
}>;
};
readonly name: string;
readonly owner: {
readonly fullName: string;
readonly id: string;
} | null | undefined;
readonly residualImpact: number;
readonly residualLikelihood: number;
readonly treatment: RiskTreatment;
@@ -53,6 +65,13 @@ v1 = {
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
};
return {
"argumentDefinitions": [
@@ -185,6 +204,7 @@ return {
"name": "description",
"storageKey": null
},
(v2/*: any*/),
{
"alias": null,
"args": null,
@@ -199,6 +219,65 @@ return {
"name": "updatedAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "owner",
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": [
{
"kind": "Literal",
"name": "first",
"value": 1
}
],
"concreteType": "MesureConnection",
"kind": "LinkedField",
"name": "mesures",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "MesureEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Mesure",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "mesures(first:1)"
},
{
"alias": null,
"args": null,
@@ -280,6 +359,6 @@ return {
};
})();
(node as any).hash = "a5f7d6424459d2a3b471bb0a4f0a4169";
(node as any).hash = "3fc46af4f252617f4547c988184bb168";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<f5de62a6351fe2691ad8aff671be4aad>>
* @generated SignedSource<<5b015e6ca9ba83b884026cca65dcdc1c>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -11,6 +11,7 @@
import { ConcreteRequest } from 'relay-runtime';
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
export type CreateRiskInput = {
category: string;
description: string;
inherentImpact: number;
inherentLikelihood: number;
@@ -29,6 +30,7 @@ export type NewRiskViewCreateRiskMutation$data = {
readonly createRisk: {
readonly riskEdge: {
readonly node: {
readonly category: string;
readonly createdAt: string;
readonly description: string;
readonly id: string;
@@ -103,6 +105,13 @@ v3 = {
"name": "description",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
},
{
"alias": null,
"args": null,
@@ -224,16 +233,16 @@ return {
]
},
"params": {
"cacheID": "9f296661d12f36362aeecd2a1fd4aa63",
"cacheID": "c568f60a75535b2597f860405b4eba79",
"id": null,
"metadata": {},
"name": "NewRiskViewCreateRiskMutation",
"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 treatment\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 category\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n treatment\n createdAt\n updatedAt\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "7f70a20771d9f05f62e952a59c5484e3";
(node as any).hash = "bcacfff0f67ad5cf0ecbfe26c0a5b6f9";
export default node;

1
go.mod
View File

@@ -50,7 +50,6 @@ require (
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect

50
go.sum
View File

@@ -1,27 +1,21 @@
gearno.de/ref v0.0.0-20221013162104-a522beda40f4 h1:tS3oPI89+Y33vZRR/DwbNTewefycz1UzEeDYgMKNdzY=
gearno.de/ref v0.0.0-20221013162104-a522beda40f4/go.mod h1:yMxgb+Im8XTCLBBgpy8p5xE6/OaWkKyfypNd3HPQpLw=
github.com/99designs/gqlgen v0.17.66 h1:2/SRc+h3115fCOZeTtsqrB5R5gTGm+8qCAwcrZa+CXA=
github.com/99designs/gqlgen v0.17.66/go.mod h1:gucrb5jK5pgCKzAGuOMMVU9C8PnReecHEHd2UxLQwCg=
github.com/99designs/gqlgen v0.17.70 h1:xgLIgQuG+Q2L/AE9cW595CT7xCWCe/bpPIFGSfsGSGs=
github.com/99designs/gqlgen v0.17.70/go.mod h1:fvCiqQAu2VLhKXez2xFvLmE47QgAPf/KTPN5XQ4rsHQ=
github.com/PuerkitoBio/goquery v1.9.3 h1:mpJr/ikUA9/GNJB/DBZcGeFDXUtosHRyRrwh7KGdTG0=
github.com/PuerkitoBio/goquery v1.9.3/go.mod h1:1ndLHPdTz+DyQPICCWYlYQMPl0oXZj0G6D4LCYA6u4U=
github.com/PuerkitoBio/goquery v1.10.2 h1:7fh2BdHcG6VFZsK7toXBT/Bh1z5Wmy8Q9MV9HqT2AM8=
github.com/PuerkitoBio/goquery v1.10.2/go.mod h1:0guWGjcLu9AYC7C1GHnpysHy056u9aEkUHwhdnePMCU=
github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM=
github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14=
github.com/aws/aws-sdk-go-v2/credentials v1.17.62 h1:fvtQY3zFzYJ9CfixuAQ96IxDrBajbBWGqjNTCa79ocU=
github.com/aws/aws-sdk-go-v2/credentials v1.17.62/go.mod h1:ElETBxIQqcxej++Cs8GyPBbgMys5DgQPTwo7cUPDKt8=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
@@ -34,16 +28,12 @@ github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcu
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.6.2 h1:t/gZFyrijKuSU0elA5kRngP/oU3mc0I+Dvp8HwRE4c0=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.6.2/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0 h1:lguz0bmOoGzozP9XfRJR1QIayEYo+2vP/No3OfLF0pU=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.0/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA=
github.com/aws/aws-sdk-go-v2/service/s3 v1.78.1 h1:1M0gSbyP6q06gl3384wpoKPaH9G16NPqZFieEhLboSU=
github.com/aws/aws-sdk-go-v2/service/s3 v1.78.1/go.mod h1:4qzsZSzB/KiX2EzDjs9D7A8rI/WGJxZceVJIHqtJjIU=
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2 h1:tWUG+4wZqdMl/znThEk9tcCy8tTMxq8dW0JTgamohrY=
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.2/go.mod h1:U5SNqwhXB3Xe6F47kXvWihPl/ilGaEDe8HD/50Z9wxc=
github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=
@@ -95,8 +85,6 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.3 h1:PO1wNKj/bTAwxSJnO1Z4Ai8j4magtqg2SLNjEDzcXQo=
github.com/jackc/pgx/v5 v5.7.3/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
@@ -114,8 +102,6 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
@@ -126,12 +112,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
@@ -139,8 +121,6 @@ github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9
github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM=
github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
@@ -160,12 +140,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/vektah/gqlparser/v2 v2.5.23 h1:PurJ9wpgEVB7tty1seRUwkIDa/QH5RzkzraiKIjKLfA=
github.com/vektah/gqlparser/v2 v2.5.23/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
github.com/vektah/gqlparser/v2 v2.5.25 h1:FmWtFEa+invTIzWlWK6Vk7BVEZU/97QBzeI8Z1JjGt8=
github.com/vektah/gqlparser/v2 v2.5.25/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
@@ -196,48 +172,26 @@ go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 h1:IFnXJq3UPB3oBREOodn1v1aGQeZYQclEmvWRMN0PSsY=
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:c8q6Z6OCqnfVIqUFJkCzKcrj8eCvUrz+K4KRzSTuANg=
google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e h1:UdXH7Kzbj+Vzastr5nVfccbmFsmYNygVLSPk1pEfDoY=
google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e/go.mod h1:085qFyf2+XaZlRdCgKNCIZ3afY2p4HHZdoIRpId8F4A=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e h1:ztQaXfzEXTmCBvbtWYRhJxW+0iJcz2qXfd38/e9l7bA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -0,0 +1,2 @@
ALTER TABLE risks ADD COLUMN category TEXT NOT NULL DEFAULT 'Other';
ALTER TABLE risks ALTER COLUMN category DROP DEFAULT;

View File

@@ -32,6 +32,7 @@ type (
OrganizationID gid.GID `db:"organization_id"`
Name string `db:"name"`
Description string `db:"description"`
Category string `db:"category"`
Treatment RiskTreatment `db:"treatment"`
OwnerID *gid.GID `db:"owner_id"`
InherentLikelihood int `db:"inherent_likelihood"`
@@ -76,6 +77,7 @@ WITH rsks AS (
r.organization_id,
r.name,
r.description,
r.category,
r.owner_id,
r.treatment,
r.inherent_likelihood,
@@ -96,6 +98,7 @@ SELECT
organization_id,
name,
description,
category,
owner_id,
treatment,
inherent_likelihood,
@@ -148,6 +151,7 @@ SELECT
inherent_impact,
residual_likelihood,
residual_impact,
category,
created_at,
updated_at
FROM risks
@@ -187,6 +191,7 @@ SELECT
organization_id,
name,
description,
category,
owner_id,
treatment,
inherent_likelihood,
@@ -226,8 +231,8 @@ func (r *Risk) Insert(
scope Scoper,
) error {
q := `
INSERT INTO risks (id, tenant_id, organization_id, name, description, owner_id, treatment, inherent_likelihood, inherent_impact, residual_likelihood, residual_impact, created_at, updated_at)
VALUES (@id, @tenant_id, @organization_id, @name, @description, @owner_id, @treatment, @inherent_likelihood, @inherent_impact, @residual_likelihood, @residual_impact, @created_at, @updated_at)
INSERT INTO risks (id, tenant_id, organization_id, name, description, category, owner_id, treatment, inherent_likelihood, inherent_impact, residual_likelihood, residual_impact, created_at, updated_at)
VALUES (@id, @tenant_id, @organization_id, @name, @description, @category, @owner_id, @treatment, @inherent_likelihood, @inherent_impact, @residual_likelihood, @residual_impact, @created_at, @updated_at)
`
args := pgx.StrictNamedArgs{
@@ -236,6 +241,7 @@ VALUES (@id, @tenant_id, @organization_id, @name, @description, @owner_id, @trea
"organization_id": r.OrganizationID,
"name": r.Name,
"description": r.Description,
"category": r.Category,
"owner_id": r.OwnerID,
"treatment": r.Treatment,
"inherent_likelihood": r.InherentLikelihood,
@@ -266,6 +272,7 @@ SET
inherent_impact = @inherent_impact,
residual_likelihood = @residual_likelihood,
residual_impact = @residual_impact,
category = @category,
updated_at = @updated_at
WHERE %s
AND id = @risk_id
@@ -276,6 +283,7 @@ WHERE %s
"risk_id": r.ID,
"name": r.Name,
"description": r.Description,
"category": r.Category,
"owner_id": r.OwnerID,
"treatment": r.Treatment,
"inherent_likelihood": r.InherentLikelihood,

View File

@@ -0,0 +1,15 @@
type Risk {
id: ID!
organizationId: ID!
name: String!
description: String!
category: String!
treatment: RiskTreatment!
ownerId: ID
inherentLikelihood: Int!
inherentImpact: Int!
residualLikelihood: Int!
residualImpact: Int!
createdAt: Time!
updatedAt: Time!
}

View File

@@ -34,6 +34,7 @@ type (
OrganizationID gid.GID
Name string
Description string
Category string
Treatment coredata.RiskTreatment
OwnerID *gid.GID
InherentLikelihood int
@@ -46,6 +47,7 @@ type (
ID gid.GID
Name *string
Description *string
Category *string
Treatment *coredata.RiskTreatment
OwnerID *gid.GID
InherentLikelihood *int
@@ -171,6 +173,7 @@ func (s RiskService) Create(
OrganizationID: req.OrganizationID,
Name: req.Name,
Description: req.Description,
Category: req.Category,
OwnerID: req.OwnerID,
InherentLikelihood: req.InherentLikelihood,
InherentImpact: req.InherentImpact,
@@ -268,6 +271,10 @@ func (s RiskService) Update(
risk.OwnerID = req.OwnerID
}
if req.Category != nil {
risk.Category = *req.Category
}
risk.UpdatedAt = time.Now()
if err := risk.Update(ctx, conn, s.svc.scope); err != nil {

View File

@@ -627,6 +627,7 @@ type Risk implements Node {
id: ID!
name: String!
description: String!
category: String!
treatment: RiskTreatment!
inherentLikelihood: Int!
inherentImpact: Int!
@@ -1090,6 +1091,7 @@ input CreateRiskInput {
organizationId: ID!
name: String!
description: String!
category: String!
ownerId: ID
treatment: RiskTreatment!
inherentLikelihood: Int!
@@ -1102,6 +1104,7 @@ input UpdateRiskInput {
id: ID!
name: String
description: String
category: String
ownerId: ID
treatment: RiskTreatment
inherentLikelihood: Int

View File

@@ -412,6 +412,7 @@ type ComplexityRoot struct {
}
Risk struct {
Category func(childComplexity int) int
Controls func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy) int
CreatedAt func(childComplexity int) int
Description func(childComplexity int) int
@@ -2239,6 +2240,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.RequestEvidencePayload.EvidenceEdge(childComplexity), true
case "Risk.category":
if e.complexity.Risk.Category == nil {
break
}
return e.complexity.Risk.Category(childComplexity), true
case "Risk.controls":
if e.complexity.Risk.Controls == nil {
break
@@ -3738,6 +3746,7 @@ type Risk implements Node {
id: ID!
name: String!
description: String!
category: String!
treatment: RiskTreatment!
inherentLikelihood: Int!
inherentImpact: Int!
@@ -4201,6 +4210,7 @@ input CreateRiskInput {
organizationId: ID!
name: String!
description: String!
category: String!
ownerId: ID
treatment: RiskTreatment!
inherentLikelihood: Int!
@@ -4213,6 +4223,7 @@ input UpdateRiskInput {
id: ID!
name: String
description: String
category: String
ownerId: ID
treatment: RiskTreatment
inherentLikelihood: Int
@@ -16837,6 +16848,50 @@ func (ec *executionContext) fieldContext_Risk_description(_ context.Context, fie
return fc, nil
}
func (ec *executionContext) _Risk_category(ctx context.Context, field graphql.CollectedField, obj *types.Risk) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Risk_category(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.Category, 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.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Risk_category(_ 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 String does not have child fields")
},
}
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 {
@@ -17666,6 +17721,8 @@ func (ec *executionContext) fieldContext_RiskEdge_node(_ context.Context, field
return ec.fieldContext_Risk_name(ctx, field)
case "description":
return ec.fieldContext_Risk_description(ctx, field)
case "category":
return ec.fieldContext_Risk_category(ctx, field)
case "treatment":
return ec.fieldContext_Risk_treatment(ctx, field)
case "inherentLikelihood":
@@ -18851,6 +18908,8 @@ func (ec *executionContext) fieldContext_UpdateRiskPayload_risk(_ context.Contex
return ec.fieldContext_Risk_name(ctx, field)
case "description":
return ec.fieldContext_Risk_description(ctx, field)
case "category":
return ec.fieldContext_Risk_category(ctx, field)
case "treatment":
return ec.fieldContext_Risk_treatment(ctx, field)
case "inherentLikelihood":
@@ -24010,7 +24069,7 @@ func (ec *executionContext) unmarshalInputCreateRiskInput(ctx context.Context, o
asMap[k] = v
}
fieldsInOrder := [...]string{"organizationId", "name", "description", "ownerId", "treatment", "inherentLikelihood", "inherentImpact", "residualLikelihood", "residualImpact"}
fieldsInOrder := [...]string{"organizationId", "name", "description", "category", "ownerId", "treatment", "inherentLikelihood", "inherentImpact", "residualLikelihood", "residualImpact"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -24038,6 +24097,13 @@ func (ec *executionContext) unmarshalInputCreateRiskInput(ctx context.Context, o
return it, err
}
it.Description = data
case "category":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("category"))
data, err := ec.unmarshalNString2string(ctx, v)
if err != nil {
return it, err
}
it.Category = data
case "ownerId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ownerId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
@@ -25561,7 +25627,7 @@ func (ec *executionContext) unmarshalInputUpdateRiskInput(ctx context.Context, o
asMap[k] = v
}
fieldsInOrder := [...]string{"id", "name", "description", "ownerId", "treatment", "inherentLikelihood", "inherentImpact", "residualLikelihood", "residualImpact"}
fieldsInOrder := [...]string{"id", "name", "description", "category", "ownerId", "treatment", "inherentLikelihood", "inherentImpact", "residualLikelihood", "residualImpact"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -25589,6 +25655,13 @@ func (ec *executionContext) unmarshalInputUpdateRiskInput(ctx context.Context, o
return it, err
}
it.Description = data
case "category":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("category"))
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
it.Category = data
case "ownerId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ownerId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
@@ -26024,34 +26097,6 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
switch obj := (obj).(type) {
case nil:
return graphql.Null
case types.Organization:
return ec._Organization(ctx, sel, &obj)
case *types.Organization:
if obj == nil {
return graphql.Null
}
return ec._Organization(ctx, sel, obj)
case types.User:
return ec._User(ctx, sel, &obj)
case *types.User:
if obj == nil {
return graphql.Null
}
return ec._User(ctx, sel, obj)
case types.People:
return ec._People(ctx, sel, &obj)
case *types.People:
if obj == nil {
return graphql.Null
}
return ec._People(ctx, sel, obj)
case types.Vendor:
return ec._Vendor(ctx, sel, &obj)
case *types.Vendor:
if obj == nil {
return graphql.Null
}
return ec._Vendor(ctx, sel, obj)
case types.VendorComplianceReport:
return ec._VendorComplianceReport(ctx, sel, &obj)
case *types.VendorComplianceReport:
@@ -26059,27 +26104,20 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
return graphql.Null
}
return ec._VendorComplianceReport(ctx, sel, obj)
case types.Framework:
return ec._Framework(ctx, sel, &obj)
case *types.Framework:
case types.Vendor:
return ec._Vendor(ctx, sel, &obj)
case *types.Vendor:
if obj == nil {
return graphql.Null
}
return ec._Framework(ctx, sel, obj)
case types.Control:
return ec._Control(ctx, sel, &obj)
case *types.Control:
return ec._Vendor(ctx, sel, obj)
case types.User:
return ec._User(ctx, sel, &obj)
case *types.User:
if obj == nil {
return graphql.Null
}
return ec._Control(ctx, sel, obj)
case types.Mesure:
return ec._Mesure(ctx, sel, &obj)
case *types.Mesure:
if obj == nil {
return graphql.Null
}
return ec._Mesure(ctx, sel, obj)
return ec._User(ctx, sel, obj)
case types.Task:
return ec._Task(ctx, sel, &obj)
case *types.Task:
@@ -26087,20 +26125,6 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
return graphql.Null
}
return ec._Task(ctx, sel, obj)
case types.Evidence:
return ec._Evidence(ctx, sel, &obj)
case *types.Evidence:
if obj == nil {
return graphql.Null
}
return ec._Evidence(ctx, sel, obj)
case types.Policy:
return ec._Policy(ctx, sel, &obj)
case *types.Policy:
if obj == nil {
return graphql.Null
}
return ec._Policy(ctx, sel, obj)
case types.Risk:
return ec._Risk(ctx, sel, &obj)
case *types.Risk:
@@ -26108,6 +26132,55 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
return graphql.Null
}
return ec._Risk(ctx, sel, obj)
case types.Policy:
return ec._Policy(ctx, sel, &obj)
case *types.Policy:
if obj == nil {
return graphql.Null
}
return ec._Policy(ctx, sel, obj)
case types.People:
return ec._People(ctx, sel, &obj)
case *types.People:
if obj == nil {
return graphql.Null
}
return ec._People(ctx, sel, obj)
case types.Organization:
return ec._Organization(ctx, sel, &obj)
case *types.Organization:
if obj == nil {
return graphql.Null
}
return ec._Organization(ctx, sel, obj)
case types.Mesure:
return ec._Mesure(ctx, sel, &obj)
case *types.Mesure:
if obj == nil {
return graphql.Null
}
return ec._Mesure(ctx, sel, obj)
case types.Framework:
return ec._Framework(ctx, sel, &obj)
case *types.Framework:
if obj == nil {
return graphql.Null
}
return ec._Framework(ctx, sel, obj)
case types.Evidence:
return ec._Evidence(ctx, sel, &obj)
case *types.Evidence:
if obj == nil {
return graphql.Null
}
return ec._Evidence(ctx, sel, obj)
case types.Control:
return ec._Control(ctx, sel, &obj)
case *types.Control:
if obj == nil {
return graphql.Null
}
return ec._Control(ctx, sel, obj)
default:
panic(fmt.Errorf("unexpected type %T", obj))
}
@@ -29650,6 +29723,11 @@ func (ec *executionContext) _Risk(ctx context.Context, sel ast.SelectionSet, obj
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "category":
out.Values[i] = ec._Risk_category(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "treatment":
out.Values[i] = ec._Risk_treatment(ctx, field, obj)
if out.Values[i] == graphql.Null {
@@ -33521,9 +33599,7 @@ func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.S
func (ec *executionContext) unmarshalNString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
var vSlice []any
if v != nil {
vSlice = graphql.CoerceList(v)
}
vSlice = graphql.CoerceList(v)
var err error
res := make([]string, len(vSlice))
for i := range vSlice {
@@ -34262,9 +34338,7 @@ func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Conte
func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
var vSlice []any
if v != nil {
vSlice = graphql.CoerceList(v)
}
vSlice = graphql.CoerceList(v)
var err error
res := make([]string, len(vSlice))
for i := range vSlice {
@@ -34844,9 +34918,7 @@ func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v
return nil, nil
}
var vSlice []any
if v != nil {
vSlice = graphql.CoerceList(v)
}
vSlice = graphql.CoerceList(v)
var err error
res := make([]string, len(vSlice))
for i := range vSlice {

View File

@@ -55,6 +55,7 @@ func NewRisk(r *coredata.Risk) *Risk {
ResidualLikelihood: r.ResidualLikelihood,
ResidualImpact: r.ResidualImpact,
ResidualSeverity: r.ResidualSeverity(),
Category: r.Category,
CreatedAt: r.CreatedAt,
UpdatedAt: r.UpdatedAt,
}

View File

@@ -150,6 +150,7 @@ type CreateRiskInput struct {
OrganizationID gid.GID `json:"organizationId"`
Name string `json:"name"`
Description string `json:"description"`
Category string `json:"category"`
OwnerID *gid.GID `json:"ownerId,omitempty"`
Treatment coredata.RiskTreatment `json:"treatment"`
InherentLikelihood int `json:"inherentLikelihood"`
@@ -561,6 +562,7 @@ type Risk struct {
ID gid.GID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Category string `json:"category"`
Treatment coredata.RiskTreatment `json:"treatment"`
InherentLikelihood int `json:"inherentLikelihood"`
InherentImpact int `json:"inherentImpact"`
@@ -689,6 +691,7 @@ type UpdateRiskInput struct {
ID gid.GID `json:"id"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Category *string `json:"category,omitempty"`
OwnerID *gid.GID `json:"ownerId,omitempty"`
Treatment *coredata.RiskTreatment `json:"treatment,omitempty"`
InherentLikelihood *int `json:"inherentLikelihood,omitempty"`

View File

@@ -2,7 +2,7 @@ package console_v1
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.66
// Code generated by github.com/99designs/gqlgen version v0.17.70
import (
"context"
@@ -730,6 +730,7 @@ func (r *mutationResolver) CreateRisk(ctx context.Context, input types.CreateRis
OrganizationID: input.OrganizationID,
Name: input.Name,
Description: input.Description,
Category: input.Category,
Treatment: input.Treatment,
OwnerID: input.OwnerID,
InherentLikelihood: input.InherentLikelihood,
@@ -757,6 +758,7 @@ func (r *mutationResolver) UpdateRisk(ctx context.Context, input types.UpdateRis
ID: input.ID,
Name: input.Name,
Description: input.Description,
Category: input.Category,
Treatment: input.Treatment,
OwnerID: input.OwnerID,
InherentLikelihood: input.InherentLikelihood,