diff --git a/apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql.ts b/apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql.ts new file mode 100644 index 000000000..a543bcf5d --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql.ts @@ -0,0 +1,265 @@ +/** + * @generated SignedSource<<8626547ee7655aabebf153f2429023d7>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment } from 'relay-runtime'; +export type ComplianceFrameworkVisibility = "NONE" | "PUBLIC"; +import { FragmentRefs } from "relay-runtime"; +export type CompliancePageFrameworkList_compliancePageFragment$data = { + readonly canUpdate: boolean; + readonly complianceFrameworks: { + readonly __id: string; + readonly edges: ReadonlyArray<{ + readonly node: { + readonly framework: { + readonly darkLogoURL: string | null | undefined; + readonly id: string; + readonly lightLogoURL: string | null | undefined; + readonly name: string; + }; + readonly id: string; + readonly rank: number; + readonly visibility: ComplianceFrameworkVisibility; + }; + }>; + }; + readonly id: string; + readonly " $fragmentType": "CompliancePageFrameworkList_compliancePageFragment"; +}; +export type CompliancePageFrameworkList_compliancePageFragment$key = { + readonly " $data"?: CompliancePageFrameworkList_compliancePageFragment$data; + readonly " $fragmentSpreads": FragmentRefs<"CompliancePageFrameworkList_compliancePageFragment">; +}; + +import CompliancePageFrameworkList_compliancePageRefetchQuery_graphql from './CompliancePageFrameworkList_compliancePageRefetchQuery.graphql'; + +const node: ReaderFragment = (function(){ +var v0 = [ + "complianceFrameworks" +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "argumentDefinitions": [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" + }, + { + "defaultValue": 100, + "kind": "LocalArgument", + "name": "first" + }, + { + "defaultValue": { + "direction": "ASC", + "field": "RANK" + }, + "kind": "LocalArgument", + "name": "order" + } + ], + "kind": "Fragment", + "metadata": { + "connection": [ + { + "count": "first", + "cursor": "after", + "direction": "forward", + "path": (v0/*: any*/) + } + ], + "refetch": { + "connection": { + "forward": { + "count": "first", + "cursor": "after" + }, + "backward": null, + "path": (v0/*: any*/) + }, + "fragmentPathInResult": [ + "node" + ], + "operation": CompliancePageFrameworkList_compliancePageRefetchQuery_graphql, + "identifierInfo": { + "identifierField": "id", + "identifierQueryVariableName": "id" + } + } + }, + "name": "CompliancePageFrameworkList_compliancePageFragment", + "selections": [ + (v1/*: any*/), + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:update\")" + }, + { + "alias": "complianceFrameworks", + "args": [ + { + "kind": "Variable", + "name": "orderBy", + "variableName": "order" + } + ], + "concreteType": "ComplianceFrameworkConnection", + "kind": "LinkedField", + "name": "__CompliancePageFrameworkList_complianceFrameworks_connection", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFrameworkEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFramework", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "visibility", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "lightLogoURL", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "darkLogoURL", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "cursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "PageInfo", + "kind": "LinkedField", + "name": "pageInfo", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "endCursor", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasNextPage", + "storageKey": null + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": null + } + ], + "type": "TrustCenter", + "abstractKey": null +}; +})(); + +(node as any).hash = "981aff9d27dc71027541f7c3ed6984a9"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageRefetchQuery.graphql.ts b/apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageRefetchQuery.graphql.ts new file mode 100644 index 000000000..91348c796 --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageRefetchQuery.graphql.ts @@ -0,0 +1,335 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type ComplianceFrameworkOrderField = "CREATED_AT" | "RANK"; +export type OrderDirection = "ASC" | "DESC"; +export type ComplianceFrameworkOrder = { + direction: OrderDirection; + field: ComplianceFrameworkOrderField; +}; +export type CompliancePageFrameworkList_compliancePageRefetchQuery$variables = { + after?: string | null | undefined; + first?: number | null | undefined; + id: string; + order?: ComplianceFrameworkOrder | null | undefined; +}; +export type CompliancePageFrameworkList_compliancePageRefetchQuery$data = { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"CompliancePageFrameworkList_compliancePageFragment">; + }; +}; +export type CompliancePageFrameworkList_compliancePageRefetchQuery = { + response: CompliancePageFrameworkList_compliancePageRefetchQuery$data; + variables: CompliancePageFrameworkList_compliancePageRefetchQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" +}, +v1 = { + "defaultValue": 100, + "kind": "LocalArgument", + "name": "first" +}, +v2 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "id" +}, +v3 = { + "defaultValue": { + "direction": "ASC", + "field": "RANK" + }, + "kind": "LocalArgument", + "name": "order" +}, +v4 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "id" + } +], +v5 = { + "kind": "Variable", + "name": "after", + "variableName": "after" +}, +v6 = { + "kind": "Variable", + "name": "first", + "variableName": "first" +}, +v7 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v8 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v9 = [ + (v5/*: any*/), + (v6/*: any*/), + { + "kind": "Variable", + "name": "orderBy", + "variableName": "order" + } +]; +return { + "fragment": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v3/*: any*/) + ], + "kind": "Fragment", + "metadata": null, + "name": "CompliancePageFrameworkList_compliancePageRefetchQuery", + "selections": [ + { + "alias": null, + "args": (v4/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "args": [ + (v5/*: any*/), + (v6/*: any*/), + { + "kind": "Variable", + "name": "order", + "variableName": "order" + } + ], + "kind": "FragmentSpread", + "name": "CompliancePageFrameworkList_compliancePageFragment" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v3/*: any*/), + (v2/*: any*/) + ], + "kind": "Operation", + "name": "CompliancePageFrameworkList_compliancePageRefetchQuery", + "selections": [ + { + "alias": null, + "args": (v4/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v7/*: any*/), + (v8/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:update\")" + }, + { + "alias": null, + "args": (v9/*: any*/), + "concreteType": "ComplianceFrameworkConnection", + "kind": "LinkedField", + "name": "complianceFrameworks", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFrameworkEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFramework", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v8/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "visibility", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + (v8/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "lightLogoURL", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "darkLogoURL", + "storageKey": null + } + ], + "storageKey": null + }, + (v7/*: any*/) + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "cursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "PageInfo", + "kind": "LinkedField", + "name": "pageInfo", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "endCursor", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasNextPage", + "storageKey": null + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": null + }, + { + "alias": null, + "args": (v9/*: any*/), + "filters": [ + "orderBy" + ], + "handle": "connection", + "key": "CompliancePageFrameworkList_complianceFrameworks", + "kind": "LinkedHandle", + "name": "complianceFrameworks" + } + ], + "type": "TrustCenter", + "abstractKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "c3c1d708940371ebc18c2c5272f0b26d", + "id": null, + "metadata": {}, + "name": "CompliancePageFrameworkList_compliancePageRefetchQuery", + "operationKind": "query", + "text": "query CompliancePageFrameworkList_compliancePageRefetchQuery(\n $after: CursorKey = null\n $first: Int = 100\n $order: ComplianceFrameworkOrder = {field: RANK, direction: ASC}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompliancePageFrameworkList_compliancePageFragment_gOVF5\n id\n }\n}\n\nfragment CompliancePageFrameworkList_compliancePageFragment_gOVF5 on TrustCenter {\n id\n canUpdate: permission(action: \"core:trust-center:update\")\n complianceFrameworks(first: $first, after: $after, orderBy: $order) {\n edges {\n node {\n id\n rank\n visibility\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "981aff9d27dc71027541f7c3ed6984a9"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageFrameworkList_createMutation.graphql.ts b/apps/console/src/__generated__/core/CompliancePageFrameworkList_createMutation.graphql.ts new file mode 100644 index 000000000..816c00934 --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageFrameworkList_createMutation.graphql.ts @@ -0,0 +1,119 @@ +/** + * @generated SignedSource<<2980fa2d2a72851686e88a7b5402d720>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type CreateComplianceFrameworkInput = { + frameworkId: string; + trustCenterId: string; +}; +export type CompliancePageFrameworkList_createMutation$variables = { + input: CreateComplianceFrameworkInput; +}; +export type CompliancePageFrameworkList_createMutation$data = { + readonly createComplianceFramework: { + readonly complianceFrameworkEdge: { + readonly node: { + readonly id: string; + }; + }; + }; +}; +export type CompliancePageFrameworkList_createMutation = { + response: CompliancePageFrameworkList_createMutation$data; + variables: CompliancePageFrameworkList_createMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "CreateComplianceFrameworkPayload", + "kind": "LinkedField", + "name": "createComplianceFramework", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFrameworkEdge", + "kind": "LinkedField", + "name": "complianceFrameworkEdge", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFramework", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "CompliancePageFrameworkList_createMutation", + "selections": (v1/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "CompliancePageFrameworkList_createMutation", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "9caebfdeda321fb743a8d789c7e25e82", + "id": null, + "metadata": {}, + "name": "CompliancePageFrameworkList_createMutation", + "operationKind": "mutation", + "text": "mutation CompliancePageFrameworkList_createMutation(\n $input: CreateComplianceFrameworkInput!\n) {\n createComplianceFramework(input: $input) {\n complianceFrameworkEdge {\n node {\n id\n }\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "41815aaef15ed1754b4d81c1d982a2c6"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageFrameworkList_deleteMutation.graphql.ts b/apps/console/src/__generated__/core/CompliancePageFrameworkList_deleteMutation.graphql.ts new file mode 100644 index 000000000..cb7fd4eb1 --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageFrameworkList_deleteMutation.graphql.ts @@ -0,0 +1,92 @@ +/** + * @generated SignedSource<<0f29d441e95842685f0311839d3b45ef>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type DeleteComplianceFrameworkInput = { + id: string; +}; +export type CompliancePageFrameworkList_deleteMutation$variables = { + input: DeleteComplianceFrameworkInput; +}; +export type CompliancePageFrameworkList_deleteMutation$data = { + readonly deleteComplianceFramework: { + readonly deletedComplianceFrameworkId: string; + }; +}; +export type CompliancePageFrameworkList_deleteMutation = { + response: CompliancePageFrameworkList_deleteMutation$data; + variables: CompliancePageFrameworkList_deleteMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "DeleteComplianceFrameworkPayload", + "kind": "LinkedField", + "name": "deleteComplianceFramework", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "deletedComplianceFrameworkId", + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "CompliancePageFrameworkList_deleteMutation", + "selections": (v1/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "CompliancePageFrameworkList_deleteMutation", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "5792168e44352169568a1378b621df16", + "id": null, + "metadata": {}, + "name": "CompliancePageFrameworkList_deleteMutation", + "operationKind": "mutation", + "text": "mutation CompliancePageFrameworkList_deleteMutation(\n $input: DeleteComplianceFrameworkInput!\n) {\n deleteComplianceFramework(input: $input) {\n deletedComplianceFrameworkId\n }\n}\n" + } +}; +})(); + +(node as any).hash = "fed45c59adf7d88aec4bbb7eb61840c3"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageFrameworkList_updateRankMutation.graphql.ts b/apps/console/src/__generated__/core/CompliancePageFrameworkList_updateRankMutation.graphql.ts new file mode 100644 index 000000000..637571d99 --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageFrameworkList_updateRankMutation.graphql.ts @@ -0,0 +1,114 @@ +/** + * @generated SignedSource<<3c6052dff7f71548026fb23353e215b2>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type UpdateComplianceFrameworkInput = { + id: string; + rank: number; +}; +export type CompliancePageFrameworkList_updateRankMutation$variables = { + input: UpdateComplianceFrameworkInput; +}; +export type CompliancePageFrameworkList_updateRankMutation$data = { + readonly updateComplianceFramework: { + readonly complianceFramework: { + readonly id: string; + readonly rank: number; + }; + }; +}; +export type CompliancePageFrameworkList_updateRankMutation = { + response: CompliancePageFrameworkList_updateRankMutation$data; + variables: CompliancePageFrameworkList_updateRankMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "UpdateComplianceFrameworkPayload", + "kind": "LinkedField", + "name": "updateComplianceFramework", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFramework", + "kind": "LinkedField", + "name": "complianceFramework", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "CompliancePageFrameworkList_updateRankMutation", + "selections": (v1/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "CompliancePageFrameworkList_updateRankMutation", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "429989dd7550f3c5466a8098f5167592", + "id": null, + "metadata": {}, + "name": "CompliancePageFrameworkList_updateRankMutation", + "operationKind": "mutation", + "text": "mutation CompliancePageFrameworkList_updateRankMutation(\n $input: UpdateComplianceFrameworkInput!\n) {\n updateComplianceFramework(input: $input) {\n complianceFramework {\n id\n rank\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "a60d166f55bbe09a53349b400355ffc0"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageOverviewPageQuery.graphql.ts b/apps/console/src/__generated__/core/CompliancePageOverviewPageQuery.graphql.ts index 0e3948146..361719aca 100644 --- a/apps/console/src/__generated__/core/CompliancePageOverviewPageQuery.graphql.ts +++ b/apps/console/src/__generated__/core/CompliancePageOverviewPageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<18bb7ea1b507c374c33d9f4f7a56db2d>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -17,6 +17,7 @@ export type CompliancePageOverviewPageQuery$data = { readonly organization: { readonly compliancePage?: { readonly canGetNDA: boolean; + readonly " $fragmentSpreads": FragmentRefs<"CompliancePageFrameworkList_compliancePageFragment">; } | null | undefined; readonly " $fragmentSpreads": FragmentRefs<"CompliancePageNDASectionFragment" | "CompliancePageSlackSectionFragment" | "CompliancePageStatusSectionFragment">; }; @@ -55,12 +56,35 @@ v2 = { "storageKey": "permission(action:\"core:trust-center:get-nda\")" }, v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v4 = { "alias": null, "args": null, "kind": "ScalarField", "name": "id", "storageKey": null -}; +}, +v5 = { + "kind": "Literal", + "name": "first", + "value": 100 +}, +v6 = [ + (v5/*: any*/), + { + "kind": "Literal", + "name": "orderBy", + "value": { + "direction": "ASC", + "field": "RANK" + } + } +]; return { "fragment": { "argumentDefinitions": (v0/*: any*/), @@ -87,7 +111,12 @@ return { "name": "trustCenter", "plural": false, "selections": [ - (v2/*: any*/) + (v2/*: any*/), + { + "args": null, + "kind": "FragmentSpread", + "name": "CompliancePageFrameworkList_compliancePageFragment" + } ], "storageKey": null } @@ -131,13 +160,7 @@ return { "name": "node", "plural": false, "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "__typename", - "storageKey": null - }, + (v3/*: any*/), { "kind": "InlineFragment", "selections": [ @@ -150,14 +173,7 @@ return { "plural": false, "selections": [ (v2/*: any*/), - (v3/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "active", - "storageKey": null - }, + (v4/*: any*/), { "alias": "canUpdate", "args": [ @@ -171,6 +187,150 @@ return { "name": "permission", "storageKey": "permission(action:\"core:trust-center:update\")" }, + { + "alias": null, + "args": (v6/*: any*/), + "concreteType": "ComplianceFrameworkConnection", + "kind": "LinkedField", + "name": "complianceFrameworks", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFrameworkEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFramework", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v4/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "visibility", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + (v4/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "lightLogoURL", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "darkLogoURL", + "storageKey": null + } + ], + "storageKey": null + }, + (v3/*: any*/) + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "cursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "PageInfo", + "kind": "LinkedField", + "name": "pageInfo", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "endCursor", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasNextPage", + "storageKey": null + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": "complianceFrameworks(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"RANK\"})" + }, + { + "alias": null, + "args": (v6/*: any*/), + "filters": [ + "orderBy" + ], + "handle": "connection", + "key": "CompliancePageFrameworkList_complianceFrameworks", + "kind": "LinkedHandle", + "name": "complianceFrameworks" + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "active", + "storageKey": null + }, { "alias": null, "args": null, @@ -229,18 +389,14 @@ return { "name": "domain", "storageKey": null }, - (v3/*: any*/) + (v4/*: any*/) ], "storageKey": null }, { "alias": null, "args": [ - { - "kind": "Literal", - "name": "first", - "value": 100 - } + (v5/*: any*/) ], "concreteType": "SlackConnectionConnection", "kind": "LinkedField", @@ -263,7 +419,7 @@ return { "name": "node", "plural": false, "selections": [ - (v3/*: any*/), + (v4/*: any*/), { "alias": null, "args": null, @@ -291,23 +447,23 @@ return { "type": "Organization", "abstractKey": null }, - (v3/*: any*/) + (v4/*: any*/) ], "storageKey": null } ] }, "params": { - "cacheID": "0041132d3ac46a3193d9acbd6f27bdf5", + "cacheID": "e6cc68fe4df4a8dffc558f6db82ead9c", "id": null, "metadata": {}, "name": "CompliancePageOverviewPageQuery", "operationKind": "query", - "text": "query CompliancePageOverviewPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n canGetNDA: permission(action: \"core:trust-center:get-nda\")\n id\n }\n }\n ...CompliancePageStatusSectionFragment\n ...CompliancePageNDASectionFragment\n ...CompliancePageSlackSectionFragment\n id\n }\n}\n\nfragment CompliancePageNDASectionFragment on Organization {\n compliancePage: trustCenter {\n id\n ndaFileName\n ndaFileUrl\n canUpdate: permission(action: \"core:trust-center:update\")\n canUploadNDA: permission(action: \"core:trust-center:upload-nda\")\n canDeleteNDA: permission(action: \"core:trust-center:delete-nda\")\n }\n}\n\nfragment CompliancePageSlackSectionFragment on Organization {\n compliancePage: trustCenter {\n canUpdate: permission(action: \"core:trust-center:update\")\n id\n }\n slackConnections(first: 100) {\n edges {\n node {\n id\n channel\n createdAt\n }\n }\n }\n}\n\nfragment CompliancePageStatusSectionFragment on Organization {\n customDomain {\n domain\n id\n }\n compliancePage: trustCenter {\n id\n active\n canUpdate: permission(action: \"core:trust-center:update\")\n }\n}\n" + "text": "query CompliancePageOverviewPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n canGetNDA: permission(action: \"core:trust-center:get-nda\")\n ...CompliancePageFrameworkList_compliancePageFragment\n id\n }\n }\n ...CompliancePageStatusSectionFragment\n ...CompliancePageNDASectionFragment\n ...CompliancePageSlackSectionFragment\n id\n }\n}\n\nfragment CompliancePageFrameworkList_compliancePageFragment on TrustCenter {\n id\n canUpdate: permission(action: \"core:trust-center:update\")\n complianceFrameworks(first: 100, orderBy: {field: RANK, direction: ASC}) {\n edges {\n node {\n id\n rank\n visibility\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment CompliancePageNDASectionFragment on Organization {\n compliancePage: trustCenter {\n id\n ndaFileName\n ndaFileUrl\n canUpdate: permission(action: \"core:trust-center:update\")\n canUploadNDA: permission(action: \"core:trust-center:upload-nda\")\n canDeleteNDA: permission(action: \"core:trust-center:delete-nda\")\n }\n}\n\nfragment CompliancePageSlackSectionFragment on Organization {\n compliancePage: trustCenter {\n canUpdate: permission(action: \"core:trust-center:update\")\n id\n }\n slackConnections(first: 100) {\n edges {\n node {\n id\n channel\n createdAt\n }\n }\n }\n}\n\nfragment CompliancePageStatusSectionFragment on Organization {\n customDomain {\n domain\n id\n }\n compliancePage: trustCenter {\n id\n active\n canUpdate: permission(action: \"core:trust-center:update\")\n }\n}\n" } }; })(); -(node as any).hash = "689133b7f1c380266e6f15a60c527c91"; +(node as any).hash = "be0dff83941c21755ea2ff77a865805b"; export default node; diff --git a/apps/console/src/pages/organizations/compliance-page/overview/CompliancePageOverviewPage.tsx b/apps/console/src/pages/organizations/compliance-page/overview/CompliancePageOverviewPage.tsx index ffb449191..d63a55074 100644 --- a/apps/console/src/pages/organizations/compliance-page/overview/CompliancePageOverviewPage.tsx +++ b/apps/console/src/pages/organizations/compliance-page/overview/CompliancePageOverviewPage.tsx @@ -1,8 +1,10 @@ +import { useTranslate } from "@probo/i18n"; import { type PreloadedQuery, usePreloadedQuery } from "react-relay"; import { graphql } from "relay-runtime"; import type { CompliancePageOverviewPageQuery } from "#/__generated__/core/CompliancePageOverviewPageQuery.graphql"; +import { CompliancePageFrameworkList } from "./_components/CompliancePageFrameworkList"; import { CompliancePageNDASection } from "./_components/CompliancePageNDASection"; import { CompliancePageSlackSection } from "./_components/CompliancePageSlackSection"; import { CompliancePageStatusSection } from "./_components/CompliancePageStatusSection"; @@ -13,6 +15,7 @@ export const compliancePageOverviewPageQuery = graphql` ... on Organization { compliancePage: trustCenter { canGetNDA: permission(action: "core:trust-center:get-nda") + ...CompliancePageFrameworkList_compliancePageFragment } } ...CompliancePageStatusSectionFragment @@ -25,6 +28,8 @@ export const compliancePageOverviewPageQuery = graphql` export function CompliancePageOverviewPage(props: { queryRef: PreloadedQuery }) { const { queryRef } = props; + const { __ } = useTranslate(); + const { organization } = usePreloadedQuery( compliancePageOverviewPageQuery, queryRef, @@ -39,6 +44,18 @@ export function CompliancePageOverviewPage(props: { queryRef: PreloadedQuery + + {organization.compliancePage && ( +
+
+

{__("Frameworks")}

+

+ {__("Select which frameworks to display as badges on your compliance page")} +

+
+ +
+ )} ); } diff --git a/apps/console/src/pages/organizations/compliance-page/overview/_components/CompliancePageFrameworkList.tsx b/apps/console/src/pages/organizations/compliance-page/overview/_components/CompliancePageFrameworkList.tsx new file mode 100644 index 000000000..2ca561eee --- /dev/null +++ b/apps/console/src/pages/organizations/compliance-page/overview/_components/CompliancePageFrameworkList.tsx @@ -0,0 +1,358 @@ +import { useTranslate } from "@probo/i18n"; +import { Badge, Field, FrameworkLogo, Option, Table, Tbody, Td, Th, Thead, Tr } from "@probo/ui"; +import { useCallback, useState, useTransition } from "react"; +import { useRefetchableFragment } from "react-relay"; +import { ConnectionHandler, graphql } from "relay-runtime"; + +import type { CompliancePageFrameworkList_compliancePageFragment$key } from "#/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql"; +import type { CompliancePageFrameworkList_compliancePageFragment$data } from "#/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql"; +import type { CompliancePageFrameworkList_compliancePageRefetchQuery } from "#/__generated__/core/CompliancePageFrameworkList_compliancePageRefetchQuery.graphql"; +import type { CompliancePageFrameworkList_createMutation } from "#/__generated__/core/CompliancePageFrameworkList_createMutation.graphql"; +import type { CompliancePageFrameworkList_deleteMutation } from "#/__generated__/core/CompliancePageFrameworkList_deleteMutation.graphql"; +import type { CompliancePageFrameworkList_updateRankMutation } from "#/__generated__/core/CompliancePageFrameworkList_updateRankMutation.graphql"; +import { useMutationWithToasts } from "#/hooks/useMutationWithToasts"; + +const compliancePageFragment = graphql` + fragment CompliancePageFrameworkList_compliancePageFragment on TrustCenter + @refetchable(queryName: "CompliancePageFrameworkList_compliancePageRefetchQuery") + @argumentDefinitions( + first: { type: Int, defaultValue: 100 } + after: { type: CursorKey, defaultValue: null } + order: { type: ComplianceFrameworkOrder, defaultValue: { field: RANK, direction: ASC } } + ) { + id + canUpdate: permission(action: "core:trust-center:update") + complianceFrameworks(first: $first, after: $after, orderBy: $order) + @connection(key: "CompliancePageFrameworkList_complianceFrameworks", filters: ["orderBy"]) { + __id + edges { + node { + id + rank + visibility + framework { + id + name + lightLogoURL + darkLogoURL + } + } + } + } + } +`; + +const createMutation = graphql` + mutation CompliancePageFrameworkList_createMutation($input: CreateComplianceFrameworkInput!) { + createComplianceFramework(input: $input) { + complianceFrameworkEdge { + node { + id + } + } + } + } +`; + +const updateRankMutation = graphql` + mutation CompliancePageFrameworkList_updateRankMutation($input: UpdateComplianceFrameworkInput!) { + updateComplianceFramework(input: $input) { + complianceFramework { + id + rank + } + } + } +`; + +const deleteMutation = graphql` + mutation CompliancePageFrameworkList_deleteMutation($input: DeleteComplianceFrameworkInput!) { + deleteComplianceFramework(input: $input) { + deletedComplianceFrameworkId + } + } +`; + +type Edge = CompliancePageFrameworkList_compliancePageFragment$data["complianceFrameworks"]["edges"][number]; + +function CompliancePageFrameworkListItem(props: { + edge: Edge; + compliancePage: CompliancePageFrameworkList_compliancePageFragment$data; + draggedCfId: string | null; + dragOverCfId: string | null; + onDragStart: (cfId: string) => void; + onDragEnd: () => void; + onDragOver: (e: React.DragEvent, cfId: string) => void; + onDrop: (cfId: string) => void; + onRefetch: () => void; +}) { + const { edge, draggedCfId, dragOverCfId, onDragStart, onDragEnd, onDragOver, onDrop, onRefetch } = props; + const { __ } = useTranslate(); + const [isMouseDown, setIsMouseDown] = useState(false); + + const compliancePage = props.compliancePage; + const { id, visibility, framework } = edge.node; + + const isPublic = visibility === "PUBLIC"; + const canDrag = isPublic && compliancePage.canUpdate; + + const isDragging = draggedCfId === id; + const isDropTarget = dragOverCfId === id && draggedCfId !== id; + + const [createComplianceFramework, isCreating] = useMutationWithToasts( + createMutation, + { + successMessage: __("Framework visibility updated successfully."), + errorMessage: __("Failed to update framework visibility"), + }, + ); + + const [deleteComplianceFramework, isDeleting] = useMutationWithToasts( + deleteMutation, + { + successMessage: __("Framework visibility updated successfully."), + errorMessage: __("Failed to update framework visibility"), + }, + ); + + const isLoading = isCreating || isDeleting; + + const handleVisibilityChange = useCallback( + async (value: string) => { + if (value === "PUBLIC" && !isPublic) { + await createComplianceFramework({ + variables: { + input: { + trustCenterId: compliancePage.id, + frameworkId: framework.id, + }, + }, + onCompleted: (_, errors) => { + if (!errors?.length) { + onRefetch(); + } + }, + }); + } else if (value === "NONE" && isPublic) { + await deleteComplianceFramework({ + variables: { + input: { id }, + }, + onCompleted: (_, errors) => { + if (!errors?.length) { + onRefetch(); + } + }, + }); + } + }, + [compliancePage.id, framework.id, id, isPublic, onRefetch, createComplianceFramework, deleteComplianceFramework], + ); + + const visibilityOptions = [ + { value: "PUBLIC", label: __("Public"), variant: "success" as const }, + { value: "NONE", label: __("None"), variant: "neutral" as const }, + ]; + + const rowClassName = [ + canDrag && isDragging && "opacity-50 cursor-grabbing", + canDrag && !isDragging && !isMouseDown && "cursor-grab", + canDrag && !isDragging && isMouseDown && "cursor-grabbing", + isDropTarget && "!bg-primary-50 border-y-2 border-primary-500", + ] + .filter(Boolean) + .join(" "); + + return ( + onDragStart(id) : undefined} + onDragEnd={canDrag ? onDragEnd : undefined} + onDragOver={canDrag ? e => onDragOver(e, id) : undefined} + onDrop={ + canDrag + ? (e) => { + e.preventDefault(); + onDrop(id); + } + : undefined + } + onMouseDown={canDrag ? () => setIsMouseDown(true) : undefined} + onMouseUp={canDrag ? () => setIsMouseDown(false) : undefined} + onMouseLeave={canDrag ? () => setIsMouseDown(false) : undefined} + className={rowClassName} + > + +
+ + {framework.name} +
+ + + void handleVisibilityChange(value)} + disabled={isLoading || !compliancePage.canUpdate} + className="w-[105px]" + > + {visibilityOptions.map(option => ( + + ))} + + + + ); +} + +export function CompliancePageFrameworkList(props: { + compliancePageRef: CompliancePageFrameworkList_compliancePageFragment$key; +}) { + const { __ } = useTranslate(); + const [, startTransition] = useTransition(); + + const [compliancePage, refetch] = useRefetchableFragment< + CompliancePageFrameworkList_compliancePageRefetchQuery, + CompliancePageFrameworkList_compliancePageFragment$key + >(compliancePageFragment, props.compliancePageRef); + + const [updateRank] = useMutationWithToasts( + updateRankMutation, + { + successMessage: __("Order updated successfully"), + errorMessage: __("Failed to update order"), + }, + ); + + const [draggedCfId, setDraggedCfId] = useState(null); + const [dragOverCfId, setDragOverCfId] = useState(null); + + const allEdges = compliancePage.complianceFrameworks.edges; + const publicEdges = allEdges.filter(e => e.node.visibility === "PUBLIC"); + + const handleDragStart = (cfId: string) => { + setDraggedCfId(cfId); + }; + + const handleDragEnd = () => { + setDraggedCfId(null); + setDragOverCfId(null); + }; + + const handleDragOver = (e: React.DragEvent, cfId: string) => { + e.preventDefault(); + if (draggedCfId !== cfId) { + setDragOverCfId(cfId); + } + }; + + const handleDrop = async (targetCfId: string) => { + if (!draggedCfId || draggedCfId === targetCfId) { + setDraggedCfId(null); + setDragOverCfId(null); + return; + } + + const targetEdge = publicEdges.find(e => e.node.id === targetCfId); + if (!targetEdge) { + setDraggedCfId(null); + setDragOverCfId(null); + return; + } + + const draggedId = draggedCfId; + + await updateRank({ + variables: { + input: { + id: draggedId, + rank: targetEdge.node.rank, + }, + }, + updater: (store) => { + const trustCenterRecord = store.get(compliancePage.id); + if (!trustCenterRecord) return; + + const connection = ConnectionHandler.getConnection( + trustCenterRecord, + "CompliancePageFrameworkList_complianceFrameworks", + { orderBy: { field: "RANK", direction: "ASC" } }, + ); + if (!connection) return; + + const edges = connection.getLinkedRecords("edges"); + if (!edges) return; + + const fromIdx = edges.findIndex(e => e.getLinkedRecord("node")?.getDataID() === draggedId); + const toIdx = edges.findIndex(e => e.getLinkedRecord("node")?.getDataID() === targetCfId); + if (fromIdx === -1 || toIdx === -1) return; + + const reordered = [...edges]; + const [moved] = reordered.splice(fromIdx, 1); + reordered.splice(toIdx, 0, moved); + connection.setLinkedRecords(reordered, "edges"); + }, + onCompleted: (_, errors) => { + startTransition(() => { + refetch({}, { fetchPolicy: errors?.length ? "network-only" : "store-and-network" }); + }); + }, + }); + + setDraggedCfId(null); + setDragOverCfId(null); + }; + + const hasMultiplePublic = publicEdges.length > 1; + + return ( + <> + + + + + + + + + {allEdges.length === 0 && ( + + + + )} + {allEdges.map(edge => ( + void handleDrop(cfId)} + onRefetch={() => startTransition(() => { refetch({}, { fetchPolicy: "store-and-network" }); })} + /> + ))} + +
{__("Framework")}{__("Visibility")}
+ {__("No frameworks available")} +
+ + {hasMultiplePublic && compliancePage.canUpdate && ( +

+ {__("Drag and drop public frameworks to change their displayed order")} +

+ )} + + ); +} diff --git a/apps/console/src/pages/organizations/compliance-page/references/_components/CompliancePageReferenceList.tsx b/apps/console/src/pages/organizations/compliance-page/references/_components/CompliancePageReferenceList.tsx index f05a91788..32906c67d 100644 --- a/apps/console/src/pages/organizations/compliance-page/references/_components/CompliancePageReferenceList.tsx +++ b/apps/console/src/pages/organizations/compliance-page/references/_components/CompliancePageReferenceList.tsx @@ -126,7 +126,7 @@ export function CompliancePageReferenceList(props: { -

+

{__("Drag and drop references to change their displayed order")}

diff --git a/apps/trust/src/components/FrameworkBadge.tsx b/apps/trust/src/components/FrameworkBadge.tsx new file mode 100644 index 000000000..afec828b9 --- /dev/null +++ b/apps/trust/src/components/FrameworkBadge.tsx @@ -0,0 +1,32 @@ +import { FrameworkLogo } from "@probo/ui"; +import { useFragment } from "react-relay"; +import { graphql } from "relay-runtime"; + +import type { FrameworkBadgeFragment$key } from "./__generated__/FrameworkBadgeFragment.graphql"; + +const frameworkFragment = graphql` + fragment FrameworkBadgeFragment on Framework { + id + name + lightLogoURL + darkLogoURL + } +`; + +export function FrameworkBadge(props: { framework: FrameworkBadgeFragment$key }) { + const framework = useFragment(frameworkFragment, props.framework); + + return ( +
+ +
+ {framework.name} +
+
+ ); +} diff --git a/apps/trust/src/components/OrganizationSidebar.tsx b/apps/trust/src/components/OrganizationSidebar.tsx index 5ea7fdc8a..47cf917ab 100644 --- a/apps/trust/src/components/OrganizationSidebar.tsx +++ b/apps/trust/src/components/OrganizationSidebar.tsx @@ -19,7 +19,7 @@ import type { TrustGraphCurrentQuery$data } from "#/queries/__generated__/TrustG import { getPathPrefix } from "#/utils/pathPrefix"; import type { OrganizationSidebar_requestAllAccessesMutation } from "./__generated__/OrganizationSidebar_requestAllAccessesMutation.graphql"; -import { AuditRowAvatar } from "./AuditRow"; +import { FrameworkBadge } from "./FrameworkBadge"; const requestAllAccessesMutation = graphql` mutation OrganizationSidebar_requestAllAccessesMutation { @@ -154,7 +154,7 @@ export function OrganizationSidebar({
{/* Certifications */} - {trustCenter.audits.edges.length > 0 && ( + {trustCenter.complianceFrameworks.edges.length > 0 && ( <>

@@ -167,8 +167,8 @@ export function OrganizationSidebar({ gridTemplateColumns: "repeat(auto-fit, 75px", }} > - {trustCenter.audits.edges.map(audit => ( - + {trustCenter.complianceFrameworks.edges.map(edge => ( + ))}

diff --git a/apps/trust/src/components/__generated__/FrameworkBadgeFragment.graphql.ts b/apps/trust/src/components/__generated__/FrameworkBadgeFragment.graphql.ts new file mode 100644 index 000000000..d429f19dc --- /dev/null +++ b/apps/trust/src/components/__generated__/FrameworkBadgeFragment.graphql.ts @@ -0,0 +1,66 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type FrameworkBadgeFragment$data = { + readonly darkLogoURL: string | null | undefined; + readonly id: string; + readonly lightLogoURL: string | null | undefined; + readonly name: string; + readonly " $fragmentType": "FrameworkBadgeFragment"; +}; +export type FrameworkBadgeFragment$key = { + readonly " $data"?: FrameworkBadgeFragment$data; + readonly " $fragmentSpreads": FragmentRefs<"FrameworkBadgeFragment">; +}; + +const node: ReaderFragment = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "FrameworkBadgeFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "lightLogoURL", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "darkLogoURL", + "storageKey": null + } + ], + "type": "Framework", + "abstractKey": null +}; + +(node as any).hash = "cdfaf9a4a0e2cb667a5ef8d3e7db1f99"; + +export default node; diff --git a/apps/trust/src/queries/TrustGraph.ts b/apps/trust/src/queries/TrustGraph.ts index 4d614832a..eb6426dfb 100644 --- a/apps/trust/src/queries/TrustGraph.ts +++ b/apps/trust/src/queries/TrustGraph.ts @@ -34,6 +34,16 @@ export const currentTrustGraphQuery = graphql` } } } + complianceFrameworks(first: 50) { + edges { + node { + id + framework { + ...FrameworkBadgeFragment + } + } + } + } } } `; diff --git a/apps/trust/src/queries/__generated__/TrustGraphCurrentQuery.graphql.ts b/apps/trust/src/queries/__generated__/TrustGraphCurrentQuery.graphql.ts index 9613281c9..cd852af52 100644 --- a/apps/trust/src/queries/__generated__/TrustGraphCurrentQuery.graphql.ts +++ b/apps/trust/src/queries/__generated__/TrustGraphCurrentQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<47a6e80d3532b4c93d18495c2be7676d>> + * @generated SignedSource<<4eef287e3e3152affa1b16189a504c36>> * @lightSyntaxTransform * @nogrep */ @@ -22,6 +22,16 @@ export type TrustGraphCurrentQuery$data = { }; }>; }; + readonly complianceFrameworks: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly framework: { + readonly " $fragmentSpreads": FragmentRefs<"FrameworkBadgeFragment">; + }; + readonly id: string; + }; + }>; + }; readonly darkLogoFileUrl: string | null | undefined; readonly id: string; readonly logoFileUrl: string | null | undefined; @@ -193,6 +203,33 @@ v16 = { (v6/*: any*/) ], "storageKey": null +}, +v17 = { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + (v0/*: any*/), + (v7/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "lightLogoURL", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "darkLogoURL", + "storageKey": null + } + ], + "storageKey": null }; return { "fragment": { @@ -300,6 +337,56 @@ return { } ], "storageKey": "audits(first:50)" + }, + { + "alias": null, + "args": (v13/*: any*/), + "concreteType": "ComplianceFrameworkConnection", + "kind": "LinkedField", + "name": "complianceFrameworks", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFrameworkEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFramework", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v0/*: any*/), + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "FrameworkBadgeFragment" + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "complianceFrameworks(first:50)" } ], "storageKey": null @@ -612,33 +699,7 @@ return { ], "storageKey": null }, - { - "alias": null, - "args": null, - "concreteType": "Framework", - "kind": "LinkedField", - "name": "framework", - "plural": false, - "selections": [ - (v0/*: any*/), - (v7/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "lightLogoURL", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "darkLogoURL", - "storageKey": null - } - ], - "storageKey": null - } + (v17/*: any*/) ], "storageKey": null } @@ -647,6 +708,41 @@ return { } ], "storageKey": "audits(first:50)" + }, + { + "alias": null, + "args": (v13/*: any*/), + "concreteType": "ComplianceFrameworkConnection", + "kind": "LinkedField", + "name": "complianceFrameworks", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFrameworkEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFramework", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v0/*: any*/), + (v17/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "complianceFrameworks(first:50)" } ], "storageKey": null @@ -654,16 +750,16 @@ return { ] }, "params": { - "cacheID": "42b477429f092f97b0f444433a78c6d1", + "cacheID": "e64b984bdcf5a5fb2f19e69c6205ba9a", "id": null, "metadata": {}, "name": "TrustGraphCurrentQuery", "operationKind": "query", - "text": "query TrustGraphCurrentQuery {\n currentTrustCenter {\n id\n slug\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n name\n report {\n id\n filename\n isUserAuthorized\n access {\n id\n status\n }\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n" + "text": "query TrustGraphCurrentQuery {\n currentTrustCenter {\n id\n slug\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n complianceFrameworks(first: 50) {\n edges {\n node {\n id\n framework {\n ...FrameworkBadgeFragment\n id\n }\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n name\n report {\n id\n filename\n isUserAuthorized\n access {\n id\n status\n }\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment FrameworkBadgeFragment on Framework {\n id\n name\n lightLogoURL\n darkLogoURL\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n" } }; })(); -(node as any).hash = "41cf8e5383cefdd5b3b7b85263eccb1f"; +(node as any).hash = "d1ce7e38b42fad48e9f38bf00bb34d56"; export default node; diff --git a/pkg/coredata/compliance_framework.go b/pkg/coredata/compliance_framework.go new file mode 100644 index 000000000..cc4e2e6ae --- /dev/null +++ b/pkg/coredata/compliance_framework.go @@ -0,0 +1,428 @@ +// 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 ( + "context" + "errors" + "fmt" + "maps" + "time" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" + "go.gearno.de/kit/pg" + "go.probo.inc/probo/pkg/gid" + "go.probo.inc/probo/pkg/page" +) + +type ( + ComplianceFramework struct { + ID gid.GID `db:"id"` + OrganizationID gid.GID `db:"organization_id"` + TrustCenterID gid.GID `db:"trust_center_id"` + FrameworkID gid.GID `db:"framework_id"` + Rank int `db:"rank"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` + + // Visibility is a non-db field used to return all frameworks for a trust center, including hidden ones. + Visibility ComplianceFrameworkVisibility `db:"visibility"` + } + + ComplianceFrameworks []*ComplianceFramework +) + +func (c ComplianceFramework) CursorKey(orderBy ComplianceFrameworkOrderField) page.CursorKey { + switch orderBy { + case ComplianceFrameworkOrderFieldCreatedAt: + return page.NewCursorKey(c.ID, c.CreatedAt) + case ComplianceFrameworkOrderFieldRank: + return page.NewCursorKey(c.ID, c.Rank) + } + panic(fmt.Sprintf("unsupported order by: %s", orderBy)) +} + +func (c *ComplianceFramework) AuthorizationAttributes(ctx context.Context, conn pg.Conn) (map[string]string, error) { + q := `SELECT organization_id FROM compliance_frameworks WHERE id = $1 LIMIT 1;` + + var organizationID gid.GID + if err := conn.QueryRow(ctx, q, c.ID).Scan(&organizationID); err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return nil, ErrResourceNotFound + } + return nil, fmt.Errorf("cannot query compliance framework authorization attributes: %w", err) + } + + return map[string]string{"organization_id": organizationID.String()}, nil +} + +func (c *ComplianceFramework) LoadByID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + complianceFrameworkID gid.GID, +) error { + q := ` +SELECT + id, + organization_id, + trust_center_id, + framework_id, + rank, + 'PUBLIC' AS visibility, + created_at, + updated_at +FROM + compliance_frameworks +WHERE + %s + AND id = @compliance_framework_id +LIMIT 1; +` + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"compliance_framework_id": complianceFrameworkID} + maps.Copy(args, scope.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query compliance_frameworks: %w", err) + } + + cf, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[ComplianceFramework]) + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return ErrResourceNotFound + } + return fmt.Errorf("cannot collect compliance framework: %w", err) + } + + *c = cf + + return nil +} + +func (c *ComplianceFramework) LoadByTrustCenterIDAndFrameworkID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + trustCenterID gid.GID, + frameworkID gid.GID, +) error { + q := ` +SELECT + id, + organization_id, + trust_center_id, + framework_id, + rank, + 'PUBLIC' AS visibility, + created_at, + updated_at +FROM + compliance_frameworks +WHERE + %s + AND trust_center_id = @trust_center_id + AND framework_id = @framework_id +LIMIT 1; +` + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{ + "trust_center_id": trustCenterID, + "framework_id": frameworkID, + } + maps.Copy(args, scope.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query compliance_frameworks: %w", err) + } + + cf, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[ComplianceFramework]) + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return ErrResourceNotFound + } + return fmt.Errorf("cannot collect compliance framework: %w", err) + } + + *c = cf + + return nil +} + +func (c *ComplianceFramework) Insert( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +INSERT INTO + compliance_frameworks ( + id, + tenant_id, + organization_id, + trust_center_id, + framework_id, + rank, + created_at, + updated_at + ) +VALUES ( + @id, + @tenant_id, + @organization_id, + @trust_center_id, + @framework_id, + (SELECT COALESCE(MAX(rank), 0) + 1 FROM compliance_frameworks WHERE trust_center_id = @trust_center_id), + @created_at, + @updated_at +) +RETURNING rank; +` + + args := pgx.StrictNamedArgs{ + "id": c.ID, + "tenant_id": scope.GetTenantID(), + "organization_id": c.OrganizationID, + "trust_center_id": c.TrustCenterID, + "framework_id": c.FrameworkID, + "created_at": c.CreatedAt, + "updated_at": c.UpdatedAt, + } + + err := conn.QueryRow(ctx, q, args).Scan(&c.Rank) + if err != nil { + var pgErr *pgconn.PgError + if errors.As(err, &pgErr) { + if pgErr.Code == "23505" { + return ErrResourceAlreadyExists + } + } + return fmt.Errorf("cannot insert compliance framework: %w", err) + } + + return nil +} + +func (c *ComplianceFramework) UpdateRank( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +WITH old AS ( + SELECT + rank AS old_rank + FROM compliance_frameworks + WHERE %s AND id = @id AND trust_center_id = @trust_center_id +) + +UPDATE compliance_frameworks +SET + rank = CASE + WHEN id = @id THEN @new_rank + ELSE rank + CASE + WHEN @new_rank < old.old_rank THEN 1 + WHEN @new_rank > old.old_rank THEN -1 + END + END, + updated_at = @updated_at +FROM old +WHERE %s + AND ( + id = @id + OR (rank BETWEEN LEAST(old.old_rank, @new_rank) AND GREATEST(old.old_rank, @new_rank)) + ); +` + + scopeFragment := scope.SQLFragment() + q = fmt.Sprintf(q, scopeFragment, scopeFragment) + + args := pgx.StrictNamedArgs{ + "id": c.ID, + "new_rank": c.Rank, + "trust_center_id": c.TrustCenterID, + "updated_at": c.UpdatedAt, + } + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot update compliance framework rank: %w", err) + } + + return nil +} + +func (c *ComplianceFramework) Delete( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +DELETE FROM + compliance_frameworks +WHERE + %s + AND id = @id; +` + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"id": c.ID} + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot delete compliance framework: %w", err) + } + + return nil +} + +func (c *ComplianceFrameworks) LoadByTrustCenterID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + trustCenterID gid.GID, + cursor *page.Cursor[ComplianceFrameworkOrderField], +) error { + q := ` +SELECT + id, + organization_id, + trust_center_id, + framework_id, + rank, + 'PUBLIC' AS visibility, + created_at, + updated_at +FROM + compliance_frameworks +WHERE + %s + AND trust_center_id = @trust_center_id + AND %s +` + q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment()) + + args := pgx.NamedArgs{"trust_center_id": trustCenterID} + maps.Copy(args, scope.SQLArguments()) + maps.Copy(args, cursor.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query compliance_frameworks: %w", err) + } + + results, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[ComplianceFramework]) + if err != nil { + return fmt.Errorf("cannot collect compliance frameworks: %w", err) + } + + *c = results + + return nil +} + +func (c *ComplianceFrameworks) LoadWithHiddenByTrustCenterID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + trustCenterID gid.GID, + cursor *page.Cursor[ComplianceFrameworkOrderField], +) error { + q := ` +WITH combined AS ( + SELECT + COALESCE(cf.id, f.id) AS id, + COALESCE(cf.organization_id, tc.organization_id) AS organization_id, + COALESCE(cf.trust_center_id, tc.id) AS trust_center_id, + f.id AS framework_id, + CASE + WHEN cf.id IS NOT NULL THEN cf.rank + ELSE COALESCE(MAX(cf.rank) OVER (), 0) + ROW_NUMBER() OVER (PARTITION BY (cf.id IS NULL) ORDER BY f.created_at) + END AS rank, + CASE WHEN cf.id IS NULL THEN 'NONE' ELSE 'PUBLIC' END AS visibility, + COALESCE(cf.created_at, f.created_at) AS created_at, + COALESCE(cf.updated_at, f.updated_at) AS updated_at + FROM trust_centers tc + JOIN frameworks f + ON f.organization_id = tc.organization_id + AND f.tenant_id = @tenant_id + LEFT JOIN compliance_frameworks cf + ON cf.framework_id = f.id + AND cf.trust_center_id = tc.id + AND cf.tenant_id = @tenant_id + WHERE tc.id = @trust_center_id + AND tc.tenant_id = @tenant_id +) +SELECT id, organization_id, trust_center_id, framework_id, rank, visibility, created_at, updated_at +FROM combined +WHERE %s +` + q = fmt.Sprintf(q, cursor.SQLFragment()) + + args := pgx.NamedArgs{"trust_center_id": trustCenterID} + maps.Copy(args, scope.SQLArguments()) + maps.Copy(args, cursor.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query compliance frameworks with hidden: %w", err) + } + + results, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[ComplianceFramework]) + if err != nil { + return fmt.Errorf("cannot collect compliance frameworks with hidden: %w", err) + } + + *c = results + + return nil +} + +func (c *ComplianceFrameworks) CountByTrustCenterID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + trustCenterID gid.GID, +) (int, error) { + q := ` +SELECT + COUNT(*) +FROM + compliance_frameworks +WHERE + %s + AND trust_center_id = @trust_center_id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"trust_center_id": trustCenterID} + maps.Copy(args, scope.SQLArguments()) + + var count int + err := conn.QueryRow(ctx, q, args).Scan(&count) + if err != nil { + return 0, fmt.Errorf("cannot count compliance frameworks: %w", err) + } + + return count, nil +} diff --git a/pkg/coredata/compliance_framework_order_field.go b/pkg/coredata/compliance_framework_order_field.go new file mode 100644 index 000000000..6f0d8b328 --- /dev/null +++ b/pkg/coredata/compliance_framework_order_field.go @@ -0,0 +1,48 @@ +// 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 + +type ( + ComplianceFrameworkOrderField string +) + +const ( + ComplianceFrameworkOrderFieldCreatedAt ComplianceFrameworkOrderField = "CREATED_AT" + ComplianceFrameworkOrderFieldRank ComplianceFrameworkOrderField = "RANK" +) + +func (p ComplianceFrameworkOrderField) Column() string { + switch p { + case ComplianceFrameworkOrderFieldCreatedAt: + return "created_at" + case ComplianceFrameworkOrderFieldRank: + return "rank" + default: + return string(p) + } +} + +func (p ComplianceFrameworkOrderField) String() string { + return string(p) +} + +func (p ComplianceFrameworkOrderField) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *ComplianceFrameworkOrderField) UnmarshalText(text []byte) error { + *p = ComplianceFrameworkOrderField(text) + return nil +} diff --git a/pkg/coredata/compliance_framework_visibility.go b/pkg/coredata/compliance_framework_visibility.go new file mode 100644 index 000000000..165fb634d --- /dev/null +++ b/pkg/coredata/compliance_framework_visibility.go @@ -0,0 +1,26 @@ +// 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 + +type ComplianceFrameworkVisibility string + +const ( + ComplianceFrameworkVisibilityNone ComplianceFrameworkVisibility = "NONE" + ComplianceFrameworkVisibilityPublic ComplianceFrameworkVisibility = "PUBLIC" +) + +func (v ComplianceFrameworkVisibility) String() string { + return string(v) +} diff --git a/pkg/coredata/entity_type_reg.go b/pkg/coredata/entity_type_reg.go index 33183bcd1..f163f6f7b 100644 --- a/pkg/coredata/entity_type_reg.go +++ b/pkg/coredata/entity_type_reg.go @@ -85,6 +85,7 @@ const ( ElectronicSignatureEntityType uint16 = 59 ElectronicSignatureEventEntityType uint16 = 60 EmailAttachmentEntityType uint16 = 61 + ComplianceFrameworkEntityType uint16 = 62 ) func NewEntityFromID(id gid.GID) (any, bool) { @@ -209,6 +210,8 @@ func NewEntityFromID(id gid.GID) (any, bool) { return &ElectronicSignatureEvent{ID: id}, true case EmailAttachmentEntityType: return &EmailAttachment{ID: id}, true + case ComplianceFrameworkEntityType: + return &ComplianceFramework{ID: id}, true default: return nil, false } diff --git a/pkg/coredata/framework.go b/pkg/coredata/framework.go index c5b46895e..72cd7ce7a 100644 --- a/pkg/coredata/framework.go +++ b/pkg/coredata/framework.go @@ -47,7 +47,7 @@ type ( func (f *Framework) CursorKey(orderBy FrameworkOrderField) page.CursorKey { switch orderBy { case FrameworkOrderFieldCreatedAt: - return page.CursorKey{ID: f.ID, Value: f.CreatedAt} + return page.NewCursorKey(f.ID, f.CreatedAt) } panic(fmt.Sprintf("unsupported order by: %s", orderBy)) diff --git a/pkg/coredata/migrations/20260302T120000Z.sql b/pkg/coredata/migrations/20260302T120000Z.sql new file mode 100644 index 000000000..7c95242d5 --- /dev/null +++ b/pkg/coredata/migrations/20260302T120000Z.sql @@ -0,0 +1,54 @@ +CREATE TABLE compliance_frameworks ( + id TEXT NOT NULL PRIMARY KEY, + tenant_id TEXT NOT NULL, + organization_id TEXT NOT NULL REFERENCES organizations(id) ON UPDATE CASCADE ON DELETE CASCADE, + trust_center_id TEXT NOT NULL REFERENCES trust_centers(id) ON UPDATE CASCADE ON DELETE CASCADE, + framework_id TEXT NOT NULL REFERENCES frameworks(id) ON UPDATE CASCADE ON DELETE CASCADE, + rank INTEGER NOT NULL, + created_at TIMESTAMP WITH TIME ZONE NOT NULL, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL, + UNIQUE (trust_center_id, framework_id) +); + +ALTER TABLE compliance_frameworks +ADD CONSTRAINT compliance_frameworks_trust_center_id_rank_key + UNIQUE (trust_center_id, rank) + DEFERRABLE INITIALLY DEFERRED; + +INSERT INTO compliance_frameworks ( + id, + tenant_id, + organization_id, + trust_center_id, + framework_id, + rank, + created_at, + updated_at +) +WITH distinct_frameworks AS ( + SELECT DISTINCT + a.tenant_id, + a.organization_id, + a.framework_id + FROM audits a + WHERE a.trust_center_visibility IN ('PRIVATE', 'PUBLIC') + AND EXISTS ( + SELECT 1 FROM trust_centers tc + WHERE tc.organization_id = a.organization_id + ) +) +SELECT + generate_gid(decode_base64_unpadded(df.tenant_id), 62), + df.tenant_id, + df.organization_id, + tc.id AS trust_center_id, + df.framework_id, + ROW_NUMBER() OVER ( + PARTITION BY df.organization_id + ORDER BY f.created_at ASC, df.framework_id ASC + ) AS rank, + NOW(), + NOW() +FROM distinct_frameworks df +JOIN trust_centers tc ON tc.organization_id = df.organization_id +JOIN frameworks f ON f.id = df.framework_id; diff --git a/pkg/probo/actions.go b/pkg/probo/actions.go index 07475d159..bf119ea60 100644 --- a/pkg/probo/actions.go +++ b/pkg/probo/actions.go @@ -47,6 +47,12 @@ const ( ActionTrustCenterReferenceUpdate = "core:trust-center-reference:update" ActionTrustCenterReferenceDelete = "core:trust-center-reference:delete" + // ComplianceFramework actions + ActionComplianceFrameworkList = "core:compliance-framework:list" + ActionComplianceFrameworkCreate = "core:compliance-framework:create" + ActionComplianceFrameworkDelete = "core:compliance-framework:delete" + ActionComplianceFrameworkUpdateRank = "core:compliance-framework:update-rank" + // TrustCenterFile actions ActionTrustCenterFileGet = "core:trust-center-file:get" ActionTrustCenterFileList = "core:trust-center-file:list" diff --git a/pkg/probo/compliance_framework_service.go b/pkg/probo/compliance_framework_service.go new file mode 100644 index 000000000..aa20e321b --- /dev/null +++ b/pkg/probo/compliance_framework_service.go @@ -0,0 +1,204 @@ +// 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 probo + +import ( + "context" + "fmt" + "time" + + "go.gearno.de/kit/pg" + "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/gid" + "go.probo.inc/probo/pkg/page" + "go.probo.inc/probo/pkg/validator" +) + +type ( + ComplianceFrameworkService struct { + svc *TenantService + } + + CreateComplianceFrameworkRequest struct { + TrustCenterID gid.GID + FrameworkID gid.GID + } + + UpdateComplianceFrameworkRequest struct { + ID gid.GID + Rank int + } + + DeleteComplianceFrameworkRequest struct { + ID gid.GID + } +) + +func (r *CreateComplianceFrameworkRequest) Validate() error { + v := validator.New() + + v.Check(r.TrustCenterID, "trust_center_id", validator.Required(), validator.GID(coredata.TrustCenterEntityType)) + v.Check(r.FrameworkID, "framework_id", validator.Required(), validator.GID(coredata.FrameworkEntityType)) + + return v.Error() +} + +func (r *UpdateComplianceFrameworkRequest) Validate() error { + v := validator.New() + + v.Check(r.ID, "id", validator.Required(), validator.GID(coredata.ComplianceFrameworkEntityType)) + + return v.Error() +} + +func (r *DeleteComplianceFrameworkRequest) Validate() error { + v := validator.New() + + v.Check(r.ID, "id", validator.Required(), validator.GID(coredata.ComplianceFrameworkEntityType)) + + return v.Error() +} + +func (s ComplianceFrameworkService) ListWithHiddenForTrustCenterID( + ctx context.Context, + trustCenterID gid.GID, + cursor *page.Cursor[coredata.ComplianceFrameworkOrderField], +) (*page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField], error) { + var cfs coredata.ComplianceFrameworks + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + if err := cfs.LoadWithHiddenByTrustCenterID(ctx, conn, s.svc.scope, trustCenterID, cursor); err != nil { + return fmt.Errorf("cannot load compliance frameworks with hidden: %w", err) + } + return nil + }, + ) + if err != nil { + return nil, err + } + + return page.NewPage(cfs, cursor), nil +} + +func (s ComplianceFrameworkService) Create( + ctx context.Context, + req *CreateComplianceFrameworkRequest, +) (*coredata.ComplianceFramework, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + now := time.Now() + + cfID := gid.New(s.svc.scope.GetTenantID(), coredata.ComplianceFrameworkEntityType) + + var cf *coredata.ComplianceFramework + + err := s.svc.pg.WithTx( + ctx, + func(tx pg.Conn) error { + trustCenter := &coredata.TrustCenter{} + if err := trustCenter.LoadByID(ctx, tx, s.svc.scope, req.TrustCenterID); err != nil { + return fmt.Errorf("cannot load trust center: %w", err) + } + + cf = &coredata.ComplianceFramework{ + ID: cfID, + OrganizationID: trustCenter.OrganizationID, + TrustCenterID: req.TrustCenterID, + FrameworkID: req.FrameworkID, + CreatedAt: now, + UpdatedAt: now, + } + + if err := cf.Insert(ctx, tx, s.svc.scope); err != nil { + return fmt.Errorf("cannot insert compliance framework: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return cf, nil +} + +func (s ComplianceFrameworkService) Update( + ctx context.Context, + req *UpdateComplianceFrameworkRequest, +) (*coredata.ComplianceFramework, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + var cf *coredata.ComplianceFramework + + err := s.svc.pg.WithTx( + ctx, + func(tx pg.Conn) error { + cf = &coredata.ComplianceFramework{} + + if err := cf.LoadByID(ctx, tx, s.svc.scope, req.ID); err != nil { + return fmt.Errorf("cannot load compliance framework: %w", err) + } + + cf.Rank = req.Rank + cf.UpdatedAt = time.Now() + + if err := cf.UpdateRank(ctx, tx, s.svc.scope); err != nil { + return fmt.Errorf("cannot update compliance framework rank: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return cf, nil +} + +func (s ComplianceFrameworkService) Delete( + ctx context.Context, + req *DeleteComplianceFrameworkRequest, +) error { + if err := req.Validate(); err != nil { + return err + } + + return s.svc.pg.WithTx( + ctx, + func(tx pg.Conn) error { + cf := &coredata.ComplianceFramework{} + + if err := cf.LoadByID(ctx, tx, s.svc.scope, req.ID); err != nil { + return fmt.Errorf("cannot load compliance framework: %w", err) + } + + if err := cf.Delete(ctx, tx, s.svc.scope); err != nil { + return fmt.Errorf("cannot delete compliance framework: %w", err) + } + + return nil + }, + ) +} diff --git a/pkg/probo/policies.go b/pkg/probo/policies.go index 4783bdf58..a776cb538 100644 --- a/pkg/probo/policies.go +++ b/pkg/probo/policies.go @@ -88,6 +88,7 @@ var ViewerPolicy = policy.NewPolicy( ActionTrustCenterDocumentAccessList, ActionTrustCenterFileGet, ActionTrustCenterFileList, ActionTrustCenterFileGetFileUrl, ActionTrustCenterReferenceList, ActionTrustCenterReferenceGetLogoUrl, + ActionComplianceFrameworkList, ).WithSID("trust-center-read-access").When(organizationCondition), policy.Allow(ActionCustomDomainGet).WithSID("custom-domain-read").When(organizationCondition), diff --git a/pkg/probo/service.go b/pkg/probo/service.go index 14e611bd6..572614ffd 100644 --- a/pkg/probo/service.go +++ b/pkg/probo/service.go @@ -101,6 +101,7 @@ type ( TrustCenterAccesses *TrustCenterAccessService TrustCenterReferences *TrustCenterReferenceService TrustCenterFiles *TrustCenterFileService + ComplianceFrameworks *ComplianceFrameworkService Nonconformities *NonconformityService Obligations *ObligationService Snapshots *SnapshotService @@ -225,6 +226,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService { tenantService.TrustCenters = &TrustCenterService{svc: tenantService} tenantService.TrustCenterAccesses = &TrustCenterAccessService{svc: tenantService} tenantService.TrustCenterReferences = &TrustCenterReferenceService{svc: tenantService} + tenantService.ComplianceFrameworks = &ComplianceFrameworkService{svc: tenantService} tenantService.TrustCenterFiles = &TrustCenterFileService{ svc: tenantService, fileValidator: filevalidation.NewValidator( diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index 426eb86a2..3333edf33 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -1227,6 +1227,34 @@ enum TrustCenterReferenceOrderField ) } +enum ComplianceFrameworkOrderField + @goModel( + model: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderField" + ) { + CREATED_AT + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderFieldCreatedAt" + ) + RANK + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderFieldRank" + ) +} + +enum ComplianceFrameworkVisibility + @goModel( + model: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibility" + ) { + NONE + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibilityNone" + ) + PUBLIC + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibilityPublic" + ) +} + enum TrustCenterFileOrderField @goModel( model: "go.probo.inc/probo/pkg/coredata.TrustCenterFileOrderField" @@ -1463,6 +1491,14 @@ input TrustCenterFileOrder field: TrustCenterFileOrderField! } +input ComplianceFrameworkOrder + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFrameworkOrderBy" + ) { + direction: OrderDirection! + field: ComplianceFrameworkOrderField! +} + input EvidenceOrder @goModel( model: "go.probo.inc/probo/pkg/server/api/console/v1/types.EvidenceOrderBy" @@ -1614,6 +1650,14 @@ type TrustCenter implements Node { orderBy: TrustCenterReferenceOrder ): TrustCenterReferenceConnection! @goField(forceResolver: true) + complianceFrameworks( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: ComplianceFrameworkOrder + ): ComplianceFrameworkConnection! @goField(forceResolver: true) + permission(action: String!): Boolean! @goField(forceResolver: true) } @@ -2806,6 +2850,31 @@ type TrustCenterReferenceEdge { node: TrustCenterReference! } +type ComplianceFramework implements Node + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFramework" + ) { + id: ID! + framework: Framework! @goField(forceResolver: true) + rank: Int! + visibility: ComplianceFrameworkVisibility! + createdAt: Datetime! + updatedAt: Datetime! +} + +type ComplianceFrameworkConnection + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFrameworkConnection" + ) { + edges: [ComplianceFrameworkEdge!]! + pageInfo: PageInfo! +} + +type ComplianceFrameworkEdge { + cursor: CursorKey! + node: ComplianceFramework! +} + type TrustCenterFile implements Node { id: ID! name: String! @@ -3247,6 +3316,16 @@ type Mutation { deleteTrustCenterReference( input: DeleteTrustCenterReferenceInput! ): DeleteTrustCenterReferencePayload! + # Compliance Framework mutations + createComplianceFramework( + input: CreateComplianceFrameworkInput! + ): CreateComplianceFrameworkPayload! + updateComplianceFramework( + input: UpdateComplianceFrameworkInput! + ): UpdateComplianceFrameworkPayload! + deleteComplianceFramework( + input: DeleteComplianceFrameworkInput! + ): DeleteComplianceFrameworkPayload! # Trust Center File mutations createTrustCenterFile( input: CreateTrustCenterFileInput! @@ -3647,6 +3726,20 @@ input DeleteTrustCenterReferenceInput { id: ID! } +input CreateComplianceFrameworkInput { + trustCenterId: ID! + frameworkId: ID! +} + +input UpdateComplianceFrameworkInput { + id: ID! + rank: Int! +} + +input DeleteComplianceFrameworkInput { + id: ID! +} + input CreateTrustCenterFileInput { organizationId: ID! name: String! @@ -4462,6 +4555,18 @@ type DeleteTrustCenterReferencePayload { deletedTrustCenterReferenceId: ID! } +type CreateComplianceFrameworkPayload { + complianceFrameworkEdge: ComplianceFrameworkEdge! +} + +type UpdateComplianceFrameworkPayload { + complianceFramework: ComplianceFramework! +} + +type DeleteComplianceFrameworkPayload { + deletedComplianceFrameworkId: ID! +} + type CreateTrustCenterFilePayload { trustCenterFileEdge: TrustCenterFileEdge! } diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index b36074fe0..b4a5416b1 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -42,6 +42,7 @@ type ResolverRoot interface { AssetConnection() AssetConnectionResolver Audit() AuditResolver AuditConnection() AuditConnectionResolver + ComplianceFramework() ComplianceFrameworkResolver ContinualImprovement() ContinualImprovementResolver ContinualImprovementConnection() ContinualImprovementConnectionResolver Control() ControlResolver @@ -219,6 +220,25 @@ type ComplexityRoot struct { DeletedDocumentVersionSignatureID func(childComplexity int) int } + ComplianceFramework struct { + CreatedAt func(childComplexity int) int + Framework func(childComplexity int) int + ID func(childComplexity int) int + Rank func(childComplexity int) int + UpdatedAt func(childComplexity int) int + Visibility func(childComplexity int) int + } + + ComplianceFrameworkConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + } + + ComplianceFrameworkEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + ContinualImprovement struct { CreatedAt func(childComplexity int) int Description func(childComplexity int) int @@ -291,6 +311,10 @@ type ComplexityRoot struct { AuditEdge func(childComplexity int) int } + CreateComplianceFrameworkPayload struct { + ComplianceFrameworkEdge func(childComplexity int) int + } + CreateContinualImprovementPayload struct { ContinualImprovementEdge func(childComplexity int) int } @@ -525,6 +549,10 @@ type ComplexityRoot struct { Audit func(childComplexity int) int } + DeleteComplianceFrameworkPayload struct { + DeletedComplianceFrameworkID func(childComplexity int) int + } + DeleteContinualImprovementPayload struct { DeletedContinualImprovementID func(childComplexity int) int } @@ -956,6 +984,7 @@ type ComplexityRoot struct { CreateApplicabilityStatement func(childComplexity int, input types.CreateApplicabilityStatementInput) int CreateAsset func(childComplexity int, input types.CreateAssetInput) int CreateAudit func(childComplexity int, input types.CreateAuditInput) int + CreateComplianceFramework func(childComplexity int, input types.CreateComplianceFrameworkInput) int CreateContinualImprovement func(childComplexity int, input types.CreateContinualImprovementInput) int CreateControl func(childComplexity int, input types.CreateControlInput) int CreateControlAuditMapping func(childComplexity int, input types.CreateControlAuditMappingInput) int @@ -995,6 +1024,7 @@ type ComplexityRoot struct { DeleteAsset func(childComplexity int, input types.DeleteAssetInput) int DeleteAudit func(childComplexity int, input types.DeleteAuditInput) int DeleteAuditReport func(childComplexity int, input types.DeleteAuditReportInput) int + DeleteComplianceFramework func(childComplexity int, input types.DeleteComplianceFrameworkInput) int DeleteContinualImprovement func(childComplexity int, input types.DeleteContinualImprovementInput) int DeleteControl func(childComplexity int, input types.DeleteControlInput) int DeleteControlAuditMapping func(childComplexity int, input types.DeleteControlAuditMappingInput) int @@ -1052,6 +1082,7 @@ type ComplexityRoot struct { UpdateApplicabilityStatement func(childComplexity int, input types.UpdateApplicabilityStatementInput) int UpdateAsset func(childComplexity int, input types.UpdateAssetInput) int UpdateAudit func(childComplexity int, input types.UpdateAuditInput) int + UpdateComplianceFramework func(childComplexity int, input types.UpdateComplianceFrameworkInput) int UpdateContinualImprovement func(childComplexity int, input types.UpdateContinualImprovementInput) int UpdateControl func(childComplexity int, input types.UpdateControlInput) int UpdateDataProtectionImpactAssessment func(childComplexity int, input types.UpdateDataProtectionImpactAssessmentInput) int @@ -1507,18 +1538,19 @@ type ComplexityRoot struct { } TrustCenter struct { - Accesses func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterAccessOrderField]) int - Active func(childComplexity int) int - CreatedAt func(childComplexity int) int - DarkLogoFileURL func(childComplexity int) int - ID func(childComplexity int) int - LogoFileURL func(childComplexity int) int - NdaFileName func(childComplexity int) int - NdaFileURL func(childComplexity int) int - Organization func(childComplexity int) int - Permission func(childComplexity int, action string) int - References func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterReferenceOrderField]) int - UpdatedAt func(childComplexity int) int + Accesses func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterAccessOrderField]) int + Active func(childComplexity int) int + ComplianceFrameworks func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceFrameworkOrderField]) int + CreatedAt func(childComplexity int) int + DarkLogoFileURL func(childComplexity int) int + ID func(childComplexity int) int + LogoFileURL func(childComplexity int) int + NdaFileName func(childComplexity int) int + NdaFileURL func(childComplexity int) int + Organization func(childComplexity int) int + Permission func(childComplexity int, action string) int + References func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterReferenceOrderField]) int + UpdatedAt func(childComplexity int) int } TrustCenterAccess struct { @@ -1634,6 +1666,10 @@ type ComplexityRoot struct { Audit func(childComplexity int) int } + UpdateComplianceFrameworkPayload struct { + ComplianceFramework func(childComplexity int) int + } + UpdateContinualImprovementPayload struct { ContinualImprovement func(childComplexity int) int } @@ -2015,6 +2051,9 @@ type AuditResolver interface { type AuditConnectionResolver interface { TotalCount(ctx context.Context, obj *types.AuditConnection) (int, error) } +type ComplianceFrameworkResolver interface { + Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) +} type ContinualImprovementResolver interface { Organization(ctx context.Context, obj *types.ContinualImprovement) (*types.Organization, error) @@ -2159,6 +2198,9 @@ type MutationResolver interface { CreateTrustCenterReference(ctx context.Context, input types.CreateTrustCenterReferenceInput) (*types.CreateTrustCenterReferencePayload, error) UpdateTrustCenterReference(ctx context.Context, input types.UpdateTrustCenterReferenceInput) (*types.UpdateTrustCenterReferencePayload, error) DeleteTrustCenterReference(ctx context.Context, input types.DeleteTrustCenterReferenceInput) (*types.DeleteTrustCenterReferencePayload, error) + CreateComplianceFramework(ctx context.Context, input types.CreateComplianceFrameworkInput) (*types.CreateComplianceFrameworkPayload, error) + UpdateComplianceFramework(ctx context.Context, input types.UpdateComplianceFrameworkInput) (*types.UpdateComplianceFrameworkPayload, error) + DeleteComplianceFramework(ctx context.Context, input types.DeleteComplianceFrameworkInput) (*types.DeleteComplianceFrameworkPayload, error) CreateTrustCenterFile(ctx context.Context, input types.CreateTrustCenterFileInput) (*types.CreateTrustCenterFilePayload, error) UpdateTrustCenterFile(ctx context.Context, input types.UpdateTrustCenterFileInput) (*types.UpdateTrustCenterFilePayload, error) GetTrustCenterFile(ctx context.Context, input types.GetTrustCenterFileInput) (*types.GetTrustCenterFilePayload, error) @@ -2448,6 +2490,7 @@ type TrustCenterResolver interface { Organization(ctx context.Context, obj *types.TrustCenter) (*types.Organization, error) Accesses(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterAccessOrderField]) (*types.TrustCenterAccessConnection, error) References(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterReferenceOrderField]) (*types.TrustCenterReferenceConnection, error) + ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceFrameworkOrderField]) (*types.ComplianceFrameworkConnection, error) Permission(ctx context.Context, obj *types.TrustCenter, action string) (bool, error) } type TrustCenterAccessResolver interface { @@ -2944,6 +2987,69 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.CancelSignatureRequestPayload.DeletedDocumentVersionSignatureID(childComplexity), true + case "ComplianceFramework.createdAt": + if e.ComplexityRoot.ComplianceFramework.CreatedAt == nil { + break + } + + return e.ComplexityRoot.ComplianceFramework.CreatedAt(childComplexity), true + case "ComplianceFramework.framework": + if e.ComplexityRoot.ComplianceFramework.Framework == nil { + break + } + + return e.ComplexityRoot.ComplianceFramework.Framework(childComplexity), true + case "ComplianceFramework.id": + if e.ComplexityRoot.ComplianceFramework.ID == nil { + break + } + + return e.ComplexityRoot.ComplianceFramework.ID(childComplexity), true + case "ComplianceFramework.rank": + if e.ComplexityRoot.ComplianceFramework.Rank == nil { + break + } + + return e.ComplexityRoot.ComplianceFramework.Rank(childComplexity), true + case "ComplianceFramework.updatedAt": + if e.ComplexityRoot.ComplianceFramework.UpdatedAt == nil { + break + } + + return e.ComplexityRoot.ComplianceFramework.UpdatedAt(childComplexity), true + case "ComplianceFramework.visibility": + if e.ComplexityRoot.ComplianceFramework.Visibility == nil { + break + } + + return e.ComplexityRoot.ComplianceFramework.Visibility(childComplexity), true + + case "ComplianceFrameworkConnection.edges": + if e.ComplexityRoot.ComplianceFrameworkConnection.Edges == nil { + break + } + + return e.ComplexityRoot.ComplianceFrameworkConnection.Edges(childComplexity), true + case "ComplianceFrameworkConnection.pageInfo": + if e.ComplexityRoot.ComplianceFrameworkConnection.PageInfo == nil { + break + } + + return e.ComplexityRoot.ComplianceFrameworkConnection.PageInfo(childComplexity), true + + case "ComplianceFrameworkEdge.cursor": + if e.ComplexityRoot.ComplianceFrameworkEdge.Cursor == nil { + break + } + + return e.ComplexityRoot.ComplianceFrameworkEdge.Cursor(childComplexity), true + case "ComplianceFrameworkEdge.node": + if e.ComplexityRoot.ComplianceFrameworkEdge.Node == nil { + break + } + + return e.ComplexityRoot.ComplianceFrameworkEdge.Node(childComplexity), true + case "ContinualImprovement.createdAt": if e.ComplexityRoot.ContinualImprovement.CreatedAt == nil { break @@ -3258,6 +3364,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.CreateAuditPayload.AuditEdge(childComplexity), true + case "CreateComplianceFrameworkPayload.complianceFrameworkEdge": + if e.ComplexityRoot.CreateComplianceFrameworkPayload.ComplianceFrameworkEdge == nil { + break + } + + return e.ComplexityRoot.CreateComplianceFrameworkPayload.ComplianceFrameworkEdge(childComplexity), true + case "CreateContinualImprovementPayload.continualImprovementEdge": if e.ComplexityRoot.CreateContinualImprovementPayload.ContinualImprovementEdge == nil { break @@ -3883,6 +3996,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.DeleteAuditReportPayload.Audit(childComplexity), true + case "DeleteComplianceFrameworkPayload.deletedComplianceFrameworkId": + if e.ComplexityRoot.DeleteComplianceFrameworkPayload.DeletedComplianceFrameworkID == nil { + break + } + + return e.ComplexityRoot.DeleteComplianceFrameworkPayload.DeletedComplianceFrameworkID(childComplexity), true + case "DeleteContinualImprovementPayload.deletedContinualImprovementId": if e.ComplexityRoot.DeleteContinualImprovementPayload.DeletedContinualImprovementID == nil { break @@ -5335,6 +5455,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Mutation.CreateAudit(childComplexity, args["input"].(types.CreateAuditInput)), true + case "Mutation.createComplianceFramework": + if e.ComplexityRoot.Mutation.CreateComplianceFramework == nil { + break + } + + args, err := ec.field_Mutation_createComplianceFramework_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Mutation.CreateComplianceFramework(childComplexity, args["input"].(types.CreateComplianceFrameworkInput)), true case "Mutation.createContinualImprovement": if e.ComplexityRoot.Mutation.CreateContinualImprovement == nil { break @@ -5764,6 +5895,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Mutation.DeleteAuditReport(childComplexity, args["input"].(types.DeleteAuditReportInput)), true + case "Mutation.deleteComplianceFramework": + if e.ComplexityRoot.Mutation.DeleteComplianceFramework == nil { + break + } + + args, err := ec.field_Mutation_deleteComplianceFramework_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Mutation.DeleteComplianceFramework(childComplexity, args["input"].(types.DeleteComplianceFrameworkInput)), true case "Mutation.deleteContinualImprovement": if e.ComplexityRoot.Mutation.DeleteContinualImprovement == nil { break @@ -6391,6 +6533,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Mutation.UpdateAudit(childComplexity, args["input"].(types.UpdateAuditInput)), true + case "Mutation.updateComplianceFramework": + if e.ComplexityRoot.Mutation.UpdateComplianceFramework == nil { + break + } + + args, err := ec.field_Mutation_updateComplianceFramework_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Mutation.UpdateComplianceFramework(childComplexity, args["input"].(types.UpdateComplianceFrameworkInput)), true case "Mutation.updateContinualImprovement": if e.ComplexityRoot.Mutation.UpdateContinualImprovement == nil { break @@ -8761,6 +8914,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.TrustCenter.Active(childComplexity), true + case "TrustCenter.complianceFrameworks": + if e.ComplexityRoot.TrustCenter.ComplianceFrameworks == nil { + break + } + + args, err := ec.field_TrustCenter_complianceFrameworks_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.TrustCenter.ComplianceFrameworks(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.OrderBy[coredata.ComplianceFrameworkOrderField])), true case "TrustCenter.createdAt": if e.ComplexityRoot.TrustCenter.CreatedAt == nil { break @@ -9241,6 +9405,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.UpdateAuditPayload.Audit(childComplexity), true + case "UpdateComplianceFrameworkPayload.complianceFramework": + if e.ComplexityRoot.UpdateComplianceFrameworkPayload.ComplianceFramework == nil { + break + } + + return e.ComplexityRoot.UpdateComplianceFrameworkPayload.ComplianceFramework(childComplexity), true + case "UpdateContinualImprovementPayload.continualImprovement": if e.ComplexityRoot.UpdateContinualImprovementPayload.ContinualImprovement == nil { break @@ -10408,6 +10579,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputBulkPublishDocumentVersionsInput, ec.unmarshalInputBulkRequestSignaturesInput, ec.unmarshalInputCancelSignatureRequestInput, + ec.unmarshalInputComplianceFrameworkOrder, ec.unmarshalInputContinualImprovementFilter, ec.unmarshalInputContinualImprovementOrder, ec.unmarshalInputControlFilter, @@ -10415,6 +10587,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputCreateApplicabilityStatementInput, ec.unmarshalInputCreateAssetInput, ec.unmarshalInputCreateAuditInput, + ec.unmarshalInputCreateComplianceFrameworkInput, ec.unmarshalInputCreateContinualImprovementInput, ec.unmarshalInputCreateControlAuditMappingInput, ec.unmarshalInputCreateControlDocumentMappingInput, @@ -10458,6 +10631,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputDeleteAssetInput, ec.unmarshalInputDeleteAuditInput, ec.unmarshalInputDeleteAuditReportInput, + ec.unmarshalInputDeleteComplianceFrameworkInput, ec.unmarshalInputDeleteContinualImprovementInput, ec.unmarshalInputDeleteControlAuditMappingInput, ec.unmarshalInputDeleteControlDocumentMappingInput, @@ -10548,6 +10722,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputUpdateApplicabilityStatementInput, ec.unmarshalInputUpdateAssetInput, ec.unmarshalInputUpdateAuditInput, + ec.unmarshalInputUpdateComplianceFrameworkInput, ec.unmarshalInputUpdateContinualImprovementInput, ec.unmarshalInputUpdateControlInput, ec.unmarshalInputUpdateDataProtectionImpactAssessmentInput, @@ -11895,6 +12070,34 @@ enum TrustCenterReferenceOrderField ) } +enum ComplianceFrameworkOrderField + @goModel( + model: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderField" + ) { + CREATED_AT + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderFieldCreatedAt" + ) + RANK + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderFieldRank" + ) +} + +enum ComplianceFrameworkVisibility + @goModel( + model: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibility" + ) { + NONE + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibilityNone" + ) + PUBLIC + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibilityPublic" + ) +} + enum TrustCenterFileOrderField @goModel( model: "go.probo.inc/probo/pkg/coredata.TrustCenterFileOrderField" @@ -12131,6 +12334,14 @@ input TrustCenterFileOrder field: TrustCenterFileOrderField! } +input ComplianceFrameworkOrder + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFrameworkOrderBy" + ) { + direction: OrderDirection! + field: ComplianceFrameworkOrderField! +} + input EvidenceOrder @goModel( model: "go.probo.inc/probo/pkg/server/api/console/v1/types.EvidenceOrderBy" @@ -12282,6 +12493,14 @@ type TrustCenter implements Node { orderBy: TrustCenterReferenceOrder ): TrustCenterReferenceConnection! @goField(forceResolver: true) + complianceFrameworks( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: ComplianceFrameworkOrder + ): ComplianceFrameworkConnection! @goField(forceResolver: true) + permission(action: String!): Boolean! @goField(forceResolver: true) } @@ -13474,6 +13693,31 @@ type TrustCenterReferenceEdge { node: TrustCenterReference! } +type ComplianceFramework implements Node + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFramework" + ) { + id: ID! + framework: Framework! @goField(forceResolver: true) + rank: Int! + visibility: ComplianceFrameworkVisibility! + createdAt: Datetime! + updatedAt: Datetime! +} + +type ComplianceFrameworkConnection + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFrameworkConnection" + ) { + edges: [ComplianceFrameworkEdge!]! + pageInfo: PageInfo! +} + +type ComplianceFrameworkEdge { + cursor: CursorKey! + node: ComplianceFramework! +} + type TrustCenterFile implements Node { id: ID! name: String! @@ -13915,6 +14159,16 @@ type Mutation { deleteTrustCenterReference( input: DeleteTrustCenterReferenceInput! ): DeleteTrustCenterReferencePayload! + # Compliance Framework mutations + createComplianceFramework( + input: CreateComplianceFrameworkInput! + ): CreateComplianceFrameworkPayload! + updateComplianceFramework( + input: UpdateComplianceFrameworkInput! + ): UpdateComplianceFrameworkPayload! + deleteComplianceFramework( + input: DeleteComplianceFrameworkInput! + ): DeleteComplianceFrameworkPayload! # Trust Center File mutations createTrustCenterFile( input: CreateTrustCenterFileInput! @@ -14315,6 +14569,20 @@ input DeleteTrustCenterReferenceInput { id: ID! } +input CreateComplianceFrameworkInput { + trustCenterId: ID! + frameworkId: ID! +} + +input UpdateComplianceFrameworkInput { + id: ID! + rank: Int! +} + +input DeleteComplianceFrameworkInput { + id: ID! +} + input CreateTrustCenterFileInput { organizationId: ID! name: String! @@ -15130,6 +15398,18 @@ type DeleteTrustCenterReferencePayload { deletedTrustCenterReferenceId: ID! } +type CreateComplianceFrameworkPayload { + complianceFrameworkEdge: ComplianceFrameworkEdge! +} + +type UpdateComplianceFrameworkPayload { + complianceFramework: ComplianceFramework! +} + +type DeleteComplianceFrameworkPayload { + deletedComplianceFrameworkId: ID! +} + type CreateTrustCenterFilePayload { trustCenterFileEdge: TrustCenterFileEdge! } @@ -17094,6 +17374,17 @@ func (ec *executionContext) field_Mutation_createAudit_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_Mutation_createComplianceFramework_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.unmarshalNCreateComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceFrameworkInput) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_createContinualImprovement_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -17523,6 +17814,17 @@ func (ec *executionContext) field_Mutation_deleteAudit_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_Mutation_deleteComplianceFramework_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.unmarshalNDeleteComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceFrameworkInput) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_deleteContinualImprovement_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -18150,6 +18452,17 @@ func (ec *executionContext) field_Mutation_updateAudit_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_Mutation_updateComplianceFramework_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.unmarshalNUpdateComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceFrameworkInput) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_updateContinualImprovement_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -19907,6 +20220,37 @@ func (ec *executionContext) field_TrustCenter_accesses_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_TrustCenter_complianceFrameworks_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, "first", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["first"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "after", ec.unmarshalOCursorKey2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey) + if err != nil { + return nil, err + } + args["after"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "last", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["last"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "before", ec.unmarshalOCursorKey2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey) + if err != nil { + return nil, err + } + args["before"] = arg3 + arg4, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", ec.unmarshalOComplianceFrameworkOrder2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐOrderBy) + if err != nil { + return nil, err + } + args["orderBy"] = arg4 + return args, nil +} + func (ec *executionContext) field_TrustCenter_permission_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -22481,6 +22825,348 @@ func (ec *executionContext) fieldContext_CancelSignatureRequestPayload_deletedDo return fc, nil } +func (ec *executionContext) _ComplianceFramework_id(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFramework_id, + func(ctx context.Context) (any, error) { + return obj.ID, nil + }, + nil, + ec.marshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFramework_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFramework", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFramework_framework(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFramework_framework, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ComplianceFramework().Framework(ctx, obj) + }, + nil, + ec.marshalNFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐFramework, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFramework_framework(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFramework", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Framework_id(ctx, field) + case "name": + return ec.fieldContext_Framework_name(ctx, field) + case "description": + return ec.fieldContext_Framework_description(ctx, field) + case "organization": + return ec.fieldContext_Framework_organization(ctx, field) + case "controls": + return ec.fieldContext_Framework_controls(ctx, field) + case "lightLogoURL": + return ec.fieldContext_Framework_lightLogoURL(ctx, field) + case "darkLogoURL": + return ec.fieldContext_Framework_darkLogoURL(ctx, field) + case "createdAt": + return ec.fieldContext_Framework_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Framework_updatedAt(ctx, field) + case "permission": + return ec.fieldContext_Framework_permission(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Framework", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFramework_rank(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFramework_rank, + func(ctx context.Context) (any, error) { + return obj.Rank, nil + }, + nil, + ec.marshalNInt2int, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFramework_rank(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFramework", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFramework_visibility(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFramework_visibility, + func(ctx context.Context) (any, error) { + return obj.Visibility, nil + }, + nil, + ec.marshalNComplianceFrameworkVisibility2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkVisibility, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFramework_visibility(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFramework", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ComplianceFrameworkVisibility does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFramework_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFramework_createdAt, + func(ctx context.Context) (any, error) { + return obj.CreatedAt, nil + }, + nil, + ec.marshalNDatetime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFramework_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFramework", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFramework_updatedAt(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFramework_updatedAt, + func(ctx context.Context) (any, error) { + return obj.UpdatedAt, nil + }, + nil, + ec.marshalNDatetime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFramework_updatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFramework", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFrameworkConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFrameworkConnection_edges, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + ec.marshalNComplianceFrameworkEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFrameworkEdgeᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFrameworkConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFrameworkConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cursor": + return ec.fieldContext_ComplianceFrameworkEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_ComplianceFrameworkEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceFrameworkEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFrameworkConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFrameworkConnection_pageInfo, + func(ctx context.Context) (any, error) { + return obj.PageInfo, nil + }, + nil, + ec.marshalNPageInfo2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPageInfo, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFrameworkConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFrameworkConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hasNextPage": + return ec.fieldContext_PageInfo_hasNextPage(ctx, field) + case "hasPreviousPage": + return ec.fieldContext_PageInfo_hasPreviousPage(ctx, field) + case "startCursor": + return ec.fieldContext_PageInfo_startCursor(ctx, field) + case "endCursor": + return ec.fieldContext_PageInfo_endCursor(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PageInfo", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFrameworkEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFrameworkEdge_cursor, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + ec.marshalNCursorKey2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFrameworkEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFrameworkEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type CursorKey does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFrameworkEdge_node(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFrameworkEdge_node, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + ec.marshalNComplianceFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFramework, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFrameworkEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFrameworkEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ComplianceFramework_id(ctx, field) + case "framework": + return ec.fieldContext_ComplianceFramework_framework(ctx, field) + case "rank": + return ec.fieldContext_ComplianceFramework_rank(ctx, field) + case "visibility": + return ec.fieldContext_ComplianceFramework_visibility(ctx, field) + case "createdAt": + return ec.fieldContext_ComplianceFramework_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_ComplianceFramework_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceFramework", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _ContinualImprovement_id(ctx context.Context, field graphql.CollectedField, obj *types.ContinualImprovement) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -24230,6 +24916,41 @@ func (ec *executionContext) fieldContext_CreateAuditPayload_auditEdge(_ context. return fc, nil } +func (ec *executionContext) _CreateComplianceFrameworkPayload_complianceFrameworkEdge(ctx context.Context, field graphql.CollectedField, obj *types.CreateComplianceFrameworkPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CreateComplianceFrameworkPayload_complianceFrameworkEdge, + func(ctx context.Context) (any, error) { + return obj.ComplianceFrameworkEdge, nil + }, + nil, + ec.marshalNComplianceFrameworkEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFrameworkEdge, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CreateComplianceFrameworkPayload_complianceFrameworkEdge(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CreateComplianceFrameworkPayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cursor": + return ec.fieldContext_ComplianceFrameworkEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_ComplianceFrameworkEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceFrameworkEdge", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _CreateContinualImprovementPayload_continualImprovementEdge(ctx context.Context, field graphql.CollectedField, obj *types.CreateContinualImprovementPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -27735,6 +28456,35 @@ func (ec *executionContext) fieldContext_DeleteAuditReportPayload_audit(_ contex return fc, nil } +func (ec *executionContext) _DeleteComplianceFrameworkPayload_deletedComplianceFrameworkId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteComplianceFrameworkPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_DeleteComplianceFrameworkPayload_deletedComplianceFrameworkId, + func(ctx context.Context) (any, error) { + return obj.DeletedComplianceFrameworkID, nil + }, + nil, + ec.marshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_DeleteComplianceFrameworkPayload_deletedComplianceFrameworkId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeleteComplianceFrameworkPayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _DeleteContinualImprovementPayload_deletedContinualImprovementId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteContinualImprovementPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -28883,6 +29633,8 @@ func (ec *executionContext) fieldContext_DeleteTrustCenterNDAPayload_trustCenter return ec.fieldContext_TrustCenter_accesses(ctx, field) case "references": return ec.fieldContext_TrustCenter_references(ctx, field) + case "complianceFrameworks": + return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -35063,6 +35815,141 @@ func (ec *executionContext) fieldContext_Mutation_deleteTrustCenterReference(ctx return fc, nil } +func (ec *executionContext) _Mutation_createComplianceFramework(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Mutation_createComplianceFramework, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Mutation().CreateComplianceFramework(ctx, fc.Args["input"].(types.CreateComplianceFrameworkInput)) + }, + nil, + ec.marshalNCreateComplianceFrameworkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceFrameworkPayload, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Mutation_createComplianceFramework(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 "complianceFrameworkEdge": + return ec.fieldContext_CreateComplianceFrameworkPayload_complianceFrameworkEdge(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CreateComplianceFrameworkPayload", 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_createComplianceFramework_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_updateComplianceFramework(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Mutation_updateComplianceFramework, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Mutation().UpdateComplianceFramework(ctx, fc.Args["input"].(types.UpdateComplianceFrameworkInput)) + }, + nil, + ec.marshalNUpdateComplianceFrameworkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceFrameworkPayload, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Mutation_updateComplianceFramework(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 "complianceFramework": + return ec.fieldContext_UpdateComplianceFrameworkPayload_complianceFramework(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type UpdateComplianceFrameworkPayload", 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_updateComplianceFramework_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteComplianceFramework(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Mutation_deleteComplianceFramework, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Mutation().DeleteComplianceFramework(ctx, fc.Args["input"].(types.DeleteComplianceFrameworkInput)) + }, + nil, + ec.marshalNDeleteComplianceFrameworkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceFrameworkPayload, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Mutation_deleteComplianceFramework(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 "deletedComplianceFrameworkId": + return ec.fieldContext_DeleteComplianceFrameworkPayload_deletedComplianceFrameworkId(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type DeleteComplianceFrameworkPayload", 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_deleteComplianceFramework_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_createTrustCenterFile(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -43951,6 +44838,8 @@ func (ec *executionContext) fieldContext_Organization_trustCenter(_ context.Cont return ec.fieldContext_TrustCenter_accesses(ctx, field) case "references": return ec.fieldContext_TrustCenter_references(ctx, field) + case "complianceFrameworks": + return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -52171,6 +53060,53 @@ func (ec *executionContext) fieldContext_TrustCenter_references(ctx context.Cont return fc, nil } +func (ec *executionContext) _TrustCenter_complianceFrameworks(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_TrustCenter_complianceFrameworks, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.TrustCenter().ComplianceFrameworks(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.OrderBy[coredata.ComplianceFrameworkOrderField])) + }, + nil, + ec.marshalNComplianceFrameworkConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFrameworkConnection, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_TrustCenter_complianceFrameworks(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TrustCenter", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "edges": + return ec.fieldContext_ComplianceFrameworkConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_ComplianceFrameworkConnection_pageInfo(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceFrameworkConnection", 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_TrustCenter_complianceFrameworks_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _TrustCenter_permission(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -53342,6 +54278,8 @@ func (ec *executionContext) fieldContext_TrustCenterEdge_node(_ context.Context, return ec.fieldContext_TrustCenter_accesses(ctx, field) case "references": return ec.fieldContext_TrustCenter_references(ctx, field) + case "complianceFrameworks": + return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -54498,6 +55436,49 @@ func (ec *executionContext) fieldContext_UpdateAuditPayload_audit(_ context.Cont return fc, nil } +func (ec *executionContext) _UpdateComplianceFrameworkPayload_complianceFramework(ctx context.Context, field graphql.CollectedField, obj *types.UpdateComplianceFrameworkPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_UpdateComplianceFrameworkPayload_complianceFramework, + func(ctx context.Context) (any, error) { + return obj.ComplianceFramework, nil + }, + nil, + ec.marshalNComplianceFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFramework, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_UpdateComplianceFrameworkPayload_complianceFramework(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UpdateComplianceFrameworkPayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ComplianceFramework_id(ctx, field) + case "framework": + return ec.fieldContext_ComplianceFramework_framework(ctx, field) + case "rank": + return ec.fieldContext_ComplianceFramework_rank(ctx, field) + case "visibility": + return ec.fieldContext_ComplianceFramework_visibility(ctx, field) + case "createdAt": + return ec.fieldContext_ComplianceFramework_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_ComplianceFramework_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceFramework", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _UpdateContinualImprovementPayload_continualImprovement(ctx context.Context, field graphql.CollectedField, obj *types.UpdateContinualImprovementPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -55649,6 +56630,8 @@ func (ec *executionContext) fieldContext_UpdateTrustCenterBrandPayload_trustCent return ec.fieldContext_TrustCenter_accesses(ctx, field) case "references": return ec.fieldContext_TrustCenter_references(ctx, field) + case "complianceFrameworks": + return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -55753,6 +56736,8 @@ func (ec *executionContext) fieldContext_UpdateTrustCenterPayload_trustCenter(_ return ec.fieldContext_TrustCenter_accesses(ctx, field) case "references": return ec.fieldContext_TrustCenter_references(ctx, field) + case "complianceFrameworks": + return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -56291,6 +57276,8 @@ func (ec *executionContext) fieldContext_UploadTrustCenterNDAPayload_trustCenter return ec.fieldContext_TrustCenter_accesses(ctx, field) case "references": return ec.fieldContext_TrustCenter_references(ctx, field) + case "complianceFrameworks": + return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -63316,6 +64303,39 @@ func (ec *executionContext) unmarshalInputCancelSignatureRequestInput(ctx contex return it, nil } +func (ec *executionContext) unmarshalInputComplianceFrameworkOrder(ctx context.Context, obj any) (types.OrderBy[coredata.ComplianceFrameworkOrderField], error) { + var it types.OrderBy[coredata.ComplianceFrameworkOrderField] + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"direction", "field"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "direction": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("direction")) + data, err := ec.unmarshalNOrderDirection2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐOrderDirection(ctx, v) + if err != nil { + return it, err + } + it.Direction = data + case "field": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) + data, err := ec.unmarshalNComplianceFrameworkOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkOrderField(ctx, v) + if err != nil { + return it, err + } + it.Field = data + } + } + return it, nil +} + func (ec *executionContext) unmarshalInputContinualImprovementFilter(ctx context.Context, obj any) (types.ContinualImprovementFilter, error) { var it types.ContinualImprovementFilter asMap := map[string]any{} @@ -63617,6 +64637,39 @@ func (ec *executionContext) unmarshalInputCreateAuditInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputCreateComplianceFrameworkInput(ctx context.Context, obj any) (types.CreateComplianceFrameworkInput, error) { + var it types.CreateComplianceFrameworkInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"trustCenterId", "frameworkId"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "trustCenterId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("trustCenterId")) + data, err := ec.unmarshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.TrustCenterID = data + 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) unmarshalInputCreateContinualImprovementInput(ctx context.Context, obj any) (types.CreateContinualImprovementInput, error) { var it types.CreateContinualImprovementInput asMap := map[string]any{} @@ -65869,6 +66922,32 @@ func (ec *executionContext) unmarshalInputDeleteAuditReportInput(ctx context.Con return it, nil } +func (ec *executionContext) unmarshalInputDeleteComplianceFrameworkInput(ctx context.Context, obj any) (types.DeleteComplianceFrameworkInput, error) { + var it types.DeleteComplianceFrameworkInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.ID = data + } + } + return it, nil +} + func (ec *executionContext) unmarshalInputDeleteContinualImprovementInput(ctx context.Context, obj any) (types.DeleteContinualImprovementInput, error) { var it types.DeleteContinualImprovementInput asMap := map[string]any{} @@ -68601,6 +69680,39 @@ func (ec *executionContext) unmarshalInputUpdateAuditInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputUpdateComplianceFrameworkInput(ctx context.Context, obj any) (types.UpdateComplianceFrameworkInput, error) { + var it types.UpdateComplianceFrameworkInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id", "rank"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.ID = data + case "rank": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("rank")) + data, err := ec.unmarshalNInt2int(ctx, v) + if err != nil { + return it, err + } + it.Rank = data + } + } + return it, nil +} + func (ec *executionContext) unmarshalInputUpdateContinualImprovementInput(ctx context.Context, obj any) (types.UpdateContinualImprovementInput, error) { var it types.UpdateContinualImprovementInput asMap := map[string]any{} @@ -71267,6 +72379,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._ContinualImprovement(ctx, sel, obj) + case types.ComplianceFramework: + return ec._ComplianceFramework(ctx, sel, &obj) + case *types.ComplianceFramework: + if obj == nil { + return graphql.Null + } + return ec._ComplianceFramework(ctx, sel, obj) case types.Audit: return ec._Audit(ctx, sel, &obj) case *types.Audit: @@ -72569,6 +73688,189 @@ func (ec *executionContext) _CancelSignatureRequestPayload(ctx context.Context, return out } +var complianceFrameworkImplementors = []string{"ComplianceFramework", "Node"} + +func (ec *executionContext) _ComplianceFramework(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFramework) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkImplementors) + + 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("ComplianceFramework") + case "id": + out.Values[i] = ec._ComplianceFramework_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "framework": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._ComplianceFramework_framework(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "rank": + out.Values[i] = ec._ComplianceFramework_rank(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "visibility": + out.Values[i] = ec._ComplianceFramework_visibility(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "createdAt": + out.Values[i] = ec._ComplianceFramework_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "updatedAt": + out.Values[i] = ec._ComplianceFramework_updatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + 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 complianceFrameworkConnectionImplementors = []string{"ComplianceFrameworkConnection"} + +func (ec *executionContext) _ComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFrameworkConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkConnectionImplementors) + + 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("ComplianceFrameworkConnection") + case "edges": + out.Values[i] = ec._ComplianceFrameworkConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._ComplianceFrameworkConnection_pageInfo(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 complianceFrameworkEdgeImplementors = []string{"ComplianceFrameworkEdge"} + +func (ec *executionContext) _ComplianceFrameworkEdge(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFrameworkEdge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkEdgeImplementors) + + 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("ComplianceFrameworkEdge") + case "cursor": + out.Values[i] = ec._ComplianceFrameworkEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "node": + out.Values[i] = ec._ComplianceFrameworkEdge_node(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 continualImprovementImplementors = []string{"ContinualImprovement", "Node"} func (ec *executionContext) _ContinualImprovement(ctx context.Context, sel ast.SelectionSet, obj *types.ContinualImprovement) graphql.Marshaler { @@ -73575,6 +74877,45 @@ func (ec *executionContext) _CreateAuditPayload(ctx context.Context, sel ast.Sel return out } +var createComplianceFrameworkPayloadImplementors = []string{"CreateComplianceFrameworkPayload"} + +func (ec *executionContext) _CreateComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, obj *types.CreateComplianceFrameworkPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, createComplianceFrameworkPayloadImplementors) + + 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("CreateComplianceFrameworkPayload") + case "complianceFrameworkEdge": + out.Values[i] = ec._CreateComplianceFrameworkPayload_complianceFrameworkEdge(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 createContinualImprovementPayloadImplementors = []string{"CreateContinualImprovementPayload"} func (ec *executionContext) _CreateContinualImprovementPayload(ctx context.Context, sel ast.SelectionSet, obj *types.CreateContinualImprovementPayload) graphql.Marshaler { @@ -75927,6 +77268,45 @@ func (ec *executionContext) _DeleteAuditReportPayload(ctx context.Context, sel a return out } +var deleteComplianceFrameworkPayloadImplementors = []string{"DeleteComplianceFrameworkPayload"} + +func (ec *executionContext) _DeleteComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteComplianceFrameworkPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deleteComplianceFrameworkPayloadImplementors) + + 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("DeleteComplianceFrameworkPayload") + case "deletedComplianceFrameworkId": + out.Values[i] = ec._DeleteComplianceFrameworkPayload_deletedComplianceFrameworkId(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 deleteContinualImprovementPayloadImplementors = []string{"DeleteContinualImprovementPayload"} func (ec *executionContext) _DeleteContinualImprovementPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteContinualImprovementPayload) graphql.Marshaler { @@ -80726,6 +82106,27 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "createComplianceFramework": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createComplianceFramework(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "updateComplianceFramework": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updateComplianceFramework(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deleteComplianceFramework": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteComplianceFramework(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "createTrustCenterFile": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_createTrustCenterFile(ctx, field) @@ -87232,6 +88633,42 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "complianceFrameworks": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TrustCenter_complianceFrameworks(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) case "permission": field := field @@ -88658,6 +90095,45 @@ func (ec *executionContext) _UpdateAuditPayload(ctx context.Context, sel ast.Sel return out } +var updateComplianceFrameworkPayloadImplementors = []string{"UpdateComplianceFrameworkPayload"} + +func (ec *executionContext) _UpdateComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UpdateComplianceFrameworkPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, updateComplianceFrameworkPayloadImplementors) + + 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("UpdateComplianceFrameworkPayload") + case "complianceFramework": + out.Values[i] = ec._UpdateComplianceFrameworkPayload_complianceFramework(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 updateContinualImprovementPayloadImplementors = []string{"UpdateContinualImprovementPayload"} func (ec *executionContext) _UpdateContinualImprovementPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UpdateContinualImprovementPayload) graphql.Marshaler { @@ -93277,6 +94753,112 @@ func (ec *executionContext) marshalNCancelSignatureRequestPayload2ᚖgoᚗprobo return ec._CancelSignatureRequestPayload(ctx, sel, v) } +func (ec *executionContext) marshalNComplianceFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFramework(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFramework) 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._ComplianceFramework(ctx, sel, v) +} + +func (ec *executionContext) marshalNComplianceFrameworkConnection2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, v types.ComplianceFrameworkConnection) graphql.Marshaler { + return ec._ComplianceFrameworkConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNComplianceFrameworkConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFrameworkConnection) 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._ComplianceFrameworkConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNComplianceFrameworkEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFrameworkEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*types.ComplianceFrameworkEdge) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNComplianceFrameworkEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFrameworkEdge(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNComplianceFrameworkEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFrameworkEdge(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFrameworkEdge) 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._ComplianceFrameworkEdge(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNComplianceFrameworkOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkOrderField(ctx context.Context, v any) (coredata.ComplianceFrameworkOrderField, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNComplianceFrameworkOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkOrderField[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNComplianceFrameworkOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkOrderField(ctx context.Context, sel ast.SelectionSet, v coredata.ComplianceFrameworkOrderField) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(marshalNComplianceFrameworkOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkOrderField[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 ( + unmarshalNComplianceFrameworkOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkOrderField = map[string]coredata.ComplianceFrameworkOrderField{ + "CREATED_AT": coredata.ComplianceFrameworkOrderFieldCreatedAt, + "RANK": coredata.ComplianceFrameworkOrderFieldRank, + } + marshalNComplianceFrameworkOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkOrderField = map[coredata.ComplianceFrameworkOrderField]string{ + coredata.ComplianceFrameworkOrderFieldCreatedAt: "CREATED_AT", + coredata.ComplianceFrameworkOrderFieldRank: "RANK", + } +) + +func (ec *executionContext) unmarshalNComplianceFrameworkVisibility2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkVisibility(ctx context.Context, v any) (coredata.ComplianceFrameworkVisibility, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNComplianceFrameworkVisibility2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkVisibility[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNComplianceFrameworkVisibility2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkVisibility(ctx context.Context, sel ast.SelectionSet, v coredata.ComplianceFrameworkVisibility) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(marshalNComplianceFrameworkVisibility2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkVisibility[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 ( + unmarshalNComplianceFrameworkVisibility2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkVisibility = map[string]coredata.ComplianceFrameworkVisibility{ + "NONE": coredata.ComplianceFrameworkVisibilityNone, + "PUBLIC": coredata.ComplianceFrameworkVisibilityPublic, + } + marshalNComplianceFrameworkVisibility2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceFrameworkVisibility = map[coredata.ComplianceFrameworkVisibility]string{ + coredata.ComplianceFrameworkVisibilityNone: "NONE", + coredata.ComplianceFrameworkVisibilityPublic: "PUBLIC", + } +) + func (ec *executionContext) marshalNContinualImprovement2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐContinualImprovement(ctx context.Context, sel ast.SelectionSet, v *types.ContinualImprovement) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -94113,6 +95695,25 @@ func (ec *executionContext) marshalNCreateAuditPayload2ᚖgoᚗproboᚗincᚋpro return ec._CreateAuditPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNCreateComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceFrameworkInput(ctx context.Context, v any) (types.CreateComplianceFrameworkInput, error) { + res, err := ec.unmarshalInputCreateComplianceFrameworkInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNCreateComplianceFrameworkPayload2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, v types.CreateComplianceFrameworkPayload) graphql.Marshaler { + return ec._CreateComplianceFrameworkPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCreateComplianceFrameworkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, v *types.CreateComplianceFrameworkPayload) 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._CreateComplianceFrameworkPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNCreateContinualImprovementInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateContinualImprovementInput(ctx context.Context, v any) (types.CreateContinualImprovementInput, error) { res, err := ec.unmarshalInputCreateContinualImprovementInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -95144,6 +96745,25 @@ func (ec *executionContext) marshalNDeleteAuditReportPayload2ᚖgoᚗproboᚗinc return ec._DeleteAuditReportPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNDeleteComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceFrameworkInput(ctx context.Context, v any) (types.DeleteComplianceFrameworkInput, error) { + res, err := ec.unmarshalInputDeleteComplianceFrameworkInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDeleteComplianceFrameworkPayload2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, v types.DeleteComplianceFrameworkPayload) graphql.Marshaler { + return ec._DeleteComplianceFrameworkPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDeleteComplianceFrameworkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, v *types.DeleteComplianceFrameworkPayload) 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._DeleteComplianceFrameworkPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNDeleteContinualImprovementInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteContinualImprovementInput(ctx context.Context, v any) (types.DeleteContinualImprovementInput, error) { res, err := ec.unmarshalInputDeleteContinualImprovementInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -99222,6 +100842,25 @@ func (ec *executionContext) marshalNUpdateAuditPayload2ᚖgoᚗproboᚗincᚋpro return ec._UpdateAuditPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNUpdateComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceFrameworkInput(ctx context.Context, v any) (types.UpdateComplianceFrameworkInput, error) { + res, err := ec.unmarshalInputUpdateComplianceFrameworkInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNUpdateComplianceFrameworkPayload2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, v types.UpdateComplianceFrameworkPayload) graphql.Marshaler { + return ec._UpdateComplianceFrameworkPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNUpdateComplianceFrameworkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, v *types.UpdateComplianceFrameworkPayload) 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._UpdateComplianceFrameworkPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNUpdateContinualImprovementInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateContinualImprovementInput(ctx context.Context, v any) (types.UpdateContinualImprovementInput, error) { res, err := ec.unmarshalInputUpdateContinualImprovementInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -100940,6 +102579,14 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return res } +func (ec *executionContext) unmarshalOComplianceFrameworkOrder2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐOrderBy(ctx context.Context, v any) (*types.OrderBy[coredata.ComplianceFrameworkOrderField], error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputComplianceFrameworkOrder(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalOContinualImprovementFilter2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐContinualImprovementFilter(ctx context.Context, v any) (*types.ContinualImprovementFilter, error) { if v == nil { return nil, nil diff --git a/pkg/server/api/console/v1/types/compliance_framework.go b/pkg/server/api/console/v1/types/compliance_framework.go new file mode 100644 index 000000000..47f963259 --- /dev/null +++ b/pkg/server/api/console/v1/types/compliance_framework.go @@ -0,0 +1,76 @@ +// 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 types + +import ( + "time" + + "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/gid" + "go.probo.inc/probo/pkg/page" +) + +type ComplianceFrameworkOrderBy = OrderBy[coredata.ComplianceFrameworkOrderField] + +type ComplianceFramework struct { + ID gid.GID `json:"id"` + Framework *Framework `json:"framework"` + Rank int `json:"rank"` + Visibility coredata.ComplianceFrameworkVisibility `json:"visibility"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + FrameworkID gid.GID `json:"-"` +} + +func (ComplianceFramework) IsNode() {} +func (c ComplianceFramework) GetID() gid.GID { return c.ID } + +type ComplianceFrameworkConnection struct { + Edges []*ComplianceFrameworkEdge `json:"edges"` + PageInfo *PageInfo `json:"pageInfo"` +} + +func NewComplianceFramework(cf *coredata.ComplianceFramework) *ComplianceFramework { + return &ComplianceFramework{ + ID: cf.ID, + FrameworkID: cf.FrameworkID, + Rank: cf.Rank, + Visibility: cf.Visibility, + CreatedAt: cf.CreatedAt, + UpdatedAt: cf.UpdatedAt, + } +} + +func NewComplianceFrameworkConnection( + p *page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField], +) *ComplianceFrameworkConnection { + edges := make([]*ComplianceFrameworkEdge, len(p.Data)) + + for i := range edges { + edges[i] = NewComplianceFrameworkEdge(p.Data[i], p.Cursor.OrderBy.Field) + } + + return &ComplianceFrameworkConnection{ + Edges: edges, + PageInfo: NewPageInfo(p), + } +} + +func NewComplianceFrameworkEdge(cf *coredata.ComplianceFramework, orderBy coredata.ComplianceFrameworkOrderField) *ComplianceFrameworkEdge { + return &ComplianceFrameworkEdge{ + Cursor: cf.CursorKey(orderBy), + Node: NewComplianceFramework(cf), + } +} diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 02b6bc05f..2be555ec3 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -149,6 +149,11 @@ type CancelSignatureRequestPayload struct { DeletedDocumentVersionSignatureID gid.GID `json:"deletedDocumentVersionSignatureId"` } +type ComplianceFrameworkEdge struct { + Cursor page.CursorKey `json:"cursor"` + Node *ComplianceFramework `json:"node"` +} + type ContinualImprovement struct { ID gid.GID `json:"id"` SnapshotID *gid.GID `json:"snapshotId,omitempty"` @@ -250,6 +255,15 @@ type CreateAuditPayload struct { AuditEdge *AuditEdge `json:"auditEdge"` } +type CreateComplianceFrameworkInput struct { + TrustCenterID gid.GID `json:"trustCenterId"` + FrameworkID gid.GID `json:"frameworkId"` +} + +type CreateComplianceFrameworkPayload struct { + ComplianceFrameworkEdge *ComplianceFrameworkEdge `json:"complianceFrameworkEdge"` +} + type CreateContinualImprovementInput struct { OrganizationID gid.GID `json:"organizationId"` ReferenceID string `json:"referenceId"` @@ -789,6 +803,14 @@ type DeleteAuditReportPayload struct { Audit *Audit `json:"audit"` } +type DeleteComplianceFrameworkInput struct { + ID gid.GID `json:"id"` +} + +type DeleteComplianceFrameworkPayload struct { + DeletedComplianceFrameworkID gid.GID `json:"deletedComplianceFrameworkId"` +} + type DeleteContinualImprovementInput struct { ContinualImprovementID gid.GID `json:"continualImprovementId"` } @@ -1851,18 +1873,19 @@ type TransferImpactAssessmentFilter struct { } type TrustCenter struct { - ID gid.GID `json:"id"` - Active bool `json:"active"` - LogoFileURL *string `json:"logoFileUrl,omitempty"` - DarkLogoFileURL *string `json:"darkLogoFileUrl,omitempty"` - NdaFileName *string `json:"ndaFileName,omitempty"` - NdaFileURL *string `json:"ndaFileUrl,omitempty"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - Organization *Organization `json:"organization"` - Accesses *TrustCenterAccessConnection `json:"accesses"` - References *TrustCenterReferenceConnection `json:"references"` - Permission bool `json:"permission"` + ID gid.GID `json:"id"` + Active bool `json:"active"` + LogoFileURL *string `json:"logoFileUrl,omitempty"` + DarkLogoFileURL *string `json:"darkLogoFileUrl,omitempty"` + NdaFileName *string `json:"ndaFileName,omitempty"` + NdaFileURL *string `json:"ndaFileUrl,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + Organization *Organization `json:"organization"` + Accesses *TrustCenterAccessConnection `json:"accesses"` + References *TrustCenterReferenceConnection `json:"references"` + ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"` + Permission bool `json:"permission"` } func (TrustCenter) IsNode() {} @@ -1994,6 +2017,15 @@ type UpdateAuditPayload struct { Audit *Audit `json:"audit"` } +type UpdateComplianceFrameworkInput struct { + ID gid.GID `json:"id"` + Rank int `json:"rank"` +} + +type UpdateComplianceFrameworkPayload struct { + ComplianceFramework *ComplianceFramework `json:"complianceFramework"` +} + type UpdateContinualImprovementInput struct { ID gid.GID `json:"id"` ReferenceID *string `json:"referenceId,omitempty"` diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index b74fe53ed..5983719d3 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -324,6 +324,23 @@ func (r *auditConnectionResolver) TotalCount(ctx context.Context, obj *types.Aud return count, nil } +// Framework is the resolver for the framework field. +func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) { + if err := r.authorize(ctx, obj.FrameworkID, probo.ActionFrameworkGet); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, obj.FrameworkID.TenantID()) + + framework, err := prb.Frameworks.Get(ctx, obj.FrameworkID) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot load framework", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return types.NewFramework(framework), nil +} + // Organization is the resolver for the organization field. func (r *continualImprovementResolver) Organization(ctx context.Context, obj *types.ContinualImprovement) (*types.Organization, error) { if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil { @@ -2098,6 +2115,77 @@ func (r *mutationResolver) DeleteTrustCenterReference(ctx context.Context, input }, nil } +// CreateComplianceFramework is the resolver for the createComplianceFramework field. +func (r *mutationResolver) CreateComplianceFramework(ctx context.Context, input types.CreateComplianceFrameworkInput) (*types.CreateComplianceFrameworkPayload, error) { + if err := r.authorize(ctx, input.TrustCenterID, probo.ActionComplianceFrameworkCreate); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) + + cf, err := prb.ComplianceFrameworks.Create( + ctx, + &probo.CreateComplianceFrameworkRequest{ + TrustCenterID: input.TrustCenterID, + FrameworkID: input.FrameworkID, + }, + ) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot create compliance framework", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return &types.CreateComplianceFrameworkPayload{ + ComplianceFrameworkEdge: types.NewComplianceFrameworkEdge(cf, coredata.ComplianceFrameworkOrderFieldRank), + }, nil +} + +// UpdateComplianceFramework is the resolver for the updateComplianceFramework field. +func (r *mutationResolver) UpdateComplianceFramework(ctx context.Context, input types.UpdateComplianceFrameworkInput) (*types.UpdateComplianceFrameworkPayload, error) { + if err := r.authorize(ctx, input.ID, probo.ActionComplianceFrameworkUpdateRank); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, input.ID.TenantID()) + + cf, err := prb.ComplianceFrameworks.Update(ctx, &probo.UpdateComplianceFrameworkRequest{ + ID: input.ID, + Rank: input.Rank, + }) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot update compliance framework", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return &types.UpdateComplianceFrameworkPayload{ + ComplianceFramework: types.NewComplianceFramework(cf), + }, nil +} + +// DeleteComplianceFramework is the resolver for the deleteComplianceFramework field. +func (r *mutationResolver) DeleteComplianceFramework(ctx context.Context, input types.DeleteComplianceFrameworkInput) (*types.DeleteComplianceFrameworkPayload, error) { + if err := r.authorize(ctx, input.ID, probo.ActionComplianceFrameworkDelete); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, input.ID.TenantID()) + + err := prb.ComplianceFrameworks.Delete( + ctx, + &probo.DeleteComplianceFrameworkRequest{ + ID: input.ID, + }, + ) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot delete compliance framework", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return &types.DeleteComplianceFrameworkPayload{ + DeletedComplianceFrameworkID: input.ID, + }, nil +} + // CreateTrustCenterFile is the resolver for the createTrustCenterFile field. func (r *mutationResolver) CreateTrustCenterFile(ctx context.Context, input types.CreateTrustCenterFileInput) (*types.CreateTrustCenterFilePayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionTrustCenterFileCreate); err != nil { @@ -7814,6 +7902,36 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe return types.NewTrustCenterReferenceConnection(result, obj.ID), nil } +// ComplianceFrameworks is the resolver for the complianceFrameworks field. +func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceFrameworkOrderField]) (*types.ComplianceFrameworkConnection, error) { + if err := r.authorize(ctx, obj.ID, probo.ActionComplianceFrameworkList); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, obj.ID.TenantID()) + + pageOrderBy := page.OrderBy[coredata.ComplianceFrameworkOrderField]{ + Field: coredata.ComplianceFrameworkOrderFieldRank, + Direction: page.OrderDirectionAsc, + } + if orderBy != nil { + pageOrderBy = page.OrderBy[coredata.ComplianceFrameworkOrderField]{ + Field: orderBy.Field, + Direction: orderBy.Direction, + } + } + + cursor := types.NewCursor(first, after, last, before, pageOrderBy) + + result, err := prb.ComplianceFrameworks.ListWithHiddenForTrustCenterID(ctx, obj.ID, cursor) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot list compliance frameworks", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return types.NewComplianceFrameworkConnection(result), nil +} + // Permission is the resolver for the permission field. func (r *trustCenterResolver) Permission(ctx context.Context, obj *types.TrustCenter, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) @@ -8776,6 +8894,11 @@ func (r *Resolver) AuditConnection() schema.AuditConnectionResolver { return &auditConnectionResolver{r} } +// ComplianceFramework returns schema.ComplianceFrameworkResolver implementation. +func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver { + return &complianceFrameworkResolver{r} +} + // ContinualImprovement returns schema.ContinualImprovementResolver implementation. func (r *Resolver) ContinualImprovement() schema.ContinualImprovementResolver { return &continualImprovementResolver{r} @@ -9078,6 +9201,7 @@ type assetResolver struct{ *Resolver } type assetConnectionResolver struct{ *Resolver } type auditResolver struct{ *Resolver } type auditConnectionResolver struct{ *Resolver } +type complianceFrameworkResolver struct{ *Resolver } type continualImprovementResolver struct{ *Resolver } type continualImprovementConnectionResolver struct{ *Resolver } type controlResolver struct{ *Resolver } diff --git a/pkg/server/api/trust/v1/schema.graphql b/pkg/server/api/trust/v1/schema.graphql index cca3aa901..832b7f71c 100644 --- a/pkg/server/api/trust/v1/schema.graphql +++ b/pkg/server/api/trust/v1/schema.graphql @@ -107,6 +107,21 @@ type AuditEdge @nda { node: Audit! } +type ComplianceFramework implements Node { + id: ID! + framework: Framework! @goField(forceResolver: true) +} + +type ComplianceFrameworkConnection { + edges: [ComplianceFrameworkEdge!]! + pageInfo: PageInfo! +} + +type ComplianceFrameworkEdge { + cursor: CursorKey! + node: ComplianceFramework! +} + enum CountryCode @goModel(model: "go.probo.inc/probo/pkg/coredata.CountryCode") { AD @goEnum(value: "go.probo.inc/probo/pkg/coredata.CountryCodeAD") @@ -542,6 +557,13 @@ type TrustCenter implements Node { last: Int before: CursorKey ): TrustCenterFileConnection! @goField(forceResolver: true) + + complianceFrameworks( + first: Int + after: CursorKey + last: Int + before: CursorKey + ): ComplianceFrameworkConnection! @goField(forceResolver: true) } type TrustCenterAccess implements Node { diff --git a/pkg/server/api/trust/v1/schema/schema.go b/pkg/server/api/trust/v1/schema/schema.go index e5d76e497..9ef1d6049 100644 --- a/pkg/server/api/trust/v1/schema/schema.go +++ b/pkg/server/api/trust/v1/schema/schema.go @@ -37,6 +37,7 @@ type Config = graphql.Config[ResolverRoot, DirectiveRoot, ComplexityRoot] type ResolverRoot interface { Audit() AuditResolver + ComplianceFramework() ComplianceFrameworkResolver Document() DocumentResolver Framework() FrameworkResolver Mutation() MutationResolver @@ -77,6 +78,21 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + ComplianceFramework struct { + Framework func(childComplexity int) int + ID func(childComplexity int) int + } + + ComplianceFrameworkConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + } + + ComplianceFrameworkEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + Document struct { Access func(childComplexity int) int DocumentType func(childComplexity int) int @@ -216,6 +232,7 @@ type ComplexityRoot struct { TrustCenter struct { Active func(childComplexity int) int Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int + ComplianceFrameworks func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int DarkLogoFileURL func(childComplexity int) int Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int ID func(childComplexity int) int @@ -302,6 +319,9 @@ type AuditResolver interface { Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error) Report(ctx context.Context, obj *types.Audit) (*types.Report, error) } +type ComplianceFrameworkResolver interface { + Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) +} type DocumentResolver interface { IsUserAuthorized(ctx context.Context, obj *types.Document) (bool, error) Access(ctx context.Context, obj *types.Document) (*types.DocumentAccess, error) @@ -349,6 +369,7 @@ type TrustCenterResolver interface { Vendors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.VendorConnection, error) References(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.TrustCenterReferenceConnection, error) TrustCenterFiles(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.TrustCenterFileConnection, error) + ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceFrameworkConnection, error) } type TrustCenterFileResolver interface { IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error) @@ -433,6 +454,45 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.AuditEdge.Node(childComplexity), true + case "ComplianceFramework.framework": + if e.ComplexityRoot.ComplianceFramework.Framework == nil { + break + } + + return e.ComplexityRoot.ComplianceFramework.Framework(childComplexity), true + case "ComplianceFramework.id": + if e.ComplexityRoot.ComplianceFramework.ID == nil { + break + } + + return e.ComplexityRoot.ComplianceFramework.ID(childComplexity), true + + case "ComplianceFrameworkConnection.edges": + if e.ComplexityRoot.ComplianceFrameworkConnection.Edges == nil { + break + } + + return e.ComplexityRoot.ComplianceFrameworkConnection.Edges(childComplexity), true + case "ComplianceFrameworkConnection.pageInfo": + if e.ComplexityRoot.ComplianceFrameworkConnection.PageInfo == nil { + break + } + + return e.ComplexityRoot.ComplianceFrameworkConnection.PageInfo(childComplexity), true + + case "ComplianceFrameworkEdge.cursor": + if e.ComplexityRoot.ComplianceFrameworkEdge.Cursor == nil { + break + } + + return e.ComplexityRoot.ComplianceFrameworkEdge.Cursor(childComplexity), true + case "ComplianceFrameworkEdge.node": + if e.ComplexityRoot.ComplianceFrameworkEdge.Node == nil { + break + } + + return e.ComplexityRoot.ComplianceFrameworkEdge.Node(childComplexity), true + case "Document.access": if e.ComplexityRoot.Document.Access == nil { break @@ -948,6 +1008,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.TrustCenter.Audits(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true + case "TrustCenter.complianceFrameworks": + if e.ComplexityRoot.TrustCenter.ComplianceFrameworks == nil { + break + } + + args, err := ec.field_TrustCenter_complianceFrameworks_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.TrustCenter.ComplianceFrameworks(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true case "TrustCenter.darkLogoFileUrl": if e.ComplexityRoot.TrustCenter.DarkLogoFileURL == nil { break @@ -1458,6 +1529,21 @@ type AuditEdge @nda { node: Audit! } +type ComplianceFramework implements Node { + id: ID! + framework: Framework! @goField(forceResolver: true) +} + +type ComplianceFrameworkConnection { + edges: [ComplianceFrameworkEdge!]! + pageInfo: PageInfo! +} + +type ComplianceFrameworkEdge { + cursor: CursorKey! + node: ComplianceFramework! +} + enum CountryCode @goModel(model: "go.probo.inc/probo/pkg/coredata.CountryCode") { AD @goEnum(value: "go.probo.inc/probo/pkg/coredata.CountryCodeAD") @@ -1893,6 +1979,13 @@ type TrustCenter implements Node { last: Int before: CursorKey ): TrustCenterFileConnection! @goField(forceResolver: true) + + complianceFrameworks( + first: Int + after: CursorKey + last: Int + before: CursorKey + ): ComplianceFrameworkConnection! @goField(forceResolver: true) } type TrustCenterAccess implements Node { @@ -2396,6 +2489,32 @@ func (ec *executionContext) field_TrustCenter_audits_args(ctx context.Context, r return args, nil } +func (ec *executionContext) field_TrustCenter_complianceFrameworks_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, "first", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["first"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "after", ec.unmarshalOCursorKey2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey) + if err != nil { + return nil, err + } + args["after"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "last", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["last"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "before", ec.unmarshalOCursorKey2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey) + if err != nil { + return nil, err + } + args["before"] = arg3 + return args, nil +} + func (ec *executionContext) field_TrustCenter_documents_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -2929,6 +3048,212 @@ func (ec *executionContext) fieldContext_AuditEdge_node(_ context.Context, field return fc, nil } +func (ec *executionContext) _ComplianceFramework_id(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFramework_id, + func(ctx context.Context) (any, error) { + return obj.ID, nil + }, + nil, + ec.marshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFramework_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFramework", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFramework_framework(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFramework_framework, + func(ctx context.Context) (any, error) { + return ec.Resolvers.ComplianceFramework().Framework(ctx, obj) + }, + nil, + ec.marshalNFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐFramework, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFramework_framework(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFramework", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Framework_id(ctx, field) + case "name": + return ec.fieldContext_Framework_name(ctx, field) + case "lightLogoURL": + return ec.fieldContext_Framework_lightLogoURL(ctx, field) + case "darkLogoURL": + return ec.fieldContext_Framework_darkLogoURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Framework", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFrameworkConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFrameworkConnection_edges, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + ec.marshalNComplianceFrameworkEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkEdgeᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFrameworkConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFrameworkConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cursor": + return ec.fieldContext_ComplianceFrameworkEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_ComplianceFrameworkEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceFrameworkEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFrameworkConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFrameworkConnection_pageInfo, + func(ctx context.Context) (any, error) { + return obj.PageInfo, nil + }, + nil, + ec.marshalNPageInfo2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐPageInfo, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFrameworkConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFrameworkConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hasNextPage": + return ec.fieldContext_PageInfo_hasNextPage(ctx, field) + case "hasPreviousPage": + return ec.fieldContext_PageInfo_hasPreviousPage(ctx, field) + case "startCursor": + return ec.fieldContext_PageInfo_startCursor(ctx, field) + case "endCursor": + return ec.fieldContext_PageInfo_endCursor(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PageInfo", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFrameworkEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFrameworkEdge_cursor, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + ec.marshalNCursorKey2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFrameworkEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFrameworkEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type CursorKey does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceFrameworkEdge_node(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceFrameworkEdge_node, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + ec.marshalNComplianceFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFramework, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceFrameworkEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceFrameworkEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ComplianceFramework_id(ctx, field) + case "framework": + return ec.fieldContext_ComplianceFramework_framework(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceFramework", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _Document_id(ctx context.Context, field graphql.CollectedField, obj *types.Document) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -5203,6 +5528,8 @@ func (ec *executionContext) fieldContext_Query_currentTrustCenter(_ context.Cont return ec.fieldContext_TrustCenter_references(ctx, field) case "trustCenterFiles": return ec.fieldContext_TrustCenter_trustCenterFiles(ctx, field) + case "complianceFrameworks": + return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type TrustCenter", field.Name) }, @@ -6228,6 +6555,53 @@ func (ec *executionContext) fieldContext_TrustCenter_trustCenterFiles(ctx contex return fc, nil } +func (ec *executionContext) _TrustCenter_complianceFrameworks(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_TrustCenter_complianceFrameworks, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.TrustCenter().ComplianceFrameworks(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey)) + }, + nil, + ec.marshalNComplianceFrameworkConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkConnection, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_TrustCenter_complianceFrameworks(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TrustCenter", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "edges": + return ec.fieldContext_ComplianceFrameworkConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_ComplianceFrameworkConnection_pageInfo(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceFrameworkConnection", 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_TrustCenter_complianceFrameworks_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _TrustCenterAccess_id(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenterAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -9263,6 +9637,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._Document(ctx, sel, obj) + case types.ComplianceFramework: + return ec._ComplianceFramework(ctx, sel, &obj) + case *types.ComplianceFramework: + if obj == nil { + return graphql.Null + } + return ec._ComplianceFramework(ctx, sel, obj) case types.Audit: return ec._Audit(ctx, sel, &obj) case *types.Audit: @@ -9520,6 +9901,169 @@ func (ec *executionContext) _AuditEdge(ctx context.Context, sel ast.SelectionSet return out } +var complianceFrameworkImplementors = []string{"ComplianceFramework", "Node"} + +func (ec *executionContext) _ComplianceFramework(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFramework) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkImplementors) + + 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("ComplianceFramework") + case "id": + out.Values[i] = ec._ComplianceFramework_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "framework": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._ComplianceFramework_framework(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + 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 complianceFrameworkConnectionImplementors = []string{"ComplianceFrameworkConnection"} + +func (ec *executionContext) _ComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFrameworkConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkConnectionImplementors) + + 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("ComplianceFrameworkConnection") + case "edges": + out.Values[i] = ec._ComplianceFrameworkConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._ComplianceFrameworkConnection_pageInfo(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 complianceFrameworkEdgeImplementors = []string{"ComplianceFrameworkEdge"} + +func (ec *executionContext) _ComplianceFrameworkEdge(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFrameworkEdge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkEdgeImplementors) + + 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("ComplianceFrameworkEdge") + case "cursor": + out.Values[i] = ec._ComplianceFrameworkEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "node": + out.Values[i] = ec._ComplianceFrameworkEdge_node(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 documentImplementors = []string{"Document", "Node"} func (ec *executionContext) _Document(ctx context.Context, sel ast.SelectionSet, obj *types.Document) graphql.Marshaler { @@ -11265,6 +11809,42 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "complianceFrameworks": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TrustCenter_complianceFrameworks(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -12355,6 +12935,56 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } +func (ec *executionContext) marshalNComplianceFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFramework(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFramework) 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._ComplianceFramework(ctx, sel, v) +} + +func (ec *executionContext) marshalNComplianceFrameworkConnection2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, v types.ComplianceFrameworkConnection) graphql.Marshaler { + return ec._ComplianceFrameworkConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNComplianceFrameworkConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFrameworkConnection) 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._ComplianceFrameworkConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNComplianceFrameworkEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*types.ComplianceFrameworkEdge) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNComplianceFrameworkEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkEdge(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNComplianceFrameworkEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkEdge(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFrameworkEdge) 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._ComplianceFrameworkEdge(ctx, sel, v) +} + 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] diff --git a/pkg/server/api/trust/v1/types/framework.go b/pkg/server/api/trust/v1/types/framework.go index a8619373e..146e0a5c6 100644 --- a/pkg/server/api/trust/v1/types/framework.go +++ b/pkg/server/api/trust/v1/types/framework.go @@ -16,6 +16,7 @@ package types import ( "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/page" ) func NewFramework(f *coredata.Framework) *Framework { @@ -24,3 +25,31 @@ func NewFramework(f *coredata.Framework) *Framework { Name: f.Name, } } + +func NewComplianceFramework(cf *coredata.ComplianceFramework) *ComplianceFramework { + return &ComplianceFramework{ + ID: cf.ID, + FrameworkID: cf.FrameworkID, + } +} + +func NewComplianceFrameworkEdge(cf *coredata.ComplianceFramework) *ComplianceFrameworkEdge { + return &ComplianceFrameworkEdge{ + Cursor: cf.CursorKey(coredata.ComplianceFrameworkOrderFieldRank), + Node: NewComplianceFramework(cf), + } +} + +func NewComplianceFrameworkConnection( + p *page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField], +) *ComplianceFrameworkConnection { + edges := make([]*ComplianceFrameworkEdge, len(p.Data)) + for i, cf := range p.Data { + edges[i] = NewComplianceFrameworkEdge(cf) + } + + return &ComplianceFrameworkConnection{ + Edges: edges, + PageInfo: NewPageInfo(p), + } +} diff --git a/pkg/server/api/trust/v1/types/types.go b/pkg/server/api/trust/v1/types/types.go index ebf26698b..d5f594b22 100644 --- a/pkg/server/api/trust/v1/types/types.go +++ b/pkg/server/api/trust/v1/types/types.go @@ -45,6 +45,26 @@ type AuditEdge struct { Node *Audit `json:"node"` } +type ComplianceFramework struct { + ID gid.GID `json:"id"` + // FrameworkID is a non-schema field used by the Framework resolver to avoid an extra DB lookup. + FrameworkID gid.GID `json:"-"` + Framework *Framework `json:"framework"` +} + +func (ComplianceFramework) IsNode() {} +func (this ComplianceFramework) GetID() gid.GID { return this.ID } + +type ComplianceFrameworkConnection struct { + Edges []*ComplianceFrameworkEdge `json:"edges"` + PageInfo *PageInfo `json:"pageInfo"` +} + +type ComplianceFrameworkEdge struct { + Cursor page.CursorKey `json:"cursor"` + Node *ComplianceFramework `json:"node"` +} + type Document struct { ID gid.GID `json:"id"` Title string `json:"title"` @@ -235,6 +255,7 @@ type TrustCenter struct { Vendors *VendorConnection `json:"vendors"` References *TrustCenterReferenceConnection `json:"references"` TrustCenterFiles *TrustCenterFileConnection `json:"trustCenterFiles"` + ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"` } func (TrustCenter) IsNode() {} diff --git a/pkg/server/api/trust/v1/v1_resolver.go b/pkg/server/api/trust/v1/v1_resolver.go index 993fb6440..aa5f5db29 100644 --- a/pkg/server/api/trust/v1/v1_resolver.go +++ b/pkg/server/api/trust/v1/v1_resolver.go @@ -71,6 +71,19 @@ func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Re return types.NewReport(report), nil } +// Framework is the resolver for the framework field on ComplianceFramework. +func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) { + trustService := r.TrustService(ctx, obj.ID.TenantID()) + + framework, err := trustService.Frameworks.Get(ctx, obj.FrameworkID) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot load framework", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return types.NewFramework(framework), nil +} + // IsUserAuthorized is the resolver for the isUserAuthorized field. func (r *documentResolver) IsUserAuthorized(ctx context.Context, obj *types.Document) (bool, error) { trustService := r.TrustService(ctx, obj.ID.TenantID()) @@ -1014,6 +1027,25 @@ func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.T return types.NewTrustCenterFileConnection(trustCenterFilePage), nil } +// ComplianceFrameworks is the resolver for the complianceFrameworks field. +func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceFrameworkConnection, error) { + trustService := r.TrustService(ctx, obj.ID.TenantID()) + + pageOrderBy := page.OrderBy[coredata.ComplianceFrameworkOrderField]{ + Field: coredata.ComplianceFrameworkOrderFieldRank, + Direction: page.OrderDirectionAsc, + } + cursor := types.NewCursor(first, after, last, before, pageOrderBy) + + cfPage, err := trustService.ComplianceFrameworks.ListByTrustCenterID(ctx, obj.ID, cursor) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot list compliance frameworks", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return types.NewComplianceFrameworkConnection(cfPage), nil +} + // IsUserAuthorized is the resolver for the isUserAuthorized field. func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error) { trustService := r.TrustService(ctx, obj.ID.TenantID()) @@ -1124,6 +1156,11 @@ func (r *vendorConnectionResolver) TotalCount(ctx context.Context, obj *types.Ve // Audit returns schema.AuditResolver implementation. func (r *Resolver) Audit() schema.AuditResolver { return &auditResolver{r} } +// ComplianceFramework returns schema.ComplianceFrameworkResolver implementation. +func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver { + return &complianceFrameworkResolver{r} +} + // Document returns schema.DocumentResolver implementation. func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} } @@ -1166,6 +1203,7 @@ func (r *Resolver) VendorConnection() schema.VendorConnectionResolver { } type auditResolver struct{ *Resolver } +type complianceFrameworkResolver struct{ *Resolver } type documentResolver struct{ *Resolver } type frameworkResolver struct{ *Resolver } type mutationResolver struct{ *Resolver } diff --git a/pkg/trust/compliance_framework_service.go b/pkg/trust/compliance_framework_service.go new file mode 100644 index 000000000..4dbba1c88 --- /dev/null +++ b/pkg/trust/compliance_framework_service.go @@ -0,0 +1,55 @@ +// 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 trust + +import ( + "context" + "fmt" + + "go.gearno.de/kit/pg" + "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/gid" + "go.probo.inc/probo/pkg/page" +) + +type ComplianceFrameworkService struct { + svc *TenantService +} + +func (s ComplianceFrameworkService) ListByTrustCenterID( + ctx context.Context, + trustCenterID gid.GID, + cursor *page.Cursor[coredata.ComplianceFrameworkOrderField], +) (*page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField], error) { + var complianceFrameworks coredata.ComplianceFrameworks + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + err := complianceFrameworks.LoadByTrustCenterID(ctx, conn, s.svc.scope, trustCenterID, cursor) + if err != nil { + return fmt.Errorf("cannot load compliance frameworks: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return page.NewPage(complianceFrameworks, cursor), nil +} diff --git a/pkg/trust/service.go b/pkg/trust/service.go index 7fca56b6d..c48e9706f 100644 --- a/pkg/trust/service.go +++ b/pkg/trust/service.go @@ -70,6 +70,7 @@ type ( Audits *AuditService Vendors *VendorService Frameworks *FrameworkService + ComplianceFrameworks *ComplianceFrameworkService TrustCenterAccesses *TrustCenterAccessService TrustCenterReferences *TrustCenterReferenceService TrustCenterFiles *TrustCenterFileService @@ -130,6 +131,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService { tenantService.Audits = &AuditService{svc: tenantService} tenantService.Vendors = &VendorService{svc: tenantService} tenantService.Frameworks = &FrameworkService{svc: tenantService} + tenantService.ComplianceFrameworks = &ComplianceFrameworkService{svc: tenantService} tenantService.TrustCenterAccesses = &TrustCenterAccessService{svc: tenantService, iamSvc: s.iam, logger: s.logger} tenantService.TrustCenterReferences = &TrustCenterReferenceService{svc: tenantService} tenantService.TrustCenterFiles = &TrustCenterFileService{svc: tenantService}