From 40e4db927859dfe9bbd6102590bcbd4f0d34c6d4 Mon Sep 17 00:00:00 2001 From: Sacha Al Himdani Date: Tue, 17 Feb 2026 13:55:56 +0100 Subject: [PATCH] Remove deprecated SOA code Signed-off-by: Sacha Al Himdani --- ...workControlDialogCreateMutation.graphql.ts | 23 +- .../FrameworkControlDialogFragment.graphql.ts | 21 +- ...workControlDialogUpdateMutation.graphql.ts | 23 +- .../FrameworkDetailPageFragment.graphql.ts | 35 +- ...orkStateOfApplicabilityMutation.graphql.ts | 95 ---- .../FrameworkGraphControlNodeQuery.graphql.ts | 188 ++++---- .../core/FrameworkGraphNodeQuery.graphql.ts | 33 +- .../console/src/hooks/graph/FrameworkGraph.ts | 2 - .../frameworks/FrameworkControlPage.tsx | 17 +- .../frameworks/FrameworkDetailPage.tsx | 59 +-- .../dialogs/FrameworkControlDialog.tsx | 46 +- e2e/console/control_test.go | 272 ----------- e2e/console/mapping_test.go | 4 - e2e/console/rbac_test.go | 6 +- e2e/internal/factory/factory.go | 1 - go.mod | 6 - go.sum | 12 - .../Probo/actions/control/create.operation.ts | 45 +- .../Probo/actions/control/get.operation.ts | 2 - .../Probo/actions/control/getAll.operation.ts | 2 - .../Probo/actions/control/update.operation.ts | 43 -- .../ui/src/Atoms/ControlItem/ControlItem.tsx | 23 +- pkg/coredata/control.go | 94 +--- pkg/coredata/control_status.go | 59 --- .../document_version_signature_state.go | 2 +- pkg/coredata/invitation_status.go | 4 +- pkg/coredata/migrations/20260217T120000Z.sql | 6 + pkg/probo/actions.go | 3 +- pkg/probo/control_service.go | 56 +-- pkg/probo/framework_service.go | 179 ------- pkg/server/api/console/v1/schema.graphql | 25 - pkg/server/api/console/v1/schema/schema.go | 444 +----------------- pkg/server/api/console/v1/types/control.go | 14 +- pkg/server/api/console/v1/types/types.go | 70 ++- pkg/server/api/console/v1/v1_resolver.go | 46 +- pkg/server/api/mcp/v1/schema.resolvers.go | 20 +- pkg/server/api/mcp/v1/specification.yaml | 32 -- pkg/server/api/mcp/v1/types/control.go | 18 +- pkg/server/api/mcp/v1/types/types.go | 52 +- pkg/soagen/applicability.go | 56 --- pkg/soagen/excel_value.go | 28 -- pkg/soagen/field_config.go | 101 ---- pkg/soagen/generator.go | 319 ------------- pkg/soagen/header.go | 134 ------ pkg/soagen/soa_data.go | 33 -- pkg/soagen/styles.go | 95 ---- pkg/soagen/yesno.go | 60 --- pkg/validator/validation_test.go | 3 +- pkg/validator/validator_collection_test.go | 31 +- pkg/validator/validator_common_test.go | 12 +- 50 files changed, 285 insertions(+), 2669 deletions(-) delete mode 100644 apps/console/src/__generated__/core/FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation.graphql.ts delete mode 100644 pkg/coredata/control_status.go create mode 100644 pkg/coredata/migrations/20260217T120000Z.sql delete mode 100644 pkg/soagen/applicability.go delete mode 100644 pkg/soagen/excel_value.go delete mode 100644 pkg/soagen/field_config.go delete mode 100644 pkg/soagen/generator.go delete mode 100644 pkg/soagen/header.go delete mode 100644 pkg/soagen/soa_data.go delete mode 100644 pkg/soagen/styles.go delete mode 100644 pkg/soagen/yesno.go diff --git a/apps/console/src/__generated__/core/FrameworkControlDialogCreateMutation.graphql.ts b/apps/console/src/__generated__/core/FrameworkControlDialogCreateMutation.graphql.ts index 9845a1459..390ce7ce0 100644 --- a/apps/console/src/__generated__/core/FrameworkControlDialogCreateMutation.graphql.ts +++ b/apps/console/src/__generated__/core/FrameworkControlDialogCreateMutation.graphql.ts @@ -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; @@ -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" } }; })(); diff --git a/apps/console/src/__generated__/core/FrameworkControlDialogFragment.graphql.ts b/apps/console/src/__generated__/core/FrameworkControlDialogFragment.graphql.ts index 3d5f36c10..9c56dc90d 100644 --- a/apps/console/src/__generated__/core/FrameworkControlDialogFragment.graphql.ts +++ b/apps/console/src/__generated__/core/FrameworkControlDialogFragment.graphql.ts @@ -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; diff --git a/apps/console/src/__generated__/core/FrameworkControlDialogUpdateMutation.graphql.ts b/apps/console/src/__generated__/core/FrameworkControlDialogUpdateMutation.graphql.ts index d8d19fde7..023383e79 100644 --- a/apps/console/src/__generated__/core/FrameworkControlDialogUpdateMutation.graphql.ts +++ b/apps/console/src/__generated__/core/FrameworkControlDialogUpdateMutation.graphql.ts @@ -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" } }; })(); diff --git a/apps/console/src/__generated__/core/FrameworkDetailPageFragment.graphql.ts b/apps/console/src/__generated__/core/FrameworkDetailPageFragment.graphql.ts index 33152ef72..2248090f4 100644 --- a/apps/console/src/__generated__/core/FrameworkDetailPageFragment.graphql.ts +++ b/apps/console/src/__generated__/core/FrameworkDetailPageFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<3db987ede3a3aa1dfa570e76a00ef224>> + * @generated SignedSource<> * @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; diff --git a/apps/console/src/__generated__/core/FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation.graphql.ts b/apps/console/src/__generated__/core/FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation.graphql.ts deleted file mode 100644 index 08f37ee16..000000000 --- a/apps/console/src/__generated__/core/FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation.graphql.ts +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @generated SignedSource<> - * @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; diff --git a/apps/console/src/__generated__/core/FrameworkGraphControlNodeQuery.graphql.ts b/apps/console/src/__generated__/core/FrameworkGraphControlNodeQuery.graphql.ts index 2e474c3b3..d0cac42d3 100644 --- a/apps/console/src/__generated__/core/FrameworkGraphControlNodeQuery.graphql.ts +++ b/apps/console/src/__generated__/core/FrameworkGraphControlNodeQuery.graphql.ts @@ -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; diff --git a/apps/console/src/__generated__/core/FrameworkGraphNodeQuery.graphql.ts b/apps/console/src/__generated__/core/FrameworkGraphNodeQuery.graphql.ts index e710cf5d1..c3589e96c 100644 --- a/apps/console/src/__generated__/core/FrameworkGraphNodeQuery.graphql.ts +++ b/apps/console/src/__generated__/core/FrameworkGraphNodeQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @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" } }; })(); diff --git a/apps/console/src/hooks/graph/FrameworkGraph.ts b/apps/console/src/hooks/graph/FrameworkGraph.ts index c4984e162..64c5d5444 100644 --- a/apps/console/src/hooks/graph/FrameworkGraph.ts +++ b/apps/console/src/hooks/graph/FrameworkGraph.ts @@ -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( diff --git a/apps/console/src/pages/organizations/frameworks/FrameworkControlPage.tsx b/apps/console/src/pages/organizations/frameworks/FrameworkControlPage.tsx index 1bf49e90f..d241a9089 100644 --- a/apps/console/src/pages/organizations/frameworks/FrameworkControlPage.tsx +++ b/apps/console/src/pages/organizations/frameworks/FrameworkControlPage.tsx @@ -336,22 +336,7 @@ export default function FrameworkControlPage({ queryRef }: Props) { - {control.status === "EXCLUDED" && ( -
-
-
- {__("This control is excluded")} -
-
-
- {__("Justification:")} - {" "} - {control.exclusionJustification - || __("No justification provided")} -
-
- )} -
+
{control.name}
{control.description && (
diff --git a/apps/console/src/pages/organizations/frameworks/FrameworkDetailPage.tsx b/apps/console/src/pages/organizations/frameworks/FrameworkDetailPage.tsx index 7a8d64a1e..d1afa0c90 100644 --- a/apps/console/src/pages/organizations/frameworks/FrameworkDetailPage.tsx +++ b/apps/console/src/pages/organizations/frameworks/FrameworkDetailPage.tsx @@ -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( - generateFrameworkStateOfApplicabilityMutation, - { - errorMessage: - "Failed to generate framework state of applicability", - successMessage: - "Framework state of applicability generated successfully", - }, - ); - const [exportFramework] = useMutationWithToasts( 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 (
@@ -178,35 +151,6 @@ export default function FrameworkDetailPage(props: Props) { )} {hasAnyAction && ( - {framework.canGenerateSOA - && ( - { - 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")} - - )} {framework.canExport && ( diff --git a/apps/console/src/pages/organizations/frameworks/dialogs/FrameworkControlDialog.tsx b/apps/console/src/pages/organizations/frameworks/dialogs/FrameworkControlDialog.tsx index e3e6c27f8..66bad56fa 100644 --- a/apps/console/src/pages/organizations/frameworks/dialogs/FrameworkControlDialog.tsx +++ b/apps/console/src/pages/organizations/frameworks/dialogs/FrameworkControlDialog.tsx @@ -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!], }, diff --git a/e2e/console/control_test.go b/e2e/console/control_test.go index f06018c0b..9ce80e456 100644 --- a/e2e/console/control_test.go +++ b/e2e/console/control_test.go @@ -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) - }) -} diff --git a/e2e/console/mapping_test.go b/e2e/console/mapping_test.go index 9bc292400..ce71c3a3e 100644 --- a/e2e/console/mapping_test.go +++ b/e2e/console/mapping_test.go @@ -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) diff --git a/e2e/console/rbac_test.go b/e2e/console/rbac_test.go index 08190ad79..88131aa77 100644 --- a/e2e/console/rbac_test.go +++ b/e2e/console/rbac_test.go @@ -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, }, diff --git a/e2e/internal/factory/factory.go b/e2e/internal/factory/factory.go index 5d73f58fc..dcc6e3b00 100644 --- a/e2e/internal/factory/factory.go +++ b/e2e/internal/factory/factory.go @@ -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), } diff --git a/go.mod b/go.mod index 8f78f9613..352c15148 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index ac25b4073..b9adf6a25 100644 --- a/go.sum +++ b/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= diff --git a/packages/n8n-node/nodes/Probo/actions/control/create.operation.ts b/packages/n8n-node/nodes/Probo/actions/control/create.operation.ts index 2ff335bd3..ad28e9f0f 100644 --- a/packages/n8n-node/nodes/Probo/actions/control/create.operation.ts +++ b/packages/n8n-node/nodes/Probo/actions/control/create.operation.ts @@ -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 }, }; } - diff --git a/packages/n8n-node/nodes/Probo/actions/control/get.operation.ts b/packages/n8n-node/nodes/Probo/actions/control/get.operation.ts index 1f4eb499c..580087009 100644 --- a/packages/n8n-node/nodes/Probo/actions/control/get.operation.ts +++ b/packages/n8n-node/nodes/Probo/actions/control/get.operation.ts @@ -32,8 +32,6 @@ export async function execute( sectionTitle name description - status - exclusionJustification createdAt updatedAt } diff --git a/packages/n8n-node/nodes/Probo/actions/control/getAll.operation.ts b/packages/n8n-node/nodes/Probo/actions/control/getAll.operation.ts index 21fcefd37..30469ef2a 100644 --- a/packages/n8n-node/nodes/Probo/actions/control/getAll.operation.ts +++ b/packages/n8n-node/nodes/Probo/actions/control/getAll.operation.ts @@ -67,8 +67,6 @@ export async function execute( sectionTitle name description - status - exclusionJustification createdAt updatedAt } diff --git a/packages/n8n-node/nodes/Probo/actions/control/update.operation.ts b/packages/n8n-node/nodes/Probo/actions/control/update.operation.ts index ce7fc4810..6a3391b72 100644 --- a/packages/n8n-node/nodes/Probo/actions/control/update.operation.ts +++ b/packages/n8n-node/nodes/Probo/actions/control/update.operation.ts @@ -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 }, }; } - diff --git a/packages/ui/src/Atoms/ControlItem/ControlItem.tsx b/packages/ui/src/Atoms/ControlItem/ControlItem.tsx index fee6dd2bd..85803e453 100644 --- a/packages/ui/src/Atoms/ControlItem/ControlItem.tsx +++ b/packages/ui/src/Atoms/ControlItem/ControlItem.tsx @@ -6,7 +6,6 @@ type Props = { active?: boolean; id: string; description?: string; - excluded?: boolean; to: string; } & HTMLAttributes; @@ -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(null); diff --git a/pkg/coredata/control.go b/pkg/coredata/control.go index 9f967a46f..5c250cde2 100644 --- a/pkg/coredata/control.go +++ b/pkg/coredata/control.go @@ -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 diff --git a/pkg/coredata/control_status.go b/pkg/coredata/control_status.go deleted file mode 100644 index b47784ca0..000000000 --- a/pkg/coredata/control_status.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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 -} diff --git a/pkg/coredata/document_version_signature_state.go b/pkg/coredata/document_version_signature_state.go index 54312af4e..ca9839ef3 100644 --- a/pkg/coredata/document_version_signature_state.go +++ b/pkg/coredata/document_version_signature_state.go @@ -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 diff --git a/pkg/coredata/invitation_status.go b/pkg/coredata/invitation_status.go index 26bc477f9..7ea32499e 100644 --- a/pkg/coredata/invitation_status.go +++ b/pkg/coredata/invitation_status.go @@ -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 diff --git a/pkg/coredata/migrations/20260217T120000Z.sql b/pkg/coredata/migrations/20260217T120000Z.sql new file mode 100644 index 000000000..62bdc95ef --- /dev/null +++ b/pkg/coredata/migrations/20260217T120000Z.sql @@ -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; diff --git a/pkg/probo/actions.go b/pkg/probo/actions.go index a5f433ab2..13e7b5f2e 100644 --- a/pkg/probo/actions.go +++ b/pkg/probo/actions.go @@ -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 diff --git a/pkg/probo/control_service.go b/pkg/probo/control_service.go index 661b3d9f7..1febd288c 100644 --- a/pkg/probo/control_service.go +++ b/pkg/probo/control_service.go @@ -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 } diff --git a/pkg/probo/framework_service.go b/pkg/probo/framework_service.go index 4de91c6f4..1b7c08f60 100644 --- a/pkg/probo/framework_service.go +++ b/pkg/probo/framework_service.go @@ -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, diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index b50db87f5..5fb434b4b 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -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 } diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index 9a84efd82..cac7f0f20 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -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 diff --git a/pkg/server/api/console/v1/types/control.go b/pkg/server/api/console/v1/types/control.go index ae8ad3278..b36c89b8d 100644 --- a/pkg/server/api/console/v1/types/control.go +++ b/pkg/server/api/console/v1/types/control.go @@ -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, } } diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 324c67d95..98ead6f16 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -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 { diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index e683036e6..64199bc6a 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -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, }, ) diff --git a/pkg/server/api/mcp/v1/schema.resolvers.go b/pkg/server/api/mcp/v1/schema.resolvers.go index ff1ed0e6f..385e93b73 100644 --- a/pkg/server/api/mcp/v1/schema.resolvers.go +++ b/pkg/server/api/mcp/v1/schema.resolvers.go @@ -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 { diff --git a/pkg/server/api/mcp/v1/specification.yaml b/pkg/server/api/mcp/v1/specification.yaml index befa7d42a..601553081 100644 --- a/pkg/server/api/mcp/v1/specification.yaml +++ b/pkg/server/api/mcp/v1/specification.yaml @@ -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 diff --git a/pkg/server/api/mcp/v1/types/control.go b/pkg/server/api/mcp/v1/types/control.go index f5c2c30f2..063c10f64 100644 --- a/pkg/server/api/mcp/v1/types/control.go +++ b/pkg/server/api/mcp/v1/types/control.go @@ -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, } } diff --git a/pkg/server/api/mcp/v1/types/types.go b/pkg/server/api/mcp/v1/types/types.go index 9b7e8e3b1..8c3d1857f 100644 --- a/pkg/server/api/mcp/v1/types/types.go +++ b/pkg/server/api/mcp/v1/types/types.go @@ -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 diff --git a/pkg/soagen/applicability.go b/pkg/soagen/applicability.go deleted file mode 100644 index 3e9c6fbdc..000000000 --- a/pkg/soagen/applicability.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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, - } -} diff --git a/pkg/soagen/excel_value.go b/pkg/soagen/excel_value.go deleted file mode 100644 index ba476b9ea..000000000 --- a/pkg/soagen/excel_value.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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 -} diff --git a/pkg/soagen/field_config.go b/pkg/soagen/field_config.go deleted file mode 100644 index a37a94ce5..000000000 --- a/pkg/soagen/field_config.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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, - }, - } -) diff --git a/pkg/soagen/generator.go b/pkg/soagen/generator.go deleted file mode 100644 index 1aa38f5a4..000000000 --- a/pkg/soagen/generator.go +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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 -} diff --git a/pkg/soagen/header.go b/pkg/soagen/header.go deleted file mode 100644 index ea27f895c..000000000 --- a/pkg/soagen/header.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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 -} diff --git a/pkg/soagen/soa_data.go b/pkg/soagen/soa_data.go deleted file mode 100644 index b1bbf7984..000000000 --- a/pkg/soagen/soa_data.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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 -} diff --git a/pkg/soagen/styles.go b/pkg/soagen/styles.go deleted file mode 100644 index a7b370592..000000000 --- a/pkg/soagen/styles.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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 -} diff --git a/pkg/soagen/yesno.go b/pkg/soagen/yesno.go deleted file mode 100644 index 4e4d17bb5..000000000 --- a/pkg/soagen/yesno.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2025 Probo Inc . -// -// 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 -} diff --git a/pkg/validator/validation_test.go b/pkg/validator/validation_test.go index 48228d7a9..7064b2dcb 100644 --- a/pkg/validator/validation_test.go +++ b/pkg/validator/validation_test.go @@ -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) } }) diff --git a/pkg/validator/validator_collection_test.go b/pkg/validator/validator_collection_test.go index 343ed71b5..0d045113a 100644 --- a/pkg/validator/validator_collection_test.go +++ b/pkg/validator/validator_collection_test.go @@ -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) } }) diff --git a/pkg/validator/validator_common_test.go b/pkg/validator/validator_common_test.go index 3efab3246..41b2999c3 100644 --- a/pkg/validator/validator_common_test.go +++ b/pkg/validator/validator_common_test.go @@ -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) } })