Remove deprecated SOA code
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<35c2c66dca0c895c7abca2b0f4917a68>>
|
||||
* @generated SignedSource<<10bdb7f9b009009a66d93605d3d671c4>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -10,15 +10,12 @@
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type ControlStatus = "EXCLUDED" | "INCLUDED";
|
||||
export type CreateControlInput = {
|
||||
bestPractice: boolean;
|
||||
description?: string | null | undefined;
|
||||
exclusionJustification?: string | null | undefined;
|
||||
frameworkId: string;
|
||||
name: string;
|
||||
sectionTitle: string;
|
||||
status: ControlStatus;
|
||||
};
|
||||
export type FrameworkControlDialogCreateMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
@@ -169,20 +166,6 @@ return {
|
||||
"name": "sectionTitle",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "exclusionJustification",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -218,12 +201,12 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "81df1f9c65937d3e387edffc6e9a28ac",
|
||||
"cacheID": "51536092f1e2e37d1499182357306138",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "FrameworkControlDialogCreateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation FrameworkControlDialogCreateMutation(\n $input: CreateControlInput!\n) {\n createControl(input: $input) {\n controlEdge {\n node {\n ...FrameworkControlDialogFragment\n id\n }\n }\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n status\n exclusionJustification\n bestPractice\n}\n"
|
||||
"text": "mutation FrameworkControlDialogCreateMutation(\n $input: CreateControlInput!\n) {\n createControl(input: $input) {\n controlEdge {\n node {\n ...FrameworkControlDialogFragment\n id\n }\n }\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n bestPractice\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<3a62e5f931a990d83caca02ab629b0c0>>
|
||||
* @generated SignedSource<<43181b3f35ce7df5f54b19bf82eeaad0>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,16 +9,13 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type ControlStatus = "EXCLUDED" | "INCLUDED";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type FrameworkControlDialogFragment$data = {
|
||||
readonly bestPractice: boolean;
|
||||
readonly description: string | null | undefined;
|
||||
readonly exclusionJustification: string | null | undefined;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly sectionTitle: string;
|
||||
readonly status: ControlStatus;
|
||||
readonly " $fragmentType": "FrameworkControlDialogFragment";
|
||||
};
|
||||
export type FrameworkControlDialogFragment$key = {
|
||||
@@ -60,20 +57,6 @@ const node: ReaderFragment = {
|
||||
"name": "sectionTitle",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "exclusionJustification",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -86,6 +69,6 @@ const node: ReaderFragment = {
|
||||
"abstractKey": null
|
||||
};
|
||||
|
||||
(node as any).hash = "481f75ce8c525c1fa12517ef173ad868";
|
||||
(node as any).hash = "3ca9ebd60cc24f1080a594bf4ca0b928";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<7ee3c72e16fa86d6c006c004e4f93c95>>
|
||||
* @generated SignedSource<<791e18651a3911865d78b730f268f489>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -10,15 +10,12 @@
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type ControlStatus = "EXCLUDED" | "INCLUDED";
|
||||
export type UpdateControlInput = {
|
||||
bestPractice?: boolean | null | undefined;
|
||||
description?: string | null | undefined;
|
||||
exclusionJustification?: string | null | undefined;
|
||||
id: string;
|
||||
name?: string | null | undefined;
|
||||
sectionTitle?: string | null | undefined;
|
||||
status?: ControlStatus | null | undefined;
|
||||
};
|
||||
export type FrameworkControlDialogUpdateMutation$variables = {
|
||||
input: UpdateControlInput;
|
||||
@@ -138,20 +135,6 @@ return {
|
||||
"name": "sectionTitle",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "exclusionJustification",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -168,12 +151,12 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "374c69b33dd6e94dec75829fe0777f58",
|
||||
"cacheID": "a44a5055f8167fa3754f4f389cee598f",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "FrameworkControlDialogUpdateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation FrameworkControlDialogUpdateMutation(\n $input: UpdateControlInput!\n) {\n updateControl(input: $input) {\n control {\n ...FrameworkControlDialogFragment\n id\n }\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n status\n exclusionJustification\n bestPractice\n}\n"
|
||||
"text": "mutation FrameworkControlDialogUpdateMutation(\n $input: UpdateControlInput!\n) {\n updateControl(input: $input) {\n control {\n ...FrameworkControlDialogFragment\n id\n }\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n bestPractice\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<3db987ede3a3aa1dfa570e76a00ef224>>
|
||||
* @generated SignedSource<<b78ad7244ad348d2622288743eff7a9b>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -9,24 +9,20 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type ControlStatus = "EXCLUDED" | "INCLUDED";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type FrameworkDetailPageFragment$data = {
|
||||
readonly canCreateControl: boolean;
|
||||
readonly canDelete: boolean;
|
||||
readonly canExport: boolean;
|
||||
readonly canGenerateSOA: boolean;
|
||||
readonly canUpdate: boolean;
|
||||
readonly controls: {
|
||||
readonly __id: string;
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly bestPractice: boolean;
|
||||
readonly exclusionJustification: string | null | undefined;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly sectionTitle: string;
|
||||
readonly status: ControlStatus;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
@@ -141,19 +137,6 @@ return {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:create\")"
|
||||
},
|
||||
{
|
||||
"alias": "canGenerateSOA",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:framework:generate-state-of-applicability"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:framework:generate-state-of-applicability\")"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -213,20 +196,6 @@ return {
|
||||
"storageKey": null
|
||||
},
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "exclusionJustification",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -261,6 +230,6 @@ return {
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "a3eb8b9d80c69d7faa83eae88e3b986b";
|
||||
(node as any).hash = "f6eba8f00d1e491f79bc201851b8c69d";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<b7c54e98eb3ba12bf4619530b45fdbab>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation$variables = {
|
||||
frameworkId: string;
|
||||
};
|
||||
export type FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation$data = {
|
||||
readonly generateFrameworkStateOfApplicability: {
|
||||
readonly data: string;
|
||||
};
|
||||
};
|
||||
export type FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation = {
|
||||
response: FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation$data;
|
||||
variables: FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "frameworkId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"fields": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "frameworkId",
|
||||
"variableName": "frameworkId"
|
||||
}
|
||||
],
|
||||
"kind": "ObjectValue",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
"concreteType": "GenerateFrameworkStateOfApplicabilityPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "generateFrameworkStateOfApplicability",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "data",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "80185d474f3a9c5d20f97a387b219511",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation(\n $frameworkId: ID!\n) {\n generateFrameworkStateOfApplicability(input: {frameworkId: $frameworkId}) {\n data\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "eac70164d676cb8e19d7fe7f06b2b817";
|
||||
|
||||
export default node;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<0c1816374b8fe7e0c0c79e9013aeb2b4>>
|
||||
* @generated SignedSource<<72da3c2c267ec4fd2da7aee87f38c51b>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type ControlStatus = "EXCLUDED" | "INCLUDED";
|
||||
export type FrameworkGraphControlNodeQuery$variables = {
|
||||
controlId: string;
|
||||
};
|
||||
@@ -47,7 +46,6 @@ export type FrameworkGraphControlNodeQuery$data = {
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly exclusionJustification?: string | null | undefined;
|
||||
readonly id?: string;
|
||||
readonly measures?: {
|
||||
readonly __id: string;
|
||||
@@ -78,7 +76,6 @@ export type FrameworkGraphControlNodeQuery$data = {
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly status?: ControlStatus;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"FrameworkControlDialogFragment">;
|
||||
};
|
||||
};
|
||||
@@ -131,20 +128,6 @@ v5 = {
|
||||
"storageKey": null
|
||||
},
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "exclusionJustification",
|
||||
"storageKey": null
|
||||
},
|
||||
v8 = {
|
||||
"alias": "canUpdate",
|
||||
"args": [
|
||||
{
|
||||
@@ -157,7 +140,7 @@ v8 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:update\")"
|
||||
},
|
||||
v9 = {
|
||||
v7 = {
|
||||
"alias": "canDelete",
|
||||
"args": [
|
||||
{
|
||||
@@ -170,7 +153,7 @@ v9 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:delete\")"
|
||||
},
|
||||
v10 = {
|
||||
v8 = {
|
||||
"alias": "canCreateMeasureMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -183,7 +166,7 @@ v10 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:create-measure-mapping\")"
|
||||
},
|
||||
v11 = {
|
||||
v9 = {
|
||||
"alias": "canDeleteMeasureMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -196,7 +179,7 @@ v11 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:delete-measure-mapping\")"
|
||||
},
|
||||
v12 = {
|
||||
v10 = {
|
||||
"alias": "canCreateDocumentMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -209,7 +192,7 @@ v12 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:create-document-mapping\")"
|
||||
},
|
||||
v13 = {
|
||||
v11 = {
|
||||
"alias": "canDeleteDocumentMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -222,7 +205,7 @@ v13 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:delete-document-mapping\")"
|
||||
},
|
||||
v14 = {
|
||||
v12 = {
|
||||
"alias": "canCreateAuditMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -235,7 +218,7 @@ v14 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:create-audit-mapping\")"
|
||||
},
|
||||
v15 = {
|
||||
v13 = {
|
||||
"alias": "canDeleteAuditMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -248,7 +231,7 @@ v15 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:delete-audit-mapping\")"
|
||||
},
|
||||
v16 = {
|
||||
v14 = {
|
||||
"alias": "canCreateSnapshotMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -261,7 +244,7 @@ v16 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:create-snapshot-mapping\")"
|
||||
},
|
||||
v17 = {
|
||||
v15 = {
|
||||
"alias": "canDeleteSnapshotMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -274,7 +257,7 @@ v17 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:delete-snapshot-mapping\")"
|
||||
},
|
||||
v18 = {
|
||||
v16 = {
|
||||
"alias": "canCreateObligationMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -287,7 +270,7 @@ v18 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:create-obligation-mapping\")"
|
||||
},
|
||||
v19 = {
|
||||
v17 = {
|
||||
"alias": "canDeleteObligationMapping",
|
||||
"args": [
|
||||
{
|
||||
@@ -300,21 +283,21 @@ v19 = {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:delete-obligation-mapping\")"
|
||||
},
|
||||
v20 = {
|
||||
v18 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v21 = {
|
||||
v19 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v22 = {
|
||||
v20 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
@@ -339,7 +322,7 @@ v22 = {
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v23 = {
|
||||
v21 = {
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
@@ -351,26 +334,33 @@ v23 = {
|
||||
}
|
||||
]
|
||||
},
|
||||
v24 = [
|
||||
v22 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
],
|
||||
v25 = {
|
||||
v23 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
v26 = {
|
||||
v24 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v25 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
@@ -406,8 +396,6 @@ return {
|
||||
(v15/*: any*/),
|
||||
(v16/*: any*/),
|
||||
(v17/*: any*/),
|
||||
(v18/*: any*/),
|
||||
(v19/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
@@ -443,16 +431,16 @@ return {
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedMeasuresCardFragment"
|
||||
},
|
||||
(v20/*: any*/)
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
@@ -486,16 +474,16 @@ return {
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedDocumentsCardFragment"
|
||||
},
|
||||
(v20/*: any*/)
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
@@ -529,16 +517,16 @@ return {
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedAuditsCardFragment"
|
||||
},
|
||||
(v20/*: any*/)
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
@@ -572,16 +560,16 @@ return {
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedObligationsCardFragment"
|
||||
},
|
||||
(v20/*: any*/)
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
@@ -615,16 +603,16 @@ return {
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedSnapshotsCardFragment"
|
||||
},
|
||||
(v20/*: any*/)
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
@@ -653,7 +641,7 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v20/*: any*/),
|
||||
(v18/*: any*/),
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
@@ -673,8 +661,6 @@ return {
|
||||
(v15/*: any*/),
|
||||
(v16/*: any*/),
|
||||
(v17/*: any*/),
|
||||
(v18/*: any*/),
|
||||
(v19/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -684,7 +670,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"concreteType": "MeasureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "measures",
|
||||
@@ -708,23 +694,23 @@ return {
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
(v25/*: any*/),
|
||||
(v20/*: any*/)
|
||||
(v23/*: any*/),
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": "measures(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "FrameworkGraphControl_measures",
|
||||
@@ -733,7 +719,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"concreteType": "DocumentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "documents",
|
||||
@@ -763,7 +749,7 @@ return {
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
(v26/*: any*/),
|
||||
(v24/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -802,7 +788,7 @@ return {
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v6/*: any*/)
|
||||
(v25/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
@@ -812,22 +798,22 @@ return {
|
||||
],
|
||||
"storageKey": "versions(first:1)"
|
||||
},
|
||||
(v20/*: any*/)
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": "documents(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "FrameworkGraphControl_documents",
|
||||
@@ -836,7 +822,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"concreteType": "AuditConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "audits",
|
||||
@@ -860,8 +846,8 @@ return {
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
(v26/*: any*/),
|
||||
(v25/*: any*/),
|
||||
(v24/*: any*/),
|
||||
(v23/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -889,22 +875,22 @@ return {
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v20/*: any*/)
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": "audits(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "FrameworkGraphControl_audits",
|
||||
@@ -913,7 +899,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"concreteType": "ObligationConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "obligations",
|
||||
@@ -957,7 +943,7 @@ return {
|
||||
"name": "source",
|
||||
"storageKey": null
|
||||
},
|
||||
(v6/*: any*/),
|
||||
(v25/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -977,22 +963,22 @@ return {
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v20/*: any*/)
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": "obligations(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "FrameworkGraphControl_obligations",
|
||||
@@ -1001,7 +987,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"concreteType": "SnapshotConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "snapshots",
|
||||
@@ -1033,23 +1019,23 @@ return {
|
||||
"name": "type",
|
||||
"storageKey": null
|
||||
},
|
||||
(v26/*: any*/),
|
||||
(v20/*: any*/)
|
||||
(v24/*: any*/),
|
||||
(v18/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v21/*: any*/)
|
||||
(v19/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v22/*: any*/),
|
||||
(v23/*: any*/)
|
||||
(v20/*: any*/),
|
||||
(v21/*: any*/)
|
||||
],
|
||||
"storageKey": "snapshots(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v24/*: any*/),
|
||||
"args": (v22/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "FrameworkGraphControl_snapshots",
|
||||
@@ -1066,7 +1052,7 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "759f31a603a2a7d2b2ad1bfcbe1f24bd",
|
||||
"cacheID": "d177e11d82fa12c1622578238707b173",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
@@ -1119,11 +1105,11 @@ return {
|
||||
},
|
||||
"name": "FrameworkGraphControlNodeQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query FrameworkGraphControlNodeQuery(\n $controlId: ID!\n) {\n node(id: $controlId) {\n __typename\n ... on Control {\n id\n name\n sectionTitle\n description\n status\n exclusionJustification\n canUpdate: permission(action: \"core:control:update\")\n canDelete: permission(action: \"core:control:delete\")\n canCreateMeasureMapping: permission(action: \"core:control:create-measure-mapping\")\n canDeleteMeasureMapping: permission(action: \"core:control:delete-measure-mapping\")\n canCreateDocumentMapping: permission(action: \"core:control:create-document-mapping\")\n canDeleteDocumentMapping: permission(action: \"core:control:delete-document-mapping\")\n canCreateAuditMapping: permission(action: \"core:control:create-audit-mapping\")\n canDeleteAuditMapping: permission(action: \"core:control:delete-audit-mapping\")\n canCreateSnapshotMapping: permission(action: \"core:control:create-snapshot-mapping\")\n canDeleteSnapshotMapping: permission(action: \"core:control:delete-snapshot-mapping\")\n canCreateObligationMapping: permission(action: \"core:control:create-obligation-mapping\")\n canDeleteObligationMapping: permission(action: \"core:control:delete-obligation-mapping\")\n ...FrameworkControlDialogFragment\n measures(first: 100) {\n edges {\n node {\n id\n ...LinkedMeasuresCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n documents(first: 100) {\n edges {\n node {\n id\n ...LinkedDocumentsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n ...LinkedAuditsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n obligations(first: 100) {\n edges {\n node {\n id\n ...LinkedObligationsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n snapshots(first: 100) {\n edges {\n node {\n id\n ...LinkedSnapshotsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n status\n exclusionJustification\n bestPractice\n}\n\nfragment LinkedAuditsCardFragment on Audit {\n id\n name\n createdAt\n state\n validFrom\n validUntil\n framework {\n id\n name\n }\n}\n\nfragment LinkedDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment LinkedMeasuresCardFragment on Measure {\n id\n name\n state\n}\n\nfragment LinkedObligationsCardFragment on Obligation {\n id\n requirement\n area\n source\n status\n owner {\n fullName\n id\n }\n}\n\nfragment LinkedSnapshotsCardFragment on Snapshot {\n id\n name\n description\n type\n createdAt\n}\n"
|
||||
"text": "query FrameworkGraphControlNodeQuery(\n $controlId: ID!\n) {\n node(id: $controlId) {\n __typename\n ... on Control {\n id\n name\n sectionTitle\n description\n canUpdate: permission(action: \"core:control:update\")\n canDelete: permission(action: \"core:control:delete\")\n canCreateMeasureMapping: permission(action: \"core:control:create-measure-mapping\")\n canDeleteMeasureMapping: permission(action: \"core:control:delete-measure-mapping\")\n canCreateDocumentMapping: permission(action: \"core:control:create-document-mapping\")\n canDeleteDocumentMapping: permission(action: \"core:control:delete-document-mapping\")\n canCreateAuditMapping: permission(action: \"core:control:create-audit-mapping\")\n canDeleteAuditMapping: permission(action: \"core:control:delete-audit-mapping\")\n canCreateSnapshotMapping: permission(action: \"core:control:create-snapshot-mapping\")\n canDeleteSnapshotMapping: permission(action: \"core:control:delete-snapshot-mapping\")\n canCreateObligationMapping: permission(action: \"core:control:create-obligation-mapping\")\n canDeleteObligationMapping: permission(action: \"core:control:delete-obligation-mapping\")\n ...FrameworkControlDialogFragment\n measures(first: 100) {\n edges {\n node {\n id\n ...LinkedMeasuresCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n documents(first: 100) {\n edges {\n node {\n id\n ...LinkedDocumentsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n ...LinkedAuditsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n obligations(first: 100) {\n edges {\n node {\n id\n ...LinkedObligationsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n snapshots(first: 100) {\n edges {\n node {\n id\n ...LinkedSnapshotsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n bestPractice\n}\n\nfragment LinkedAuditsCardFragment on Audit {\n id\n name\n createdAt\n state\n validFrom\n validUntil\n framework {\n id\n name\n }\n}\n\nfragment LinkedDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment LinkedMeasuresCardFragment on Measure {\n id\n name\n state\n}\n\nfragment LinkedObligationsCardFragment on Obligation {\n id\n requirement\n area\n source\n status\n owner {\n fullName\n id\n }\n}\n\nfragment LinkedSnapshotsCardFragment on Snapshot {\n id\n name\n description\n type\n createdAt\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d320f2f2ee2e7f9b9f398dd1ff46ac2b";
|
||||
(node as any).hash = "c5a03208206812d371f5133c8963a710";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<a493a708fe8353db1159647a455582ad>>
|
||||
* @generated SignedSource<<4716483592ffb7c9bb7d96ea56503734>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -189,19 +189,6 @@ return {
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:control:create\")"
|
||||
},
|
||||
{
|
||||
"alias": "canGenerateSOA",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "action",
|
||||
"value": "core:framework:generate-state-of-applicability"
|
||||
}
|
||||
],
|
||||
"kind": "ScalarField",
|
||||
"name": "permission",
|
||||
"storageKey": "permission(action:\"core:framework:generate-state-of-applicability\")"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -262,20 +249,6 @@ return {
|
||||
"storageKey": null
|
||||
},
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "exclusionJustification",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -314,12 +287,12 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "58485d98106169267addab7729095131",
|
||||
"cacheID": "9cb1289702b4dd6c83330a0ef84297d6",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "FrameworkGraphNodeQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query FrameworkGraphNodeQuery(\n $frameworkId: ID!\n) {\n node(id: $frameworkId) {\n __typename\n ... on Framework {\n id\n name\n ...FrameworkDetailPageFragment\n }\n id\n }\n}\n\nfragment FrameworkDetailPageFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n canExport: permission(action: \"core:franework:export\")\n canUpdate: permission(action: \"core:framework:update\")\n canDelete: permission(action: \"core:framework:delete\")\n canCreateControl: permission(action: \"core:control:create\")\n canGenerateSOA: permission(action: \"core:framework:generate-state-of-applicability\")\n organization {\n name\n id\n }\n controls(first: 250, orderBy: {field: SECTION_TITLE, direction: ASC}) {\n edges {\n node {\n id\n sectionTitle\n name\n status\n exclusionJustification\n bestPractice\n }\n }\n }\n}\n"
|
||||
"text": "query FrameworkGraphNodeQuery(\n $frameworkId: ID!\n) {\n node(id: $frameworkId) {\n __typename\n ... on Framework {\n id\n name\n ...FrameworkDetailPageFragment\n }\n id\n }\n}\n\nfragment FrameworkDetailPageFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n canExport: permission(action: \"core:franework:export\")\n canUpdate: permission(action: \"core:framework:update\")\n canDelete: permission(action: \"core:framework:delete\")\n canCreateControl: permission(action: \"core:control:create\")\n organization {\n name\n id\n }\n controls(first: 250, orderBy: {field: SECTION_TITLE, direction: ASC}) {\n edges {\n node {\n id\n sectionTitle\n name\n bestPractice\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -101,8 +101,6 @@ export const frameworkControlNodeQuery = graphql`
|
||||
name
|
||||
sectionTitle
|
||||
description
|
||||
status
|
||||
exclusionJustification
|
||||
canUpdate: permission(action: "core:control:update")
|
||||
canDelete: permission(action: "core:control:delete")
|
||||
canCreateMeasureMapping: permission(
|
||||
|
||||
@@ -336,22 +336,7 @@ export default function FrameworkControlPage({ queryRef }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{control.status === "EXCLUDED" && (
|
||||
<div className="bg-danger border border-border-danger rounded-lg p-4">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<div className="font-medium text-txt-danger">
|
||||
{__("This control is excluded")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm">
|
||||
<strong>{__("Justification:")}</strong>
|
||||
{" "}
|
||||
{control.exclusionJustification
|
||||
|| __("No justification provided")}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={control.status === "EXCLUDED" ? "opacity-60" : ""}>
|
||||
<div>
|
||||
<div className="text-base mb-1">{control.name}</div>
|
||||
{control.description && (
|
||||
<div className="text-sm text-txt-secondary mb-4 whitespace-pre-wrap">
|
||||
|
||||
@@ -21,7 +21,6 @@ import { ConnectionHandler, graphql } from "relay-runtime";
|
||||
|
||||
import type { FrameworkDetailPageExportFrameworkMutation } from "#/__generated__/core/FrameworkDetailPageExportFrameworkMutation.graphql";
|
||||
import type { FrameworkDetailPageFragment$key } from "#/__generated__/core/FrameworkDetailPageFragment.graphql";
|
||||
import type { FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation } from "#/__generated__/core/FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation.graphql";
|
||||
import type { FrameworkGraphNodeQuery } from "#/__generated__/core/FrameworkGraphNodeQuery.graphql";
|
||||
import {
|
||||
connectionListKey,
|
||||
@@ -45,7 +44,6 @@ const frameworkDetailFragment = graphql`
|
||||
canUpdate: permission(action: "core:framework:update")
|
||||
canDelete: permission(action: "core:framework:delete")
|
||||
canCreateControl: permission(action: "core:control:create")
|
||||
canGenerateSOA: permission(action: "core:framework:generate-state-of-applicability")
|
||||
organization {
|
||||
name
|
||||
}
|
||||
@@ -59,8 +57,6 @@ const frameworkDetailFragment = graphql`
|
||||
id
|
||||
sectionTitle
|
||||
name
|
||||
status
|
||||
exclusionJustification
|
||||
bestPractice
|
||||
}
|
||||
}
|
||||
@@ -68,18 +64,6 @@ const frameworkDetailFragment = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
const generateFrameworkStateOfApplicabilityMutation = graphql`
|
||||
mutation FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation(
|
||||
$frameworkId: ID!
|
||||
) {
|
||||
generateFrameworkStateOfApplicability(
|
||||
input: { frameworkId: $frameworkId }
|
||||
) {
|
||||
data
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const exportFrameworkMutation = graphql`
|
||||
mutation FrameworkDetailPageExportFrameworkMutation($frameworkId: ID!) {
|
||||
exportFramework(input: { frameworkId: $frameworkId }) {
|
||||
@@ -116,17 +100,6 @@ export default function FrameworkDetailPage(props: Props) {
|
||||
framework,
|
||||
ConnectionHandler.getConnectionID(organizationId, connectionListKey),
|
||||
);
|
||||
const [generateFrameworkStateOfApplicability]
|
||||
= useMutationWithToasts<FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation>(
|
||||
generateFrameworkStateOfApplicabilityMutation,
|
||||
{
|
||||
errorMessage:
|
||||
"Failed to generate framework state of applicability",
|
||||
successMessage:
|
||||
"Framework state of applicability generated successfully",
|
||||
},
|
||||
);
|
||||
|
||||
const [exportFramework]
|
||||
= useMutationWithToasts<FrameworkDetailPageExportFrameworkMutation>(
|
||||
exportFrameworkMutation,
|
||||
@@ -154,7 +127,7 @@ export default function FrameworkDetailPage(props: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
const hasAnyAction = framework.canExport || framework.canDelete || framework.canGenerateSOA;
|
||||
const hasAnyAction = framework.canExport || framework.canDelete;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
@@ -178,35 +151,6 @@ export default function FrameworkDetailPage(props: Props) {
|
||||
)}
|
||||
{hasAnyAction && (
|
||||
<ActionDropdown variant="secondary">
|
||||
{framework.canGenerateSOA
|
||||
&& (
|
||||
<DropdownItem
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
void generateFrameworkStateOfApplicability({
|
||||
variables: { frameworkId: framework.id },
|
||||
onCompleted: (data) => {
|
||||
if (
|
||||
data
|
||||
.generateFrameworkStateOfApplicability
|
||||
?.data
|
||||
) {
|
||||
const link
|
||||
= window.document.createElement("a");
|
||||
link.href
|
||||
= data.generateFrameworkStateOfApplicability.data;
|
||||
link.download = `${framework.organization.name}-${framework.name}-SOA.xlsx`;
|
||||
window.document.body.appendChild(link);
|
||||
link.click();
|
||||
window.document.body.removeChild(link);
|
||||
}
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{__("Download SOA")}
|
||||
</DropdownItem>
|
||||
)}
|
||||
{framework.canExport
|
||||
&& (
|
||||
<DropdownItem
|
||||
@@ -245,7 +189,6 @@ export default function FrameworkDetailPage(props: Props) {
|
||||
key={control.id}
|
||||
id={control.sectionTitle}
|
||||
description={control.name}
|
||||
excluded={control.status === "EXCLUDED"}
|
||||
to={`/organizations/${organizationId}/frameworks/${framework.id}/controls/${control.id}`}
|
||||
active={selectedControl?.id === control.id}
|
||||
/>
|
||||
|
||||
@@ -33,8 +33,6 @@ const controlFragment = graphql`
|
||||
name
|
||||
description
|
||||
sectionTitle
|
||||
status
|
||||
exclusionJustification
|
||||
bestPractice
|
||||
}
|
||||
`;
|
||||
@@ -64,31 +62,12 @@ const updateMutation = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
const schema = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
description: z.string().optional().nullable(),
|
||||
sectionTitle: z.string(),
|
||||
status: z.enum(["INCLUDED", "EXCLUDED"]),
|
||||
exclusionJustification: z.string().optional(),
|
||||
bestPractice: z.boolean(),
|
||||
})
|
||||
.refine(
|
||||
(data) => {
|
||||
if (data.status === "EXCLUDED") {
|
||||
return (
|
||||
data.exclusionJustification
|
||||
&& data.exclusionJustification.trim().length > 0
|
||||
);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message:
|
||||
"Exclusion justification is required when status is excluded",
|
||||
path: ["exclusionJustification"],
|
||||
},
|
||||
);
|
||||
const schema = z.object({
|
||||
name: z.string(),
|
||||
description: z.string().optional().nullable(),
|
||||
sectionTitle: z.string(),
|
||||
bestPractice: z.boolean(),
|
||||
});
|
||||
|
||||
export function FrameworkControlDialog(props: Props) {
|
||||
const { __ } = useTranslate();
|
||||
@@ -111,9 +90,6 @@ export function FrameworkControlDialog(props: Props) {
|
||||
name: frameworkControl?.name ?? "",
|
||||
description: frameworkControl?.description ?? "",
|
||||
sectionTitle: frameworkControl?.sectionTitle ?? "",
|
||||
status: frameworkControl?.status ?? "INCLUDED",
|
||||
exclusionJustification:
|
||||
frameworkControl?.exclusionJustification ?? "",
|
||||
bestPractice: frameworkControl?.bestPractice ?? true,
|
||||
}),
|
||||
[frameworkControl],
|
||||
@@ -141,11 +117,6 @@ export function FrameworkControlDialog(props: Props) {
|
||||
description: data.description || null,
|
||||
sectionTitle: data.sectionTitle,
|
||||
bestPractice: data.bestPractice,
|
||||
status: data.status,
|
||||
exclusionJustification:
|
||||
data.status === "EXCLUDED"
|
||||
? data.exclusionJustification
|
||||
: null,
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -159,11 +130,6 @@ export function FrameworkControlDialog(props: Props) {
|
||||
description: data.description || null,
|
||||
sectionTitle: data.sectionTitle,
|
||||
bestPractice: data.bestPractice ?? true,
|
||||
status: data.status,
|
||||
exclusionJustification:
|
||||
data.status === "EXCLUDED"
|
||||
? data.exclusionJustification
|
||||
: null,
|
||||
},
|
||||
connections: [props.connectionId!],
|
||||
},
|
||||
|
||||
@@ -39,7 +39,6 @@ func TestControl_Create(t *testing.T) {
|
||||
id
|
||||
name
|
||||
sectionTitle
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +52,6 @@ func TestControl_Create(t *testing.T) {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Status string `json:"status"`
|
||||
} `json:"node"`
|
||||
} `json:"controlEdge"`
|
||||
} `json:"createControl"`
|
||||
@@ -65,7 +63,6 @@ func TestControl_Create(t *testing.T) {
|
||||
"sectionTitle": "A.5",
|
||||
"name": "Information Security Policies",
|
||||
"description": "Policies for information security",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
}, &result)
|
||||
@@ -75,52 +72,6 @@ func TestControl_Create(t *testing.T) {
|
||||
assert.NotEmpty(t, control.ID)
|
||||
assert.Equal(t, "Information Security Policies", control.Name)
|
||||
assert.Equal(t, "A.5", control.SectionTitle)
|
||||
assert.Equal(t, "INCLUDED", control.Status)
|
||||
})
|
||||
|
||||
t.Run("with excluded status and justification", func(t *testing.T) {
|
||||
query := `
|
||||
mutation CreateControl($input: CreateControlInput!) {
|
||||
createControl(input: $input) {
|
||||
controlEdge {
|
||||
node {
|
||||
id
|
||||
status
|
||||
exclusionJustification
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
CreateControl struct {
|
||||
ControlEdge struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
ExclusionJustification *string `json:"exclusionJustification"`
|
||||
} `json:"node"`
|
||||
} `json:"controlEdge"`
|
||||
} `json:"createControl"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"frameworkId": frameworkID,
|
||||
"sectionTitle": "A.10",
|
||||
"name": "Cryptography",
|
||||
"description": "Cryptography controls",
|
||||
"status": "EXCLUDED",
|
||||
"exclusionJustification": "Not applicable - no cryptographic data processing",
|
||||
"bestPractice": false,
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
|
||||
control := result.CreateControl.ControlEdge.Node
|
||||
assert.Equal(t, "EXCLUDED", control.Status)
|
||||
assert.Equal(t, "Not applicable - no cryptographic data processing", *control.ExclusionJustification)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -167,46 +118,6 @@ func TestControl_Update(t *testing.T) {
|
||||
assert.Equal(t, "Updated Control Name", result.UpdateControl.Control.Name)
|
||||
})
|
||||
|
||||
t.Run("changes status from INCLUDED to EXCLUDED", func(t *testing.T) {
|
||||
statusTestControlID := factory.CreateControl(owner, frameworkID, factory.Attrs{
|
||||
"name": "Status Change Control",
|
||||
"status": "INCLUDED",
|
||||
})
|
||||
|
||||
query := `
|
||||
mutation UpdateControl($input: UpdateControlInput!) {
|
||||
updateControl(input: $input) {
|
||||
control {
|
||||
id
|
||||
status
|
||||
exclusionJustification
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
UpdateControl struct {
|
||||
Control struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
ExclusionJustification *string `json:"exclusionJustification"`
|
||||
} `json:"control"`
|
||||
} `json:"updateControl"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": statusTestControlID,
|
||||
"status": "EXCLUDED",
|
||||
"exclusionJustification": "No physical assets in scope",
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "EXCLUDED", result.UpdateControl.Control.Status)
|
||||
assert.Equal(t, "No physical assets in scope", *result.UpdateControl.Control.ExclusionJustification)
|
||||
})
|
||||
}
|
||||
|
||||
func TestControl_Delete(t *testing.T) {
|
||||
@@ -357,7 +268,6 @@ func TestControl_RequiredFields(t *testing.T) {
|
||||
"name": "Test Control",
|
||||
"description": "Test",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
},
|
||||
@@ -370,7 +280,6 @@ func TestControl_RequiredFields(t *testing.T) {
|
||||
"frameworkId": frameworkID,
|
||||
"description": "Test",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
},
|
||||
@@ -383,20 +292,6 @@ func TestControl_RequiredFields(t *testing.T) {
|
||||
"frameworkId": frameworkID,
|
||||
"name": "Test Control",
|
||||
"description": "Test",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
},
|
||||
wantError: true,
|
||||
},
|
||||
{
|
||||
name: "Missing status should fail",
|
||||
variables: map[string]any{
|
||||
"input": map[string]any{
|
||||
"frameworkId": frameworkID,
|
||||
"name": "Test Control",
|
||||
"description": "Test",
|
||||
"sectionTitle": "Section 1",
|
||||
"bestPractice": true,
|
||||
},
|
||||
},
|
||||
@@ -409,7 +304,6 @@ func TestControl_RequiredFields(t *testing.T) {
|
||||
"frameworkId": frameworkID,
|
||||
"name": "Test Control",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
},
|
||||
@@ -423,21 +317,6 @@ func TestControl_RequiredFields(t *testing.T) {
|
||||
"name": "Test Control",
|
||||
"description": "Test",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
},
|
||||
},
|
||||
wantError: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid status enum should fail",
|
||||
variables: map[string]any{
|
||||
"input": map[string]any{
|
||||
"frameworkId": frameworkID,
|
||||
"name": "Test Control",
|
||||
"description": "Test",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INVALID_STATUS",
|
||||
"bestPractice": true,
|
||||
},
|
||||
},
|
||||
wantError: true,
|
||||
@@ -524,7 +403,6 @@ func TestControl_OmittableDescription(t *testing.T) {
|
||||
"name": "Omittable Test Control",
|
||||
"description": "Initial description",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
}, &createResult)
|
||||
@@ -689,7 +567,6 @@ func TestControl_SubResolvers(t *testing.T) {
|
||||
"name": "SubResolver Test Control",
|
||||
"description": "Test description",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
}, &controlResult)
|
||||
@@ -832,152 +709,3 @@ func TestControl_SubResolvers(t *testing.T) {
|
||||
assert.GreaterOrEqual(t, len(result.Node.Measures.Edges), 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestControl_ExclusionJustification(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
// Create framework
|
||||
createFrameworkQuery := `
|
||||
mutation CreateFramework($input: CreateFrameworkInput!) {
|
||||
createFramework(input: $input) {
|
||||
frameworkEdge {
|
||||
node {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var frameworkResult struct {
|
||||
CreateFramework struct {
|
||||
FrameworkEdge struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"node"`
|
||||
} `json:"frameworkEdge"`
|
||||
} `json:"createFramework"`
|
||||
}
|
||||
|
||||
err := owner.Execute(createFrameworkQuery, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"name": fmt.Sprintf("Exclusion Test %d", time.Now().UnixNano()),
|
||||
},
|
||||
}, &frameworkResult)
|
||||
require.NoError(t, err)
|
||||
frameworkID := frameworkResult.CreateFramework.FrameworkEdge.Node.ID
|
||||
|
||||
t.Run("EXCLUDED status should have exclusionJustification", func(t *testing.T) {
|
||||
createControlQuery := `
|
||||
mutation CreateControl($input: CreateControlInput!) {
|
||||
createControl(input: $input) {
|
||||
controlEdge {
|
||||
node {
|
||||
id
|
||||
status
|
||||
exclusionJustification
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
CreateControl struct {
|
||||
ControlEdge struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
ExclusionJustification string `json:"exclusionJustification"`
|
||||
} `json:"node"`
|
||||
} `json:"controlEdge"`
|
||||
} `json:"createControl"`
|
||||
}
|
||||
|
||||
err := owner.Execute(createControlQuery, map[string]any{
|
||||
"input": map[string]any{
|
||||
"frameworkId": frameworkID,
|
||||
"name": "Excluded Control",
|
||||
"description": "Test",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "EXCLUDED",
|
||||
"exclusionJustification": "Not applicable to our business",
|
||||
"bestPractice": false,
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "EXCLUDED", result.CreateControl.ControlEdge.Node.Status)
|
||||
assert.Equal(t, "Not applicable to our business", result.CreateControl.ControlEdge.Node.ExclusionJustification)
|
||||
})
|
||||
|
||||
t.Run("Change status from INCLUDED to EXCLUDED", func(t *testing.T) {
|
||||
// Create included control first
|
||||
createControlQuery := `
|
||||
mutation CreateControl($input: CreateControlInput!) {
|
||||
createControl(input: $input) {
|
||||
controlEdge {
|
||||
node {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var createResult struct {
|
||||
CreateControl struct {
|
||||
ControlEdge struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"node"`
|
||||
} `json:"controlEdge"`
|
||||
} `json:"createControl"`
|
||||
}
|
||||
|
||||
err := owner.Execute(createControlQuery, map[string]any{
|
||||
"input": map[string]any{
|
||||
"frameworkId": frameworkID,
|
||||
"name": "To Be Excluded Control",
|
||||
"description": "Test",
|
||||
"sectionTitle": "Section 2",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
}, &createResult)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Update to excluded
|
||||
updateControlQuery := `
|
||||
mutation UpdateControl($input: UpdateControlInput!) {
|
||||
updateControl(input: $input) {
|
||||
control {
|
||||
id
|
||||
status
|
||||
exclusionJustification
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var updateResult struct {
|
||||
UpdateControl struct {
|
||||
Control struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
ExclusionJustification string `json:"exclusionJustification"`
|
||||
} `json:"control"`
|
||||
} `json:"updateControl"`
|
||||
}
|
||||
|
||||
err = owner.Execute(updateControlQuery, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": createResult.CreateControl.ControlEdge.Node.ID,
|
||||
"status": "EXCLUDED",
|
||||
"exclusionJustification": "Decided to exclude",
|
||||
},
|
||||
}, &updateResult)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -81,7 +81,6 @@ func TestControlMeasureMapping_CreateDelete(t *testing.T) {
|
||||
"name": "Control for Mapping",
|
||||
"description": "Test control for mapping",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
}, &createControlResult)
|
||||
@@ -361,7 +360,6 @@ func TestControlDocumentMapping_CreateDelete(t *testing.T) {
|
||||
"name": "Control for Document Mapping",
|
||||
"description": "Test control",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
}, &createControlResult)
|
||||
@@ -503,7 +501,6 @@ func TestControlAuditMapping_CreateDelete(t *testing.T) {
|
||||
"name": "Control for Audit Mapping",
|
||||
"description": "Test control",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
}, &createControlResult)
|
||||
@@ -641,7 +638,6 @@ func TestControlSnapshotMapping_CreateDelete(t *testing.T) {
|
||||
"name": "Control for Snapshot Mapping",
|
||||
"description": "Test control",
|
||||
"sectionTitle": "Section 1",
|
||||
"status": "INCLUDED",
|
||||
"bestPractice": true,
|
||||
},
|
||||
}, &createControlResult)
|
||||
|
||||
@@ -384,7 +384,7 @@ func TestRBAC(t *testing.T) {
|
||||
client: owner,
|
||||
query: createControlMutation,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"input": map[string]any{"frameworkId": frameworkID, "name": factory.SafeName("Control"), "description": "Test", "sectionTitle": factory.SafeName("Section Owner"), "status": "INCLUDED", "bestPractice": true}}
|
||||
return map[string]any{"input": map[string]any{"frameworkId": frameworkID, "name": factory.SafeName("Control"), "description": "Test", "sectionTitle": factory.SafeName("Section Owner"), "bestPractice": true}}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
@@ -394,7 +394,7 @@ func TestRBAC(t *testing.T) {
|
||||
client: admin,
|
||||
query: createControlMutation,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"input": map[string]any{"frameworkId": frameworkID, "name": factory.SafeName("Control"), "description": "Test", "sectionTitle": factory.SafeName("Section Admin"), "status": "INCLUDED", "bestPractice": true}}
|
||||
return map[string]any{"input": map[string]any{"frameworkId": frameworkID, "name": factory.SafeName("Control"), "description": "Test", "sectionTitle": factory.SafeName("Section Admin"), "bestPractice": true}}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
@@ -404,7 +404,7 @@ func TestRBAC(t *testing.T) {
|
||||
client: viewer,
|
||||
query: createControlMutation,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"input": map[string]any{"frameworkId": frameworkID, "name": factory.SafeName("Control"), "description": "Test", "sectionTitle": factory.SafeName("Section Viewer"), "status": "INCLUDED", "bestPractice": true}}
|
||||
return map[string]any{"input": map[string]any{"frameworkId": frameworkID, "name": factory.SafeName("Control"), "description": "Test", "sectionTitle": factory.SafeName("Section Viewer"), "bestPractice": true}}
|
||||
},
|
||||
shouldAllow: false,
|
||||
},
|
||||
|
||||
@@ -205,7 +205,6 @@ func CreateControl(c *testutil.Client, frameworkID string, attrs ...Attrs) strin
|
||||
"name": a.getString("name", SafeName("Control")),
|
||||
"description": a.getString("description", "Test control description"),
|
||||
"sectionTitle": a.getString("sectionTitle", fmt.Sprintf("Section %s", gofakeit.LetterN(3))),
|
||||
"status": a.getString("status", "INCLUDED"),
|
||||
"bestPractice": a.getBool("bestPractice", true),
|
||||
}
|
||||
|
||||
|
||||
6
go.mod
6
go.mod
@@ -26,7 +26,6 @@ require (
|
||||
github.com/scim2/filter-parser/v2 v2.2.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/vektah/gqlparser/v2 v2.5.31
|
||||
github.com/xuri/excelize/v2 v2.10.0
|
||||
github.com/yuin/goldmark v1.7.16
|
||||
go.gearno.de/crypto/uuid v0.1.1-0.20251208105319-3f587312a712
|
||||
go.gearno.de/kit v0.1.1
|
||||
@@ -109,8 +108,6 @@ require (
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.67.5 // indirect
|
||||
github.com/prometheus/procfs v0.19.2 // indirect
|
||||
github.com/richardlehane/mscfb v1.0.6 // indirect
|
||||
github.com/richardlehane/msoleps v1.0.6 // indirect
|
||||
github.com/russellhaering/goxmldsig v1.5.0 // indirect
|
||||
github.com/sosodev/duration v1.3.1 // indirect
|
||||
github.com/spf13/cobra v1.10.1 // indirect
|
||||
@@ -120,10 +117,7 @@ require (
|
||||
github.com/tidwall/match v1.2.0 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
github.com/tiendc/go-deepcopy v1.7.2 // indirect
|
||||
github.com/urfave/cli/v3 v3.6.1 // indirect
|
||||
github.com/xuri/efp v0.0.1 // indirect
|
||||
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
||||
go.gearno.de/x/panicf v0.1.1 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
|
||||
12
go.sum
12
go.sum
@@ -205,10 +205,6 @@ github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTU
|
||||
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
|
||||
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||
github.com/richardlehane/mscfb v1.0.6 h1:eN3bvvZCp00bs7Zf52bxNwAx5lJDBK1tCuH19qq5aC8=
|
||||
github.com/richardlehane/mscfb v1.0.6/go.mod h1:pe0+IUIc0AHh0+teNzBlJCtSyZdFOGgV4ZK9bsoV+Jo=
|
||||
github.com/richardlehane/msoleps v1.0.6 h1:9BvkpjvD+iUBalUY4esMwv6uBkfOip/Lzvd93jvR9gg=
|
||||
github.com/richardlehane/msoleps v1.0.6/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/russellhaering/goxmldsig v1.5.0 h1:AU2UkkYIUOTyZRbe08XMThaOCelArgvNfYapcmSjBNw=
|
||||
@@ -245,18 +241,10 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/tiendc/go-deepcopy v1.7.2 h1:Ut2yYR7W9tWjTQitganoIue4UGxZwCcJy3orjrrIj44=
|
||||
github.com/tiendc/go-deepcopy v1.7.2/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ=
|
||||
github.com/urfave/cli/v3 v3.6.1 h1:j8Qq8NyUawj/7rTYdBGrxcH7A/j7/G8Q5LhWEW4G3Mo=
|
||||
github.com/urfave/cli/v3 v3.6.1/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
|
||||
github.com/vektah/gqlparser/v2 v2.5.31 h1:YhWGA1mfTjID7qJhd1+Vxhpk5HTgydrGU9IgkWBTJ7k=
|
||||
github.com/vektah/gqlparser/v2 v2.5.31/go.mod h1:c1I28gSOVNzlfc4WuDlqU7voQnsqI6OG2amkBAFmgts=
|
||||
github.com/xuri/efp v0.0.1 h1:fws5Rv3myXyYni8uwj2qKjVaRP30PdjeYe2Y6FDsCL8=
|
||||
github.com/xuri/efp v0.0.1/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
||||
github.com/xuri/excelize/v2 v2.10.0 h1:8aKsP7JD39iKLc6dH5Tw3dgV3sPRh8uRVXu/fMstfW4=
|
||||
github.com/xuri/excelize/v2 v2.10.0/go.mod h1:SC5TzhQkaOsTWpANfm+7bJCldzcnU/jrhqkTi/iBHBU=
|
||||
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 h1:+C0TIdyyYmzadGaL/HBLbf3WdLgC29pgyhTjAT/0nuE=
|
||||
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
|
||||
github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE=
|
||||
|
||||
@@ -44,30 +44,6 @@ export const description: INodeProperties[] = [
|
||||
description: 'The name of the control',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Status',
|
||||
name: 'status',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['control'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Included',
|
||||
value: 'INCLUDED',
|
||||
},
|
||||
{
|
||||
name: 'Excluded',
|
||||
value: 'EXCLUDED',
|
||||
},
|
||||
],
|
||||
default: 'INCLUDED',
|
||||
description: 'The status of the control',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Description',
|
||||
name: 'description',
|
||||
@@ -81,19 +57,6 @@ export const description: INodeProperties[] = [
|
||||
default: '',
|
||||
description: 'The description of the control',
|
||||
},
|
||||
{
|
||||
displayName: 'Exclusion Justification',
|
||||
name: 'exclusionJustification',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['control'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description: 'The justification for excluding the control',
|
||||
},
|
||||
];
|
||||
|
||||
export async function execute(
|
||||
@@ -103,9 +66,7 @@ export async function execute(
|
||||
const frameworkId = this.getNodeParameter('frameworkId', itemIndex) as string;
|
||||
const sectionTitle = this.getNodeParameter('sectionTitle', itemIndex) as string;
|
||||
const name = this.getNodeParameter('name', itemIndex) as string;
|
||||
const status = this.getNodeParameter('status', itemIndex) as string;
|
||||
const description = this.getNodeParameter('description', itemIndex, '') as string;
|
||||
const exclusionJustification = this.getNodeParameter('exclusionJustification', itemIndex, '') as string;
|
||||
|
||||
const query = `
|
||||
mutation CreateControl($input: CreateControlInput!) {
|
||||
@@ -116,8 +77,6 @@ export async function execute(
|
||||
sectionTitle
|
||||
name
|
||||
description
|
||||
status
|
||||
exclusionJustification
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
@@ -131,9 +90,8 @@ export async function execute(
|
||||
frameworkId,
|
||||
sectionTitle,
|
||||
name,
|
||||
status,
|
||||
bestPractice: true,
|
||||
...(description && { description }),
|
||||
...(exclusionJustification && { exclusionJustification }),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -144,4 +102,3 @@ export async function execute(
|
||||
pairedItem: { item: itemIndex },
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ export async function execute(
|
||||
sectionTitle
|
||||
name
|
||||
description
|
||||
status
|
||||
exclusionJustification
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
|
||||
@@ -67,8 +67,6 @@ export async function execute(
|
||||
sectionTitle
|
||||
name
|
||||
description
|
||||
status
|
||||
exclusionJustification
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
|
||||
@@ -55,42 +55,6 @@ export const description: INodeProperties[] = [
|
||||
default: '',
|
||||
description: 'The description of the control',
|
||||
},
|
||||
{
|
||||
displayName: 'Status',
|
||||
name: 'status',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['control'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Included',
|
||||
value: 'INCLUDED',
|
||||
},
|
||||
{
|
||||
name: 'Excluded',
|
||||
value: 'EXCLUDED',
|
||||
},
|
||||
],
|
||||
default: 'INCLUDED',
|
||||
description: 'The status of the control',
|
||||
},
|
||||
{
|
||||
displayName: 'Exclusion Justification',
|
||||
name: 'exclusionJustification',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['control'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description: 'The justification for excluding the control',
|
||||
},
|
||||
];
|
||||
|
||||
export async function execute(
|
||||
@@ -101,8 +65,6 @@ export async function execute(
|
||||
const sectionTitle = this.getNodeParameter('sectionTitle', itemIndex, '') as string;
|
||||
const name = this.getNodeParameter('name', itemIndex, '') as string;
|
||||
const description = this.getNodeParameter('description', itemIndex, '') as string;
|
||||
const status = this.getNodeParameter('status', itemIndex, '') as string;
|
||||
const exclusionJustification = this.getNodeParameter('exclusionJustification', itemIndex, '') as string;
|
||||
|
||||
const query = `
|
||||
mutation UpdateControl($input: UpdateControlInput!) {
|
||||
@@ -112,8 +74,6 @@ export async function execute(
|
||||
sectionTitle
|
||||
name
|
||||
description
|
||||
status
|
||||
exclusionJustification
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
@@ -125,8 +85,6 @@ export async function execute(
|
||||
if (sectionTitle) input.sectionTitle = sectionTitle;
|
||||
if (name) input.name = name;
|
||||
if (description) input.description = description;
|
||||
if (status) input.status = status;
|
||||
if (exclusionJustification) input.exclusionJustification = exclusionJustification;
|
||||
|
||||
const responseData = await proboApiRequest.call(this, query, { input });
|
||||
|
||||
@@ -135,4 +93,3 @@ export async function execute(
|
||||
pairedItem: { item: itemIndex },
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ type Props = {
|
||||
active?: boolean;
|
||||
id: string;
|
||||
description?: string;
|
||||
excluded?: boolean;
|
||||
to: string;
|
||||
} & HTMLAttributes<HTMLAnchorElement>;
|
||||
|
||||
@@ -27,39 +26,19 @@ const classNames = tv({
|
||||
id: "bg-highlight",
|
||||
},
|
||||
},
|
||||
excluded: {
|
||||
true: {
|
||||
wrapper: "opacity-60",
|
||||
},
|
||||
false: {
|
||||
wrapper: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
active: true,
|
||||
excluded: true,
|
||||
class: {
|
||||
wrapper: "bg-tertiary-pressed opacity-60",
|
||||
id: "bg-active",
|
||||
},
|
||||
},
|
||||
],
|
||||
defaultVariants: {
|
||||
active: false,
|
||||
excluded: false,
|
||||
},
|
||||
});
|
||||
|
||||
export function ControlItem({ active, id, description, excluded, to, ...props }: Props) {
|
||||
export function ControlItem({ active, id, description, to, ...props }: Props) {
|
||||
const {
|
||||
wrapper,
|
||||
id: idCls,
|
||||
description: descriptionCls,
|
||||
} = classNames({
|
||||
active,
|
||||
excluded,
|
||||
});
|
||||
|
||||
const ref = useRef<HTMLAnchorElement>(null);
|
||||
|
||||
@@ -30,17 +30,15 @@ import (
|
||||
|
||||
type (
|
||||
Control struct {
|
||||
ID gid.GID `db:"id"`
|
||||
OrganizationID gid.GID `db:"organization_id"`
|
||||
SectionTitle string `db:"section_title"`
|
||||
FrameworkID gid.GID `db:"framework_id"`
|
||||
Name string `db:"name"`
|
||||
Description *string `db:"description"`
|
||||
Status ControlStatus `db:"status"`
|
||||
ExclusionJustification *string `db:"exclusion_justification"`
|
||||
BestPractice bool `db:"best_practice"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
ID gid.GID `db:"id"`
|
||||
OrganizationID gid.GID `db:"organization_id"`
|
||||
SectionTitle string `db:"section_title"`
|
||||
FrameworkID gid.GID `db:"framework_id"`
|
||||
Name string `db:"name"`
|
||||
Description *string `db:"description"`
|
||||
BestPractice bool `db:"best_practice"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
Controls []*Control
|
||||
@@ -132,8 +130,6 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.best_practice,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
@@ -152,8 +148,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -245,8 +239,6 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.best_practice,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
@@ -265,8 +257,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -364,8 +354,6 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.best_practice,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
@@ -390,8 +378,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -471,8 +457,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -567,8 +551,6 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.best_practice,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
@@ -587,8 +569,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -635,8 +615,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -685,8 +663,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -739,8 +715,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -783,8 +757,6 @@ INSERT INTO
|
||||
section_title,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -797,8 +769,6 @@ VALUES (
|
||||
@section_title,
|
||||
@name,
|
||||
@description,
|
||||
@status,
|
||||
@exclusion_justification,
|
||||
@best_practice,
|
||||
@created_at,
|
||||
@updated_at
|
||||
@@ -806,18 +776,16 @@ VALUES (
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"control_id": c.ID,
|
||||
"organization_id": c.OrganizationID,
|
||||
"framework_id": c.FrameworkID,
|
||||
"section_title": c.SectionTitle,
|
||||
"name": c.Name,
|
||||
"description": c.Description,
|
||||
"status": c.Status,
|
||||
"exclusion_justification": c.ExclusionJustification,
|
||||
"best_practice": c.BestPractice,
|
||||
"created_at": c.CreatedAt,
|
||||
"updated_at": c.UpdatedAt,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"control_id": c.ID,
|
||||
"organization_id": c.OrganizationID,
|
||||
"framework_id": c.FrameworkID,
|
||||
"section_title": c.SectionTitle,
|
||||
"name": c.Name,
|
||||
"description": c.Description,
|
||||
"best_practice": c.BestPractice,
|
||||
"created_at": c.CreatedAt,
|
||||
"updated_at": c.UpdatedAt,
|
||||
}
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
|
||||
@@ -866,8 +834,6 @@ UPDATE controls SET
|
||||
name = @name,
|
||||
description = @description,
|
||||
section_title = @section_title,
|
||||
status = @status,
|
||||
exclusion_justification = @exclusion_justification,
|
||||
best_practice = @best_practice,
|
||||
updated_at = @updated_at
|
||||
WHERE %s
|
||||
@@ -876,14 +842,12 @@ WHERE %s
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"control_id": c.ID,
|
||||
"name": c.Name,
|
||||
"description": c.Description,
|
||||
"section_title": c.SectionTitle,
|
||||
"status": c.Status,
|
||||
"exclusion_justification": c.ExclusionJustification,
|
||||
"best_practice": c.BestPractice,
|
||||
"updated_at": c.UpdatedAt,
|
||||
"control_id": c.ID,
|
||||
"name": c.Name,
|
||||
"description": c.Description,
|
||||
"section_title": c.SectionTitle,
|
||||
"best_practice": c.BestPractice,
|
||||
"updated_at": c.UpdatedAt,
|
||||
}
|
||||
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
@@ -963,8 +927,6 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.best_practice,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
@@ -983,8 +945,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -1077,8 +1037,6 @@ WITH ctrl AS (
|
||||
c.tenant_id,
|
||||
c.name,
|
||||
c.description,
|
||||
c.status,
|
||||
c.exclusion_justification,
|
||||
c.best_practice,
|
||||
c.created_at,
|
||||
c.updated_at,
|
||||
@@ -1097,8 +1055,6 @@ SELECT
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
exclusion_justification,
|
||||
best_practice,
|
||||
created_at,
|
||||
updated_at
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ControlStatus string
|
||||
|
||||
const (
|
||||
ControlStatusIncluded ControlStatus = "INCLUDED"
|
||||
ControlStatusExcluded ControlStatus = "EXCLUDED"
|
||||
)
|
||||
|
||||
func ControlStatuses() []ControlStatus {
|
||||
return []ControlStatus{
|
||||
ControlStatusIncluded,
|
||||
ControlStatusExcluded,
|
||||
}
|
||||
}
|
||||
|
||||
func (cs ControlStatus) String() string {
|
||||
return string(cs)
|
||||
}
|
||||
|
||||
func (cs *ControlStatus) Scan(value interface{}) error {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
switch v {
|
||||
case "INCLUDED":
|
||||
*cs = ControlStatusIncluded
|
||||
case "EXCLUDED":
|
||||
*cs = ControlStatusExcluded
|
||||
default:
|
||||
return fmt.Errorf("invalid ControlStatus value: %q", v)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unsupported type for ControlStatus: %T", value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cs ControlStatus) Value() (driver.Value, error) {
|
||||
return cs.String(), nil
|
||||
}
|
||||
@@ -88,7 +88,7 @@ func (states DocumentVersionSignatureStates) Value() (driver.Value, error) {
|
||||
if i > 0 {
|
||||
result.WriteString(",")
|
||||
}
|
||||
result.WriteString(fmt.Sprintf("%q", state.String()))
|
||||
fmt.Fprintf(&result, "%q", state.String())
|
||||
}
|
||||
result.WriteString("}")
|
||||
return result.String(), nil
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
InvitationStatus string
|
||||
InvitationStatus string
|
||||
InvitationStatuses []InvitationStatus
|
||||
)
|
||||
|
||||
@@ -74,7 +74,7 @@ func (statuses InvitationStatuses) Value() (driver.Value, error) {
|
||||
if i > 0 {
|
||||
result.WriteString(",")
|
||||
}
|
||||
result.WriteString(fmt.Sprintf("%q", status.String()))
|
||||
fmt.Fprintf(&result, "%q", status.String())
|
||||
}
|
||||
result.WriteString("}")
|
||||
return result.String(), nil
|
||||
|
||||
6
pkg/coredata/migrations/20260217T120000Z.sql
Normal file
6
pkg/coredata/migrations/20260217T120000Z.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
ALTER TABLE controls ALTER COLUMN status DROP NOT NULL;
|
||||
|
||||
-- TODO: drop columns and type once all code references are fully removed
|
||||
-- ALTER TABLE controls DROP COLUMN status;
|
||||
-- ALTER TABLE controls DROP COLUMN exclusion_justification;
|
||||
-- DROP TYPE control_status;
|
||||
@@ -105,8 +105,7 @@ const (
|
||||
ActionFrameworkCreate = "core:framework:create"
|
||||
ActionFrameworkUpdate = "core:framework:update"
|
||||
ActionFrameworkDelete = "core:framework:delete"
|
||||
ActionFrameworkStateOfApplicabilityGenerate = "core:framework:generate-state-of-applicability"
|
||||
ActionFrameworkExport = "core:framework:export"
|
||||
ActionFrameworkExport = "core:framework:export"
|
||||
ActionFrameworkImport = "core:framework:import"
|
||||
|
||||
// Control actions
|
||||
|
||||
@@ -32,24 +32,20 @@ type (
|
||||
}
|
||||
|
||||
CreateControlRequest struct {
|
||||
ID gid.GID
|
||||
FrameworkID gid.GID
|
||||
Name string
|
||||
Description *string
|
||||
SectionTitle string
|
||||
Status *coredata.ControlStatus
|
||||
ExclusionJustification *string
|
||||
BestPractice bool
|
||||
ID gid.GID
|
||||
FrameworkID gid.GID
|
||||
Name string
|
||||
Description *string
|
||||
SectionTitle string
|
||||
BestPractice bool
|
||||
}
|
||||
|
||||
UpdateControlRequest struct {
|
||||
ID gid.GID
|
||||
Name *string
|
||||
Description **string
|
||||
SectionTitle *string
|
||||
Status *coredata.ControlStatus
|
||||
ExclusionJustification *string
|
||||
BestPractice *bool
|
||||
ID gid.GID
|
||||
Name *string
|
||||
Description **string
|
||||
SectionTitle *string
|
||||
BestPractice *bool
|
||||
}
|
||||
)
|
||||
|
||||
@@ -60,8 +56,6 @@ func (ccr *CreateControlRequest) Validate() error {
|
||||
v.Check(ccr.Name, "name", validator.Required(), validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(ccr.Description, "description", validator.Required(), validator.SafeText(ContentMaxLength))
|
||||
v.Check(ccr.SectionTitle, "section_title", validator.Required(), validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(ccr.Status, "status", validator.Required(), validator.OneOfSlice(coredata.ControlStatuses()))
|
||||
v.Check(ccr.ExclusionJustification, "exclusion_justification", validator.SafeText(TitleMaxLength))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
@@ -73,8 +67,6 @@ func (ucr *UpdateControlRequest) Validate() error {
|
||||
v.Check(ucr.Name, "name", validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(ucr.Description, "description", validator.SafeText(ContentMaxLength))
|
||||
v.Check(ucr.SectionTitle, "section_title", validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(ucr.Status, "status", validator.OneOfSlice(coredata.ControlStatuses()))
|
||||
v.Check(ucr.ExclusionJustification, "exclusion_justification", validator.SafeText(TitleMaxLength))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
@@ -839,16 +831,14 @@ func (s ControlService) Create(
|
||||
framework := &coredata.Framework{}
|
||||
|
||||
control := &coredata.Control{
|
||||
ID: gid.New(s.svc.scope.GetTenantID(), coredata.ControlEntityType),
|
||||
FrameworkID: req.FrameworkID,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
SectionTitle: req.SectionTitle,
|
||||
Status: *req.Status,
|
||||
ExclusionJustification: req.ExclusionJustification,
|
||||
BestPractice: req.BestPractice,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
ID: gid.New(s.svc.scope.GetTenantID(), coredata.ControlEntityType),
|
||||
FrameworkID: req.FrameworkID,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
SectionTitle: req.SectionTitle,
|
||||
BestPractice: req.BestPractice,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
@@ -921,14 +911,6 @@ func (s ControlService) Update(
|
||||
control.SectionTitle = *req.SectionTitle
|
||||
}
|
||||
|
||||
if req.Status != nil {
|
||||
control.Status = *req.Status
|
||||
}
|
||||
|
||||
if req.ExclusionJustification != nil {
|
||||
control.ExclusionJustification = req.ExclusionJustification
|
||||
}
|
||||
|
||||
if req.BestPractice != nil {
|
||||
control.BestPractice = *req.BestPractice
|
||||
}
|
||||
|
||||
@@ -36,12 +36,10 @@ import (
|
||||
"go.probo.inc/probo/pkg/mail"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/slug"
|
||||
"go.probo.inc/probo/pkg/soagen"
|
||||
"go.probo.inc/probo/pkg/validator"
|
||||
)
|
||||
|
||||
const (
|
||||
maxStateOfApplicabilityLimit = 10_000
|
||||
frameworkExportEmailExpiresIn = 24 * time.Hour
|
||||
)
|
||||
|
||||
@@ -584,7 +582,6 @@ func (s FrameworkService) Import(
|
||||
SectionTitle: control.ID,
|
||||
Name: control.Name,
|
||||
Description: &description,
|
||||
Status: coredata.ControlStatusIncluded,
|
||||
BestPractice: bestPractice,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
@@ -605,182 +602,6 @@ func (s FrameworkService) Import(
|
||||
return framework, nil
|
||||
}
|
||||
|
||||
func (s FrameworkService) StateOfApplicability(ctx context.Context, frameworkID gid.GID) ([]byte, error) {
|
||||
rows := []soagen.SOARowData{}
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
framework := &coredata.Framework{}
|
||||
if err := framework.LoadByID(ctx, conn, s.svc.scope, frameworkID); err != nil {
|
||||
return fmt.Errorf("cannot load framework: %w", err)
|
||||
}
|
||||
|
||||
controls := coredata.Controls{}
|
||||
err := controls.LoadByFrameworkID(
|
||||
ctx,
|
||||
conn,
|
||||
s.svc.scope,
|
||||
frameworkID,
|
||||
page.NewCursor(
|
||||
maxStateOfApplicabilityLimit,
|
||||
nil,
|
||||
page.Head,
|
||||
page.OrderBy[coredata.ControlOrderField]{
|
||||
Field: coredata.ControlOrderFieldSectionTitle,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
},
|
||||
),
|
||||
coredata.NewControlFilter(nil),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load controls: %w", err)
|
||||
}
|
||||
|
||||
for _, control := range controls {
|
||||
exclusionJustification := ""
|
||||
if control.Status == coredata.ControlStatusExcluded {
|
||||
if control.ExclusionJustification == nil {
|
||||
return fmt.Errorf("exclusion justification is required for excluded controls")
|
||||
}
|
||||
exclusionJustification = *control.ExclusionJustification
|
||||
}
|
||||
|
||||
applicability := soagen.NewApplicability("Yes", true)
|
||||
if control.Status == coredata.ControlStatusExcluded {
|
||||
applicability = soagen.NewApplicability("No", false)
|
||||
}
|
||||
|
||||
bestPractice := ref.Ref(true)
|
||||
if control.Status == coredata.ControlStatusExcluded {
|
||||
bestPractice = ref.Ref(false)
|
||||
}
|
||||
|
||||
row := soagen.SOARowData{
|
||||
SectionTitle: control.SectionTitle,
|
||||
ControlName: control.Name,
|
||||
Applicability: applicability,
|
||||
ExclusionJustification: exclusionJustification,
|
||||
Regulatory: ref.Ref(false),
|
||||
Contractual: ref.Ref(false),
|
||||
BestPractice: bestPractice,
|
||||
RiskAssessment: ref.Ref(false),
|
||||
SecurityMeasures: []string{},
|
||||
}
|
||||
|
||||
if control.Status == coredata.ControlStatusExcluded {
|
||||
rows = append(rows, row)
|
||||
continue
|
||||
}
|
||||
|
||||
measures := coredata.Measures{}
|
||||
err = measures.LoadByControlID(
|
||||
ctx,
|
||||
conn,
|
||||
s.svc.scope,
|
||||
control.ID,
|
||||
page.NewCursor(
|
||||
maxStateOfApplicabilityLimit,
|
||||
nil,
|
||||
page.Head,
|
||||
page.OrderBy[coredata.MeasureOrderField]{
|
||||
Field: coredata.MeasureOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
},
|
||||
),
|
||||
coredata.NewMeasureFilter(nil, nil),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load measures: %w", err)
|
||||
}
|
||||
|
||||
for _, measure := range measures {
|
||||
risks := coredata.Risks{}
|
||||
var nilSnapshotID *gid.GID = nil
|
||||
risksCount, err := risks.CountByMeasureID(
|
||||
ctx,
|
||||
conn,
|
||||
s.svc.scope,
|
||||
measure.ID,
|
||||
coredata.NewRiskFilter(nil, &nilSnapshotID),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot count risks: %w", err)
|
||||
}
|
||||
|
||||
if risksCount > 0 {
|
||||
row.RiskAssessment = ref.Ref(true)
|
||||
}
|
||||
|
||||
row.SecurityMeasures = append(row.SecurityMeasures, measure.Name)
|
||||
}
|
||||
|
||||
documents := coredata.Documents{}
|
||||
err = documents.LoadByControlID(
|
||||
ctx,
|
||||
conn,
|
||||
s.svc.scope,
|
||||
control.ID,
|
||||
page.NewCursor(
|
||||
0,
|
||||
nil,
|
||||
page.Head,
|
||||
page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
},
|
||||
),
|
||||
coredata.NewDocumentFilter(nil),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load documents: %w", err)
|
||||
}
|
||||
|
||||
for _, document := range documents {
|
||||
risks := coredata.Risks{}
|
||||
var nilSnapshotID *gid.GID = nil
|
||||
risksCount, err := risks.CountByDocumentID(
|
||||
ctx,
|
||||
conn,
|
||||
s.svc.scope,
|
||||
document.ID,
|
||||
coredata.NewRiskFilter(nil, &nilSnapshotID),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot count risks: %w", err)
|
||||
}
|
||||
|
||||
if risksCount > 0 {
|
||||
row.RiskAssessment = ref.Ref(true)
|
||||
}
|
||||
|
||||
row.SecurityMeasures = append(row.SecurityMeasures, document.Title)
|
||||
}
|
||||
|
||||
rows = append(rows, row)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
output, err := soagen.GenerateExcel(
|
||||
soagen.SOAData{
|
||||
Rows: rows,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot generate Excel file: %w", err)
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (s FrameworkService) SendExportEmail(
|
||||
ctx context.Context,
|
||||
fileID gid.GID,
|
||||
|
||||
@@ -1030,14 +1030,6 @@ enum DataClassification
|
||||
)
|
||||
}
|
||||
|
||||
enum ControlStatus
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.ControlStatus") {
|
||||
INCLUDED
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ControlStatusIncluded")
|
||||
EXCLUDED
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ControlStatusExcluded")
|
||||
}
|
||||
|
||||
enum AuditOrderField
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.AuditOrderField") {
|
||||
CREATED_AT
|
||||
@@ -2051,8 +2043,6 @@ type Control implements Node {
|
||||
sectionTitle: String!
|
||||
name: String!
|
||||
description: String
|
||||
status: ControlStatus!
|
||||
exclusionJustification: String
|
||||
bestPractice: Boolean!
|
||||
regulatory: Boolean! @goField(forceResolver: true)
|
||||
contractual: Boolean! @goField(forceResolver: true)
|
||||
@@ -3287,9 +3277,6 @@ type Mutation {
|
||||
updateFramework(input: UpdateFrameworkInput!): UpdateFrameworkPayload!
|
||||
importFramework(input: ImportFrameworkInput!): ImportFrameworkPayload!
|
||||
deleteFramework(input: DeleteFrameworkInput!): DeleteFrameworkPayload!
|
||||
generateFrameworkStateOfApplicability(
|
||||
input: GenerateFrameworkStateOfApplicabilityInput!
|
||||
): GenerateFrameworkStateOfApplicabilityPayload!
|
||||
exportFramework(input: ExportFrameworkInput!): ExportFrameworkPayload!
|
||||
# Control mutations
|
||||
createControl(input: CreateControlInput!): CreateControlPayload!
|
||||
@@ -3576,14 +3563,6 @@ type Mutation {
|
||||
}
|
||||
|
||||
# Input Types
|
||||
input GenerateFrameworkStateOfApplicabilityInput {
|
||||
frameworkId: ID!
|
||||
}
|
||||
|
||||
type GenerateFrameworkStateOfApplicabilityPayload {
|
||||
data: String!
|
||||
}
|
||||
|
||||
input UpdateOrganizationContextInput {
|
||||
organizationId: ID!
|
||||
summary: String @goField(omittable: true)
|
||||
@@ -4146,8 +4125,6 @@ input CreateControlInput {
|
||||
sectionTitle: String!
|
||||
name: String!
|
||||
description: String
|
||||
status: ControlStatus!
|
||||
exclusionJustification: String
|
||||
bestPractice: Boolean!
|
||||
}
|
||||
|
||||
@@ -4156,8 +4133,6 @@ input UpdateControlInput {
|
||||
sectionTitle: String
|
||||
name: String
|
||||
description: String @goField(omittable: true)
|
||||
status: ControlStatus
|
||||
exclusionJustification: String
|
||||
bestPractice: Boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -258,26 +258,24 @@ type ComplexityRoot struct {
|
||||
}
|
||||
|
||||
Control struct {
|
||||
Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) int
|
||||
BestPractice func(childComplexity int) int
|
||||
Contractual func(childComplexity int) int
|
||||
CreatedAt func(childComplexity int) int
|
||||
Description func(childComplexity int) int
|
||||
Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) int
|
||||
ExclusionJustification func(childComplexity int) int
|
||||
Framework func(childComplexity int) int
|
||||
ID func(childComplexity int) int
|
||||
Measures func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) int
|
||||
Name func(childComplexity int) int
|
||||
Obligations func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) int
|
||||
Organization func(childComplexity int) int
|
||||
Permission func(childComplexity int, action string) int
|
||||
Regulatory func(childComplexity int) int
|
||||
RiskAssessment func(childComplexity int) int
|
||||
SectionTitle func(childComplexity int) int
|
||||
Snapshots func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) int
|
||||
Status func(childComplexity int) int
|
||||
UpdatedAt func(childComplexity int) int
|
||||
Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.AuditOrderBy) int
|
||||
BestPractice func(childComplexity int) int
|
||||
Contractual func(childComplexity int) int
|
||||
CreatedAt func(childComplexity int) int
|
||||
Description func(childComplexity int) int
|
||||
Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) int
|
||||
Framework func(childComplexity int) int
|
||||
ID func(childComplexity int) int
|
||||
Measures func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) int
|
||||
Name func(childComplexity int) int
|
||||
Obligations func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ObligationOrderBy, filter *types.ObligationFilter) int
|
||||
Organization func(childComplexity int) int
|
||||
Permission func(childComplexity int, action string) int
|
||||
Regulatory func(childComplexity int) int
|
||||
RiskAssessment func(childComplexity int) int
|
||||
SectionTitle func(childComplexity int) int
|
||||
Snapshots func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) int
|
||||
UpdatedAt func(childComplexity int) int
|
||||
}
|
||||
|
||||
ControlConnection struct {
|
||||
@@ -873,10 +871,6 @@ type ComplexityRoot struct {
|
||||
Changelog func(childComplexity int) int
|
||||
}
|
||||
|
||||
GenerateFrameworkStateOfApplicabilityPayload struct {
|
||||
Data func(childComplexity int) int
|
||||
}
|
||||
|
||||
GetTrustCenterFilePayload struct {
|
||||
TrustCenterFile func(childComplexity int) int
|
||||
}
|
||||
@@ -1034,7 +1028,6 @@ type ComplexityRoot struct {
|
||||
ExportStateOfApplicabilityPDF func(childComplexity int, input types.ExportStateOfApplicabilityPDFInput) int
|
||||
ExportTransferImpactAssessmentsPDF func(childComplexity int, input types.ExportTransferImpactAssessmentsPDFInput) int
|
||||
GenerateDocumentChangelog func(childComplexity int, input types.GenerateDocumentChangelogInput) int
|
||||
GenerateFrameworkStateOfApplicability func(childComplexity int, input types.GenerateFrameworkStateOfApplicabilityInput) int
|
||||
GetTrustCenterFile func(childComplexity int, input types.GetTrustCenterFileInput) int
|
||||
ImportFramework func(childComplexity int, input types.ImportFrameworkInput) int
|
||||
ImportMeasure func(childComplexity int, input types.ImportMeasureInput) int
|
||||
@@ -2164,7 +2157,6 @@ type MutationResolver interface {
|
||||
UpdateFramework(ctx context.Context, input types.UpdateFrameworkInput) (*types.UpdateFrameworkPayload, error)
|
||||
ImportFramework(ctx context.Context, input types.ImportFrameworkInput) (*types.ImportFrameworkPayload, error)
|
||||
DeleteFramework(ctx context.Context, input types.DeleteFrameworkInput) (*types.DeleteFrameworkPayload, error)
|
||||
GenerateFrameworkStateOfApplicability(ctx context.Context, input types.GenerateFrameworkStateOfApplicabilityInput) (*types.GenerateFrameworkStateOfApplicabilityPayload, error)
|
||||
ExportFramework(ctx context.Context, input types.ExportFrameworkInput) (*types.ExportFrameworkPayload, error)
|
||||
CreateControl(ctx context.Context, input types.CreateControlInput) (*types.CreateControlPayload, error)
|
||||
UpdateControl(ctx context.Context, input types.UpdateControlInput) (*types.UpdateControlPayload, error)
|
||||
@@ -3104,12 +3096,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
}
|
||||
|
||||
return e.complexity.Control.Documents(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.DocumentOrderBy), args["filter"].(*types.DocumentFilter)), true
|
||||
case "Control.exclusionJustification":
|
||||
if e.complexity.Control.ExclusionJustification == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Control.ExclusionJustification(childComplexity), true
|
||||
case "Control.framework":
|
||||
if e.complexity.Control.Framework == nil {
|
||||
break
|
||||
@@ -3196,12 +3182,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
}
|
||||
|
||||
return e.complexity.Control.Snapshots(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.SnapshotOrderBy)), true
|
||||
case "Control.status":
|
||||
if e.complexity.Control.Status == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Control.Status(childComplexity), true
|
||||
case "Control.updatedAt":
|
||||
if e.complexity.Control.UpdatedAt == nil {
|
||||
break
|
||||
@@ -4887,13 +4867,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
|
||||
return e.complexity.GenerateDocumentChangelogPayload.Changelog(childComplexity), true
|
||||
|
||||
case "GenerateFrameworkStateOfApplicabilityPayload.data":
|
||||
if e.complexity.GenerateFrameworkStateOfApplicabilityPayload.Data == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.GenerateFrameworkStateOfApplicabilityPayload.Data(childComplexity), true
|
||||
|
||||
case "GetTrustCenterFilePayload.trustCenterFile":
|
||||
if e.complexity.GetTrustCenterFilePayload.TrustCenterFile == nil {
|
||||
break
|
||||
@@ -6182,17 +6155,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
}
|
||||
|
||||
return e.complexity.Mutation.GenerateDocumentChangelog(childComplexity, args["input"].(types.GenerateDocumentChangelogInput)), true
|
||||
case "Mutation.generateFrameworkStateOfApplicability":
|
||||
if e.complexity.Mutation.GenerateFrameworkStateOfApplicability == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Mutation_generateFrameworkStateOfApplicability_args(ctx, rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Mutation.GenerateFrameworkStateOfApplicability(childComplexity, args["input"].(types.GenerateFrameworkStateOfApplicabilityInput)), true
|
||||
case "Mutation.getTrustCenterFile":
|
||||
if e.complexity.Mutation.GetTrustCenterFile == nil {
|
||||
break
|
||||
@@ -10419,7 +10381,6 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
ec.unmarshalInputExportTransferImpactAssessmentsPDFInput,
|
||||
ec.unmarshalInputFrameworkOrder,
|
||||
ec.unmarshalInputGenerateDocumentChangelogInput,
|
||||
ec.unmarshalInputGenerateFrameworkStateOfApplicabilityInput,
|
||||
ec.unmarshalInputGetTrustCenterFileInput,
|
||||
ec.unmarshalInputImportFrameworkInput,
|
||||
ec.unmarshalInputImportMeasureInput,
|
||||
@@ -11627,14 +11588,6 @@ enum DataClassification
|
||||
)
|
||||
}
|
||||
|
||||
enum ControlStatus
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.ControlStatus") {
|
||||
INCLUDED
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ControlStatusIncluded")
|
||||
EXCLUDED
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.ControlStatusExcluded")
|
||||
}
|
||||
|
||||
enum AuditOrderField
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.AuditOrderField") {
|
||||
CREATED_AT
|
||||
@@ -12648,8 +12601,6 @@ type Control implements Node {
|
||||
sectionTitle: String!
|
||||
name: String!
|
||||
description: String
|
||||
status: ControlStatus!
|
||||
exclusionJustification: String
|
||||
bestPractice: Boolean!
|
||||
regulatory: Boolean! @goField(forceResolver: true)
|
||||
contractual: Boolean! @goField(forceResolver: true)
|
||||
@@ -13884,9 +13835,6 @@ type Mutation {
|
||||
updateFramework(input: UpdateFrameworkInput!): UpdateFrameworkPayload!
|
||||
importFramework(input: ImportFrameworkInput!): ImportFrameworkPayload!
|
||||
deleteFramework(input: DeleteFrameworkInput!): DeleteFrameworkPayload!
|
||||
generateFrameworkStateOfApplicability(
|
||||
input: GenerateFrameworkStateOfApplicabilityInput!
|
||||
): GenerateFrameworkStateOfApplicabilityPayload!
|
||||
exportFramework(input: ExportFrameworkInput!): ExportFrameworkPayload!
|
||||
# Control mutations
|
||||
createControl(input: CreateControlInput!): CreateControlPayload!
|
||||
@@ -14173,14 +14121,6 @@ type Mutation {
|
||||
}
|
||||
|
||||
# Input Types
|
||||
input GenerateFrameworkStateOfApplicabilityInput {
|
||||
frameworkId: ID!
|
||||
}
|
||||
|
||||
type GenerateFrameworkStateOfApplicabilityPayload {
|
||||
data: String!
|
||||
}
|
||||
|
||||
input UpdateOrganizationContextInput {
|
||||
organizationId: ID!
|
||||
summary: String @goField(omittable: true)
|
||||
@@ -14743,8 +14683,6 @@ input CreateControlInput {
|
||||
sectionTitle: String!
|
||||
name: String!
|
||||
description: String
|
||||
status: ControlStatus!
|
||||
exclusionJustification: String
|
||||
bestPractice: Boolean!
|
||||
}
|
||||
|
||||
@@ -14753,8 +14691,6 @@ input UpdateControlInput {
|
||||
sectionTitle: String
|
||||
name: String
|
||||
description: String @goField(omittable: true)
|
||||
status: ControlStatus
|
||||
exclusionJustification: String
|
||||
bestPractice: Boolean
|
||||
}
|
||||
|
||||
@@ -17835,17 +17771,6 @@ func (ec *executionContext) field_Mutation_generateDocumentChangelog_args(ctx co
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation_generateFrameworkStateOfApplicability_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||
var err error
|
||||
args := map[string]any{}
|
||||
arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", ec.unmarshalNGenerateFrameworkStateOfApplicabilityInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐGenerateFrameworkStateOfApplicabilityInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args["input"] = arg0
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation_getTrustCenterFile_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||
var err error
|
||||
args := map[string]any{}
|
||||
@@ -20211,10 +20136,6 @@ func (ec *executionContext) fieldContext_ApplicabilityStatement_control(_ contex
|
||||
return ec.fieldContext_Control_name(ctx, field)
|
||||
case "description":
|
||||
return ec.fieldContext_Control_description(ctx, field)
|
||||
case "status":
|
||||
return ec.fieldContext_Control_status(ctx, field)
|
||||
case "exclusionJustification":
|
||||
return ec.fieldContext_Control_exclusionJustification(ctx, field)
|
||||
case "bestPractice":
|
||||
return ec.fieldContext_Control_bestPractice(ctx, field)
|
||||
case "regulatory":
|
||||
@@ -23225,64 +23146,6 @@ func (ec *executionContext) fieldContext_Control_description(_ context.Context,
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Control_status(ctx context.Context, field graphql.CollectedField, obj *types.Control) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_Control_status,
|
||||
func(ctx context.Context) (any, error) {
|
||||
return obj.Status, nil
|
||||
},
|
||||
nil,
|
||||
ec.marshalNControlStatus2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Control_status(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Control",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type ControlStatus does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Control_exclusionJustification(ctx context.Context, field graphql.CollectedField, obj *types.Control) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_Control_exclusionJustification,
|
||||
func(ctx context.Context) (any, error) {
|
||||
return obj.ExclusionJustification, nil
|
||||
},
|
||||
nil,
|
||||
ec.marshalOString2ᚖstring,
|
||||
true,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Control_exclusionJustification(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Control",
|
||||
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) _Control_bestPractice(ctx context.Context, field graphql.CollectedField, obj *types.Control) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
@@ -23960,10 +23823,6 @@ func (ec *executionContext) fieldContext_ControlEdge_node(_ context.Context, fie
|
||||
return ec.fieldContext_Control_name(ctx, field)
|
||||
case "description":
|
||||
return ec.fieldContext_Control_description(ctx, field)
|
||||
case "status":
|
||||
return ec.fieldContext_Control_status(ctx, field)
|
||||
case "exclusionJustification":
|
||||
return ec.fieldContext_Control_exclusionJustification(ctx, field)
|
||||
case "bestPractice":
|
||||
return ec.fieldContext_Control_bestPractice(ctx, field)
|
||||
case "regulatory":
|
||||
@@ -32598,35 +32457,6 @@ func (ec *executionContext) fieldContext_GenerateDocumentChangelogPayload_change
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _GenerateFrameworkStateOfApplicabilityPayload_data(ctx context.Context, field graphql.CollectedField, obj *types.GenerateFrameworkStateOfApplicabilityPayload) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_GenerateFrameworkStateOfApplicabilityPayload_data,
|
||||
func(ctx context.Context) (any, error) {
|
||||
return obj.Data, nil
|
||||
},
|
||||
nil,
|
||||
ec.marshalNString2string,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_GenerateFrameworkStateOfApplicabilityPayload_data(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "GenerateFrameworkStateOfApplicabilityPayload",
|
||||
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) _GetTrustCenterFilePayload_trustCenterFile(ctx context.Context, field graphql.CollectedField, obj *types.GetTrustCenterFilePayload) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
@@ -35189,51 +35019,6 @@ func (ec *executionContext) fieldContext_Mutation_deleteFramework(ctx context.Co
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation_generateFrameworkStateOfApplicability(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_Mutation_generateFrameworkStateOfApplicability,
|
||||
func(ctx context.Context) (any, error) {
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.resolvers.Mutation().GenerateFrameworkStateOfApplicability(ctx, fc.Args["input"].(types.GenerateFrameworkStateOfApplicabilityInput))
|
||||
},
|
||||
nil,
|
||||
ec.marshalNGenerateFrameworkStateOfApplicabilityPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐGenerateFrameworkStateOfApplicabilityPayload,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Mutation_generateFrameworkStateOfApplicability(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Mutation",
|
||||
Field: field,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
switch field.Name {
|
||||
case "data":
|
||||
return ec.fieldContext_GenerateFrameworkStateOfApplicabilityPayload_data(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type GenerateFrameworkStateOfApplicabilityPayload", field.Name)
|
||||
},
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = ec.Recover(ctx, r)
|
||||
ec.Error(ctx, err)
|
||||
}
|
||||
}()
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
if fc.Args, err = ec.field_Mutation_generateFrameworkStateOfApplicability_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return fc, err
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation_exportFramework(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
@@ -53944,10 +53729,6 @@ func (ec *executionContext) fieldContext_UpdateControlPayload_control(_ context.
|
||||
return ec.fieldContext_Control_name(ctx, field)
|
||||
case "description":
|
||||
return ec.fieldContext_Control_description(ctx, field)
|
||||
case "status":
|
||||
return ec.fieldContext_Control_status(ctx, field)
|
||||
case "exclusionJustification":
|
||||
return ec.fieldContext_Control_exclusionJustification(ctx, field)
|
||||
case "bestPractice":
|
||||
return ec.fieldContext_Control_bestPractice(ctx, field)
|
||||
case "regulatory":
|
||||
@@ -63141,7 +62922,7 @@ func (ec *executionContext) unmarshalInputCreateControlInput(ctx context.Context
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"frameworkId", "sectionTitle", "name", "description", "status", "exclusionJustification", "bestPractice"}
|
||||
fieldsInOrder := [...]string{"frameworkId", "sectionTitle", "name", "description", "bestPractice"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
@@ -63176,20 +62957,6 @@ func (ec *executionContext) unmarshalInputCreateControlInput(ctx context.Context
|
||||
return it, err
|
||||
}
|
||||
it.Description = data
|
||||
case "status":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("status"))
|
||||
data, err := ec.unmarshalNControlStatus2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.Status = data
|
||||
case "exclusionJustification":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("exclusionJustification"))
|
||||
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.ExclusionJustification = data
|
||||
case "bestPractice":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("bestPractice"))
|
||||
data, err := ec.unmarshalNBoolean2bool(ctx, v)
|
||||
@@ -66924,33 +66691,6 @@ func (ec *executionContext) unmarshalInputGenerateDocumentChangelogInput(ctx con
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputGenerateFrameworkStateOfApplicabilityInput(ctx context.Context, obj any) (types.GenerateFrameworkStateOfApplicabilityInput, error) {
|
||||
var it types.GenerateFrameworkStateOfApplicabilityInput
|
||||
asMap := map[string]any{}
|
||||
for k, v := range obj.(map[string]any) {
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"frameworkId"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
switch k {
|
||||
case "frameworkId":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("frameworkId"))
|
||||
data, err := ec.unmarshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.FrameworkID = data
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputGetTrustCenterFileInput(ctx context.Context, obj any) (types.GetTrustCenterFileInput, error) {
|
||||
var it types.GetTrustCenterFileInput
|
||||
asMap := map[string]any{}
|
||||
@@ -68231,7 +67971,7 @@ func (ec *executionContext) unmarshalInputUpdateControlInput(ctx context.Context
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"id", "sectionTitle", "name", "description", "status", "exclusionJustification", "bestPractice"}
|
||||
fieldsInOrder := [...]string{"id", "sectionTitle", "name", "description", "bestPractice"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
@@ -68266,20 +68006,6 @@ func (ec *executionContext) unmarshalInputUpdateControlInput(ctx context.Context
|
||||
return it, err
|
||||
}
|
||||
it.Description = graphql.OmittableOf(data)
|
||||
case "status":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("status"))
|
||||
data, err := ec.unmarshalOControlStatus2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.Status = data
|
||||
case "exclusionJustification":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("exclusionJustification"))
|
||||
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.ExclusionJustification = data
|
||||
case "bestPractice":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("bestPractice"))
|
||||
data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v)
|
||||
@@ -72533,13 +72259,6 @@ func (ec *executionContext) _Control(ctx context.Context, sel ast.SelectionSet,
|
||||
}
|
||||
case "description":
|
||||
out.Values[i] = ec._Control_description(ctx, field, obj)
|
||||
case "status":
|
||||
out.Values[i] = ec._Control_status(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
}
|
||||
case "exclusionJustification":
|
||||
out.Values[i] = ec._Control_exclusionJustification(ctx, field, obj)
|
||||
case "bestPractice":
|
||||
out.Values[i] = ec._Control_bestPractice(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
@@ -79243,45 +78962,6 @@ func (ec *executionContext) _GenerateDocumentChangelogPayload(ctx context.Contex
|
||||
return out
|
||||
}
|
||||
|
||||
var generateFrameworkStateOfApplicabilityPayloadImplementors = []string{"GenerateFrameworkStateOfApplicabilityPayload"}
|
||||
|
||||
func (ec *executionContext) _GenerateFrameworkStateOfApplicabilityPayload(ctx context.Context, sel ast.SelectionSet, obj *types.GenerateFrameworkStateOfApplicabilityPayload) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, generateFrameworkStateOfApplicabilityPayloadImplementors)
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
deferred := make(map[string]*graphql.FieldSet)
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("GenerateFrameworkStateOfApplicabilityPayload")
|
||||
case "data":
|
||||
out.Values[i] = ec._GenerateFrameworkStateOfApplicabilityPayload_data(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch(ctx)
|
||||
if out.Invalids > 0 {
|
||||
return graphql.Null
|
||||
}
|
||||
|
||||
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
|
||||
|
||||
for label, dfs := range deferred {
|
||||
ec.processDeferredGroup(graphql.DeferredGroup{
|
||||
Label: label,
|
||||
Path: graphql.GetPath(ctx),
|
||||
FieldSet: dfs,
|
||||
Context: ctx,
|
||||
})
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
var getTrustCenterFilePayloadImplementors = []string{"GetTrustCenterFilePayload"}
|
||||
|
||||
func (ec *executionContext) _GetTrustCenterFilePayload(ctx context.Context, sel ast.SelectionSet, obj *types.GetTrustCenterFilePayload) graphql.Marshaler {
|
||||
@@ -80277,13 +79957,6 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
case "generateFrameworkStateOfApplicability":
|
||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||
return ec._Mutation_generateFrameworkStateOfApplicability(ctx, field)
|
||||
})
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
case "exportFramework":
|
||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||
return ec._Mutation_exportFramework(ctx, field)
|
||||
@@ -93049,34 +92722,6 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func (ec *executionContext) unmarshalNControlStatus2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx context.Context, v any) (coredata.ControlStatus, error) {
|
||||
tmp, err := graphql.UnmarshalString(v)
|
||||
res := unmarshalNControlStatus2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus[tmp]
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNControlStatus2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx context.Context, sel ast.SelectionSet, v coredata.ControlStatus) graphql.Marshaler {
|
||||
_ = sel
|
||||
res := graphql.MarshalString(marshalNControlStatus2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus[v])
|
||||
if res == graphql.Null {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow")
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
var (
|
||||
unmarshalNControlStatus2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus = map[string]coredata.ControlStatus{
|
||||
"INCLUDED": coredata.ControlStatusIncluded,
|
||||
"EXCLUDED": coredata.ControlStatusExcluded,
|
||||
}
|
||||
marshalNControlStatus2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus = map[coredata.ControlStatus]string{
|
||||
coredata.ControlStatusIncluded: "INCLUDED",
|
||||
coredata.ControlStatusExcluded: "EXCLUDED",
|
||||
}
|
||||
)
|
||||
|
||||
func (ec *executionContext) unmarshalNCountryCode2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐCountryCode(ctx context.Context, v any) (coredata.CountryCode, error) {
|
||||
tmp, err := graphql.UnmarshalString(v)
|
||||
res := unmarshalNCountryCode2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐCountryCode[tmp]
|
||||
@@ -96474,25 +96119,6 @@ func (ec *executionContext) marshalNGenerateDocumentChangelogPayload2ᚖgoᚗpro
|
||||
return ec._GenerateDocumentChangelogPayload(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNGenerateFrameworkStateOfApplicabilityInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐGenerateFrameworkStateOfApplicabilityInput(ctx context.Context, v any) (types.GenerateFrameworkStateOfApplicabilityInput, error) {
|
||||
res, err := ec.unmarshalInputGenerateFrameworkStateOfApplicabilityInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNGenerateFrameworkStateOfApplicabilityPayload2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐGenerateFrameworkStateOfApplicabilityPayload(ctx context.Context, sel ast.SelectionSet, v types.GenerateFrameworkStateOfApplicabilityPayload) graphql.Marshaler {
|
||||
return ec._GenerateFrameworkStateOfApplicabilityPayload(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNGenerateFrameworkStateOfApplicabilityPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐGenerateFrameworkStateOfApplicabilityPayload(ctx context.Context, sel ast.SelectionSet, v *types.GenerateFrameworkStateOfApplicabilityPayload) graphql.Marshaler {
|
||||
if v == nil {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._GenerateFrameworkStateOfApplicabilityPayload(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNGetTrustCenterFileInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐGetTrustCenterFileInput(ctx context.Context, v any) (types.GetTrustCenterFileInput, error) {
|
||||
res, err := ec.unmarshalInputGetTrustCenterFileInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
@@ -101595,36 +101221,6 @@ func (ec *executionContext) unmarshalOControlOrder2ᚖgoᚗproboᚗincᚋprobo
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalOControlStatus2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx context.Context, v any) (*coredata.ControlStatus, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
tmp, err := graphql.UnmarshalString(v)
|
||||
res := unmarshalOControlStatus2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus[tmp]
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOControlStatus2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus(ctx context.Context, sel ast.SelectionSet, v *coredata.ControlStatus) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
_ = sel
|
||||
_ = ctx
|
||||
res := graphql.MarshalString(marshalOControlStatus2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus[*v])
|
||||
return res
|
||||
}
|
||||
|
||||
var (
|
||||
unmarshalOControlStatus2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus = map[string]coredata.ControlStatus{
|
||||
"INCLUDED": coredata.ControlStatusIncluded,
|
||||
"EXCLUDED": coredata.ControlStatusExcluded,
|
||||
}
|
||||
marshalOControlStatus2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐControlStatus = map[coredata.ControlStatus]string{
|
||||
coredata.ControlStatusIncluded: "INCLUDED",
|
||||
coredata.ControlStatusExcluded: "EXCLUDED",
|
||||
}
|
||||
)
|
||||
|
||||
func (ec *executionContext) unmarshalOCountryCode2ᚕgoᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐCountryCodeᚄ(ctx context.Context, v any) ([]coredata.CountryCode, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
|
||||
@@ -57,13 +57,11 @@ func NewControl(control *coredata.Control) *Control {
|
||||
Framework: &Framework{
|
||||
ID: control.FrameworkID,
|
||||
},
|
||||
SectionTitle: control.SectionTitle,
|
||||
Name: control.Name,
|
||||
Description: control.Description,
|
||||
Status: control.Status,
|
||||
ExclusionJustification: control.ExclusionJustification,
|
||||
BestPractice: control.BestPractice,
|
||||
CreatedAt: control.CreatedAt,
|
||||
UpdatedAt: control.UpdatedAt,
|
||||
SectionTitle: control.SectionTitle,
|
||||
Name: control.Name,
|
||||
Description: control.Description,
|
||||
BestPractice: control.BestPractice,
|
||||
CreatedAt: control.CreatedAt,
|
||||
UpdatedAt: control.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,26 +179,24 @@ type ContinualImprovementFilter struct {
|
||||
}
|
||||
|
||||
type Control struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Status coredata.ControlStatus `json:"status"`
|
||||
ExclusionJustification *string `json:"exclusionJustification,omitempty"`
|
||||
BestPractice bool `json:"bestPractice"`
|
||||
Regulatory bool `json:"regulatory"`
|
||||
Contractual bool `json:"contractual"`
|
||||
RiskAssessment bool `json:"riskAssessment"`
|
||||
Framework *Framework `json:"framework"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Documents *DocumentConnection `json:"documents"`
|
||||
Audits *AuditConnection `json:"audits"`
|
||||
Obligations *ObligationConnection `json:"obligations"`
|
||||
Snapshots *SnapshotConnection `json:"snapshots"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Permission bool `json:"permission"`
|
||||
ID gid.GID `json:"id"`
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
BestPractice bool `json:"bestPractice"`
|
||||
Regulatory bool `json:"regulatory"`
|
||||
Contractual bool `json:"contractual"`
|
||||
RiskAssessment bool `json:"riskAssessment"`
|
||||
Framework *Framework `json:"framework"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Documents *DocumentConnection `json:"documents"`
|
||||
Audits *AuditConnection `json:"audits"`
|
||||
Obligations *ObligationConnection `json:"obligations"`
|
||||
Snapshots *SnapshotConnection `json:"snapshots"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Permission bool `json:"permission"`
|
||||
}
|
||||
|
||||
func (Control) IsNode() {}
|
||||
@@ -288,13 +286,11 @@ type CreateControlDocumentMappingPayload struct {
|
||||
}
|
||||
|
||||
type CreateControlInput struct {
|
||||
FrameworkID gid.GID `json:"frameworkId"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Status coredata.ControlStatus `json:"status"`
|
||||
ExclusionJustification *string `json:"exclusionJustification,omitempty"`
|
||||
BestPractice bool `json:"bestPractice"`
|
||||
FrameworkID gid.GID `json:"frameworkId"`
|
||||
SectionTitle string `json:"sectionTitle"`
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
BestPractice bool `json:"bestPractice"`
|
||||
}
|
||||
|
||||
type CreateControlMeasureMappingInput struct {
|
||||
@@ -1334,14 +1330,6 @@ type GenerateDocumentChangelogPayload struct {
|
||||
Changelog string `json:"changelog"`
|
||||
}
|
||||
|
||||
type GenerateFrameworkStateOfApplicabilityInput struct {
|
||||
FrameworkID gid.GID `json:"frameworkId"`
|
||||
}
|
||||
|
||||
type GenerateFrameworkStateOfApplicabilityPayload struct {
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type GetTrustCenterFileInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
}
|
||||
@@ -1994,13 +1982,11 @@ type UpdateContinualImprovementPayload struct {
|
||||
}
|
||||
|
||||
type UpdateControlInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
SectionTitle *string `json:"sectionTitle,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description graphql.Omittable[*string] `json:"description,omitempty"`
|
||||
Status *coredata.ControlStatus `json:"status,omitempty"`
|
||||
ExclusionJustification *string `json:"exclusionJustification,omitempty"`
|
||||
BestPractice *bool `json:"bestPractice,omitempty"`
|
||||
ID gid.GID `json:"id"`
|
||||
SectionTitle *string `json:"sectionTitle,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Description graphql.Omittable[*string] `json:"description,omitempty"`
|
||||
BestPractice *bool `json:"bestPractice,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateControlPayload struct {
|
||||
|
||||
@@ -2511,28 +2511,6 @@ func (r *mutationResolver) DeleteFramework(ctx context.Context, input types.Dele
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GenerateFrameworkStateOfApplicability is the resolver for the generateFrameworkStateOfApplicability field.
|
||||
func (r *mutationResolver) GenerateFrameworkStateOfApplicability(ctx context.Context, input types.GenerateFrameworkStateOfApplicabilityInput) (*types.GenerateFrameworkStateOfApplicabilityPayload, error) {
|
||||
if err := r.authorize(ctx, input.FrameworkID, probo.ActionFrameworkStateOfApplicabilityGenerate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, input.FrameworkID.TenantID())
|
||||
|
||||
soa, err := prb.Frameworks.StateOfApplicability(ctx, input.FrameworkID)
|
||||
if err != nil {
|
||||
// TODO no panic use gqlutils.InternalError
|
||||
panic(fmt.Errorf("cannot generate framework SOA: %w", err))
|
||||
}
|
||||
|
||||
return &types.GenerateFrameworkStateOfApplicabilityPayload{
|
||||
Data: fmt.Sprintf(
|
||||
"data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,%s",
|
||||
base64.StdEncoding.EncodeToString(soa),
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ExportFramework is the resolver for the exportFramework field.
|
||||
func (r *mutationResolver) ExportFramework(ctx context.Context, input types.ExportFrameworkInput) (*types.ExportFrameworkPayload, error) {
|
||||
if err := r.authorize(ctx, input.FrameworkID, probo.ActionFrameworkExport); err != nil {
|
||||
@@ -2569,13 +2547,11 @@ func (r *mutationResolver) CreateControl(ctx context.Context, input types.Create
|
||||
control, err := prb.Controls.Create(
|
||||
ctx,
|
||||
probo.CreateControlRequest{
|
||||
FrameworkID: input.FrameworkID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
SectionTitle: input.SectionTitle,
|
||||
Status: &input.Status,
|
||||
ExclusionJustification: input.ExclusionJustification,
|
||||
BestPractice: input.BestPractice,
|
||||
FrameworkID: input.FrameworkID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
SectionTitle: input.SectionTitle,
|
||||
BestPractice: input.BestPractice,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -2603,13 +2579,11 @@ func (r *mutationResolver) UpdateControl(ctx context.Context, input types.Update
|
||||
control, err := prb.Controls.Update(
|
||||
ctx,
|
||||
probo.UpdateControlRequest{
|
||||
ID: input.ID,
|
||||
Name: input.Name,
|
||||
Description: gqlutils.UnwrapOmittable(input.Description),
|
||||
SectionTitle: input.SectionTitle,
|
||||
Status: input.Status,
|
||||
ExclusionJustification: input.ExclusionJustification,
|
||||
BestPractice: input.BestPractice,
|
||||
ID: input.ID,
|
||||
Name: input.Name,
|
||||
Description: gqlutils.UnwrapOmittable(input.Description),
|
||||
SectionTitle: input.SectionTitle,
|
||||
BestPractice: input.BestPractice,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -1182,12 +1182,10 @@ func (r *Resolver) AddControlTool(ctx context.Context, req *mcp.CallToolRequest,
|
||||
control, err := svc.Controls.Create(
|
||||
ctx,
|
||||
probo.CreateControlRequest{
|
||||
FrameworkID: input.FrameworkID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
SectionTitle: input.SectionTitle,
|
||||
Status: input.Status,
|
||||
ExclusionJustification: input.ExclusionJustification,
|
||||
FrameworkID: input.FrameworkID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
SectionTitle: input.SectionTitle,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -1207,12 +1205,10 @@ func (r *Resolver) UpdateControlTool(ctx context.Context, req *mcp.CallToolReque
|
||||
control, err := svc.Controls.Update(
|
||||
ctx,
|
||||
probo.UpdateControlRequest{
|
||||
ID: input.ID,
|
||||
Name: input.Name,
|
||||
Description: UnwrapOmittable(input.Description),
|
||||
SectionTitle: input.SectionTitle,
|
||||
Status: input.Status,
|
||||
ExclusionJustification: input.ExclusionJustification,
|
||||
ID: input.ID,
|
||||
Name: input.Name,
|
||||
Description: UnwrapOmittable(input.Description),
|
||||
SectionTitle: input.SectionTitle,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
@@ -2758,13 +2758,6 @@ components:
|
||||
audit:
|
||||
$ref: "#/components/schemas/Audit"
|
||||
|
||||
ControlStatus:
|
||||
type: string
|
||||
enum:
|
||||
- INCLUDED
|
||||
- EXCLUDED
|
||||
go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.ControlStatus
|
||||
|
||||
ControlOrderField:
|
||||
type: string
|
||||
enum:
|
||||
@@ -2793,7 +2786,6 @@ components:
|
||||
- framework_id
|
||||
- section_title
|
||||
- name
|
||||
- status
|
||||
- created_at
|
||||
- updated_at
|
||||
properties:
|
||||
@@ -2817,14 +2809,6 @@ components:
|
||||
- string
|
||||
- "null"
|
||||
description: Control description
|
||||
status:
|
||||
$ref: "#/components/schemas/ControlStatus"
|
||||
description: Control status
|
||||
exclusion_justification:
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
description: Exclusion justification
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
@@ -2914,12 +2898,6 @@ components:
|
||||
description:
|
||||
type: string
|
||||
description: Control description
|
||||
status:
|
||||
$ref: "#/components/schemas/ControlStatus"
|
||||
description: Control status
|
||||
exclusion_justification:
|
||||
type: string
|
||||
description: Exclusion justification
|
||||
|
||||
AddControlOutput:
|
||||
type: object
|
||||
@@ -2947,16 +2925,6 @@ components:
|
||||
type: ["string", "null"]
|
||||
description: Control description
|
||||
go.probo.inc/mcpgen/omittable: true
|
||||
status:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/ControlStatus"
|
||||
description: Control status
|
||||
- type: "null"
|
||||
description: No status
|
||||
description: Control status
|
||||
exclusion_justification:
|
||||
type: string
|
||||
description: Exclusion justification
|
||||
|
||||
UpdateControlOutput:
|
||||
type: object
|
||||
|
||||
@@ -20,16 +20,14 @@ import (
|
||||
|
||||
func NewControl(c *coredata.Control) *Control {
|
||||
return &Control{
|
||||
ID: c.ID,
|
||||
OrganizationID: c.OrganizationID,
|
||||
SectionTitle: c.SectionTitle,
|
||||
FrameworkID: c.FrameworkID,
|
||||
Name: c.Name,
|
||||
Description: c.Description,
|
||||
Status: c.Status,
|
||||
ExclusionJustification: c.ExclusionJustification,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
ID: c.ID,
|
||||
OrganizationID: c.OrganizationID,
|
||||
SectionTitle: c.SectionTitle,
|
||||
FrameworkID: c.FrameworkID,
|
||||
Name: c.Name,
|
||||
Description: c.Description,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ var (
|
||||
AddAuditToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"audit":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"description":"Audit name"},"organization_id":{"type":"string","format":"string"},"state":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED","REJECTED","OUTDATED"]},"trust_center_visibility":{"type":"string","enum":["NONE","PRIVATE","PUBLIC"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"},"valid_from":{"description":"Valid from date","format":"date-time"},"valid_until":{"description":"Valid until date","format":"date-time"}},"required":["id","organization_id","framework_id","state","trust_center_visibility","created_at","updated_at"]}},"required":["audit"]}`)
|
||||
AddContinualImprovementToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"description":{"type":"string","description":"Description"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"priority":{"description":"Priority","anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null","description":"No priority"}]},"reference_id":{"type":"string","description":"Reference ID"},"source":{"type":"string","description":"Source"},"status":{"description":"Status","anyOf":[{"type":"string","enum":["OPEN","IN_PROGRESS","CLOSED"]},{"type":"null","description":"No status"}]},"target_date":{"type":"string","description":"Target date","format":"date-time"}},"required":["organization_id","reference_id","owner_id"]}`)
|
||||
AddContinualImprovementToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"continual_improvement":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Description"},"id":{"type":"string","format":"string"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"reference_id":{"type":"string","description":"Reference ID"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"source":{"description":"Source"},"source_id":{"description":"Source ID"},"status":{"type":"string","enum":["OPEN","IN_PROGRESS","CLOSED"]},"target_date":{"description":"Target date","format":"date-time"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","reference_id","owner_id","status","priority","created_at","updated_at"]}},"required":["continual_improvement"]}`)
|
||||
AddControlToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"description":{"type":"string","description":"Control description"},"exclusion_justification":{"type":"string","description":"Exclusion justification"},"framework_id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"status":{"type":"string","enum":["INCLUDED","EXCLUDED"]}},"required":["organization_id","framework_id","section_title","name"]}`)
|
||||
AddControlToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Control description"},"exclusion_justification":{"description":"Exclusion justification"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"status":{"type":"string","enum":["INCLUDED","EXCLUDED"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","status","created_at","updated_at"]}},"required":["control"]}`)
|
||||
AddControlToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"description":{"type":"string","description":"Control description"},"framework_id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"}},"required":["organization_id","framework_id","section_title","name"]}`)
|
||||
AddControlToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Control description"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","created_at","updated_at"]}},"required":["control"]}`)
|
||||
AddDatumToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"vendor_ids":{"type":"array","items":{"type":"string","format":"string"},"description":"Vendor IDs"}},"required":["organization_id","name","data_classification","owner_id"]}`)
|
||||
AddDatumToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"datum":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","name","data_classification","owner_id","created_at","updated_at"]}},"required":["datum"]}`)
|
||||
AddDocumentToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"approver_ids":{"type":"array","items":{"type":"string","format":"string"},"description":"Approver IDs"},"classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"content":{"type":"string","description":"Document content"},"document_type":{"type":"string","enum":["OTHER","ISMS","POLICY","PROCEDURE"]},"organization_id":{"type":"string","format":"string"},"title":{"type":"string","description":"Document title"},"trust_center_visibility":{"type":"string","enum":["NONE","PRIVATE","PUBLIC"]}},"required":["organization_id","title","content","approver_ids","classification","document_type"]}`)
|
||||
@@ -54,11 +54,11 @@ var (
|
||||
DeleteDraftDocumentVersionToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"document_version_id":{"type":"string","format":"string"}},"required":["document_version_id"]}`)
|
||||
DeleteDraftDocumentVersionToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"deleted_document_version_id":{"type":"string","format":"string"}},"required":["deleted_document_version_id"]}`)
|
||||
DeleteMeetingToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
DeleteTaskToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
DeleteTaskToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"deleted_task_id":{"type":"string","format":"string"}},"required":["deleted_task_id"]}`)
|
||||
DeleteMeetingToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"deleted_meeting_id":{"type":"string","format":"string"}},"required":["deleted_meeting_id"]}`)
|
||||
DeleteRiskToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
DeleteRiskToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"deleted_risk_id":{"type":"string","format":"string"}},"required":["deleted_risk_id"]}`)
|
||||
DeleteTaskToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
DeleteTaskToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"deleted_task_id":{"type":"string","format":"string"}},"required":["deleted_task_id"]}`)
|
||||
GetAssetToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
GetAssetToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"asset":{"type":"object","properties":{"amount":{"type":"integer","description":"Asset amount"},"asset_type":{"type":"string","enum":["PHYSICAL","VIRTUAL"]},"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_types_stored":{"type":"string","description":"Data types stored"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Asset name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","name","amount","owner_id","asset_type","data_types_stored","created_at","updated_at"]}},"required":["asset"]}`)
|
||||
GetAuditToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
@@ -66,7 +66,7 @@ var (
|
||||
GetContinualImprovementToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
GetContinualImprovementToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"continual_improvement":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Description"},"id":{"type":"string","format":"string"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"reference_id":{"type":"string","description":"Reference ID"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"source":{"description":"Source"},"source_id":{"description":"Source ID"},"status":{"type":"string","enum":["OPEN","IN_PROGRESS","CLOSED"]},"target_date":{"description":"Target date","format":"date-time"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","reference_id","owner_id","status","priority","created_at","updated_at"]}},"required":["continual_improvement"]}`)
|
||||
GetControlToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
GetControlToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Control description"},"exclusion_justification":{"description":"Exclusion justification"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"status":{"type":"string","enum":["INCLUDED","EXCLUDED"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","status","created_at","updated_at"]}},"required":["control"]}`)
|
||||
GetControlToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Control description"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","created_at","updated_at"]}},"required":["control"]}`)
|
||||
GetDatumToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
GetDatumToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"datum":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","name","data_classification","owner_id","created_at","updated_at"]}},"required":["datum"]}`)
|
||||
GetDocumentToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"id":{"type":"string","format":"string"}},"required":["id"]}`)
|
||||
@@ -108,7 +108,7 @@ var (
|
||||
ListContinualImprovementsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"snapshot_id":{"type":"string","format":"string"}}},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","REFERENCE_ID","TARGET_DATE","STATUS","PRIORITY"]}},"required":["field","direction"]},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}},"required":["organization_id"]}`)
|
||||
ListContinualImprovementsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"continual_improvements":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Description"},"id":{"type":"string","format":"string"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"reference_id":{"type":"string","description":"Reference ID"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"source":{"description":"Source"},"source_id":{"description":"Source ID"},"status":{"type":"string","enum":["OPEN","IN_PROGRESS","CLOSED"]},"target_date":{"description":"Target date","format":"date-time"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","reference_id","owner_id","status","priority","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["continual_improvements"]}`)
|
||||
ListControlsToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"query":{"type":"string","description":"Search query"}}},"framework_id":{"type":"string","format":"string"},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","SECTION_TITLE"]}},"required":["field","direction"]},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}},"required":["organization_id"]}`)
|
||||
ListControlsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"controls":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Control description"},"exclusion_justification":{"description":"Exclusion justification"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"status":{"type":"string","enum":["INCLUDED","EXCLUDED"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","status","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["controls"]}`)
|
||||
ListControlsToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"controls":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Control description"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["controls"]}`)
|
||||
ListDataToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"cursor":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"snapshot_id":{"type":"string","format":"string"}}},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","NAME","DATA_CLASSIFICATION"]}},"required":["field","direction"]},"organization_id":{"type":"string","format":"string"},"size":{"type":"integer","description":"Page size"}},"required":["organization_id"]}`)
|
||||
ListDataToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","name","data_classification","owner_id","created_at","updated_at"]}},"next_cursor":{"type":"string","format":"string"}},"required":["data"]}`)
|
||||
ListDocumentVersionSignaturesToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"cursor":{"type":"string","format":"string"},"document_version_id":{"type":"string","format":"string"},"filter":{"type":"object","properties":{"active_contract":{"type":"boolean","description":"Signatory contract status"},"states":{"type":"array","items":{"type":"string","enum":["REQUESTED","SIGNED"]},"description":"Signature states"}}},"order_by":{"type":"object","properties":{"direction":{"type":"string","enum":["ASC","DESC"]},"field":{"type":"string","enum":["CREATED_AT","SIGNED_AT"]}},"required":["field","direction"]},"size":{"type":"integer","description":"Page size"}},"required":["document_version_id"]}`)
|
||||
@@ -163,8 +163,8 @@ var (
|
||||
UpdateAuditToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"audit":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"description":"Audit name"},"organization_id":{"type":"string","format":"string"},"state":{"type":"string","enum":["NOT_STARTED","IN_PROGRESS","COMPLETED","REJECTED","OUTDATED"]},"trust_center_visibility":{"type":"string","enum":["NONE","PRIVATE","PUBLIC"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"},"valid_from":{"description":"Valid from date","format":"date-time"},"valid_until":{"description":"Valid until date","format":"date-time"}},"required":["id","organization_id","framework_id","state","trust_center_visibility","created_at","updated_at"]}},"required":["audit"]}`)
|
||||
UpdateContinualImprovementToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"description":{"description":"Description"},"id":{"type":"string","format":"string"},"owner_id":{"description":"Owner ID","anyOf":[{"type":"string","format":"string"},{"type":"null"}]},"priority":{"description":"Priority","anyOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH"]},{"type":"null","description":"No priority"}]},"reference_id":{"type":"string","description":"Reference ID"},"source":{"description":"Source"},"status":{"description":"Status","anyOf":[{"type":"string","enum":["OPEN","IN_PROGRESS","CLOSED"]},{"type":"null","description":"No status"}]},"target_date":{"description":"Target date","format":"date-time"}},"required":["id"]}`)
|
||||
UpdateContinualImprovementToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"continual_improvement":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Description"},"id":{"type":"string","format":"string"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH"]},"reference_id":{"type":"string","description":"Reference ID"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"source":{"description":"Source"},"source_id":{"description":"Source ID"},"status":{"type":"string","enum":["OPEN","IN_PROGRESS","CLOSED"]},"target_date":{"description":"Target date","format":"date-time"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","reference_id","owner_id","status","priority","created_at","updated_at"]}},"required":["continual_improvement"]}`)
|
||||
UpdateControlToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"description":{"description":"Control description"},"exclusion_justification":{"type":"string","description":"Exclusion justification"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"section_title":{"type":"string","description":"Section title"},"status":{"description":"Control status","anyOf":[{"type":"string","enum":["INCLUDED","EXCLUDED"]},{"type":"null","description":"No status"}]}},"required":["id"]}`)
|
||||
UpdateControlToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Control description"},"exclusion_justification":{"description":"Exclusion justification"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"status":{"type":"string","enum":["INCLUDED","EXCLUDED"]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","status","created_at","updated_at"]}},"required":["control"]}`)
|
||||
UpdateControlToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"description":{"description":"Control description"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"section_title":{"type":"string","description":"Section title"}},"required":["id"]}`)
|
||||
UpdateControlToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"control":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"description":{"description":"Control description"},"framework_id":{"type":"string","format":"string"},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Control name"},"organization_id":{"type":"string","format":"string"},"section_title":{"type":"string","description":"Section title"},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","framework_id","section_title","name","created_at","updated_at"]}},"required":["control"]}`)
|
||||
UpdateDatumToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"owner_id":{"description":"Owner ID","anyOf":[{"type":"string","format":"string"},{"type":"null"}]},"vendor_ids":{"type":"array","items":{"type":"string","format":"string"},"description":"Vendor IDs"}},"required":["id"]}`)
|
||||
UpdateDatumToolOutputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"datum":{"type":"object","properties":{"created_at":{"type":"string","description":"Creation timestamp","format":"date-time"},"data_classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"id":{"type":"string","format":"string"},"name":{"type":"string","description":"Datum name"},"organization_id":{"type":"string","format":"string"},"owner_id":{"type":"string","format":"string"},"snapshot_id":{"description":"Snapshot ID","anyOf":[{"type":"string","format":"string"},{"type":"null","description":"No snapshot"}]},"updated_at":{"type":"string","description":"Update timestamp","format":"date-time"}},"required":["id","organization_id","name","data_classification","owner_id","created_at","updated_at"]}},"required":["datum"]}`)
|
||||
UpdateDocumentToolInputSchema = mcp.MustUnmarshalSchema(`{"type":"object","properties":{"approver_ids":{"type":"array","items":{"type":"string","format":"string"},"description":"Approver IDs"},"classification":{"type":"string","enum":["PUBLIC","INTERNAL","CONFIDENTIAL","SECRET"]},"document_type":{"type":"string","enum":["OTHER","ISMS","POLICY","PROCEDURE"]},"id":{"type":"string","format":"string"},"title":{"type":"string","description":"Document title"},"trust_center_visibility":{"type":"string","enum":["NONE","PRIVATE","PUBLIC"]}},"required":["id"]}`)
|
||||
@@ -564,8 +564,6 @@ type AddContinualImprovementOutput struct {
|
||||
type AddControlInput struct {
|
||||
// Control description
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Exclusion justification
|
||||
ExclusionJustification *string `json:"exclusion_justification,omitempty"`
|
||||
// Framework ID
|
||||
FrameworkID gid.GID `json:"framework_id"`
|
||||
// Control name
|
||||
@@ -574,8 +572,6 @@ type AddControlInput struct {
|
||||
OrganizationID gid.GID `json:"organization_id"`
|
||||
// Section title
|
||||
SectionTitle string `json:"section_title"`
|
||||
// Control status
|
||||
Status *coredata.ControlStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// AddControlOutput represents the schema
|
||||
@@ -975,8 +971,6 @@ type Control struct {
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
// Control description
|
||||
Description *string `json:"description,omitempty"`
|
||||
// Exclusion justification
|
||||
ExclusionJustification *string `json:"exclusion_justification,omitempty"`
|
||||
// Framework ID
|
||||
FrameworkID gid.GID `json:"framework_id"`
|
||||
// Control ID
|
||||
@@ -987,8 +981,6 @@ type Control struct {
|
||||
OrganizationID gid.GID `json:"organization_id"`
|
||||
// Section title
|
||||
SectionTitle string `json:"section_title"`
|
||||
// Control status
|
||||
Status coredata.ControlStatus `json:"status"`
|
||||
// Update timestamp
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
@@ -1088,6 +1080,18 @@ type DeleteRiskOutput struct {
|
||||
DeletedRiskID gid.GID `json:"deleted_risk_id"`
|
||||
}
|
||||
|
||||
// DeleteTaskInput represents the schema
|
||||
type DeleteTaskInput struct {
|
||||
// Task ID
|
||||
ID gid.GID `json:"id"`
|
||||
}
|
||||
|
||||
// DeleteTaskOutput represents the schema
|
||||
type DeleteTaskOutput struct {
|
||||
// Deleted task ID
|
||||
DeletedTaskID gid.GID `json:"deleted_task_id"`
|
||||
}
|
||||
|
||||
// Document represents the schema
|
||||
type Document struct {
|
||||
// Approver IDs
|
||||
@@ -2171,18 +2175,6 @@ type UnassignTaskOutput struct {
|
||||
Task *Task `json:"task"`
|
||||
}
|
||||
|
||||
// DeleteTaskInput represents the schema
|
||||
type DeleteTaskInput struct {
|
||||
// Task ID
|
||||
ID gid.GID `json:"id"`
|
||||
}
|
||||
|
||||
// DeleteTaskOutput represents the schema
|
||||
type DeleteTaskOutput struct {
|
||||
// Deleted task ID
|
||||
DeletedTaskID gid.GID `json:"deleted_task_id"`
|
||||
}
|
||||
|
||||
// UnlinkControlAuditInput represents the schema
|
||||
type UnlinkControlAuditInput struct {
|
||||
// Audit ID
|
||||
@@ -2304,16 +2296,12 @@ type UpdateContinualImprovementOutput struct {
|
||||
type UpdateControlInput struct {
|
||||
// Control description
|
||||
Description mcp.Omittable[*string] `json:"description,omitempty"`
|
||||
// Exclusion justification
|
||||
ExclusionJustification *string `json:"exclusion_justification,omitempty"`
|
||||
// Control ID
|
||||
ID gid.GID `json:"id"`
|
||||
// Control name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Section title
|
||||
SectionTitle *string `json:"section_title,omitempty"`
|
||||
// Control status
|
||||
Status *coredata.ControlStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateControlOutput represents the schema
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package soagen
|
||||
|
||||
import "github.com/xuri/excelize/v2"
|
||||
|
||||
type Applicability struct {
|
||||
Value string
|
||||
IsApplicable bool
|
||||
}
|
||||
|
||||
func NewApplicability(value string, isApplicable bool) Applicability {
|
||||
return Applicability{
|
||||
Value: value,
|
||||
IsApplicable: isApplicable,
|
||||
}
|
||||
}
|
||||
|
||||
func (a Applicability) String() string {
|
||||
return a.Value
|
||||
}
|
||||
|
||||
func (a Applicability) MarshalExcel() ExcelValue {
|
||||
color := "FFB6C1" // Light red for not applicable
|
||||
if a.IsApplicable {
|
||||
color = "90EE90" // Light green for applicable
|
||||
}
|
||||
|
||||
return ExcelValue{
|
||||
Value: a.Value,
|
||||
Style: &excelize.Style{
|
||||
Border: []excelize.Border{
|
||||
{Type: "left", Color: "000000", Style: 1},
|
||||
{Type: "top", Color: "000000", Style: 1},
|
||||
{Type: "bottom", Color: "000000", Style: 1},
|
||||
{Type: "right", Color: "000000", Style: 1},
|
||||
},
|
||||
Fill: excelize.Fill{Type: "pattern", Color: []string{color}, Pattern: 1},
|
||||
Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
|
||||
},
|
||||
Validation: []string{"Yes", "No"},
|
||||
Width: 12,
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package soagen
|
||||
|
||||
import "github.com/xuri/excelize/v2"
|
||||
|
||||
type ExcelValue struct {
|
||||
Value interface{}
|
||||
Style *excelize.Style
|
||||
Validation []string
|
||||
Width float64
|
||||
}
|
||||
|
||||
type ExcelMarshaler interface {
|
||||
MarshalExcel() ExcelValue
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package soagen
|
||||
|
||||
type FieldConfiguration struct {
|
||||
Field string
|
||||
Columns []string
|
||||
FilterColumns []string // Specific columns that should have filters (subset of Columns)
|
||||
Width []float64 // Width for each column
|
||||
DefaultWidth float64 // Default width if not specified
|
||||
HasFilter bool // Whether to enable auto-filter
|
||||
}
|
||||
|
||||
var (
|
||||
soaFieldConfigs = []FieldConfiguration{
|
||||
{
|
||||
Field: "SectionTitle",
|
||||
Columns: []string{"A"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{12},
|
||||
DefaultWidth: 12,
|
||||
HasFilter: false,
|
||||
},
|
||||
{
|
||||
Field: "ControlName",
|
||||
Columns: []string{"B"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{35},
|
||||
DefaultWidth: 35,
|
||||
HasFilter: false,
|
||||
},
|
||||
{
|
||||
Field: "Applicability",
|
||||
Columns: []string{"C"},
|
||||
FilterColumns: []string{"C"},
|
||||
Width: []float64{12},
|
||||
DefaultWidth: 12,
|
||||
HasFilter: true,
|
||||
},
|
||||
{
|
||||
Field: "ExclusionJustification",
|
||||
Columns: []string{"D"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{25},
|
||||
DefaultWidth: 25,
|
||||
HasFilter: false,
|
||||
},
|
||||
{
|
||||
Field: "Regulatory",
|
||||
Columns: []string{"E"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{12},
|
||||
DefaultWidth: 12,
|
||||
HasFilter: false,
|
||||
},
|
||||
{
|
||||
Field: "Contractual",
|
||||
Columns: []string{"F"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{12},
|
||||
DefaultWidth: 12,
|
||||
HasFilter: false,
|
||||
},
|
||||
{
|
||||
Field: "BestPractice",
|
||||
Columns: []string{"G"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{12},
|
||||
DefaultWidth: 12,
|
||||
HasFilter: false,
|
||||
},
|
||||
{
|
||||
Field: "RiskAssessment",
|
||||
Columns: []string{"H"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{12},
|
||||
DefaultWidth: 12,
|
||||
HasFilter: false,
|
||||
},
|
||||
{
|
||||
Field: "SecurityMeasures",
|
||||
Columns: []string{"I"},
|
||||
FilterColumns: []string{},
|
||||
Width: []float64{40},
|
||||
DefaultWidth: 40,
|
||||
HasFilter: false,
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -1,319 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package soagen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
func GenerateSOAExcel(data SOAData) ([]byte, error) {
|
||||
f := excelize.NewFile()
|
||||
defer func() { _ = f.Close() }()
|
||||
|
||||
sheetName := "State of Applicability"
|
||||
_, err := f.NewSheet(sheetName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot create sheet: %w", err)
|
||||
}
|
||||
|
||||
if err := f.DeleteSheet("Sheet1"); err != nil {
|
||||
return nil, fmt.Errorf("cannot delete sheet: %w", err)
|
||||
}
|
||||
|
||||
if err := setupSOAHeader(f, sheetName); err != nil {
|
||||
return nil, fmt.Errorf("cannot setup Excel header: %w", err)
|
||||
}
|
||||
|
||||
if err := populateSOAData(f, sheetName, data.Rows); err != nil {
|
||||
return nil, fmt.Errorf("cannot populate Excel data: %w", err)
|
||||
}
|
||||
|
||||
if err := applySOAFinalFormatting(f, sheetName, len(data.Rows)); err != nil {
|
||||
return nil, fmt.Errorf("cannot apply final formatting: %w", err)
|
||||
}
|
||||
|
||||
buf, err := f.WriteToBuffer()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot write Excel file to buffer: %w", err)
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func setupSOAHeader(f *excelize.File, sheetName string) error {
|
||||
headerStyle, err := f.NewStyle(getHeaderStyle())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cellStyle, err := f.NewStyle(getCellStyle())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return applyHeaderLayout(f, sheetName, getSOAHeaderLayout(), headerStyle, cellStyle)
|
||||
}
|
||||
|
||||
func populateSOAData(f *excelize.File, sheetName string, rows []SOARowData) error {
|
||||
dataStartRow := 8
|
||||
|
||||
for i, rowData := range rows {
|
||||
isFirstRow := i == 0
|
||||
filterColumns, err := writeSOARow(f, sheetName, dataStartRow+i, rowData, isFirstRow)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot write row %d: %w", dataStartRow+i, err)
|
||||
}
|
||||
|
||||
if isFirstRow && len(filterColumns) > 0 {
|
||||
if err := applySOAAutoFilter(f, sheetName, filterColumns); err != nil {
|
||||
return fmt.Errorf("cannot apply auto filter: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeSOARow(f *excelize.File, sheetName string, row int, data SOARowData, isFirstRow bool) ([]string, error) {
|
||||
var allFilterColumns []string
|
||||
|
||||
fields := []struct {
|
||||
name string
|
||||
value interface{}
|
||||
}{
|
||||
{"SectionTitle", data.SectionTitle},
|
||||
{"ControlName", data.ControlName},
|
||||
{"Applicability", data.Applicability},
|
||||
{"Regulatory", data.Regulatory},
|
||||
{"Contractual", data.Contractual},
|
||||
{"BestPractice", data.BestPractice},
|
||||
{"RiskAssessment", data.RiskAssessment},
|
||||
{"ExclusionJustification", data.ExclusionJustification},
|
||||
{"SecurityMeasures", data.SecurityMeasures},
|
||||
}
|
||||
|
||||
for _, field := range fields {
|
||||
fieldConfig := getSOAFieldConfig(field.name)
|
||||
if fieldConfig == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
filterColumns, err := processField(f, sheetName, row, field.value, *fieldConfig, isFirstRow)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot write field %s: %w", field.name, err)
|
||||
}
|
||||
|
||||
allFilterColumns = append(allFilterColumns, filterColumns...)
|
||||
}
|
||||
|
||||
return allFilterColumns, nil
|
||||
}
|
||||
|
||||
func getSOAFieldConfig(fieldName string) *FieldConfiguration {
|
||||
for _, config := range soaFieldConfigs {
|
||||
if config.Field == fieldName {
|
||||
return &config
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func applySOAAutoFilter(f *excelize.File, sheetName string, filterColumns []string) error {
|
||||
if len(filterColumns) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
firstCol, lastCol := filterColumns[0], filterColumns[0]
|
||||
for _, col := range filterColumns {
|
||||
if col < firstCol {
|
||||
firstCol = col
|
||||
}
|
||||
if col > lastCol {
|
||||
lastCol = col
|
||||
}
|
||||
}
|
||||
|
||||
filterRange := fmt.Sprintf("%s7:%s1000", firstCol, lastCol)
|
||||
return f.AutoFilter(sheetName, filterRange, []excelize.AutoFilterOptions{})
|
||||
}
|
||||
|
||||
func applySOAFinalFormatting(f *excelize.File, sheetName string, dataRowCount int) error {
|
||||
if dataRowCount > 0 {
|
||||
headerRowHeight := 30.0
|
||||
_ = f.SetRowHeight(sheetName, 6, headerRowHeight)
|
||||
_ = f.SetRowHeight(sheetName, 7, headerRowHeight)
|
||||
|
||||
return f.SetPanes(sheetName, &excelize.Panes{
|
||||
Freeze: true,
|
||||
XSplit: 0,
|
||||
YSplit: 7,
|
||||
TopLeftCell: "A8",
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processField(f *excelize.File, sheetName string, row int, value interface{}, config FieldConfiguration, isFirstRow bool) ([]string, error) {
|
||||
switch v := value.(type) {
|
||||
case ExcelMarshaler:
|
||||
marshaler := v
|
||||
excelValue := marshaler.MarshalExcel()
|
||||
|
||||
styleID, err := createCellStyle(f, excelValue.Style)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeSingleColumnField(f, sheetName, row, excelValue, &config, styleID, isFirstRow)
|
||||
|
||||
case string:
|
||||
if len(config.Columns) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
col := config.Columns[0]
|
||||
cellRef := fmt.Sprintf("%s%d", col, row)
|
||||
|
||||
if err := f.SetCellValue(sheetName, cellRef, v); err != nil {
|
||||
return nil, fmt.Errorf("cannot set cell value: %w", err)
|
||||
}
|
||||
|
||||
textStyleID, err := createCellStyle(f, getTextStyle())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot create text style: %w", err)
|
||||
}
|
||||
if err := f.SetCellStyle(sheetName, cellRef, cellRef, textStyleID); err != nil {
|
||||
return nil, fmt.Errorf("cannot set cell style: %w", err)
|
||||
}
|
||||
|
||||
if isFirstRow {
|
||||
width := config.DefaultWidth
|
||||
if len(config.Width) > 0 {
|
||||
width = config.Width[0]
|
||||
}
|
||||
if err := f.SetColWidth(sheetName, col, col, width); err != nil {
|
||||
return nil, fmt.Errorf("cannot set column width: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.HasFilter {
|
||||
if len(config.FilterColumns) > 0 {
|
||||
return config.FilterColumns, nil
|
||||
}
|
||||
return []string{col}, nil
|
||||
}
|
||||
return []string{}, nil
|
||||
|
||||
case []string:
|
||||
var formattedLines []string
|
||||
for _, item := range v {
|
||||
lines := strings.Split(item, "\n")
|
||||
for _, line := range lines {
|
||||
if strings.TrimSpace(line) != "" {
|
||||
formattedLines = append(formattedLines, "• "+strings.TrimSpace(line))
|
||||
}
|
||||
}
|
||||
}
|
||||
joinedValue := strings.Join(formattedLines, "\n")
|
||||
|
||||
if len(config.Columns) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
col := config.Columns[0]
|
||||
cellRef := fmt.Sprintf("%s%d", col, row)
|
||||
|
||||
if err := f.SetCellValue(sheetName, cellRef, joinedValue); err != nil {
|
||||
return nil, fmt.Errorf("cannot set cell value: %w", err)
|
||||
}
|
||||
|
||||
textStyleID, err := createCellStyle(f, getTextStyle())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot create text style: %w", err)
|
||||
}
|
||||
if err := f.SetCellStyle(sheetName, cellRef, cellRef, textStyleID); err != nil {
|
||||
return nil, fmt.Errorf("cannot set cell style: %w", err)
|
||||
}
|
||||
|
||||
if isFirstRow {
|
||||
width := config.DefaultWidth
|
||||
if len(config.Width) > 0 {
|
||||
width = config.Width[0]
|
||||
}
|
||||
if err := f.SetColWidth(sheetName, col, col, width); err != nil {
|
||||
return nil, fmt.Errorf("cannot set column width: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if config.HasFilter {
|
||||
if len(config.FilterColumns) > 0 {
|
||||
return config.FilterColumns, nil
|
||||
}
|
||||
return []string{col}, nil
|
||||
}
|
||||
return []string{}, nil
|
||||
|
||||
case *bool:
|
||||
yesNoValue := boolToYesNo(v)
|
||||
excelValue := yesNoValue.MarshalExcel()
|
||||
|
||||
styleID, err := createCellStyle(f, excelValue.Style)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeSingleColumnField(f, sheetName, row, excelValue, &config, styleID, isFirstRow)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("no handler found for field type: %T", value)
|
||||
}
|
||||
}
|
||||
|
||||
func GenerateExcel(data SOAData) ([]byte, error) {
|
||||
return GenerateSOAExcel(data)
|
||||
}
|
||||
|
||||
func writeSingleColumnField(f *excelize.File, sheetName string, row int, excelValue ExcelValue, colDef *FieldConfiguration, styleID int, isFirstRow bool) ([]string, error) {
|
||||
if len(colDef.Columns) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
col := colDef.Columns[0]
|
||||
cellRef := fmt.Sprintf("%s%d", col, row)
|
||||
|
||||
_ = f.SetCellValue(sheetName, cellRef, excelValue.Value)
|
||||
_ = f.SetCellStyle(sheetName, cellRef, cellRef, styleID)
|
||||
|
||||
if isFirstRow {
|
||||
if err := applyDataValidation(f, sheetName, col, row, excelValue.Validation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := setColumnWidth(f, sheetName, col, excelValue.Width); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if colDef.HasFilter {
|
||||
if len(colDef.FilterColumns) > 0 {
|
||||
return colDef.FilterColumns, nil
|
||||
}
|
||||
return []string{col}, nil
|
||||
}
|
||||
return []string{}, nil
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package soagen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
type HeaderCell struct {
|
||||
Cell string
|
||||
Value string
|
||||
Style string // "header" or "cell"
|
||||
}
|
||||
|
||||
type MergedCell struct {
|
||||
StartCell string
|
||||
EndCell string
|
||||
}
|
||||
|
||||
type HeaderLayout struct {
|
||||
InfoHeader []HeaderCell
|
||||
InfoData []HeaderCell
|
||||
MainHeader []HeaderCell
|
||||
SubHeader []HeaderCell
|
||||
Merges []MergedCell
|
||||
}
|
||||
|
||||
func getSOAHeaderLayout() HeaderLayout {
|
||||
return HeaderLayout{
|
||||
InfoHeader: []HeaderCell{
|
||||
{"A2", "Version", "header"},
|
||||
{"C2", "Date", "header"},
|
||||
{"D2", "Comment", "header"},
|
||||
{"E2", "Author", "header"},
|
||||
{"F2", "Approver", "header"},
|
||||
},
|
||||
InfoData: []HeaderCell{
|
||||
{"A3", "1.0", "cell"},
|
||||
{"C3", time.Now().Format("01/02/2006"), "cell"},
|
||||
{"D3", "Initial SoA", "cell"},
|
||||
{"E3", "System Admin", "cell"},
|
||||
{"F3", "Security Manager", "cell"},
|
||||
},
|
||||
MainHeader: []HeaderCell{
|
||||
{"A6", "Control", "header"},
|
||||
{"B6", "Control name", "header"},
|
||||
{"C6", "Applicability", "header"},
|
||||
{"D6", "Justification for exclusion", "header"},
|
||||
{"E6", "Justification for inclusion", "header"},
|
||||
{"F6", "Justification for inclusion", "header"},
|
||||
{"G6", "Justification for inclusion", "header"},
|
||||
{"H6", "Justification for inclusion", "header"},
|
||||
{"I6", "List of security measure or policy", "header"},
|
||||
},
|
||||
SubHeader: []HeaderCell{
|
||||
{"A7", "Control", "header"},
|
||||
{"B7", "Control name", "header"},
|
||||
{"C7", "Applicability", "header"},
|
||||
{"D7", "Justification for exclusion", "header"},
|
||||
{"E7", "Regulatory", "header"},
|
||||
{"F7", "Contractual", "header"},
|
||||
{"G7", "Best practice", "header"},
|
||||
{"H7", "Risk assessment", "header"},
|
||||
{"I7", "List of security measure or policy", "header"},
|
||||
},
|
||||
Merges: []MergedCell{
|
||||
{"A6", "A7"},
|
||||
{"B6", "B7"},
|
||||
{"C6", "C7"},
|
||||
{"D6", "D7"},
|
||||
{"E6", "H6"},
|
||||
{"I6", "I7"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func applyHeaderLayout(f *excelize.File, sheetName string, layout HeaderLayout, headerStyle, cellStyle int) error {
|
||||
if err := applyCells(f, sheetName, layout.InfoHeader, headerStyle, cellStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := applyCells(f, sheetName, layout.InfoData, headerStyle, cellStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := applyCells(f, sheetName, layout.MainHeader, headerStyle, cellStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := applyCells(f, sheetName, layout.SubHeader, headerStyle, cellStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, merge := range layout.Merges {
|
||||
if err := f.MergeCell(sheetName, merge.StartCell, merge.EndCell); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyCells(f *excelize.File, sheetName string, cells []HeaderCell, headerStyle, cellStyle int) error {
|
||||
for _, cell := range cells {
|
||||
if err := f.SetCellValue(sheetName, cell.Cell, cell.Value); err != nil {
|
||||
return fmt.Errorf("cannot set cell value: %w", err)
|
||||
}
|
||||
|
||||
style := cellStyle
|
||||
if cell.Style == "header" {
|
||||
style = headerStyle
|
||||
}
|
||||
|
||||
if err := f.SetCellStyle(sheetName, cell.Cell, cell.Cell, style); err != nil {
|
||||
return fmt.Errorf("cannot set cell style: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package soagen
|
||||
|
||||
// SOARowData represents a single row in the State of Applicability Excel
|
||||
type SOARowData struct {
|
||||
SectionTitle string
|
||||
ControlName string
|
||||
Applicability Applicability
|
||||
Regulatory *bool
|
||||
Contractual *bool
|
||||
BestPractice *bool
|
||||
RiskAssessment *bool
|
||||
ExclusionJustification string
|
||||
SecurityMeasures []string
|
||||
}
|
||||
|
||||
// SOAData contains all the data needed for State of Applicability generation
|
||||
type SOAData struct {
|
||||
Rows []SOARowData
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package soagen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
|
||||
// getTextStyle returns the standard text style for string fields
|
||||
func getTextStyle() *excelize.Style {
|
||||
return &excelize.Style{
|
||||
Border: []excelize.Border{
|
||||
{Type: "left", Color: "#000000", Style: 1},
|
||||
{Type: "top", Color: "#000000", Style: 1},
|
||||
{Type: "bottom", Color: "#000000", Style: 1},
|
||||
{Type: "right", Color: "#000000", Style: 1},
|
||||
},
|
||||
Alignment: &excelize.Alignment{Horizontal: "left", Vertical: "center", WrapText: true},
|
||||
}
|
||||
}
|
||||
|
||||
// getHeaderStyle returns the standard header style
|
||||
func getHeaderStyle() *excelize.Style {
|
||||
return &excelize.Style{
|
||||
Font: &excelize.Font{Bold: true, Size: 10, Color: "#000000"},
|
||||
Fill: excelize.Fill{Type: "pattern", Color: []string{"#D9D9D9"}, Pattern: 1},
|
||||
Border: []excelize.Border{
|
||||
{Type: "left", Color: "#000000", Style: 1},
|
||||
{Type: "top", Color: "#000000", Style: 1},
|
||||
{Type: "bottom", Color: "#000000", Style: 1},
|
||||
{Type: "right", Color: "#000000", Style: 1},
|
||||
},
|
||||
Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
|
||||
}
|
||||
}
|
||||
|
||||
// getCellStyle returns the standard cell style
|
||||
func getCellStyle() *excelize.Style {
|
||||
return &excelize.Style{
|
||||
Border: []excelize.Border{
|
||||
{Type: "left", Color: "#000000", Style: 1},
|
||||
{Type: "top", Color: "#000000", Style: 1},
|
||||
{Type: "bottom", Color: "#000000", Style: 1},
|
||||
{Type: "right", Color: "#000000", Style: 1},
|
||||
},
|
||||
Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
|
||||
}
|
||||
}
|
||||
|
||||
func createCellStyle(f *excelize.File, style *excelize.Style) (int, error) {
|
||||
styleID, err := f.NewStyle(style)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("cannot create style: %w", err)
|
||||
}
|
||||
return styleID, nil
|
||||
}
|
||||
|
||||
func applyDataValidation(f *excelize.File, sheetName, col string, row int, validation []string) error {
|
||||
if len(validation) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
dv := excelize.NewDataValidation(true)
|
||||
dv.Sqref = fmt.Sprintf("%s%d:%s1000", col, row, col) // Apply to reasonable range
|
||||
_ = dv.SetDropList(validation)
|
||||
dv.SetError(excelize.DataValidationErrorStyleStop, "Invalid Input", "Please select from the dropdown list.")
|
||||
if err := f.AddDataValidation(sheetName, dv); err != nil {
|
||||
return fmt.Errorf("cannot add data validation: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setColumnWidth(f *excelize.File, sheetName, col string, width float64) error {
|
||||
if width > 0 {
|
||||
if err := f.SetColWidth(sheetName, col, col, width); err != nil {
|
||||
return fmt.Errorf("cannot set column width: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package soagen
|
||||
|
||||
import "github.com/xuri/excelize/v2"
|
||||
|
||||
// YesNo represents a YES/NO/Empty value
|
||||
type YesNo string
|
||||
|
||||
const (
|
||||
Yes YesNo = "YES"
|
||||
No YesNo = "NO"
|
||||
Empty YesNo = ""
|
||||
)
|
||||
|
||||
// String returns the string representation of YesNo
|
||||
func (yn YesNo) String() string {
|
||||
return string(yn)
|
||||
}
|
||||
|
||||
// MarshalExcel implements ExcelMarshaler for YesNo
|
||||
func (yn YesNo) MarshalExcel() ExcelValue {
|
||||
return ExcelValue{
|
||||
Value: yn.String(),
|
||||
Style: &excelize.Style{
|
||||
Border: []excelize.Border{
|
||||
{Type: "left", Color: "#000000", Style: 1},
|
||||
{Type: "top", Color: "#000000", Style: 1},
|
||||
{Type: "bottom", Color: "#000000", Style: 1},
|
||||
{Type: "right", Color: "#000000", Style: 1},
|
||||
},
|
||||
Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
|
||||
},
|
||||
Validation: []string{string(Yes), string(No), string(Empty)},
|
||||
Width: 12,
|
||||
}
|
||||
}
|
||||
|
||||
// boolToYesNo converts *bool to YesNo type for Excel output
|
||||
func boolToYesNo(b *bool) YesNo {
|
||||
if b == nil {
|
||||
return Empty
|
||||
}
|
||||
if *b {
|
||||
return Yes
|
||||
}
|
||||
return No
|
||||
}
|
||||
@@ -154,8 +154,7 @@ func TestValidationErrors_Methods(t *testing.T) {
|
||||
first := errors.First()
|
||||
if first == nil {
|
||||
t.Fatal("expected first error")
|
||||
}
|
||||
if first.Field != "email" {
|
||||
} else if first.Field != "email" {
|
||||
t.Errorf("expected first field to be 'email', got '%s'", first.Field)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -40,8 +40,7 @@ func TestMinItems(t *testing.T) {
|
||||
err := MinItems(2)(&items)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error")
|
||||
}
|
||||
if err.Code != ErrorCodeOutOfRange {
|
||||
} else if err.Code != ErrorCodeOutOfRange {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeOutOfRange, err.Code)
|
||||
}
|
||||
})
|
||||
@@ -85,8 +84,7 @@ func TestMaxItems(t *testing.T) {
|
||||
err := MaxItems(2)(&items)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error")
|
||||
}
|
||||
if err.Code != ErrorCodeOutOfRange {
|
||||
} else if err.Code != ErrorCodeOutOfRange {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeOutOfRange, err.Code)
|
||||
}
|
||||
})
|
||||
@@ -114,8 +112,7 @@ func TestUniqueItems(t *testing.T) {
|
||||
err := UniqueItems()(&items)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error")
|
||||
}
|
||||
if err.Code != ErrorCodeInvalidFormat {
|
||||
} else if err.Code != ErrorCodeInvalidFormat {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeInvalidFormat, err.Code)
|
||||
}
|
||||
})
|
||||
@@ -157,12 +154,13 @@ func TestUniqueItems(t *testing.T) {
|
||||
err := UniqueItems()(&items)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error for non-comparable type")
|
||||
}
|
||||
if err.Code != ErrorCodeInvalidFormat {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeInvalidFormat, err.Code)
|
||||
}
|
||||
if err.Message != "cannot validate uniqueness for non-comparable types" {
|
||||
t.Errorf("unexpected error message: %s", err.Message)
|
||||
} else {
|
||||
if err.Code != ErrorCodeInvalidFormat {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeInvalidFormat, err.Code)
|
||||
}
|
||||
if err.Message != "cannot validate uniqueness for non-comparable types" {
|
||||
t.Errorf("unexpected error message: %s", err.Message)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -171,8 +169,7 @@ func TestUniqueItems(t *testing.T) {
|
||||
err := UniqueItems()(&items)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error for non-comparable type")
|
||||
}
|
||||
if err.Code != ErrorCodeInvalidFormat {
|
||||
} else if err.Code != ErrorCodeInvalidFormat {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeInvalidFormat, err.Code)
|
||||
}
|
||||
})
|
||||
@@ -185,8 +182,7 @@ func TestUniqueItems(t *testing.T) {
|
||||
err := UniqueItems()(&items)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error for non-comparable type")
|
||||
}
|
||||
if err.Code != ErrorCodeInvalidFormat {
|
||||
} else if err.Code != ErrorCodeInvalidFormat {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeInvalidFormat, err.Code)
|
||||
}
|
||||
})
|
||||
@@ -212,8 +208,7 @@ func TestUniqueItems(t *testing.T) {
|
||||
err := UniqueItems()(&items)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error for duplicate comparable structs")
|
||||
}
|
||||
if err.Code != ErrorCodeInvalidFormat {
|
||||
} else if err.Code != ErrorCodeInvalidFormat {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeInvalidFormat, err.Code)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -103,8 +103,7 @@ func TestRequired(t *testing.T) {
|
||||
err := Required()(&str)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error")
|
||||
}
|
||||
if err.Code != ErrorCodeRequired {
|
||||
} else if err.Code != ErrorCodeRequired {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeRequired, err.Code)
|
||||
}
|
||||
})
|
||||
@@ -193,8 +192,7 @@ func TestRequired(t *testing.T) {
|
||||
err := Required()(slice)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error for empty []string slice")
|
||||
}
|
||||
if err.Code != ErrorCodeRequired {
|
||||
} else if err.Code != ErrorCodeRequired {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeRequired, err.Code)
|
||||
}
|
||||
})
|
||||
@@ -212,8 +210,7 @@ func TestRequired(t *testing.T) {
|
||||
err := Required()(slice)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error for empty []int slice")
|
||||
}
|
||||
if err.Code != ErrorCodeRequired {
|
||||
} else if err.Code != ErrorCodeRequired {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeRequired, err.Code)
|
||||
}
|
||||
})
|
||||
@@ -234,8 +231,7 @@ func TestRequired(t *testing.T) {
|
||||
err := Required()(slice)
|
||||
if err == nil {
|
||||
t.Fatal("expected validation error for empty custom type slice")
|
||||
}
|
||||
if err.Code != ErrorCodeRequired {
|
||||
} else if err.Code != ErrorCodeRequired {
|
||||
t.Errorf("expected error code %s, got %s", ErrorCodeRequired, err.Code)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user