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

View File

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

View File

@@ -30,7 +30,7 @@ import {
} from "@/components/ui/select"; } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import PeopleSelector from "@/components/PeopleSelector"; import PeopleSelector from "@/components/PeopleSelector";
import { User } from "lucide-react"; import { User, Loader2 } from "lucide-react";
import { Suspense } from "react"; import { Suspense } from "react";
import type { NewRiskViewQuery } from "./__generated__/NewRiskViewQuery.graphql"; import type { NewRiskViewQuery } from "./__generated__/NewRiskViewQuery.graphql";
@@ -43,6 +43,7 @@ interface RiskTemplate {
likelihood: number; likelihood: number;
recommendedTreatment: string; recommendedTreatment: string;
}[]; }[];
category: string;
} }
const newRiskQuery = graphql` const newRiskQuery = graphql`
@@ -64,6 +65,7 @@ const createRiskMutation = graphql`
id id
name name
description description
category
inherentLikelihood inherentLikelihood
inherentImpact inherentImpact
residualLikelihood residualLikelihood
@@ -95,14 +97,45 @@ function NewRiskForm({
const [ownerId, setOwnerId] = useState<string | null>(null); const [ownerId, setOwnerId] = useState<string | null>(null);
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [selectedTemplate, setSelectedTemplate] = useState<string>(""); const [selectedTemplate, setSelectedTemplate] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string>("");
const [riskTemplates, setRiskTemplates] = useState<RiskTemplate[]>([]); const [riskTemplates, setRiskTemplates] = useState<RiskTemplate[]>([]);
const [ownerError, setOwnerError] = useState<string>("");
const [isLoadingTemplates, setIsLoadingTemplates] = useState(true);
const { toast } = useToast(); const { toast } = useToast();
const [createRisk, isInFlight] = useMutation(createRiskMutation); 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(() => { useEffect(() => {
const loadRiskTemplates = async () => { const loadRiskTemplates = async () => {
try { try {
setIsLoadingTemplates(true);
const response = await fetch("/data/risks/risks.json"); const response = await fetch("/data/risks/risks.json");
const data = await response.json(); const data = await response.json();
setRiskTemplates(data); setRiskTemplates(data);
@@ -113,6 +146,8 @@ function NewRiskForm({
description: "Failed to load risk templates. Please try again.", description: "Failed to load risk templates. Please try again.",
variant: "destructive", variant: "destructive",
}); });
} finally {
setIsLoadingTemplates(false);
} }
}; };
@@ -135,33 +170,24 @@ function NewRiskForm({
return; return;
} }
const template = riskTemplates[parseInt(templateId)]; const selectedIndex = parseInt(templateId);
const template = riskTemplates[selectedIndex];
if (template) { if (template) {
setName(template.name); setName(template.name);
setDescription(template.description); setDescription(template.description);
setTreatment("MITIGATED");
// 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());
}
} }
}; };
// Clear error when owner is selected
const handleOwnerSelect = (id: string | null) => {
setOwnerId(id);
setOwnerError("");
};
const handleSubmit = (e: React.FormEvent) => { const handleSubmit = (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
let hasError = false;
if (!name.trim()) { if (!name.trim()) {
toast({ toast({
@@ -169,6 +195,15 @@ function NewRiskForm({
description: "Please enter a name for the risk.", description: "Please enter a name for the risk.",
variant: "destructive", variant: "destructive",
}); });
hasError = true;
}
if (!ownerId) {
setOwnerError("Please select a risk owner");
hasError = true;
}
if (hasError) {
return; return;
} }
@@ -178,6 +213,7 @@ function NewRiskForm({
organizationId: organizationId!, organizationId: organizationId!,
name, name,
description, description,
category: selectedCategory,
inherentLikelihood, inherentLikelihood,
inherentImpact, inherentImpact,
residualLikelihood, residualLikelihood,
@@ -242,8 +278,29 @@ function NewRiskForm({
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<form onSubmit={handleSubmit} className="space-y-6"> <form onSubmit={handleSubmit} className="space-y-6">
<div className="space-y-4">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="template">Risk Template</Label> <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 <Select
value={selectedTemplate} value={selectedTemplate}
onValueChange={handleTemplateChange} onValueChange={handleTemplateChange}
@@ -253,17 +310,21 @@ function NewRiskForm({
</SelectTrigger> </SelectTrigger>
<SelectContent className="max-h-[300px] overflow-y-auto"> <SelectContent className="max-h-[300px] overflow-y-auto">
<SelectItem value="none">Select a template</SelectItem> <SelectItem value="none">Select a template</SelectItem>
{riskTemplates.map((template, index) => ( {filteredRisks.map((template) => (
<SelectItem key={index} value={index.toString()}> <SelectItem
key={template.originalIndex}
value={template.originalIndex.toString()}
>
{template.name} {template.name}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>
</Select> </Select>
<p className="text-sm text-tertiary"> <p className="text-sm text-tertiary">
Select a template to prefill the form or create a custom risk. Select a risk template to prefill the form or create a custom risk.
</p> </p>
</div> </div>
</div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="name">Name</Label> <Label htmlFor="name">Name</Label>
@@ -291,14 +352,18 @@ function NewRiskForm({
<Label htmlFor="owner" className="flex items-center gap-2"> <Label htmlFor="owner" className="flex items-center gap-2">
<User className="h-4 w-4" /> <User className="h-4 w-4" />
Risk Owner Risk Owner
<span className="text-destructive">*</span>
</Label> </Label>
<PeopleSelector <PeopleSelector
organizationRef={data.organization} organizationRef={data.organization}
selectedPersonId={ownerId} selectedPersonId={ownerId}
onSelect={setOwnerId} onSelect={handleOwnerSelect}
placeholder="Select risk owner (optional)" placeholder="Select risk owner"
required={false} required={true}
/> />
{ownerError && (
<p className="text-sm text-destructive mt-1">Please select a risk owner</p>
)}
</div> </div>
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<121c9ad6ab399476692b98d1838f70d7>> * @generated SignedSource<<f0234c8da839e9d7babc696edb1171aa>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -95,6 +95,13 @@ v8 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "id", "name": "id",
"storageKey": null "storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
}; };
return { return {
"fragment": { "fragment": {
@@ -228,6 +235,7 @@ return {
"name": "description", "name": "description",
"storageKey": null "storageKey": null
}, },
(v9/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -242,6 +250,66 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "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*/) (v7/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -329,16 +397,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "402fdc7c2f504ba8640e2ecd2f8f2cb8", "cacheID": "398efd65ce3f24d13b357e8cf32c4f6e",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ListRiskViewPaginationQuery", "name": "ListRiskViewPaginationQuery",
"operationKind": "query", "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; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<677eff2bfb212e672f0d95b56adeebe7>> * @generated SignedSource<<d4fc01f5c38bce1054b2198af7e021f2>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -96,6 +96,13 @@ v8 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
}; };
return { return {
"fragment": { "fragment": {
@@ -230,6 +237,7 @@ return {
"name": "description", "name": "description",
"storageKey": null "storageKey": null
}, },
(v9/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -244,6 +252,66 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "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*/) (v8/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -331,12 +399,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "fcdb0ca740c0a11d5e4961407baadffa", "cacheID": "519139d7f492b8d719abf1b0e788853a",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ListRiskViewQuery", "name": "ListRiskViewQuery",
"operationKind": "query", "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 * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -17,12 +17,24 @@ export type ListRiskView_risks$data = {
readonly __id: string; readonly __id: string;
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly category: string;
readonly createdAt: string; readonly createdAt: string;
readonly description: string; readonly description: string;
readonly id: string; readonly id: string;
readonly inherentImpact: number; readonly inherentImpact: number;
readonly inherentLikelihood: number; readonly inherentLikelihood: number;
readonly mesures: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: string;
};
}>;
};
readonly name: string; readonly name: string;
readonly owner: {
readonly fullName: string;
readonly id: string;
} | null | undefined;
readonly residualImpact: number; readonly residualImpact: number;
readonly residualLikelihood: number; readonly residualLikelihood: number;
readonly treatment: RiskTreatment; readonly treatment: RiskTreatment;
@@ -53,6 +65,13 @@ v1 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "id", "name": "id",
"storageKey": null "storageKey": null
},
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
}; };
return { return {
"argumentDefinitions": [ "argumentDefinitions": [
@@ -185,6 +204,7 @@ return {
"name": "description", "name": "description",
"storageKey": null "storageKey": null
}, },
(v2/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -199,6 +219,65 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "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, "alias": null,
"args": null, "args": null,
@@ -280,6 +359,6 @@ return {
}; };
})(); })();
(node as any).hash = "a5f7d6424459d2a3b471bb0a4f0a4169"; (node as any).hash = "3fc46af4f252617f4547c988184bb168";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<f5de62a6351fe2691ad8aff671be4aad>> * @generated SignedSource<<5b015e6ca9ba83b884026cca65dcdc1c>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -11,6 +11,7 @@
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED"; export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
export type CreateRiskInput = { export type CreateRiskInput = {
category: string;
description: string; description: string;
inherentImpact: number; inherentImpact: number;
inherentLikelihood: number; inherentLikelihood: number;
@@ -29,6 +30,7 @@ export type NewRiskViewCreateRiskMutation$data = {
readonly createRisk: { readonly createRisk: {
readonly riskEdge: { readonly riskEdge: {
readonly node: { readonly node: {
readonly category: string;
readonly createdAt: string; readonly createdAt: string;
readonly description: string; readonly description: string;
readonly id: string; readonly id: string;
@@ -103,6 +105,13 @@ v3 = {
"name": "description", "name": "description",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -224,16 +233,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "9f296661d12f36362aeecd2a1fd4aa63", "cacheID": "c568f60a75535b2597f860405b4eba79",
"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 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; 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/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // 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/mattn/go-runewidth v0.0.16 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/olekukonko/tablewriter v0.0.5 // 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 h1:tS3oPI89+Y33vZRR/DwbNTewefycz1UzEeDYgMKNdzY=
gearno.de/ref v0.0.0-20221013162104-a522beda40f4/go.mod h1:yMxgb+Im8XTCLBBgpy8p5xE6/OaWkKyfypNd3HPQpLw= 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 h1:xgLIgQuG+Q2L/AE9cW595CT7xCWCe/bpPIFGSfsGSGs=
github.com/99designs/gqlgen v0.17.70/go.mod h1:fvCiqQAu2VLhKXez2xFvLmE47QgAPf/KTPN5XQ4rsHQ= 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 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 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM=
github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= 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 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= 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 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 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= 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 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= 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 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/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 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/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= 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/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 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/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 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/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 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/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 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/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 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/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= 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/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 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= 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 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= 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= 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 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= 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.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 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 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= 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/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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= 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 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= 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 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM=
github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= 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.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 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= 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.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 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= 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 h1:FmWtFEa+invTIzWlWK6Vk7BVEZU/97QBzeI8Z1JjGt8=
github.com/vektah/gqlparser/v2 v2.5.25/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= 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= 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.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 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= 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 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= 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 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 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 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= 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 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 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 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= 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 h1:UdXH7Kzbj+Vzastr5nVfccbmFsmYNygVLSPk1pEfDoY=
google.golang.org/genproto/googleapis/api v0.0.0-20250414145226-207652e42e2e/go.mod h1:085qFyf2+XaZlRdCgKNCIZ3afY2p4HHZdoIRpId8F4A= 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 h1:ztQaXfzEXTmCBvbtWYRhJxW+0iJcz2qXfd38/e9l7bA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= 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 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= 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 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 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= 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"` OrganizationID gid.GID `db:"organization_id"`
Name string `db:"name"` Name string `db:"name"`
Description string `db:"description"` Description string `db:"description"`
Category string `db:"category"`
Treatment RiskTreatment `db:"treatment"` Treatment RiskTreatment `db:"treatment"`
OwnerID *gid.GID `db:"owner_id"` OwnerID *gid.GID `db:"owner_id"`
InherentLikelihood int `db:"inherent_likelihood"` InherentLikelihood int `db:"inherent_likelihood"`
@@ -76,6 +77,7 @@ WITH rsks AS (
r.organization_id, r.organization_id,
r.name, r.name,
r.description, r.description,
r.category,
r.owner_id, r.owner_id,
r.treatment, r.treatment,
r.inherent_likelihood, r.inherent_likelihood,
@@ -96,6 +98,7 @@ SELECT
organization_id, organization_id,
name, name,
description, description,
category,
owner_id, owner_id,
treatment, treatment,
inherent_likelihood, inherent_likelihood,
@@ -148,6 +151,7 @@ SELECT
inherent_impact, inherent_impact,
residual_likelihood, residual_likelihood,
residual_impact, residual_impact,
category,
created_at, created_at,
updated_at updated_at
FROM risks FROM risks
@@ -187,6 +191,7 @@ SELECT
organization_id, organization_id,
name, name,
description, description,
category,
owner_id, owner_id,
treatment, treatment,
inherent_likelihood, inherent_likelihood,
@@ -226,8 +231,8 @@ func (r *Risk) Insert(
scope Scoper, scope Scoper,
) error { ) error {
q := ` 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) 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, @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{ args := pgx.StrictNamedArgs{
@@ -236,6 +241,7 @@ VALUES (@id, @tenant_id, @organization_id, @name, @description, @owner_id, @trea
"organization_id": r.OrganizationID, "organization_id": r.OrganizationID,
"name": r.Name, "name": r.Name,
"description": r.Description, "description": r.Description,
"category": r.Category,
"owner_id": r.OwnerID, "owner_id": r.OwnerID,
"treatment": r.Treatment, "treatment": r.Treatment,
"inherent_likelihood": r.InherentLikelihood, "inherent_likelihood": r.InherentLikelihood,
@@ -266,6 +272,7 @@ SET
inherent_impact = @inherent_impact, inherent_impact = @inherent_impact,
residual_likelihood = @residual_likelihood, residual_likelihood = @residual_likelihood,
residual_impact = @residual_impact, residual_impact = @residual_impact,
category = @category,
updated_at = @updated_at updated_at = @updated_at
WHERE %s WHERE %s
AND id = @risk_id AND id = @risk_id
@@ -276,6 +283,7 @@ WHERE %s
"risk_id": r.ID, "risk_id": r.ID,
"name": r.Name, "name": r.Name,
"description": r.Description, "description": r.Description,
"category": r.Category,
"owner_id": r.OwnerID, "owner_id": r.OwnerID,
"treatment": r.Treatment, "treatment": r.Treatment,
"inherent_likelihood": r.InherentLikelihood, "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 OrganizationID gid.GID
Name string Name string
Description string Description string
Category string
Treatment coredata.RiskTreatment Treatment coredata.RiskTreatment
OwnerID *gid.GID OwnerID *gid.GID
InherentLikelihood int InherentLikelihood int
@@ -46,6 +47,7 @@ type (
ID gid.GID ID gid.GID
Name *string Name *string
Description *string Description *string
Category *string
Treatment *coredata.RiskTreatment Treatment *coredata.RiskTreatment
OwnerID *gid.GID OwnerID *gid.GID
InherentLikelihood *int InherentLikelihood *int
@@ -171,6 +173,7 @@ func (s RiskService) Create(
OrganizationID: req.OrganizationID, OrganizationID: req.OrganizationID,
Name: req.Name, Name: req.Name,
Description: req.Description, Description: req.Description,
Category: req.Category,
OwnerID: req.OwnerID, OwnerID: req.OwnerID,
InherentLikelihood: req.InherentLikelihood, InherentLikelihood: req.InherentLikelihood,
InherentImpact: req.InherentImpact, InherentImpact: req.InherentImpact,
@@ -268,6 +271,10 @@ func (s RiskService) Update(
risk.OwnerID = req.OwnerID risk.OwnerID = req.OwnerID
} }
if req.Category != nil {
risk.Category = *req.Category
}
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

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

View File

@@ -412,6 +412,7 @@ type ComplexityRoot struct {
} }
Risk 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 Controls func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy) int
CreatedAt func(childComplexity int) int CreatedAt func(childComplexity int) int
Description 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 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": case "Risk.controls":
if e.complexity.Risk.Controls == nil { if e.complexity.Risk.Controls == nil {
break break
@@ -3738,6 +3746,7 @@ type Risk implements Node {
id: ID! id: ID!
name: String! name: String!
description: String! description: String!
category: String!
treatment: RiskTreatment! treatment: RiskTreatment!
inherentLikelihood: Int! inherentLikelihood: Int!
inherentImpact: Int! inherentImpact: Int!
@@ -4201,6 +4210,7 @@ input CreateRiskInput {
organizationId: ID! organizationId: ID!
name: String! name: String!
description: String! description: String!
category: String!
ownerId: ID ownerId: ID
treatment: RiskTreatment! treatment: RiskTreatment!
inherentLikelihood: Int! inherentLikelihood: Int!
@@ -4213,6 +4223,7 @@ input UpdateRiskInput {
id: ID! id: ID!
name: String name: String
description: String description: String
category: String
ownerId: ID ownerId: ID
treatment: RiskTreatment treatment: RiskTreatment
inherentLikelihood: Int inherentLikelihood: Int
@@ -16837,6 +16848,50 @@ func (ec *executionContext) fieldContext_Risk_description(_ context.Context, fie
return fc, nil 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) { 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) fc, err := ec.fieldContext_Risk_treatment(ctx, field)
if err != nil { if err != nil {
@@ -17666,6 +17721,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 "category":
return ec.fieldContext_Risk_category(ctx, field)
case "treatment": case "treatment":
return ec.fieldContext_Risk_treatment(ctx, field) return ec.fieldContext_Risk_treatment(ctx, field)
case "inherentLikelihood": case "inherentLikelihood":
@@ -18851,6 +18908,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 "category":
return ec.fieldContext_Risk_category(ctx, field)
case "treatment": case "treatment":
return ec.fieldContext_Risk_treatment(ctx, field) return ec.fieldContext_Risk_treatment(ctx, field)
case "inherentLikelihood": case "inherentLikelihood":
@@ -24010,7 +24069,7 @@ func (ec *executionContext) unmarshalInputCreateRiskInput(ctx context.Context, o
asMap[k] = v 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 { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -24038,6 +24097,13 @@ func (ec *executionContext) unmarshalInputCreateRiskInput(ctx context.Context, o
return it, err return it, err
} }
it.Description = data 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": case "ownerId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ownerId")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ownerId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) 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 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 { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -25589,6 +25655,13 @@ func (ec *executionContext) unmarshalInputUpdateRiskInput(ctx context.Context, o
return it, err return it, err
} }
it.Description = data 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": case "ownerId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ownerId")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ownerId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) 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) { switch obj := (obj).(type) {
case nil: case nil:
return graphql.Null 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: case types.VendorComplianceReport:
return ec._VendorComplianceReport(ctx, sel, &obj) return ec._VendorComplianceReport(ctx, sel, &obj)
case *types.VendorComplianceReport: case *types.VendorComplianceReport:
@@ -26059,27 +26104,20 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
return graphql.Null return graphql.Null
} }
return ec._VendorComplianceReport(ctx, sel, obj) return ec._VendorComplianceReport(ctx, sel, obj)
case types.Framework: case types.Vendor:
return ec._Framework(ctx, sel, &obj) return ec._Vendor(ctx, sel, &obj)
case *types.Framework: case *types.Vendor:
if obj == nil { if obj == nil {
return graphql.Null return graphql.Null
} }
return ec._Framework(ctx, sel, obj) return ec._Vendor(ctx, sel, obj)
case types.Control: case types.User:
return ec._Control(ctx, sel, &obj) return ec._User(ctx, sel, &obj)
case *types.Control: case *types.User:
if obj == nil { if obj == nil {
return graphql.Null return graphql.Null
} }
return ec._Control(ctx, sel, obj) return ec._User(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.Task: case types.Task:
return ec._Task(ctx, sel, &obj) return ec._Task(ctx, sel, &obj)
case *types.Task: case *types.Task:
@@ -26087,20 +26125,6 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
return graphql.Null return graphql.Null
} }
return ec._Task(ctx, sel, obj) 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: case types.Risk:
return ec._Risk(ctx, sel, &obj) return ec._Risk(ctx, sel, &obj)
case *types.Risk: case *types.Risk:
@@ -26108,6 +26132,55 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
return graphql.Null return graphql.Null
} }
return ec._Risk(ctx, sel, obj) 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: default:
panic(fmt.Errorf("unexpected type %T", obj)) 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 { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) 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": case "treatment":
out.Values[i] = ec._Risk_treatment(ctx, field, obj) out.Values[i] = ec._Risk_treatment(ctx, field, obj)
if out.Values[i] == graphql.Null { 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) { func (ec *executionContext) unmarshalNString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
var vSlice []any var vSlice []any
if v != nil {
vSlice = graphql.CoerceList(v) vSlice = graphql.CoerceList(v)
}
var err error var err error
res := make([]string, len(vSlice)) res := make([]string, len(vSlice))
for i := range 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) { func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
var vSlice []any var vSlice []any
if v != nil {
vSlice = graphql.CoerceList(v) vSlice = graphql.CoerceList(v)
}
var err error var err error
res := make([]string, len(vSlice)) res := make([]string, len(vSlice))
for i := range vSlice { for i := range vSlice {
@@ -34844,9 +34918,7 @@ func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v
return nil, nil return nil, nil
} }
var vSlice []any var vSlice []any
if v != nil {
vSlice = graphql.CoerceList(v) vSlice = graphql.CoerceList(v)
}
var err error var err error
res := make([]string, len(vSlice)) res := make([]string, len(vSlice))
for i := range vSlice { for i := range vSlice {

View File

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

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"`
Category string `json:"category"`
OwnerID *gid.GID `json:"ownerId,omitempty"` OwnerID *gid.GID `json:"ownerId,omitempty"`
Treatment coredata.RiskTreatment `json:"treatment"` Treatment coredata.RiskTreatment `json:"treatment"`
InherentLikelihood int `json:"inherentLikelihood"` InherentLikelihood int `json:"inherentLikelihood"`
@@ -561,6 +562,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"`
Category string `json:"category"`
Treatment coredata.RiskTreatment `json:"treatment"` Treatment coredata.RiskTreatment `json:"treatment"`
InherentLikelihood int `json:"inherentLikelihood"` InherentLikelihood int `json:"inherentLikelihood"`
InherentImpact int `json:"inherentImpact"` InherentImpact int `json:"inherentImpact"`
@@ -689,6 +691,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"`
Category *string `json:"category,omitempty"`
OwnerID *gid.GID `json:"ownerId,omitempty"` OwnerID *gid.GID `json:"ownerId,omitempty"`
Treatment *coredata.RiskTreatment `json:"treatment,omitempty"` Treatment *coredata.RiskTreatment `json:"treatment,omitempty"`
InherentLikelihood *int `json:"inherentLikelihood,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 // 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. // 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 ( import (
"context" "context"
@@ -730,6 +730,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,
Category: input.Category,
Treatment: input.Treatment, Treatment: input.Treatment,
OwnerID: input.OwnerID, OwnerID: input.OwnerID,
InherentLikelihood: input.InherentLikelihood, InherentLikelihood: input.InherentLikelihood,
@@ -757,6 +758,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,
Category: input.Category,
Treatment: input.Treatment, Treatment: input.Treatment,
OwnerID: input.OwnerID, OwnerID: input.OwnerID,
InherentLikelihood: input.InherentLikelihood, InherentLikelihood: input.InherentLikelihood,